关于架构模式:朴素系统优化思维的实践

作者:京东物流 严孝男一、问题去年年中时候,我有个好敌人(能够叫他华哥)顶着过后还很重大的疫情模式激情守业,斥巨资承包了他原公司食堂的几个摊位,摇身一变成了老板。当了老板的华哥没有丝毫懈怠,岂但做了短缺的市场调研,还联合他本人以前就餐时的痛点做了翻新,比方以前食堂除了最惯例的面,饺子,米线一类的之外就是一份份的卖炒菜,差不多一份荤菜十几块,一份素菜近十块的样子,这就导致一个问题,个别男生花了几十块钱也就只能吃到2-3个菜,岂但养分不够丰盛,万一踩坑遇到了本来抱有很高期待但发现理论菜并不好吃的状况,体验就更差了。 所以华哥借鉴了市面上麻辣烫自选称重模式的特点推出了自助选菜称重的模式,餐台上会摆放很多种做好的菜(荤素凉都有),大家依据本人的爱好本人打菜,主食的米饭和馒头收费,粥和汤也收费,而后还提供一些免费的主食比方红薯,玉米一类的,打菜的流程就是大家从台子两边按程序开始自选打菜,而后抉择主食,而后抉择汤粥,而后结账刷卡,如下图所示: 华哥不愧是前互联网大厂的金牌产品经理,其敏锐的抓住了用户的痛点,并很好的给出了相应的解决方案,自助称重模式自从推出后就受到了共事们的热烈欢迎,每次都排了长长的队伍,甚至中午11点半开餐,不到11点20就有很多共事在排队等着,写到这里我想举个排长队的例子给大家一个直观的印象,我最开始想到的例子是五道口那个枣糕店门口排的长队,起初一想当初京东2号楼B座4楼餐厅里排瓦罐的队伍如同更贴切。 华哥开始的时候十分开心,但一个月后做了营开盘点发现有点不对,尽管看上去队伍排得很长很火爆的样子,但实际上营收并不如预期。华哥剖析了一下排除了客单价低的因素,自选模式下好多菜大家看到后都想来一点,一来二去就会打好大一盘,根本都是20元起步的客单价;而后就剩下单量低这个可能性了,理论剖析一下就能够发现,因为菜的可选种类很多,所以选菜环节每个人须要花很长的工夫选菜,再加上须要打汤和打饭,一个人理论实现整个取餐的过程耗时是很长的,尽管前面的共事能够跟在后面共事前面串行打菜,但因为每个人的爱好不一样,所以每个人在不同菜前的停留时间不一样,这就导致当后面的共事在某个菜盘前耗时稍长的时候,前面的共事是处于期待状态的。 而且有的时候还会遇到一些极其的状况,比方有些共事会在某些他爱吃的菜前停留很久挑挑拣拣,还有些共事会在打收费汤时拿着大勺顺逆时针交替着疯狂搅动,以此希图捞起汤里那些零散的沉底的菜叶和鸡蛋白,华哥就亲眼目睹了他以前汇报的经理在辣子鸡丁菜盆里翻来覆去的寻找隐匿在辣椒深处的那一点点鸡肉,每发现一块鸡肉时经理的脸上还会露出那种称心如意充斥成就感的笑容,话说回来其实在经理挑鸡肉时整个队伍理论是处于齐全停滞状态的,所以综合来看整个队伍的执行就餐过程是十分迟缓的,也就导致理论打完餐付费的人数并不如设想中多。 二、计划起初在一次好友团聚时,华哥和我聊起了这个事件,他问我:你们搞技术的不都各种吹牛什么系统优化,降本增效一类的吗,你帮我想想方法。听完华哥这略带寻衅象征的要求,我忽然感觉本人身上有了很重的责任感,感觉本人要守住技术人的尊严。于是本人好好想了想,而后感觉这个商业问题实际上也能够看成一个技术问题,这个餐台能够看成一个零碎,打餐的流程能够认为是零碎的一次交互流程,每个打菜的共事能够看成是一次调用,因为每次调用执行起来的性能太差,导致系统整体的吞吐量太低,影响了整体零碎的效力,因而整个零碎的效力很低,尽管过后曾经是酒过三巡,脑子不太苏醒了,然而本人还是尽力给华哥想了好几个方法。 2.1 零碎扩容第一个想到的方法就是扩容,在工程技术畛域当遇到零碎性能不达标时,第一个想到的解决方案也个别都是扩容,工程畛域里的扩容个别能够分垂直扩容和程度扩容两种形式:垂直扩容是通过晋升单体实例的硬件能力来晋升单体解决能力,程度扩容则是通过减少实例节点的形式来减少整个零碎的解决能力。 套用这两个实践,看看怎么晋升餐台的吞吐,如同垂直扩容这块能做的不多,总不能把打饭的勺子降级一下变成德国原装进口低温武火蹴练镀金勺吧;不过尽管垂直扩容没什么好方法, 然而程度扩容如同能做的事件很多了,只有多减少几套打菜餐台,这样并行执行的2条打饭队伍就能够变成4条,甚至8条,间接实现了多线程并发,这样零碎整体的吞吐能力能够立马取得翻倍式晋升,成果岂但奏效块,成果也堪称是空谷传声,于是我给画了一个程度扩容示意图,如下图所示: 不过程度扩容的计划很快就被华哥否了,尽管在工程技术畛域,随着云原生技术的成熟,利用级别的扩容缩容都是很成熟的晋升零碎解决能力的解决方案了,然而在华哥这里,想再搭一个餐台是不可能的,且不说华哥承包的摊位没有这么大的中央去搞第二个餐台,就算有,从新施工装修,水电革新一系列的老本也简直是不可能实现的。 尽管这个世界上能用钱解决的问题都不叫问题,但当初的问题是华哥没钱了。 2.2 单次执行优化晋升零碎并发能力的路走不通后,那么晋升零碎的吞吐量的方法就是缩短单条申请的解决执行工夫,这样单位工夫内零碎解决的申请条数就会有晋升,从而晋升零碎吞吐量,那回到餐台这里,就变成了须要缩短单人打餐的工夫,尤其是遇到华哥前经理那种在单个菜盘前会消耗大量工夫的状况该如何优化呢? 咱们拆分一下每次调用,把在每个菜盘前打菜的过程能够模仿了解为执行一段逻辑,这样全副的打菜过程能够被拆解成一个个小的代码块,总的调用工夫是由这些代码块的执行工夫之和决定的,从工程技术视角的话就是保障每段逻辑都在一个可预期的工夫内实现,所以每段逻辑都能够通过一个超时判断逻辑来管制每段代码的执行工夫,这里举一个百度搜寻的例子,百度为了加强返回后果的多样性,推出了阿拉丁架构,每个query通过星图模型解析后会分发给不同的垂类,每个垂类会加工生产属于本人业务畛域的卡片,而后阿拉丁的root利用聚合垂类返回的各个后果并返回给用户,那某些垂类场景执行会比较慢,比方当遇到用户搜一款药的场景时,衰弱垂类的利用会依据搜寻人的经纬度筛选左近的o2o的药店,并计算该药品在该门店的促销折扣价,这种计算往往会耗时很久,所以root利用会减少一个380ms的超时判断,对所有的垂类利用都是一样,当你返回的内容超过这个工夫后后果会被抛弃,举这个例子让大家能够明确通过减少对每个环节的超时设置,这样能够保障整体的流程在一个可控的工夫范畴内失去执行,从而保障用户体验的一致性。 程序里的超时好加,因为程序没有喜怒哀乐,但打餐的场景不一样,总不能在每个菜前面安顿一个服务员在背地数123计时,超过5s往前推他一把,总不能这样吧,究其原因就是打菜是主观能动的,他想在一个菜前停多久就停多久,想到这个问题后,我有了主见,把用户自主停留的权力给剥夺,发明对立的停留时间,所以我给华哥设计了一套超时安装,那就是在餐台的两边各减少一套主动传送安装,相似于飞机场里安检后赶去航站楼的传送带一样,这样人们在两边打菜时不须要本人走动了,而且每个人在每个菜盘前停留时间是一样的,就不会呈现一个人在某个菜前停留时间过久的问题,也防止了餐台因后面某个人的长时间停留而呈现整体停滞的问题,晋升了餐台的吞吐量,而且传送带的减少还有个益处就是人不多时能够开得很慢甚至停掉,在高峰期时能够适当减少传送带的速度,从而管制每一个人打菜的工夫,保障整个餐台的吞吐率。 华哥听到我这个有点蠢才的想法后愣了很久,盘算了一下可能性后他感觉这个方法还真的可行,只是须要等到十一或者五一长假期间动工在两边减少传送带,终于听到一个可行计划的华哥有点兴奋,两腮也泛出了点点的红晕。 2.3 非核心流程剔除看到华哥接收了我的这个计划,我登时感触到了很大的激励,于是又持续思考这块流程还能怎么优化,在工程技术畛域,一个流程在接受很大流量时还能够做的一个事件就是流程简化,只保留外围的流程环节,也就是大家常说的黄金流程,而将非核心的业务节点从主流程中剔除,这样精简后的主流程能够肯定水平上缩短执行工夫,而且主流程执行的逻辑少了,出错的概率也同时就升高了,举一个京东批发的下单计算流程为例,批发侧结算时须要做以下的事件: 实际上结算这块还有很多的非次要节点要解决,比方删除购物车中相干已结算商品,预占自提柜等等,然而这些属于非核心的流程,能够从主流程中剔掉。 回到餐台这里,什么流程是黄金流程,没错,就是那些和营收间接相干的流程,而那些不产生收益的我的项目,比方米饭馒头,汤粥的环节就能够认为是非次要流程,能够从主流程中剔掉,这样一直简化了大家取餐的主流程,而且还节俭了餐厅的空间,残余的空间能够用来做几件事,一个是能够多放一些免费的主食或者减少一些菜品,以此能够增加收入,第二个能够减少一些自助收银设施,之前2个收银台在之前打餐比较慢时能够满足需要,但当初整个流程简化了,整体每个人的打餐速度晋升了,这样2个收银台就会变成新的瓶颈,尤其是遇到有扫码直付的同学就会瓶颈的更显著,这样通过减少收银台的数量,从而晋升了收银环节的并发解决能力,保障了整个取餐流程的晦涩,防止新的性能瓶颈的呈现,完满! 华哥听完这个倡议很称心,他正嫌餐台太小摆放的菜系不够多呢,这样空间被更正当的利用到能带来收益的食品上了,正合华哥之意,华哥很开心的敬了我一个。 2.4 分布式缓存除此之外,互联网减少零碎吞吐能力,缩短单次执行工夫的一个很次要的法宝利器就是利用分布式缓存技术,分布式缓存技术能够让很多存在零碎瓶颈的调用通过缩短数据获取工夫从而极大缩短解决工夫,在这里分布式缓存技术是不是也能够利用到餐台这里呢。 我想了一下,后面从主流程中拿掉的收费主食局部和汤粥局部能够利用缓存的原理,尤其是CDN缓存的原理,把主食和汤粥分布式的放在离共事们就餐的餐桌左近,这样能够让就餐的共事们最近范畴就能够盛到主食和汤粥,外表上看对营收没晋升,但实际上一是大家打饭近了,就餐体验好了,二是大家打饭加饭不便了,就餐的工夫就会升高,从而晋升餐桌的利用率。保障下一个打到饭的共事能疾速找到座位,体验同样也会晋升。这里我就不画图了,置信大家都能明确。 三、后记华哥整体听完我的优化计划后抬头陷入了深思,许久之后他抬起头看着我,眼神有些许迷离,我登时有点缓和,认为他要零碎点评一下我的计划,没想到华哥闭口问我的是,当初几点了,我才意识到华哥方才是喝多了抬头睡着了。

March 21, 2023 · 1 min · jiezi

关于架构模式:互动玩法任务平台介绍

作者:京东科技 雷自海 一、概述工作平台是科技内各业务方发展互动玩法的中心化平台,撑持科技内拉新、促活、交易等业务场景,蕴含根底工作、基于工作的通用流动玩法和业务投放能力。提供了工作玩法的创立、投放、曝光、实现等全生命周期的精细化治理,打造了基于工作的裂变、时间轴等通用流动玩法的规则化经营,致力于晋升在多场景、多玩法、多频次的业务投放能力。工作核心次要战场是金融APP,目前日均500W的实现量,月UV100W,大促期间日实现量达2000W。 整体架构图如下: 工作日常投放有小金库、白条、保险、签到、养猪猪、权利核心等,并在大促、年货节等有重要流量入口,如图所示: 二、工作玩法工作玩法是最根本的流动玩法。APP中的每个投放位在工作玩法零碎中被定义为渠道,经营能够配置多个工作在某个渠道,也能够将本人的工作投放到其余渠道中,以增大流量。根底工作分为工作查问、工作接取、工作实现、领奖四个步骤,其中工作接取又分为手动接取、主动接取,领奖也分为手动支付、主动支付。 从操作上能够分为经营端、C端,经营保护工作及工作投放,C端接取工作、实现工作、支付处分。C端整体流程上分成二个局部,用户操作层和后端业务层。工作核心提供前端插件提供根本工作性能,业务零碎也能够自建用户页面。后端业务层方面,C端页面能够间接调用工作核心提供网关接口,业务零碎也能够通过JSF调用工作核心。 1、工作玩法配置工作核心提供工作玩法的场景化配置,目前反对根底工作、跳转工作、流量工作、全场景工作、交易工作、内部工作,目前工作反对人群、防重、库存等多维度的策略。工作核心为经营提供弱小配置性能的同时,还从场景化、在线验证、预上线验证等计划解决经营配置谬误等问题。 工作惯例配置如图: (1)根底工作是惯例的工作玩法,经营须要配置工作实现的地址。工作曝光时,C端用户点击去实现时,会跳转到工作实现地址,该类型工作须要配置工作实现策略,不便工作核心拦挡用户行为,从而实现工作。 (2)浏览工作提供倒计时插件,业务零碎能够应用工作提供的插件来疾速实现本人的业务性能,该工作不须要配置实现策略。 工作倒计时插件如图: (3)跳转工作是的含意是,C端用户跳转到指定指标页后即实现工作,该工作不须要配置实现策略,目前工作核心反对H5、原生页面、RN跳转等,微信小程序等非凡场景的跳转也在继续建设中。 (4)基金交易工作反对多策略模式,次要用在随时调整实现策略的场景。在多策略模式下,最初失效的策略默认为主策略,C端用户接取工作时会绑定主策略,并依照主策略判断工作是否实现。该场景下随时批改策不影响曾经接取工作的C端用户。 (5)全场景工作是无需接取的工作,该工作没有投放、曝光场景,经营只须要配置实现策略即可,该工作在实现时会主动接取工作。 (6)内部换量工作次要利用和内部公司流量调换的场景,针对新业务的对接形式会有肯定的开发联调环节,目前反对掌阅APP的换量。 2、工作的投放及实现目前工作次要场景是金融APP,目前根本笼罩了整个金融APP的业务场景,并在大促、重大流动场景下提提供外围入口,工作投放、实现、领奖的示意图如下: 3、工作零碎对接工作核心提供了丰盛的JSF接口、网关接口、前端组件、MQ音讯,用来不便业务方疾速接入。 如图所示 三、裂变玩法1、术语和缩略语名词介绍MGMmember get member,会员拉会员,老(M1)带新(M2)M1(发起人)老(M1)用户:指间接从流动资源位进入到裂变流动页面的用户(无邀请人)M2(受邀人)新(M2)用户:指通过M1邀请进入到裂变流动页面的用户(有邀请人)裂变工作规定用户邀请流程:【XX条件用户】邀请【XX条件用户】实现【XX工作】,M1 得【XX处分】,M2 得 【XX处分】;【】内为变量2、性能介绍裂变获客,是以微信生态和京东金融APP场作为承接客户的载体,进行获客引流。通过相干权利进行吸引用户,让M1发起人扫码分享海报,再邀请若干好友实现设置的指定工作(答题、购买基金、股票开户等),M1取得拉新处分,M2受邀人实现工作也可取得处分。 3、裂变能力阐明与配置介绍裂变能力介绍1.M1邀请M2能力,关系绑定 2.查问M1邀请列表能力,用于展现 3.获取M1的邀请码 4.查问M1跑马灯数据 5.M2实现工作(一般、浏览、跳转)并取得处分,满足M1的发奖规定后M1也取得处分 裂变限度类型1.绑定关系人数限度 2.邀请M2实现工作限度 3.绑定限度(单帮定和最新绑定) 4.助力限度 5.人群 6.邀请有效期 配置介绍1)通用配置▪公布渠道:抉择该工作所属的渠道,若无渠道可点击“新增渠道”进行申请。 ▪邀请有效期:按邀请工夫缩短(流动期间内设置按人邀请天数缩短,依照发起人和受邀人的邀请关系绑定具体工夫戳向后缩短x天进行解绑)、指定天数过期(流动期间内设置按具体天数限度,依照具体x天的自 然日23:59:59进行解绑); 2)发起人规定▪发起人规定配置 ▪获奖类型:可抉择按规定发奖,处分类型为三类(阶梯处分、循环处分、单次处分); ▪邀请人数限度:不限度(流动期间内邀请人数不设置下限)、日限度(流动期间内每日邀请人数限度x人); ▪实现工作限度:流动期间内设置发起人每日实现裂变工作次数限度; ▪发起人处分配置 1.阶梯处分:阶梯工作人数为累计值,阶梯累计值=M2裂变工作实现人数,最多能够累计增加5个级阶梯; 2.循环处分:依据裂变工作人头统计,每累计邀请N人发一次处分,循环次数暂不限度; 3.单次处分:依据裂变工作人头统计,每累计邀请1人发一次处分,循环次数暂不限度; 另:每个类型中的奖品最多可增加5个奖品 3)M1与M2的发奖逻辑▪M1可进行关联M2裂变工作进行组合类型发奖;M2可关联多个一般工作进行独自发奖,且非裂变工作实现给M1发奖; ▪M1发奖规定 —— 按规定发奖(可配置多处分组合) ▪阶梯发奖:每阶梯累计x人,发放xx处分(最多5个),阶梯规定最多5个; ▪循环发奖:每邀请x人,发放xx处分(最多5个); ▪M2发奖规定 —— 受邀人实现多任务(大于等于1个工作) ▪M2工作实现给M2处分(最多5个,M2的处分全副在工作中);多任务下(最多5个工作),仅标记1个工作为M2实现工作,M1人头数+1; 4)裂变业务逻辑流程图 4、裂变投放目前裂变次要场景是金融APP,目前根本笼罩了整个金融APP的拉新需要,并在大促、18会员日流动场景下提提供外围入口,裂变投放的示意图如下: 5、接入形式•间接JSF接入,业务方自行开发前端 •工作工作台组件接入 ...

February 13, 2023 · 1 min · jiezi

关于架构模式:入选爱分析银行数字化厂商全景报告网易数帆助力金融数字化场景落地

【点击即可收费获取残缺报告】近日,国内当先的产业数字化钻研与咨询机构爱剖析公布《2022·爱剖析银行数字化厂商全景报告》。网易数帆凭借全面当先的产品实力与丰盛多样的实践经验,别离在BI商业智能、数据治理、数据中台、通用低代码平台四大数字化畛域作为银行代表厂商强势入选。报告指出,在自主可控的背景下,银行信创数字化投入比例逐步变大。另一方面,银行IT我的项目对产品智能化、精准化越来越来高,与之对应的解决方案的深度、广度均比之前年度更高。本次报告爱剖析将银行数字化市场分为“前端利用”“撑持平台层”“基础设施”三层。其中, “撑持平台层”涵盖BI商业智能、数据治理、数据中台、通用低代码平台、银行隐衷计算解决方案等能够向多个银行部门提供撑持能力的零碎或解决方案。网易数帆作为撑持平台层的代表厂商,在多项重点技术畛域均为银行提供了无力撑持与赋能。 数据中台已成为银行数字化的重要选项数据作为撑持银行数字化转型的外围生产因素,随着财产、营销、风控等业务场景的一直拓展,其作用也日益显著,然而银行传统以大数据平台、数据仓库等为主的数据体系,大多是基于繁多业务部门需要所搭建的,难以对全行业务进行赋能,各部门间数据孤岛景象重大,数据价值难以无效施展。因而,数据中台解决方案凭借着能够帮忙银行对全量数据进行对立治理和利用等外围劣势,成为了银行的重要选项。具体而言,银行的需要次要有以下几点: 可能对全量数据进行接入和存储;建设对立的全链路数据利用体系;能与银行原有基础设施疾速对接,防止大规模革新;提供全流程的服务,保障应用体验。联合在大数据畛域十余年的技术积攒与面向金融客户多年的服务教训,网易数帆精准洞察到银行客户对于数据中台的需要,可提供更合乎具体金融业务场景的数字化解决方案。 网易数帆数据中台解决方案,打造金融机构最佳落地实际网易数帆数据中台解决方案,具备麻利开发平台、指标零碎、数据地图、数据品质核心、数据资产治理以及数据对立查问服务等多种外围性能,以及BI、数据开发及治理平台、实时计算平台、机器学习平台等多个数据利用平台,帮忙企业建设从数据采集、存储、开发、到治理、服务的全链路数据利用体系,助力企业数字化转型,让数据产生价值。整体来看,网易数帆在产品功能完善度、产品稳定性、灵便的部署施行能力以及全流程的服务能力四方面均具备当先劣势。欠缺的产品性能矩阵,大幅晋升银行数据利用能力。首先,在数据基础设施层,网易数帆能为银行提供大数据存储、大数据计算以及OLAP引擎等多种底层数据组件,晋升银行根底数据处理能力。其次,在数据中台层,网易数帆可能帮忙银行疾速建设起从数据研发、数据治理、到数据服务的全链路数据利用体系。最初,在数据应用层,还具备BI、实时计算、机器学习等多种数据利用平台,可按需抉择,帮忙银行进一步欠缺本身数据利用体系,更好地为业务赋能。如在杭州联结银行我的项目中,网易数帆为杭州联结银行提供了从大数据平台底层、中台组件、标签画像、自助剖析到机器学习平台等一整套计划,助力杭州联结银行村镇银行疾速实现数字化转型指标的同时,升高了数据相干组件的整体运维老本。除了工具的搭建,数据治理、监管报送、实时场景、自助剖析、风控营销等场景的落地,也让杭州联结银行外部的数据可能更充沛地施展价值。较强的产品稳定性,无效保障系统的安稳运行。通过多年的产品技术打磨与业务服务教训积淀,网易数帆曾经打造造成了可实用于大多数银行的通用数据中台解决方案,在技术栈完整性、产品成熟度、内核技术掌控力等方面都具备肯定劣势,产品整体稳定性较高;同时,该计划已在网易团体外部进行了实际验证,在帮忙银行高效搭建数据利用体系的同时,也能无效保障IT零碎的稳定性及银行业务的连续性。灵便的交付施行形式,满足不同银行性能及部署需要。一方面,网易数帆可为银行提供标准化的数据中台产品以及定制化性能开发服务,无效满足不同规模银行的个性化数据中台性能需要;另一方面,网易数帆数据中台解决方案,基于开源技术路线打造,反对对接多种第三方基础设施,便于银行的疾速部署,并可能帮忙银行无效防止技术绑定景象,更好地保障技术的平安可控。全流程服务能力,为数据中台的短暂应用提供保障。依靠于全面的数据中台解决方案在团体外部的实际验证,网易数帆曾经把握了较为成熟的数据中台建设方法论,可在部署前依据不同规模银行的理论状况制订出详尽的零碎建设布局,并可能独立交付施行,助力数据中台在银行的全面落地;同时,在部署后,网易数帆还能为银行提供全面的运维培训服务,无效升高银行前期运维压力,为中台零碎的短暂应用提供了保障。基于以上劣势,该解决方案已在杭州联结银行、浙商银行等多家头部金融客户落地利用,可全面涵盖银行多种数字化利用场景,为客户业务提供更多反对,提供更加贴合本地理论状况的开发及运维计划。接下来,网易数帆将持续聚焦金融行业,“技术创新+产品服务”并行不悖,满足更多金融级数字化业务需要,更高效、更敏捷地实现技术落地。

August 5, 2022 · 1 min · jiezi

关于架构模式:领域驱动设计事件溯源

事件溯源事件溯源是构建业务逻辑和长久化聚合的另一种抉择。通过聚合一系列事件的形式长久化保留。每个事件代表聚合的一次状态变动。应用程序通过重放来从新创立聚合的以后状态。 模式:事件溯源应用一系列示意状态更改的畛域事件来长久化聚合。1. 传统长久化技术的问题对象和关系的“阻抗失调”关系型数据的表格构造模式,与畛域模型及其简单关系的图状构造之间,存在基本概念不匹配的问题。不足聚合的历史传统长久化的另一个限度是,它只存储聚合的以后状态。聚合更新后,其先前的状态将会失落。如果应用程序必须保留聚合的历史,那么必须实现相应的业务逻辑。实现这个逻辑是十分耗时的一项工作,因为其中还有波及到复制必须与业务逻辑保持一致的代码。实现审计性能十分繁琐且容易出错为了满足安全性或监管的要求,要实现审计性能以反对。挑战在于,除了这个是一个耗时的工作之外,负责审计日志的业务代码,可能与业务逻辑产生偏离,导致各种谬误。事件公布凌驾于业务逻辑之上传统长久化的另一个限度是,它通常不反对公布畛域事件。2. 什么是事件溯源事件溯源是一种以事件为核心的技术,用于实现业务逻辑和聚合的长久化。事件溯源通过事件来长久化聚合通过设置事件存储库(event表),构造如下: evenv_idevent_typeentity_typeentity_idevent_data101OrderCreatedOrder101{...}102OrderApprovedOrder101{...}103OrderShippedOrder101{...}104OrderDeliveredOrder101{...}...............记录了Order变动的事件及所需的数据,通过加载事件存储库,可重放事件加载聚合。 一般来说,依照以下步骤:加载聚合事件列表应用默认构造方法创立聚合实例调用聚合事件绝对应的apply办法,重放事件事件溯源罕用实现如下:应用process办法接受命令,返回事件列表应用apply办法,承受事件,更新聚合2.1 通过事件来长久化聚合2.2 事件代表状态的扭转2.3 聚合办法都与事件相干2.3.1 创立聚合的步骤如下:应用聚合默认的构造函数实例化聚合根调用process办法,生成事件列表1遍历事件列表1,并调用apply办法更新聚合的状态将事件列表保留至事件存储库2.3.2 更新聚合的步骤如下:从事件存储库加载事件列表1应用其默认构造函数实例化聚合根遍历加载的事件列表1,并在聚合根上调用apply办法调用process办法以生成事件列表2遍历事件列表2,并调用apply办法更新来聚合的状态将新事件存储至事件存储库2.4 并发更新两个或多个申请同时更新同一聚合。对于并发,防止问题呈现的形式是,进行串行化的解决。 对事件存储库新增一列,is_publish event_idis_publish1010将事件存储至事件存储库(即时),is_publish为0投递事件至音讯代理将事件标记为已公布,is_publish=1事件执行反馈记录,这里不聊2.5 畛域事件的演变事件溯源的构造分为三个档次: 由一个或多个聚合组成定义每个聚合收回的事件定义事件的构造2.6 事件溯源的优劣2.6.1 事件溯源的益处牢靠的公布畛域事件保留聚合的历史最大水平的防止对象和关系的“阻抗失调”为开发者提供一个时光机 2.6.2 事件溯源的弊病编程模式有肯定的学习曲线基于消息传递的应用程序的复杂性处理事件的演变有肯定的难度随着工夫的推移,畛域模型及构造都可能会有调整。 迁徙旧构造,以反对以后最新的畛域模型代码中减少适配器,以兼容旧构造删除数据有肯定的难度事件溯源自身是要保留聚合的历史,永恒的保留数据,所以传统的做法是进行软删除应用软删除应用多种数据,然而依据欧洲的数据保护和隐衷法规(GDPR),应用程序必须彻底删除用户的个人信息。做法是,通过用户设置UUID,依据UUID关联敏感数据。删除数据时,删除关联即可。查问事件存储库十分有挑战性须要在事件存储库,找到没有间接搜寻条件的数据。通过CQRS可实现该查问2.7 通过快照来进步溯源的性能

August 1, 2021 · 1 min · jiezi

关于架构模式:架构模式DCI

DCI(Data, Context, Interactive)(未完待续) 以性能权限配置为例子介绍:controller:解析申请参数,validate入参,调用service层办法,实现业务操作。例子:配置性能权限。解析申请参数,validate参数是否非法,调用service层办法,实现业务。相干接口,对应SystemControllerservice:操作model,实现业务逻辑所需最小的数据操作。例子:配置性能权限,需判断以后操作人身份,而后进行配置。通过解析操作人所对应权限组、权限、接口通过数据权限解析操作人对应system校验是否存在性能权限和相应数据权限再进行事务,检测是否存在,不存在通过model层办法,增加权限配置。相干业务,汇聚成FuncPermissionServicemodel:多张表(对应Gorm多个struct)组成模型。例子:零碎性能权限配置须要:systemsystem-privilege-groupprivilege-groupprivilege-group-privilegeprivilegeprivilege-apiapi等数据表,这些表独特形成FuncPermissionModel

June 28, 2021 · 1 min · jiezi

分布式消息队列详解10min搞懂同步和异步架构等问题

分布式消息队列是是大型分布式系统不可缺少的中间件,主要解决应用耦合、异步消息、流量削锋等问题。实现高性能、高可用、可伸缩和最终一致性架构。 对于一个架构师来说,在大型系统设计中,会经常需要面对同步和异步等架构问题,搞明白这些问题,能更好地实现程序并行执行,减少等待或无效操作,以及充分利用计算机的性能! 本文将详细讲解:1.同步架构和异步架构的区别 2.异步架构的主要组成部分:消息生产者、消息消费者、分布式消息队列 3.异步架构的两种主要模型:点对点模型和发布订阅模型。 4.消息队列的好处 5.消息队列相关产品 建议用10min通读,搞懂分布式消息队列的核心内容。 一、同步架构和异步架构的区别 1.同步调用 是指从请求的发起一直到最终的处理完成期间,请求的调用方一直在同步阻塞等待调用的处理完成。 如图,在这个例子中客户端代码ClientCode,需要执行发送邮件sendEmail这样一个操作,它会调用EmailService进行发送,而EmailService会调用SmtpEmailAdapter这样一个类来进行处理,而这个类会调用远程的一个服务,通过SMTP和TCP协议把请求发送给它。 而远程服务器收到消息以后会对消息进行一系列的操作,然后将邮件发送出去,再进行返回。Adapter收到返回后,再返回给EmailService,EmailService收到返回后再把返回结果返回给Clientcode。 ClientCode在sendEmail发出请求后,就一直都阻塞在这里,等待最终调用结果的返回,是成功还是失败。因为这个过程是阻塞等待的,所以这个过程也就是同步调用。 2.异步调用 是指在请求发起的处理过程中,客户端的代码已经返回了,它可以继续进行自己的后续操作,而不需要等待调用处理完成,这就叫做异步调用。 异步调用过程,同样看刚刚发送邮件的例子,用户Clientcode调用EmailService以后,EmailService会把这个调用请求发送给消息队列,然后就立即返回了。Clientcode收到返回以后继续向下处理,不会继续阻塞等待。实际上消息发送到Queue后,还没有被处理,我们看到后面的消息消费,其实要比EmailService返回可能还要晚一点,EmailService返回以后消息才会被消费处理。 有一个QueueConsumer消息队列的消费者,从消息队列中取出这个消息,再把这个消息发送给SmtpAdapter,也就是调用SmtpAdapter,处理逻辑跟同步调用一样,SmtpAdapter通过SMTP的通讯协议,把消息发送给远程的一个服务器,进行邮件发送,通过RemoteServer进行处理,处理完了收到返回,再把返回结果通知消息队列Queue。 在这个过程中,客户端的调用,也就是应用程序的调用,和业务逻辑真正发送邮件的操作是不同步的。 二、异步架构的主要组成部分 使用异步调用架构的主要手段,就是通过消息队列构建,如下是它的架构图。 消息的生产者将消息发送到消息队列以后,由消息的消费者从消息队列中获取消息,然后进行业务逻辑的处理,消息的生产者和消费者是异步处理的,彼此不会等待阻塞,所以叫做异步架构。 使用消息队列构建一个异步调用架构,你需要了解如下3种角色。 1.消息的生产者 是客户端应用程序代码的一部分,用来初始化异步调用处理流程。在基于消息队列的处理中,生产者的职责非常少,它要做的就是创建一个合法的消息,并把这个消息发送到消息队列中,由应用开发者决定生产者的代码在哪里执行,什么时候发送消息。 2.消息队列 消息队列是消息发送的目的地和发给消费者的一个缓冲。消息队列实现的方法有好多种,可以用共享文件夹,也可以用关系数据库或者NoSQL系统,当然最主要的还是使用专门的分布式消息队列服务器来实现。 3.消息的消费者 消息的消费者从消息队列中接受并处理消息,消息的消费者也是由应用开发者实现的,但是它是一个异步处理的组件。消息的消费者不需要知道生产者存在,它只依赖消息队列中的消息。消息的消费者通常部署在独立的服务器上,和消息的生产者完全隔离,并且可以通过添加硬件的方式进行伸缩。 三、异步架构的两种主要模型 使用消息队列构建异步的调用架构,你还需要知道两种模型:点对点模型和发布订阅模型。 1.点对点模型 消费者和生产者只需要知道消息队列的名字,生产者发送消息到消息队列中,而消息队列的另一端是多个消费者竞争消费消息,每个到达消息队列的消息只会被路由到一个消费者中去,所以消费者看到的是全部消息的一个子集。我们看这张图,消息的生产者有多个,消息的消费者也有多个,多个生产者将消息发送到消息队列中,而有多个消费者去消息队列中对消息进行竞争性的消费。每个消息只会被一个消费者消费,每个消费者只会消费消息队列中的一部分消息。 2.发布订阅模型 在发布订阅模型中,消息可能被发送到不止一个消费者,生产者发送消息到一个主题,而不是队列中。消息被发布到主题后,就会被克隆给每一个订阅它的消费者,每个消费者接收一份消息复制到自己的私有队列。消费者可以独立于其他消费者使用自己订阅的消息,消费者之间不会竞争消息。常用的分布式消息队列都支持发布订阅模型,也就是说消息的发布订阅模型是分布式消息队列的一个功能特性。 3.两个模型的应用 点对点模型:主要用于一些耗时较长的、逻辑相对独立的业务。 比如说我前面的讲到的发送邮件这样一个操作。因为发送邮件比较耗时,而且应用程序其实也并不太关心邮件发送是否成功,发送邮件的逻辑也相对比较独立,所以它只需要把邮件消息丢到消息队列中就可以返回了,而消费者也不需要关心是哪个生产者去发送的邮件,它只需要把邮件消息内容取出来以后进行消费,通过远程服务器将邮件发送出去就可以了。而且每个邮件只需要被发送一次。所以消息只被一个消费者消费就可以了。 发布订阅模型:如新用户注册这样一个消息,需要使用按主题发布的方式。 比如新用户注册,一个新用户注册成功以后,需要给用户发送一封激活邮件,发送一条欢迎短信,还需要将用户注册数据写入数据库,甚至需要将新用户信息发送给关联企业的系统,比如淘宝新用户信息发送给支付宝,这样允许用户可以一次注册就能登录使用多个关联产品。一个新用户注册,会把注册消息发送给一个主题,多种消费者可以订阅这个主题。比如发送邮件的消费者、发送短信的消费者、将注册信息写入数据库的消费者,跨系统同步消息的消费者等。 四、消息队列的好处 1.实现异步处理,提升处理性能 对一些比较耗时的操作,可以把处理过程通过消息队列进行异步处理。这样做可以推迟耗时操作的处理,使耗时操作异步化,而不必阻塞客户端的程序,客户端的程序在得到处理结果之前就可以继续执行,从而提高客户端程序的处理性能。 2.可以让系统获得更好的伸缩性 耗时的任务可以通过分布式消息队列,向多台消费者服务器并行发送消息,然后在很多台消费者服务器上并行处理消息,也就是说可以在多台物理服务器上运行消费者。那么当负载上升的时候,可以很容易地添加更多的机器成为消费者。 如图中的例子,用户上传文件后,通过发布消息的方式,通知后端的消费者获取数据、读取文件,进行异步的文件处理操作。那么当前端发布更多文件的时候,或者处理逻辑比较复杂的时候,就可以通过添加后端的消费者服务器,提供更强大的处理能力。 3.可以平衡流量峰值,削峰填谷 使用消息队列,即便是访问流量持续的增长,系统依然可以持续地接收请求。这种情况下,虽然生产者发布消息的速度比消费者消费消息的速度快,但是可以持续的将消息纳入到消息队列中,用消息队列作为消息的缓冲,因此短时间内,发布者不会受到消费处理能力的影响。 从这张图可以看到,因为消息的生产者是直接面向用户请求的,而用户的请求访问压力是不均衡的。如淘宝每天的访问高峰是在上午10点左右,而新浪微博则可能在某个明星半夜发一条微博后突然出现访问高峰。 在访问高峰,用户的并发访问数可能超过了系统的处理能力,所以在高峰期就可能会导致系统负载过大,响应速度变慢,更严重的可能会导致系统崩溃。这种情况下,通过消息队列将用户请求的消息纳入到消息队列中,通过消息队列缓冲消费者处理消息的速度。 如图中所示,消息的生产者它有高峰有低谷,但是到了消费者这里,只会按照自己的最佳处理能力去消费消息。高峰期它会把消息缓冲在消息队列中,而在低谷期它也还是使用自己最大的处理能力去获取消息,将前面缓冲起来、来不及及时处理的消息处理掉。那么,通过这种手段可以实现系统负载消峰填谷,也就是说将访问的高峰消掉,而将访问的低谷填平,使系统处在一个最佳的处理状态之下,不会对系统的负载产生太大的冲击。 4.失败隔离和自我修复 因为发布者不直接依赖消费者,所以分布式消息队列可以将消费者系统产生的错误异常与生产者系统隔离开来,生产者不受消费者失败的影响。 当在消息消费过程中出现处理逻辑失败的时候,这个错误只会影响到消费者自身,而不会传递给消息的生产者,也就是应用程序可以按照原来的处理逻辑继续执行。 所以,这也就意味着在任何时候都可以对后端的服务器执行维护和发布操作。可以重启、添加或删除服务器,而不影响生产者的可用性,这样简化了部署和服务器管理的难度。 5.可以使生产者和消费者的代码实现解耦合 也就是说可以多个生产者发布消息,多个消费者处理消息,共同完成完整的业务处理逻辑,但是它们的不需要直接的交互调用,没有代码的依赖耦合。在传统的同步调用中,调用者代码必须要依赖被调用者的代码,也就是生产者代码必须要依赖消费者的处理逻辑代码,代码需要直接的耦合,而使用消息队列,这两部分的代码不需要进行任何的耦合。 耦合程度越低的代码越容易维护,也越容易进行扩展。 比如新用户注册,如果用传统同步调用的方式,那么发邮件、发短信、写数据库、通知关联系统这些代码会和用户注册代码直接耦合起来,整个代码看起来就是完成用户注册逻辑后,后面必然跟着发邮件、发短信这些代码。如果要新增一个功能,比如将监控用户注册情况,将注册信息发送到业务监控系统,就必须要修改前面的代码,至少增加一行代码,发送注册信息到监控系统,我们知道,任何代码的修改都可能会引起bug。 而使用分布式消息队列实现生产者和消费者解耦合以后,用户注册以后,不需要调用任何后续处理代码,只需要将注册消息发送到分布式消息队列就可以了。如果要增加新功能,只需要写个新功能的消费者程序,在分布式消息队列中,订阅用户注册主题就可以了,不需要修改原来任何一行代码。 这种解耦的特点对于团队的工作分工也很有帮助!从消息生产者的视角看,它只需要构建消息,将消息放入消息队列中,开发就完成了。而从消费者的开发视角看,它只需要从消息队列中获取消息,然后进行逻辑处理。它们彼此之间不进行任何耦合。消息的生产者不关心放入消息队列中下一步会发生什么,而消费者也不需要知道消息从哪里来。这两部分程序的开发者也可以不关心彼此的工作进展,他们开发的代码也不需要集成在一起,只要约定好消息格式,就可以各自开发了。 ...

June 6, 2019 · 1 min · jiezi

胡海洋Hive-Metastore-Federation-在滴滴的实践

出品 | 滴滴技术作者 | 胡海洋 前言:本文来自滴滴基础平台大数据架构离线引擎组,针对内部hive元数据上亿级别存储方案的实践;该架构体系从根本上提高了hive元数据服务的稳定性及扩展性问题。 ▍背景 Apache Hive 是基于 Apache Hadoop 之上构建的数据仓库,提供了简单易用的类 SQL 查询语言,适合对大规模数据进行存储、查询操作,被广泛使用。 Hive 元数据 Metadata 包含用 Hive 创建的 Database、Table、Partition 等的元信息。此类元信息一般存储在关系型数据库中,如 Derby、MySQL 等。 在滴滴,我们是将元数据存储在MySQL 里,随着业务的不断增长,Hive 元数据越来越庞大,出现单表存储超过上亿条记录的情况,这种情况下会导致 MySQL查询压力过大,而且在高峰期间,经常导致机器 CPU 使用率达到 100%,影响服务稳定性。 为此,我们开始调研元数据 Federation 方案,实现元数据水平扩展能力,为 MySQL 解压,提升 Hive 稳定性。 ▍Federation 方案介绍 ▍2.1 Hive 架构体系演变 引入 Federation 之前的 Hive 架构体系: 该架构体系中用户使用的 Hive 客户端或者 Hivesever2 服务、Spark 引擎、Presto 引擎等都是访问统一 Hive Metastore 服务获取 Hive 元数据。 Hive Metastore 服务主要是使用 LVS + 多个 Hive Metastore 实例组成。所有的 Hive Metastore 实例共享一套主从 MySQL 环境作为 Hive 元数据存储 DB。 ...

June 3, 2019 · 2 min · jiezi

支撑亿级用户的架构从0到1演化全过程

本文从以下2个方向,对互联网系统架构演化进行了一个综述: 1.大型互联网架构目前面临的挑战及其解决思路2.大型互联网系统架构演化过程,包含了所有的现在主要的互联网架构的考量点、技术方案、要解决的问题等。 建议用10min阅读,可以了解互联网架构的全貌。 一、架构演进面临的挑战及解决思路 互联网主要面对的技术挑战,用一句话概括:就是用户不断上升产生的并发访问压力以及数据存储压力,所以系统需要更强的处理能力才能解决这些问题。 而系统处理能力提升,主要有两种途径: 1.垂直伸缩: 提升单台服务器的处理能力,比如用更快频率的cpu,用更多核的cpu,用更大的内存,用更快的网卡,用更多的磁盘组成一台服务器,使单台服务器的处理能力得到提升,通过这种手段提升系统的处理能力。 缺点如下: a.当垂直伸缩达到一定程度以后,继续增加计算需要花费更多的钱。 b.垂直伸缩是有物理极限的,即使是大型机,也有自己的物理极限,它不可能无限地伸缩下去的。 c.操作系统的设计或者应用程序的设计制约着垂直伸缩,最多只能达到一个点无法继续提高。 在大型互联网出现之前,传统的软件,比如银行、电信这些企业的软件系统,主要是使用垂直伸缩这种手段实现系统能力提升的,在服务器上增强,提升服务器的硬件水平。当某种类型的服务器能力提升到了瓶颈以后,就会用更强大的服务器,比如说从服务器升级到小型机,从小型机提升到中型机,从中型机提升到大型机,服务器越来越强大,处理能力越来越强大,当然价格也越来越昂贵,运维越来越复杂。 2.水平伸缩: 单机的处理能力并不提升,也不使用更昂贵的更快的更厉害的硬件,而是通过更多的服务器,将这些服务器构成一个分布式集群,通过这个集群,统一对外提供服务,以此来提高系统整体的处理能力。 水平伸缩优点: a.只要架构合理,能够添加服务器到集群中,你的系统就是永远可以正常运行。 b.它没有极限,它的成本也不会说到了某个临界点就突然增加。而且逐渐的增加服务器,获得相同的计算处理能力,只会比以前的服务器更便宜,不会更贵,因为硬件的价格总是在不断地下降的。 c.应用程序运行在一个服务器上,是为单一服务器而设计的,而增加服务器的话只是让程序部署在更多的服务器上,所以也不需要对应用程序进行太多的改变,应用程序不会受到硬件制约。 在互联网行业中多采用水平伸缩的手段。 二、大型互联网系统架构演化过程 要让更多的服务器构成一个整体,需要在架构上进行设计,让这些服务器成为整体系统中的一个部分,有效地组织起来,统一提升系统的处理能力。 以下将通过大型互联网系统架构的演进过程,来详细理解如何通过以上两种伸缩方式逐步提升系统处理能力的。 这个过程对外看起来是一个业务演进过程,也就是用户量不断增长的一个过程。 实际上大型互联网整个的技术驱动就是因为用户量不断地在增加,数据量不断增加,导致并发访问压力持续增大,产生了一系列技术挑战。为了应对这个挑战,要不断地增强系统的技术处理能力,优化系统的架构。 最早的时候是单机系统,这时候可以满足少量用户的使用; 随着数据量提升,需要进行应用服务器与数据库分离,这个时候可以满足万级用户的使用; 再然后需要通过分布式缓存和服务器集群提升系统性能,这时候可以满足10万级的用户,之后需要进行反向代理,CDN加速还需要数据库读写分离,以满足百万用户级的访问; 随着数据量爆发式增长,使用分布式文件系统和分布式数据库系统,以满足千万级用户的访问; 最后使用搜索引擎、NoSQL、消息队列、分布式服务等更复杂的技术方案,以满足亿级用户的访问。 1.单机系统 在最早的时候,系统因为用户量比较少,可能只是有限的几个用户,这个阶段系统主要是用来验证技术以及业务模式是否可行的,系统也不需要太复杂,有限的几个主要功能。 开发完应用程序以后,部署在应用服务器上,一个应用访问自己服务器上的数据库,访问自己服务器的文件系统,构成了一个单机系统,这个系统就可以满足少量用户使用了。 如果这个系统被证明是可行的,是有价值的,好用的,如Google 最早就是部署在斯坦福的实验室里面,给实验室的同学和老师使用的。这些同学和老师使用后发现Google的搜索引擎比以前的搜索引擎(比如像Yahoo这样的搜索引擎)要好用的多,很快这个消息就扩散出去了。整个斯坦福大学的老师同学可能都过来访问这个服务器。这个时候服务器就不能够承受访问压力了,需要进行第一次升级,数据库与应用分离。 2、数据库与应用程序分离 前面单机的时候,数据库和应用程序是部署在一起的。 进行第一次分离的时候,应用程序、数据库、文件系统分别部署在不同的服务器上,从1台服务器变成了3台服务器,那么相应的处理能力就提升了3倍。 这种分离几乎是不需要花什么技术成本的,只需要把数据库文件系统进行远程部署,进行远程访问就可以了,这个时候的处理能力提升了3倍。 3、使用缓存改善性能 随着用户进一步的增加,更多的用户过来访,3台服务器也不能够承受这样的压力了,那么就需要使用缓存改善性能。 缓存主要有分布式缓存和本地缓存两种。 分布式缓存可以构成一个集群,存储更多的缓存数据,通过使用缓存一则应用程序不需要去访问数据库,因为数据库的数据是存在磁盘上的,访问数据库需要花费更多的时间,而缓存中的数据只是存储在内存中的,访问时间更短。 另一方面,数据库中的数据是以原始数据的形式存在的,而缓存中的数据通常是以结果形式存在,如果说已经构建成某个对象,缓存的就是这个对象,不需要进行对象的计算,这样就减少了计算的时间,同时也减少了CPU的压力。 这样不管是对计算资源的节约,还是对访问时间的节约,都会得到比较大的提升。通过使用缓存可以极大的改善性能。 4、应用服务集群化 虽然通过数据库分离和使用缓存,加快了系统的响应时间,减少了系统的计算压力,但是随着用户的进一步增加,应用服务器可能会成为瓶颈,一台应用服务器连接大量的并发用户的访问可能会成为一个瓶颈点,这时候就需要对应用服务器进行升级。 解决办法就是通过负载均衡服务器,将应用服务器部署为一个集群,添加更多的应用服务去处理用户的访问。 5、数据库读写分离 虽然通过负载均衡可以不断的添加应用服务器,为更多的用户提供系统访问服务。但是这个时候数据库会再一次成为整个系统的瓶颈点。 因为大量的用户过来访问,他们的主要操作都需要落在数据库上。虽然缓存可以缓存一部分的数据库读操作,但是还是有一部分读操作在缓存中找不到,还需要访问数据库,而且所有的写操作几乎都要访问数据库,这时候数据库就会成为瓶颈。 单一的数据库不能够承受这么大的访问压力。 这时候的解决办法就是数据库的读写分离,将一个数据库通过数据复制的方式,分裂为两个数据库,主数据库主要负责数据的写操作,所有的写操作都复制到从数据库上,保证从数据库的数据和主数据库数据一致,而从数据库主要提供数据的读操作。 通过这样一种手段,将一台数据库服务器水平伸缩成两台数据库服务器,可以提供更强大的数据处理能力。 6、使用反向代理和CDN加速相应 在对数据库做读写分离以后,要想更进一步增加系统的处理能力,需要使用反向代理和CDN加速。 所谓的CDN是指距离用户最近的一个服务器,当访问一个互联网应用的时候,我们的访问请求并不是直接到达互联网站的数据中心的,而是通过运营服务商进行数据转发的。 那么在进行数据转发的时候,最好已经有我们想要访问的数据了,这样就不需要访问互联网数据中心了。这个服务就叫做CDN服务,CDN服务就是部署在网络运营商机房里的离用户最近的一个服务器,用户请求先到这里查询有没有用户需要的数据,如果有,就从CDN直接返回,如果没有,再通过CDN进一步访问网站的数据中心,得到数据后再缓存到CDN供其他用户访问或下一次访问,所以CDN的本质还是一个缓存。 用户请求到达网站的数据中心后,也不是直接请求应用服务器,依然是查找一次缓存,这个缓存叫做反向代理服务器。 ...

May 24, 2019 · 1 min · jiezi

TiDB 在银行核心金融领域的研究与两地三中心实践

作者介绍:于振华,北京银行软件开发部资深架构师,长期从事银行核心系统研发、规划,参与过多个核心信息系统建设工作,包括一、二代支付系统、第四代银行核心系统建设、分布式核心系统建设等企业级项目工作。当前主要研发方向集中在构建先进、高效、面向 OLTP 的银行交易系统,提升银行信息系统服务能力。本文整理自于振华老师在 TiDB DevCon 2019 上的演讲实录,演讲主题为《TiDB 在银行核心金融领域的研究与实践》。今天参加 TiDB DevCon 2019 能够和这么多各行各业的朋友一起来交流 TiDB 的实践情况,这个机会非常难得,因为平时都是我们技术团队和 TiDB 团队单向的交流,横向的这种客户之间交流的机会很少,像刚才几位老师讲的,我觉得都很有意思,也希望通过咱们这次大会,大家能擦出不一样的火花。北京银行和 PingCAP 团队进行了深度的合作,目前有几套重要的实时交易类系统已经对接,包括比较重要网联系统、银联无卡支付、金融互联服务平台等。现在怎么来评价一款产品到底稳不稳,很大程度上要看这款产品在金融,尤其是核心金融的场景有没有应用,能不能支持金融场景的要求。我们是在 2018 年 3 月份、5 月份、6 月份进行了投产。经过半年多的时间,我们看到 TiDB 也能够支持金融场景了。从侧面来讲,分布式数据库技术,确实已经到达了一定的成熟度。一、背景介绍我相信这几年,尤其是这三四年,大家应该都有感触。无论是工作方式,还是生活方式,都发生了很大的变化,各种信息、科技产品铺面而来,有人说是这种变化叫工业科技革命 4.0。不知道这种提法准确不准确,但这种变化确实对我们银行的系统产生了比较大的挑战。<center>图 1</center>在图 1 中 ,我列出了几项,比如高并发的要求,要求你具备很快的扩展能力。再比如产品发布,要求你具备快速的发布能力,在座的应该有很多做产品、做实施的团队,大家应该很有感触,比如可能前一天还无人问津的产品,第二天可能就会卖的很火爆,来的每个项目都是紧急项目,都要求你在最快的时间发布出去。当然还包括一些老生常谈的问题,像传统架构成本难以控制,还有自主可控亟待攻关,其实在传统闭源的生态里面,我们很难达到自主可控的要求。二、系统分析<center>图 2</center>在这种背景下,我们从全局的角度出发,对银行以往的技术形态做了系统性的分析,图 2 中列举了一些典型的架构形态,有一些在现在的银行架构里边还是存在的,比如单体的应用,再比如传统的数据库,现在用的最多的 DB2 和 Oracle,还有传统的单机或者集群部署模式,以及瀑布开发模型,当然还有面向传统架构的运维模式。今天我们来谈分布式数据库,它是一个新技术,但不能说把以往技术架构就否定掉。以往的技术形态好不好?坦白讲,我认为很好,不好的话不可能支撑了这么多年的金融业务发展,但站在今天这样的时间点来说问题也是存在的。像刚才讲到的,高并发的要求、扩展能力、成本、以及产品交付能力都存在一些不尽如人意的地方。在这种情况下,我们启动了北京银行新一轮的架构转型的工作,分布式数据库也纳入到我们的工作范围里。我们和 PingCAP 很早就接触了,在一年多的工作过程中,要谈的技术细节、技术方案、工作流程等等这些内容会很多,如果真的来总结一下这项工作是怎么做的话,我总结出以下三条。大家一看可能会觉得很虚,但是你如果真的来实践这件事,也许会有同样的感触。第一个就是「务实」。架构转型不是一个为了技术而技术,为了新产品而新产品的工作,而是确实要对你的业务发展、开发、运维的效率有所提升。第二个,我觉得可能是最重要的,就是要做到「速赢」。无论是你在什么样的企业来做技术升级,技术转型,或多或少的都会遇到一些阻力,尤其是在传统企业。那做到速赢,迅速的释放价值,让你周围的人、让你的团队、让你的组织,迅速看到它的价值,会让你未来的工作开展更加平滑。第三个是「全栈」。因为是整体的架构转型工作,我们希望建设一套平台,它能够释放整体的价值,而不是在乎一城一池的得失。今天本来我想介绍北京银行的应用架构和分布式数据库架构,因为时间关系今天只说一下分布式数据库建设的情况。三、进展情况<center>图 3</center>在介绍具体内容之前,先跟大家同步一下,我们现在的工作进展。2018 年 3 月,我们投产了行业内首个面向核心金融业务的分布式数据库,采用的是两地三中心五副本的架构模式。以分布式数据库为基础,5 月份我们投产了网联支付清算平台,这也是很重要的一个带资金业务的实时交易系统,6 月份投产了银联无卡支付平台。这张图(图 3)可能稍微有点老,现在我们投产的还包括金融互联服务平台,IFRS9 减值系统。我们未来要做的事其实和刚才刘奇讲的比较一致,包括 HTAP,包括容器云的这些方案等等,这也是我们目前最迫切的需求。3.1 专项评测现在回想起来,北京银行开展分布式数据库建设的工作,其实是在行业里面算很早的,也是因为我们开展这件工作的时间比较早,所以在整个过程中遇到了很多的困难困惑。行里的技术力量集中在 DB2、Oracle 上可能比较多,对于分布式数据库的掌握来讲,需要有一个周期。我们做的第一步,为了保证产品可用,建设了面向金融业务的评测体系。<center>图 4</center>图 4 左上角是面向这个功能的测试,比如数据库有没有高可用性,能不能做线性扩展,有没有在线升级能力,这些都是我们的测试点。图 4 左下角这块,是面向性能的测试,我们并没有采用市面上已经有的工具,比如 TPCC、Sysbench 等等。因为我们实际分析下来觉得市面已经有的这些工具和我们的金融场景有一些距离,用它们来测试可能不会有很好的参考意义,所以我们自研了这套面向分布式数据库的金融性能评测体系,能够让我们明确出分布式数据库可以应用在金融场景,并且对于功能和性能,让大家能有一个可度量的工具。在这个过程中,要感谢支付清算协会、信通院等上级单位和组织给予我们的帮助,另外,我们也和硬件厂商英特尔进行了比较深的合作,比如今年(2018 年)新的硬件平台,我们也做了专项的分布式数据库测试,为未来我们硬件的架构选型提供了有效的参考。3.2 部署模式<center>图 5</center>对于分布式数据库的技术层面来讲,刚才几位讲师介绍的比较多了,我就来讲一些北京银行比较不一样的、走在前面的一些地方。 大家看到图 5 这套架构是北京银行的数据存储层的架构。北京银行的架构采用两地三中心五副本的模式部署。跨城长距离的分布式数据库建设具有很大的挑战。比如北京和西安大概一千多公里,两地距离比较远,延时比较高,我们实测的延时大概是十七毫秒左右。这十七毫秒,如果放在一条 SQL 来讲,一来一回三十几毫秒,这样的延时我们肯定是接受不了。所以在这种情况下,我们用了一个五副本的模式:北京两个 IDC,各放置两副本,西安一个 IDC 放置一个副本,采用 2:2:1 的模式。这样做的好处就是当前端应用请求过来之后,不需要用到北京到西安的这个网络,北京的四个副本中成功三个,就可以给前端实时返回,而且北京的部分实例允许失效。这样做 SQL 平均延时,大概在 1.2 毫秒左右,.95 延时大概 5 毫秒左右,这是比较不错的一个成绩(网联、银联的业务其实要比互联网业务复杂很多)。这里给大家分享一个我们实际在生产过程中遇到的一个小故事。在某个周六的中午我接到我们运维值班人员的电话,他说 TiKV 存储服务器坏了一台,当日我第一时间问的是:坏了一台有没有影响服务。他说没有影响服务,服务还是正常的。我说那就赶紧找硬件厂商给修一下机器。当时还觉得挺高兴的,不经意间在生产系统验证了一把。到了第二天周日的中午,他又给我打了一个电话,说又坏了一台服务器。当时有一些担心,是不是我们这批采购的硬件服务器有什么问题,想到这点就立马做排查,当然第一时间问的还是有没有影响服务,他说没有影响服务。这样连着两天坏了两台存储服务器都没有影响服务,也证明了多副本方案的有效性。3.3 两地三中心<center>图 6</center>图 6 展示的是整个包括应用、F5 到 TiDB、PD、TiKV 等整个部署的模式。目前我们接着有网联、银联这两个比较大的系统,这两个系统业务量相对来讲比较大,每天有一两百万笔的业务。在西安,我们还部署了一个从集群,那这个从集群是做什么呢?这个从集群就是为了对接一些 OLAP 或者说比较大的报表的情况,从而避免它对主集群的负载产生过大的影响。四、应用实践4.1 出现过的问题<center>图 7</center>有人说“当你有了锤子,好像什么问题都看上去像钉子”。我们期待从传统数据库过渡到分布式数据库,什么问题都可以解决。但事实上,肯定是没有一个万能的技术方案。图 7 右下角,我列了一些从我们项目开展之初到现在,产生一些问题或者说一些小插曲。比如我们刚才介绍了行里的 DB2、Oracle 应用的比较多。DB2、Oracle 以前用的是 READ COMMITTED 的隔离级别,那现在到了 TiDB 的 Repeatable Read 的这种形式可能还需要适应。我们建设初期也出现过这种问题:这边 Insert 的数据,那边却查不到,就因为 TiDB 是这种快照的隔离级别。还有执行计划的索引没有选中的问题,这个在我们实际的生产过程中也遇到过,明明有索引,却没有精确选中那一个索引。造成 SQL 运行的特别慢,内存吃的也比较多。这个问题,我觉得是可以解决好的,临时解决方案就是手动强制加 Hint,未来我相信 TiDB 在版本升级上也会考虑这一点,让执行计划更加准确。还有热点数据的问题,热点数据指望数据库来解决,现阶段来看是不可能了。无论是传统数据库,还是分布式数据库,要引入另外的应用缓存的组件才可以解决,在传统方案里边,我们做的技术方案也有很多,像比较传统的散列方式,把热点数据散列出去来解决,现在有了缓存,可以引入缓存解决这件事。我们应用架构采用微服务的形态,对比单体应用形态,微服务对于数据库的要求会更高。因为传统的单体应用,事务的 SQL 数量比较多,划分成微服务的话,无论是应用逻辑,还是数据库的处理逻辑,都会比较细粒度,事务提交次数成倍增长,对于 MVCC 的乐观提交模型有一定的压力,在我们实测的过程中,越细粒度的可能表现的性能越不好。以上就是我们实践过程中出现的一些小插曲。4.2 与互联网行业在应用实践上的区别<center>图 8</center>今天很多来自互联网企业的朋友也分享了自己的经验,那在金融行业做分布式数据库落地和互联网行业有什么不同呢?首先来讲,银行的发展时期和很多互联网新兴科技公司是不同的,银行有很成熟的硬件体系、部署模式、软件的设计模式、开发模式、运维模式,站在这种平台上来做新型技术落地会更加的困难。为什么会得到这个结论?因为现在也有很多的软件厂商,很多做产品的人,大家都希望做新建系统的事情。但对于庞大的历史系统做迁移的话,肯定不会是一刀切的方案,因为代价太大了。所以需要并行运行,对于这种新旧架构并行,很多时候就没有了方案,做不了。其实现在我们也在做这项工作,做一个新旧系统优雅的并行方案,包括业务逻辑的并行,还有业务数据的并行,如果大家有兴趣的话,也可以和我们私下交流这部分内容,我觉得这是很重要的一个事情。第二点就是组织架构不同。就拿微服务来说,单体的应用发展这么多年,每一个应用它的技术负责人是谁,对应的业务负责人是谁,是哪个部门,都很明确。如果做微服务化,进行拆分,很多情况下很难确定权责,如果要企业组织架构来适应系统架构也不太现实。当然历史资产、业务场景和互联网企业也是不一样的,银行信息化历史资产更多、业务比互联网更加复杂。4.3 新型架构<center>图 9</center>图 9 是我们系统建设架构图的一部分,最底下是分布式 NewSQL 数据库的基础平台,上边是应用系统,目前是传统架构和新型微服务架构并存。五、未来展望<center>图 10</center>最后再介绍一下未来我们的建设方向。第一,经过阶段性的实践,新的架构仍需要进行多方位的验证,来确保高可用性、扩展性、成本等方面的优势。下一个阶段我们希望扩大应用范围,把业务发展快、规模大、对并发要求高的系统,逐步的迁移过去。第二,我们要建立一套应用规范,或者说面向 TiDB 的金融级开发的规范指引。目前我们正在做这个事儿,包括最佳研发应用实践以及新老架构并行方案。建设传统数据库和 TiDB 之间的异构数据库传输的中间件是我们目前很重要的一项工作,这部分做完之后,相信对我们扩大应用会比较有好处。第三,我们还要做 HTAP,这点和刚才刘奇谈到的可能会比较契合。之前我看过 TiFlash 的设计理念和设计方式,我觉得是比较新颖的一种方式,比现在有些还需要 T+1 的数据分析方案会好很多,技术架构更加一体化、业务过程更加流畅。另外,我们一直在做性能提升、网络依赖消减等工作。最后,我们也希望能够把北京银行的经验和大家多多分享,让大家不再遇到我们建设过程中遇到的问题和麻烦,更加顺畅的进行架构转型工作。以上就是我今天分享的内容,谢谢大家。 ...

April 18, 2019 · 1 min · jiezi

第十一天-《企业应用架构模式》-对象-关系行为模式

工作单元用于维护受业务事务影响的对象列表,并协调变化的写入和并发问题的解决。如下:1)运行机制:关键:是提交时,决定要做什么。它打开一个事务,做所有的并发检查(使用悲观离线锁或乐观离线锁)并向数据库写入所做的修改。(开发人员根本不用显示调用数据库更新方法)记录对象更新的方法:调用者注册方式:用户如果改变了某个对象就必须将他注册到工作单元,任何没有注册的对象提交时都不会写入数据库。 对象注册方式:注册方法置于对象中,从数据库加载对象会将加载的对象注册为“干净”的,setting方法将要设置的对象注册为“脏”的。 工作单元控制器:工作单元控制所有数据库的读操作,一旦对象被读取,将将它注册为“干净”的对象。工作单元在读操作时将产生一个拷贝,在提交时比较当前对象和拷贝对象(这种的办法是指发生改变的对象),看对象是否发生了改变。 用途:数据库(使用引用完整性时保证更新顺序、批量更新)、事务资源(调整消息队列、事务监控).Net环境工作单元实现:使用无连接的数据集,每一行都有版本(当前版本、原始版本、建议版本)、状态(不变、增加、删除、修改)概念2)使用时机:基本目的:记录操作过的各种对象,以便知道为了使内存中数据与数据库同步需要考虑哪些对象。2. 标识映射通过在映射中保存每个已经加载的对象,确保每个对象只加载一次。当要访问对象时,通过映射来查找它们。 1)运行机制:键选择:数据表主键(或其他简单的数据类型)显示的还是通用的(如findPerson(1),还是find(“Person”, 1)?):当所有对象键类型相同时使用通用的,其他情况下使用显示的数量(单映射、多映射):(没看明白)标识映射存放位置:有工作单元时,放在工作单元;没有工作单元时,捆绑到会话的注册表2)使用时机:一般来说,用一个标识映射来管理所有修改了的数据库读出数据;作为数据库读取操作的告诉缓存。3. 延迟加载一个对象,它虽然不包含所需要的所有数据,但是知道怎么获取这些数据1)运行机制:4种实现方法:延迟初始化:实现思想:每次访问属性域都要先检查该域是否为空。如果为空,在返回域值之前计算出这个域的值(注意这个域需要自封装,即便是类的内部也只能通过它来访问)优缺点:简单,但往往会在对象和数据库间强加依赖关系适用场景:活动记录、表数据库入口、行数据入口虚代理:定义:虚代理是这样一个对象,它看起来应该是域中的一个对象,但实际上它并不包含任何东西。只有当他的一个方法被调用时,它才从数据库加载适当的对象优缺点:看上去完全就是需要的对象,但并不真的是那个对象,容易陷入标识问题;同一个实对象,可能有多个不同对象特征的虚代理(需要覆盖Equals方法,而不用标识方法)适用场景:数据映射器值保持器:实现思想:要想获取某对象,可以访问值保持器得到它的值,但只有第一次访问值保持器时它才真正从数据库读取数据优缺点:可避免标识问题;类需要知道值保持器的存在,丧失强数据类型显式性;重影:实现思想:当从数据库加载对象时,它只包含其ID。当每次要访问某个域时,它就会加载其完全状态(可以把域数据分为不同组,按需加载)延迟加载的问题:继承(虚代理、重影,需要知道要创建什么类型的重影或虚对象);波动加载(产生超出需要的数据库访问),影响应用程序性能(解决办法:不适用延迟加载集合中的项,但集合整体可以延迟加载)适用场景:面向方面的程序(将延迟加载置于一个单独的方面,能独立改变延迟加载策略)2)使用时机:最佳时机:需要额外的调用,并且当使用主对象时所调用的数据没有到的时候(取决于加载一个对象时需要从数据库读取多少数据和数据库调用的次数)

February 3, 2019 · 1 min · jiezi

第十天-《企业应用架构模式》-数据源架构模式

表数据入口 充当数据库表访问入口的对象,一个实例处理表中所有的行。1)运行机制: 表数据入口包含了用于访问单个表或试图的所有SQL,如选择、插入、更新、删除等。其他代码调用它的方法来实现所有与数据库的交互。 表数据入口可以和表模块一起使用,它产生一个记录集数据结构由表模块处理2)使用时机: 数据入口特别适用于事务脚本,行数据入口和表数据入口间的选择归结于如何处理多数据行,当结果集的表现便于事务脚本处理时,用表数据入口。3)示例: 如下2图分别是普通情况下、充分利用.net特征下的表数据入口实现: 2. 行数据入口 充当数据源中单条记录入口的对象,每行一个实例。1)运行机制: 特征:行数据入口是和单条记录及其相似的对象,如数据库中的一行(该对象中数据库中的每一列变成了一个域) 问题:在哪里存放产生该模式的查找操作?鉴于选择静态查找方法不支持为不同数据源提供不同查找方法的多态,需要设置单独的查找方法对象(这样关系数据库每一张表都一个查找方法类和入口来获得结果) 行数据入口和活动记录之间的区别:是否存在任何领域逻辑,如果存在,则是活动记录2)使用时机: 事务脚本(关于表数据入口和行数据入口之间的选择,参考表数据入口) 行数据入口可以和数据映射器一起配合使用:行数据入口从元数据自动生成,数据映射器由手动实现3)实例: 3. 活动记录 一个对象,它包含数据库表或视图中的某一行,封装数据库访问,并在这些数据上增加了领域逻辑1)运行机制: 活动记录的本质是一个领域模型,这个领域模型中的类和基数据库中记录结构十分吻合。 活动记录通常具有如下方法: 由SQL结果集中的一行构造一个活动记录实例; 为将来对表的插入构造一个新的实例; 用静态查找方法来包装常用的SQL查询和返回活动记录(也可以分离为一个单独的类); 更新数据库并将活动记录中的数据插入数据库; 获取或设置域; 实现部分业务逻辑。2)使用时机: 适合于创建、读、更新、删除等不太复杂的领域逻辑; 优点:简单,容易创建,易于理解; 缺点:要求对象的设计和数据库的设计紧耦合,项目中难以进一步重构;当业务逻辑复杂,对象间有引用、集合和继承等关心时,难以映射到活动记录3)示例: 其中,标圈的是领域逻辑实现。4. 数据映射器 在保持对象和数据库(以及映射器本身)彼此独立的情况下在二者之间移动数据的一个映射器层,如下: 1)运行机制: 主要功能:分离领域和数据源 延时加载 基于元数据的映射2)使用时机: 业务逻辑复杂,数据库方案和对象模型需要彼此独立演变时3)实例: 其中,DataMapper实现了IPersonFinder接口,用于查找方法实现。

February 1, 2019 · 1 min · jiezi

第九天-《企业应用架构模式》-领域逻辑模式

事务脚本1)调用数据库:事务脚本将所有逻辑组成单个过程,在过程中直接调用数据库,或者只通过一个简单的数据库封存器。2)脚本处理:每个事务都有自己的事务脚本,尽管事务间的公共子任务可以被分解成多个子程序。3)运行机制:a.事务脚本应该置于与其他处理表现层和数据源层的类相独立的类中,把事务脚本组织成类的两种方法:a. 将数个事务脚本放在一个类中,每个类围绕一个主题将相关的事务脚本组织在一起;b. 使用Command模式,每一个事务脚本对应一个类 (command)4)使用时机:业务逻辑简单场景(同时注意谨慎提取公共子程序以减少代码冗余),当业务复杂时则需要建立领域模型5)优点:当问题本身是简单的时,使用事务脚本可以加快开发速度,而且运行更快6)示例:假如有如下需求:数据库设计为:其中,RevenueRecognition表引用Contract表的Id作为外键。根据需求和数据库设计,事务脚本类图设计为:这里,Gateway为数据库访问封存器,RecognitionServices为事务脚本类。CalculateRevenueRecognitions方法用于计算并保存需入账信息(合同编号、时间、收费金额),RecognizedRevenue用于按照合同编号、指定日期查询已收费用。应用程序只需要分别单个调取这2个方法即可。2. 领域模型1)运行机制领域模型与数据库模型的区别:领域模型混合数据和处理过程,拥有多值属性和复杂的关联网,并且使用继承、策略、设计模式,是一张由互联的细粒度对象组成的复杂网络;使用领域逻辑的一个常见问题: 领域对象过于臃肿,可能会产生冗余代码数据库映射:简单领域模型可以使用活动记录,而复杂领域模型需要使用数据映射器。领域模型应当使用细粒度的对象,这些对象应有细粒度的接口。2)使用时机当业务规则复杂多变,涉及到校验、计算、衍生时。数据库交互方式:首选数据映射器3)示例:对于上文中需求,设计类图如下: 可以看到,这里收费方式使用了策略模式。3. 表模块表模块以一个类对应数据库中的一个表来组织领域逻辑,而且使用单一的类实例来包含将对数据进行的各种操作程序。表模块与领域逻辑的区别:如果有多个订单,领域模型对每个订单都有一个对象,而表模块则只用一个对象来处理所有订单(表模块没有标识符来标出它所代表的实体对象)。1)运行机制长处:允许你将数据与行为封装在一起,同时有可以充分利用关系数据库的优点2)使用时机当使用记录集存取表数据时使用(表模块很大程度上依赖于以表方式组织的数据) 3)示例:设计类图如下: 4. 服务层服务层定义了应用的边界和从接口客户层角度所能看到的可用操作集。它封装了应用的业务逻辑、事务控制及其操作实现中的响应协调。 1)运行机制业务逻辑分类:领域逻辑、应用逻辑两种基本的实现方法:领域外观方法:服务层以领域模型之上的瘦外观集合方式实现(负责实现外观的类不包含任何业务逻辑,所有业务逻辑均由领域模型实现)操作脚本方法:服务层由一组相对复杂的类组成,这些类直接实现应用逻辑,但将领域逻辑委托给封装好的领域对象类服务层接口时粗粒度的,必要时候可以远程调用(在服务层之上增加远程外观或者直接让服务层实现远程接口) 2)使用时机服务层优点:它定义了一个公共的应用操作集合,这个集合可被各种客户使用,而且服务层在每个操作中都会协调应用的响应。当业务逻辑有多种客户,或者用例响应中的多个事务性资源,则需要服务层

February 1, 2019 · 1 min · jiezi

第八天-《企业应用架构模式》-通盘考虑

思考三个方面的技术实践:持续集成、驱动测试开发和重构1. 从领域层开始1)事务脚本模式最简单,适合于在关系数据库之上构建;领域模型需要非常专业的技术,还有鱼数据库的连接;表模块模式折中,在.Net这类有非常强大记录集支持的环境非常合适2)理论上,可以根据架构来选取工具;实践中,可以让架构和工具相匹配2. 深入到数据源层1)事务脚本的数据源:可供选择的数据库模式为:行数据入口和表数据入口,两者之间选哪个取决于实现平台的方便以及系统未来的发展方向(如:开发平台所包含的工具,比如支持记录集合工具)2)表模块的数据源:有一个良好的记录集框架 -> 与表数据入口模式配合得天衣无缝3)领域模型的数据源:如果模型相当简单(如只有十几个与数据库相关的类),则活动记录即可;如果希望耦合更松一些,可以用表数据集入口或行数据入口;当更复杂性时,可以考虑使用数据映射器(工作单元模式取作用)3. 表现层1)如果情况允许,尽可能使用html而不是胖客户界面;2)如果走html路线,使用mvc;3).net使用页面控制器 + 模板视图,Java使用前端控制器 + 模板视图;4)站点面向文档,使用页面控制器,复杂情况下可考虑使用前端控制器;5)视图选择:模板视图(服务器页面)、转换视图(XSLT)4. 一些关于具体技术的建议5. 其他分层方式

January 30, 2019 · 1 min · jiezi

第七天-《企业应用架构模式》-分布策略

分布对象的诱惑:中间件的对象分布对上层透明崔然非常有用,但跨进程、跨机器(还有网络)调用,影响性能!2. 远程接口和本地接口: 1)远程访问的对象需要使用粗粒度接口,而本地访问的对象需要使用细粒度接口(优化性能时,本地接扣可以提供粗粒度对象) 2)基于1),就不能把在单进程中设计的类原封不动地搬到分布模型环境中 3)分布对象设计第一定律:不要分布使用对象! 4)怎样有效利用多处理器资源:使用集群系统(在每个处理器上都部署所有对象,每个处理器上的对象都只需要用到本地调用 -> 运行更快,还可以使用细粒度接口设计对象模型)3. 必须使用分布的情况 1)传统客户机/服务器架构 2)应用软件与数据库 3)web服务器和应用服务器(指的是web service么? 没搞懂!) 4)不同厂商的软件包4. 关于分布边界 1)远程外观:进程内使用细粒度对象,分布边界上放置粗粒度对象 2)数据传输对象:一般只引用其他数据传输对象和一些如字符串等原始类型对象 3)代理:用延迟加载来传递对象5. 分布接口 1)如果两个系统使用相同的平台构建,使用系统自己的远程调用机制高效得多!(web service虽跨平台,但传输数据来回转换增加不少开销) 2)使用http协议和远程面向对象API(没弄明白怎么玩) 3)异步、基于消息的处理方式

January 30, 2019 · 1 min · jiezi

第六天-《企业应用架构模式》-会话状态

无状态的价值:无状态可以仅用很少的对象就可以处理很多的用户,空闲状态的用户越多,无状态服务器就越有用2. 会话状态:相关性:会话状态只与当前会话有关,它存在于业务事务中,与其他会话及他们的业务事务是分开的;与记录数据信息的区别:记录数据时长期保存在数据库中的持久化数据,它对所有会话可见,会话状态需要提交成为数据库中的记录;最大问题:出现在处理隔离性的时候(同时操作,或者相关联操作)不能把会话中所有数据都看成是会话状态3. 存储会话状态的方法:1)存储会话状态的3种方法:客户会话状态:在客户端保存数据(在web中可用url、cookie、hidden域等)适用场景:会话数据较少、用户经常取消会话(如B2C用户直接关闭站点消失)问题:安全性、完整性服务器会话状态:在服务器内存、文件系统、一张简单的数据库表(以会话标识号为key、以已序列化对象为值)优点:容易直接访问会话状态数据库会话状态:在服务器端存储(将数据分解为多个表和域)优点:状态持久化不易丢失问题:隔离性差(需要将会话数据与记录数据相隔离)以上3种模式并不相互排斥,可以混合使用。使用时,还需要注意:客户机崩溃、服务器死掉、网络连接断掉2)会话扩容:会话迁移:允许一次会话从一台服务器转移到另一台服务器,从而可以有一台服务器处理一个请求,其他服务器处理其他请求优点:可均衡服务器缺点:难以找到会话状态,难以支持会话迁移服务器亲和:某次特定会话的所有请求只能由一台服务器处理 缺点:当客户端有使用代理是,可能会有大量负载集中在某台服务器上

January 30, 2019 · 1 min · jiezi

第五天-《企业应用架构模式》-并发

离线并发:多个数据库事务中支持多线程的各种应用服务器1. 并发问题:1)丢失更新(同时编辑文件,相继保存,最终丢失先保存者更新的内容)2)不一致性(读取期间,数据有更新)2. 执行语境:1)从与外界交互角度看的2个语境:请求:对应于软件工作的外部环境发出的单个调用,处理请求的软件会决定是否返回一个应答(过程大部分是在服务器端进行,而客户端则假设为在等待应答)会话:客户端和服务器端之间一次长时间的交互2)操作系统的2个语境:进程:重量级的执行语境,将其正在处理的内部数据域外部隔离开(有效隔离,减少冲突,但需要消耗很多资源)线程:轻量级的执行语境,一个单独的进程里可以存在多个线程(可以充分利用资源,但易导致并发问题)3. 隔离与不变性:企业应用2个解决方案:1)隔离:方案1:划分数据,使得每一个片数据都只能被一个执行单元访问(操作系统为每个进程单独分配一片内存,并且只有这个进程可以对这片内存进行读写操作)方案2:文件锁,一个人打开文件,其他人再无法打开或者只打开该文件只读拷贝并且不能修改(好的并发设计应该是:找到各种创建隔离区的办法,并且保证在每个隔离区里能够完成尽可能多的任务)2)不变性:方案1:识别哪些是不变的数据(只有在共享数据可以修改的情况下,并发问题才会出现),不用考虑这些数据的并发问题二广泛地共享它们方案2:把那些只读取数据的程序分开,让他们只是用拷贝的数据源4. 乐观并发控制盒悲观并发控制:1)2种锁:乐观锁:关于冲突检测的(仅当提交更新时才检查冲突)优点:并发性高,限制较少,使用起来比较自由缺点:业务数据比较复杂,难以自动合并,并且使用者难以发现差别时,只能丢弃原有数据,从头开始更新悲观锁:关于冲突避免的(只要有人已是用当前数据或者文件,拒绝其他人使用当前数据或文件)优点:减少并发程度缺点:用户体验差两种策略选择标准:冲突的频率与严重性(冲突少或者冲突后果不严重时,选择乐观锁;否则选择悲观锁)2)避免不一致性:a. 检测不一致读:悲观策略:通过读加锁(read lock,共享锁)和写加锁(write lock,排他锁),可以一次多个人对同一份数据加只读锁,但只要有人得到一个只读锁,其他人就都无法得到写锁;一旦有人得到一个写锁,其他人都不能得到两种所中任意一种乐观策略:基于数据的某种版本标识(时间戳或者顺序计数器),核对将要更新数据的版本标识和共享数据的版本标识,如果两者一样,系统允许更新数据并更新共享数据的版本标识b. 时序读:每次读取数据时都是用某种时间戳或其他不变的标签作为约束条件,数据库根据时间或者标签返回数据(源代码控软件可以用,但数据库比较困难并且代价昂贵)3)死锁:处理死锁的方法:a. 用软件来检测死锁的发生,选择一个牺牲者,放弃他的工作和他所加的锁;b. 给每个锁都加上时间限制,一旦达到时间限制,所加的锁就会失效,工作就会丢失;防止死锁的方法:强制人们在开始工作时就获得所有可能需要的锁,在此之后就不再允许得到更多的锁;可以硬性规定每个人获得锁的顺序(如按姓名字母顺序)5. 事务:1)ACID:原子性、一致性、隔离性、持久性2)事务资源:定义:可以进行事务处理的任何事物事务控制方法:保证事务尽可能短(尽可能不让事务跨越多个请求,跨越多个请求的事务称为长事务);尽可能晚打开事务3)减少事务隔离以提高灵活性:SQL的4种隔离级别:可串行化的、可重复读、读已提交、读未提交不必给所有的事务设置相同的隔离级别,而应该仔细观察每个事务并根据每个事务具体情况来决定如何权衡灵活性与正确性4)业务事务和系统事务:系统事务:由关系数据库系统和事务监视器所支持的事务 (一般不用干预)业务事务:简单办法:在单个系统事务中执行完整的业务事务(产生长系统事务);复杂的,采用离线并发(通过工作单元来保存更新数据)6. 离线并发控制的模式:乐观离线锁、悲观离线锁7. 应用服务器并发:每会话一线程 VS 每会话一进程:线程节省资源,但创建和进入隔离区很重要

January 27, 2019 · 1 min · jiezi

第四天-《企业应用架构模式》-WEB表现层

构建web服务器上应用程序的2种方法:1)使用脚本:CGI、Java Servlet,通过write stream操作输出字符串;适合于解释请求消息2)使用服务器页面:把程序和返回文本也组合在一起,在html中编写返回页面(Asp、php、jsp等);适合于格式化应答消息1. 视图模式:1)转换视图:特点:使用程序的一种转换风格(如XSLT)2)模板视图:特点:允许你在网页结构中编写表现层,并允许在网页中嵌入标签,用以知名网页中动态内容需要导向到哪里(如ASP、JSP、PHP等) 优点:提供强大功能、灵活 缺点:代码混乱以至于难以维护3)两步视图:2个阶段:由领域数据产生一个逻辑屏幕,然后把它发送到html网页中。(每一个屏幕都有一个第一阶段的视图,而整个程序中只有一个第二阶段的视图)优点:它可以决定把什么样的html网页用在一个地方,全局改变html变得容易缺点:当站点设计得过分精细时,通常不容易提取出很好的逻辑屏幕结构2. 输入控制器模式:1)输入控制器2个责任:处理http的请求消息;根据请求的消息来决定下一步做什么2)2个模式:为每个页面准备一个输入控制器,输入控制器再创建适当的对象来完成处理,并实例化适当的视图来返回结果;单个对象处理所有请求消息,创建一个分离的对象来处理它(前端控制器)。【当站点行为结构有所改变时,可以避免重新配置web服务器】

January 26, 2019 · 1 min · jiezi

第三天-《企业应用架构模式》-映射到关系数据库

关系数据库之所以取得成功,最重要的原因之一就是SQL的存在,它是数据库通信标准语言。1. 架构模式:驱动领域逻辑访问数据的方式:SQL语句嵌入在程序设计语言中;行数据入口、表数据入口:把SQL访问从领域逻辑中分离出来,并把它放到独立的类中(让它们以数据库中的表结构为基础,每一个数据表对应一个类),这些类为数据库建立了一个入口;活动记录:领域模型简单时,每个领域对象负责对应数据库的表的存取过程数据映射器:领域模型复杂时,处理数据库和领域模型之间的所有存取操作,并且允许双方都能独立变化面向对象数据库:领域模型不管有多复杂,均可使用(因为风险,使用不多)。主要好处在于能够提高生产率!2. 行为问题:1)所谓行文问题,就是如何让个中对象从数据库中读取出来以及存到数据库中2)工作单元:充当数据库映射的控制器,会跟踪所有从数据库中读取的对象以及所有以任何形式修改过的对象,并将更新提交到数据库(用来解决内存对象和数据库中数据同步的问题)3)标识映射:在标识映射里记录读取的每一行,防止同一对象重复加载4)延迟加载:减少领域模型每次读取的数据3. 读取数据:1)查找器:读取数据的时候,可以把读取数据的方法看做一个查找器2)查找器对象:如果数据库交互类基于表,把插入和更新操作也绑定在查找器方法中;如果数据库交互基于行的类,创建独立的查找器对象(每个查找器类都有很多封装了SQL语句的方法,当执行查询操作时查找器对象返回一个适当的基于行的对象集合)3)读取数据性能经验法则:如果需要,尽量一次读取多行;需要多个表数据时,使用Join4. 结构映射模式:1)关系的映射:解决关系表间关联关系和对象间引用关系的方法:通过对象中的一个标识域来保持每个对象的关系特性,并且通过查找这些值来保持对象引用和关系键之间的相互映射对于一些小的值对象(比如日期范围和钱),不需要用标识域来把对象间引用变为外键(不应该描述成数据库中它们自己的表),而应去除值对象中所有的域,以嵌入值方式把它们嵌入到关联对象中也可以通过序列化LOB将一组对象存储为表中的单个列2)继承:单表继承:为继承体系层次中的所有类建立一个表(修改容易并且避免join,但每一行都必须为每种可能地子类博阿六一些列,浪费空间)具体表继承:为继承体系层次中每个具体类均建立一个表(避免join操作,允许从一个表中获取一个对象,但改变起来比较困难,如对超类的任何改变都不得不改变所有的表和映射代码)类表继承:为继承体系层次中每个类均建立一个表(需要多个join操作来载入一个对象,通常会损失性能)以上3种模式,需要考虑自己的环境和偏好(Martin倾向于:使用单表继承,用另外2个模式辅助来帮助解决不可避免的不相关和无用列问题)5. 建立映射:自己选择数据库方案:使用经典数据库设计技术围绕数据来设计表,使用行数据入口或者表数据入口把SQL从领域逻辑中剔除使用已存在数据库方案:简单的领域逻辑可创建行数据入口或者表数据入口类来模拟数据库,并在此之上创建领域逻辑。复杂的逐步建立领域模型并包含数据映射器对于多个数据源:建立多个映射层,每个数据源一个。 如果数据非常类似,可把数据从内存方案中转化到逻辑数据存储方案,映射从逻辑数据存储方案到实际物理存储方案(第二部包含区别)6. 使用元数据:元数据映射基于把映射浓缩到元数据文件的方法。元数据文件详细描述数据库中列如何映射到对象的域。如:7. 数据库连接:数据库连接池8. 其他问题:select * from 的问题多使用预编译好的静态SQL

January 25, 2019 · 1 min · jiezi

第二天-《企业应用架构模式》-组织领域逻辑

模型抉择:1)领域逻辑复杂度: 2)抉择: 领域逻辑复杂度较低时,选择事物脚本; 如果开发环境拥有大量基于记录集的工具(.Net和VS),可以选择表模块; 开发小组经验丰富时,选择领域模型; 3种模式并不互相排斥,可以同时使用2. 服务层: 1)服务层是从领域层分离出来的,用于置于底层的领域模型或表模块之上 2)服务层用于放置事物控制和安全等功能 3)如果确实需要,服务层尽可能最小化(充当于一个Facade层)

January 24, 2019 · 1 min · jiezi

第一天-《企业应用架构模式》-分层

分层优缺点:1)优点:在无需过多了解其他层次的基础上,可以将某一层作为一个有机整体来理解;可以替换某层的具体实现,只要前后提供的服务相同即可;可以将层次间的依赖性减到最低;分层有利于标准化工作;一旦构建好了某一层次,就可以用它为很多上层服务提供支持2)缺点:层次并不能封装所有东西,有时会带来级联修改;过多层次会影响性能;决定建立那些层次以及每一层的职责是什么难以决定2. 企业应用中层次的演化:C/S(领域逻辑放在客户端) -> 领域逻辑放到数据库,作为存储过程 -> 三层架构:表现层 + 领域层 + 数据源层3. 三个基本层次:职责如下:层次职责表现层提供服务,显示信息(例如在Windows或HTML页面中,处理用户请求(鼠标点击、键盘敲击等),HTTP请求,命令行调用,批处理API)领域层逻辑,系统中真正的核心数据源层与数据库,消息系统、事务管理器及其他软件包通信其中,领域层,也称为业务逻辑。它的相关工作:对表现层输入的数据进行验证,根据输入数据或已有数据进行计算,根据从表现层接收到的命令来确定应该调度那些数据源逻辑4. 为各层选择运行环境:1)运行环境:1.数据源层:服务器2.表现层:胖客户,客户端;web:服务器端 (只要可能就用web表现方式,只在必须的情况下才使用胖客户方式)3.领域层:全部运行在服务器端,或者全部运行于客户端,如果必须要分离则至少保证相关的部分在一起2)一旦选择了处理节点,尽可能使所有代码保持在单一进程内完成(可能拷贝在集群中的多个节点上),否则不但损失性能,还会增加复杂性3)复杂性增压器:分布、显示多线程、范型差异(如对象/关系)、多平台开发以及极限性要求

January 23, 2019 · 1 min · jiezi