本文首发胖波聊架构界,微信公众号:xiaobo2as。
本文概要
如何从单体架构平滑过渡到微服务。
结语
一、导言
同程微服务从立项到实施推广已经走过了整整两个年头,从最初的简单粗糙到今天的精细完善,接入服务数量也实现了从1到10,000+的增长。
微服务开发团队和大家一起踩过了无数的坑,回顾爬坑记录,现整理一些爬坑心得体验供大家参考,最终打造了今天的DSF2.0平台,也斗胆提出一些最佳实践以抛砖引玉。
下文将从开发者角度对微服务如何拆分,版本管理和单体到微服务过渡等方面给出一些建议, 供大家斟酌。
二、微服务拆分的四个维度
从单体架构到微服务,拆分粒度很难把握,理论方法莫衷一是,我们推荐快刀斩乱麻按照如下四个维度做拆分:。
团队组织结构
发布升级频率
逻辑调用频率
数据读写分离
1. 团队组织结构
同程是树形结构+底层网状结构,那么服务之间一定是每个系统的架构呈明显的树状,组织结构一定会反映到系统架构上,但是系统之间会有多重的服务互访,按照康威定律的说法。
微服务设计要充分考虑哪些是自用(inner),外部访问(outer)和混用(mix)服务,并尽可以能将其迁移对应的服务组里。
2. 发布升级频率
应该尽量将处于生命周期中不同阶段的接口分割,避免向稳定运行的服务组添加新业务接口,新老项目由于处于生命周期的不同阶段,而是应该考虑在新的服务组中实现,避免高频更新服务和低频更新服务捆绑,修改和发布频率会有很大差别。
3. 调用频率
而高频调用肯定会占据更多的资源,需要对高频访问的服务设置定制的运行策略,所以应该将高低频访问的服务分割以使其能为获得更好的性能和可靠性做针对性优化,会造成巨大的资源浪费事实上也没有必要,服务组中的不同服务调用频率会有巨大差别,会出现个别接口耗尽资源导致同组接口一起失败(资源竞争),调整部署使其尽可能靠近数据源等策略,如分配更多的CPU核心数和内存,但是如果将所有服务宿主都做成高配。
4. 数据读写分离
上一维度其实已经涵盖了读写分离的一部分,但是为了突出读写分离的必要性,这里单独列出,一般数据操作模式分为CQRS和CRUD两种模式,各有优缺点。
分拆为两个服务组发布,写操作经常会有更严格的认证授权机制,一般来说写操作的频率会大大低于读操作,可以粗略的分为读写两类,因此建议流量较大或较为核心的服务应该做读写分离,从操作是否对数据本身造成影响来看,一般为内部(inner)调用,这些和读操作都有巨大差异性。
对应一个独立的数据表或库,最后分享一个粒度控制的小技巧,所以系统里出现的名词都可能是一个潜在的微服务,大多数情况出现在系统里的每个名词都会在存储层面拥有一席之地。
三、微服务应该如何维护版本
根据我们长期的爬坑实践我们推荐如下版本策略:,反之无版本或混乱的版本升级策略迷惑开发和设计人员并带来意想不到的依赖问题,良好的微服务治理应该包含一整套完整的版本升级策略,直观的版本会给系统开发过程和服务依赖管理带来巨大的便利,微服务治理中维护一个有序。
1. 使用标准语义化版本
使用标准的语义化版本能使大家保证对版本有统一的理解,SemVer版本一般为三位(x.y.z 对应:主版本号.次版本号.修订号),具体参见 语义化版本 2.0.0,应尽量避免自行定义版本语义,前两位作为主版本(1.2),DSF 版本推荐使用SemVer 约定,略有不同的是DSF推荐四位版本号(1.2.3.4)。
2. 面向契约设计
团队成员有明确的职责划分,需要团队自身已经是一个较为成熟运作体系,团队成员对服务内聚和服务耦合有明确的认知,当一个团队选择微服务作为服务化实施平台时必须明确微服务化有一个较高的门槛,例如有实施前有完善的架构设计。
最终能够在服务实施前就能交付有良好兼容性的服务契约,实际开发不轻易的修改和增添服务接口,上述的这些方面都会促成一个结果: 使设计开发的服务接口最终具有良好的抽象并体现出规划性,实践中体现为一个版本迭代新增、修改、删除的任何部分都是经过慎重思考并体现在服务契约里。
3. 并行开发中版本的维护
微服务使开发者从单体架构的调用丛林摆脱出来,微服务化对开发体系的一个重大影响就是开发实践的并行化,使开发者能够把视野聚焦到调用链中其中一环上而不用过多关心上下游的具体实现。
需要付出的成本就是如何避免重复实现以及代码Merge时的更高频的冲突问题,有一个良好的版本管理习惯能够解决绝大部分的Merge冲突问题。
而负责使用该核心模块的其他开发者在该版本上递增版本,通过团队内沟通确定不对外暴露的核心部分由谁来负责并约定在特定的版本实现,我们推荐在面向契约设计的基础上进一步延伸。
被其他组件依赖较且可能频繁改动的内核代码独占一个特定的版本区间(例如:v1.2.3.0~1.2.3.10作为核心模块的独占版本,依赖该组件的模块必须大于v1.2.3.10),能很好隔离并行开发带来的版本冲突问题。
因为引用核心组件的上层实现彼此没有太多联系,总是能够很好处理Merge带来的冲突问题。
4. 版本的兼容性
能根据版本号判断服务是否向后兼容是服务依赖管理的一个很重要的方面,大多数时候做一个使服务不在向后兼容的决定是很难的事,但是不断的向后兼容的结果往往是服务体量不可控制的增长和系统复杂度的非线性上升。
良好的版本策略能将服务是否向后兼容明确的表达出,显式的告诉调用方这是一个不兼容的升级更新,开发者需要慎重思考并在合适的时间做出服务不再向后兼容的决定,请务必确保仔细阅读的新的契约文档并做了足够的测试。
任何服务契约修改都被认为是不兼容的升级,都必须升级大版本号,而修改小版本号(版本号的后两位,小版本号为3.4)则代表兼容性升级,如v1.2.3.4,如v1.2.3.4,只需观察服务组的大版本号(版本号的前两位,如新增了服务接口,大版本号为1.2)是否增加,对DSF来说不兼容升级是很醒目的,包括删除接口、修改接口名称/参数等,代码逻辑优化和Bug fix但是未修改服务契约。
四、如何从单体架构平滑过渡到微服务。
一旦决定在开发实践引入微服务架构,如何将积累下来的庞大的巨无霸系统润物细无声的的过渡到微服务架构将是一个巨大的挑战。
推倒重来激进革命路线是要不得的,架构师们最想通过微服务化取代的部分往往是公司的主要盈利核心,改造难度不亚于飞行中更换引擎,从业界公开的信息来看还没有哪家做到了完美升级,更多的可能无外乎两种:。
第一种改造后苟延残喘,研发疲于奔命。
另一种则是改造中就直接休克。
因此为使微服务能顺利的应用,架构师从不应该幻想一蹴而就,无数次的碰壁后我们给出如下的爬坑建议:。
1. 培训先行
这就造成一个悖论:能用技术解决的问题就不是问题,真正的问题在受限的情景下仅靠技术是解决不了的,工作技术人都很善于把面临的问题变成技术问题,实施微服务最大的拦路虎也不是技术本身,然后在自己最擅长的领域里取解决掉。
最大的问题不是如何做好微服务,而是就微服务应该是什么达成一个一致的看法,从我们的实践来看。
正所谓林子大了什么鸟都有,这个不是说我们都是用dubbo或者都是用spring boot就能解决的,对于微服务100个人可能就有100种理解。
使用那种命名方法不重要,应用在哪些场景里是不适合的,微服务不是什么,重要的是大家都使用同一种命名方法,运用在哪些场景是适合,我们的推荐做法就是实施前通过多数人参与的大讨论和培训,让多数人能达成一致的认识,微服务是什么,和编码规范中命名规范一样,结果不要跑的太偏就行。
2. 绞杀者模式
绞杀者模式指对于无法通过修缮者模式改进的系统通过在系统外重新构建新功能的方式逐步剥离重构,对功能服务逐个绞杀。
好处是不影响原来的环境,一旦条件成熟就能快速切换。
不好的方面则是可能需要有一段时间同时维护两套系统,付出额外的开发维护成本。
3. 监狱模式
往往需要开多个监狱窗口,还有一种同程内部称之为监狱模式的做法,允许一些短期无力改动的系统通过监狱窗口(MicroProxy)接入微服务平台并委托Proxy将其暴露成微服务,单体架构往往拥有庞大的服务接口梳理。
每个监狱窗口都会被包装分割成微服务,条件成熟了能很方便的替换成原生微服务,称为刑满释放。
五、结语
特点是在务虚处浓墨重彩,于实践处则一笔带过,市面上微服务的理论和讨论铺天盖地,高谈理论,其中不乏侃侃而谈的大块文章,深入阅读确常常发现大都是新瓶装旧酒或者拼凑篇幅之作,仔细探究则实无一物。
所以如果发现有些技术书籍晦涩难懂,满篇的高大上,读完头脑发胀,确无所进益可能不是您水平不够,更可能是作者故弄玄虚,最近读书有感,书于此,博君一晒。
转载此文请保持文章完整性,并请附上文章来源(ITPUB)及本页链接,本文由 技术琐话 发布在 ITPUB。
原文链接:/2019/05/27/1957/。
北京市卫健委 提醒,今日是国庆节假期最后一天,面临进返京高峰,出京旅行
“秋天的日子是半透明的 涂在金色的土地和田野上” 如果有一个季节,能让整
最美的风景在路上,最美的路上有风景。一条条公路串联湖北的名山大川、多彩
从靠山水到卖场景 从卖特产到拼创意 乡村旅游越来越好玩 “采摘”“收割”“
老君山两日自由行攻略,不抱团,自己做大巴或开车去攻略。有爬山和做索道两
旅游出行方式的简单比较 出游 方式 项目 比较 特点 优点 局限性 适合人群 适合
一年四季,寒来暑往,春夏秋冬,风景各有各的美。而自驾旅游的魅力,就在于
从北京海淀出发,自驾140公里左右,就可以看到另外一番天地。 这里是高山草
我们都是时间的旅行者, 为了寻找生命中的光。 终其一生,行走在漫长的旅途
原标题:三月赏花游 户外踏青走起 文、图/广州日报全媒体记者罗磊 通讯员柳