架构风格:微服务
本⽂探讨:
什么是微服务
微服务的约束
微服务对架构属性的影响
什么是微服务
「微服务」是⼀种架构风格,也就是说,「微服务」是⼀组架构约束。
前⾯说到REST是⼀种复合式的架构风格,微服务也是!微服务的约束⾯更⼴,它对开发过程和开发⼈员也进⾏了约束!
微服务的约束
MartinFlower在Microservices⼀⽂中,详细阐述了微服务所需要具有的约束!
- Componentization via Services:基于服务的组件化
- Organized around Business Capabilities:围绕业务能⼒进⾏组织
- Products not Projects:产品⽽不是项⽬
- Smart endpoints and dumb pipes:智能终端和静默管道
- Decentralized Governance:去中⼼化治理
- Decentralized Data Management:去中⼼化数据管理
- Infrastructure Automation:基础设施⾃动化
- Design for failure:容错性设计
- Evolutionary Design:进化式设计
实际上这些约束回答了架构设计所关⼼的⼏个问题:
系统如何切分:围绕业务能⼒进⾏组织,去中⼼化数据管理
模块之间如何通信:基于服务的组件化,智能终端和静默管道
如何进⾏技术选型:去中⼼化治理
容错性:容错性设计
扩展性:产品⽽不是项⽬,进化式设计
可维护性:基础设施⾃动化
下⾯⼀个个的说明!
系统如何切分?
在「」⼀⽂中,最后提到,⼀般情况下,当你不知道⼀个系统使⽤何种架构⽐较好时,可以先使⽤分层架构。分层架构就是将系统⼀层⼀层的切分,下层为上层提供服务。
每⼀层的边界是什么呢?是「系统功能」!展现、业务逻辑、数据存储。你会发现,这种切分⽅式和业务本⾝没有任何关系,所以才是「万⾦油」!
另外,这种切分⽅法也将开发⼈员划分成了前端、后端、DBA!这是⽬前主流的做法,好像也没有出现什么⼤问题!
如果你在⼤公司待过,你就会发现进⾏⼀个需求变更是多么⿇烦的⼀件事。即使⼀个很简单的需求,都可能要所有团队都参与进来。
导致这个问题的原因是什么呢?是沟通成本!
项⽬管理算法的复杂度是O(N 2),当⼈员变得越来越多时,沟通成本成倍增长:
5⼈团队,需要沟通的渠道是 5*(5–1)/2 = 10
15⼈团队,需要沟通的渠道是15*(15–1)/2 = 105
50⼈团队,需要沟通的渠道是50*(50–1)/2 = 1,225
150⼈团队,需要沟通的渠道是150*(150–1)/2 = 11,175
我们都知道「技术是为业务服务的」!如果⼀个架构和业务没有关系,如何为业务服务呢?如果沟通要花费⼤量的时间,如何快速推进项⽬呢?
所以,微服务「围绕业务能⼒进⾏组织」!
既包括了系统的切分
也包括了对⼈员的组织
因为康威定律提到:
"Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations." - Melvin Conway (1967).
在微服务中,每个模块(这⾥的模块和我们平常所理解的模块有些区别,它的粒度更⼤,所以在微服务⾥⼀般称为是服务,下⾯均使⽤「服务」)都是⼀个完整的业务系统!包括了展现、业务逻辑和数据存储!相应的,负责开发的⼈员需要具备开发这个服务所需要的所有技能!
也就是说,在微服务中服务的边界是业务的边界!
这很类似韩都⾐舍的「以产品⼩组为核⼼的单品全程运营体系(IOSSP)」!将企业划分为“⼩集体”,像⾃由⾃在重复分裂的“阿⽶巴”——以各个“阿⽶巴”为核⼼,⾃⾏制订计划,独⽴核算,持续⾃主成长。以3⼈⼀组的产品组为例,这三个⼈分别是设计师、页⾯制作、库存管理员。这三⼈全权负责某⼀单品的页⾯制作、款式设计、尺码以及库存深度的预估等⼯作。
对应到微服务中,即两到三个⼈负责⼀个服务,这个服务包含了完整的业务流程,开发⼈员需要掌握开发这个服务所需要的完整的技能,包括UI、编程、DBA!
这⾥的难点是:
⼀是要划分好业务边界,使得每个服务能够⾼内聚、低耦合!
⼆是制定规范,利于各个服务之间的通信
三是⼈员技能的要求更⾼
如何进⾏业务划分,需要根据具体的业务来具体进⾏。这⾥暂不展开。只提⼀点,就是要将事务考虑在内!
就是说在切分系统的时候,要考虑事务问题!我们都知道远程事务是⼀个⽐较难处理的问题!两阶段提交、三阶段提交都不能很好的解决分布式事务问题!Paxos算法过于复杂,且性能较差。
所以微服务的建议是:
尽量保证事务在⼀个服务中执⾏
通过补偿的⽅式来弥补事务操作的问题
服务如何通信?
对于⼀般系统来说,我们都是使⽤的进程内通信,即通过调⽤同⼀内存内的⽅法的⽅式进⾏通信!公⽤的代码我们可以以「库」的形式进⾏组织,避免代码重复!这种系统我们⼀般称为「单体系统」!
「单体系统」的伸缩性不理想!⽐如说,双11需要做个活动,瞬间⽤户量⼤增!如果需要应对流量峰值,就需要对系统进⾏扩容。但是因为是单体系统,扩容只能整体扩容,⽽实际上需要扩容的只是那个活动页⾯!这就导致了资源的浪费。另外⼀个问题就是,如果这个活动导致了系统崩溃,这将导致这个系统的所有功能都不能使⽤!
⼀种解决⽅案是进⾏「服务化」!即将需要多个系统公⽤的逻辑或TPS较⾼的模块独⽴部署,通过进程间通信的⽅式,进⾏服务调⽤。⽐如上⾯的活动模块,当活动模块以服务的⽅式对外服务后,需要扩容时,只需要扩容活动服务就可以了。同时,如果活动服务出现了问题,只会导致这个活动相关内容⽆法访问,⽽不会影响系统的其它功能。今年双11淘宝的地址服务就挂了,但是并不影响淘宝本⾝的访问。
这⾥所说的「服务化」是使⽤dubbo这类服务化框架进⾏的服务化,⽽不是使⽤ESB的SOA!
基于ESB的SOA主要是为了将企业中的各个系统连接起来!ESB像⼀根「聪明」的管道,⽤来连接各个「愚笨」的节点。为了集成不同系统,不同协议的服务,ESB做了很多事情:
消息路由
编排
转换
业务处理规则
这就导致ESB很重、很复杂。这也是基于ESB的SOA被⼈诟病的⼀个原因。
dubbo这类服务化框架主要解决的是运⾏时代码复⽤、系统伸缩性以及⾼性能问题!但是服务粒度相对较⼩,带来的问题就是维护的成本相对较⾼!
⽽微服务可以说做了⼀些折中:
服务粒度较⼤,包含了⼀个完整的业务的展⽰、逻辑和存储。相对的数量就较服务化少,维护相对较容易
分布式和微服务的关系以进程间通信的⽅式提供服务。包括对外服务、以及其它服务。保证了伸缩性。
业务逻辑处理都在服务内部进⾏,通信组件只提供单纯的通信功能。保证了简单性。
这样既摆脱了繁重的ESB,也降低了维护难度!
如何进⾏技术选型?
对于「如何进⾏技术选型」,微服务不强制开发平台!因为「没有银弹」!微服务偏向于「适合的⼯具解决适合的问题」!
每个程序员都有⾃⼰喜欢的技术体系!有喜欢Java的、有喜欢.Net的、有喜欢C++的,还有喜欢Lisp的。。。。
那开发系统时需要选择哪种技术体系呢?按微服务的观点就是:哪种技术合适就⽤哪种技术吧!这个服务需要⾼并发,可以⽤Go来进⾏开发!这个服务需要快速推进,可以⽤PHP!这个服务需要稳定,可以⽤Java!看起来很完美!
⽽实际上内,这导致的是不可控!为什么Java语⾔会被很多企业使⽤?其中⼀个原因就是可控!
举个例⼦,国内公司的技术栈相对⽐较单⼀!⽐如,公司的主流语⾔是Java,.Net,PHP等,其它语⾔就只是辅助!⼀般不会有两种、甚⾄三种主流语⾔!
假设⼀家公司的主流语⾔是Java!开发⼀个系统,可能需要10个⼈。那公司可以招5~6个⼀般的,2~3个不错的,1个⽜逼的!公司只要稳住那个⽜逼的就⾏了!如果有⼈⾛了,只要其他⼈顶上就⾏了!
⽽如果每种服务都使⽤不同的语⾔,那⼀个系统使⽤了三个左右的语⾔,每种语⾔得有个熟练掌握的吧?每种语⾔,公司都得稳住个相对⽜逼的吧?成本⾼不说,难度也⼤了不少!
容错性
系统按照业务切分为⼀个个的服务,相对单体应⽤来说,运⾏的系统多了,系统整体不可⽤的⼏率降低了,但是单个服务出现问题的⼏率却变⼤了!这就需要微服务系统需要有⽐单体应⽤更好的容错性!
任何服务可能因为供应商的不可靠⽽故障,客户端需要尽可能的优化这种场景的响应。与单体构架相⽐,这是⼀个缺点,因为它带来额外的复杂性。这将让微服务团队时刻需要关注服务故障的情况下的⽤户体验。
由于服务可能随时出现问题,所以快速故障检测,甚⾄⾃动恢复就变更⾮常重要。微服务应⽤把实时的监控放在应⽤的各个阶段中,检测构架元素(每秒数据库的接收的请求数)和业务相关的指标(每分钟接收的订单数)。监控系统可以提供⼀种早期故障告警系统,让开发团队跟进并调查。
这⼜⽆形中提⾼了对开发⼈员的技术要求!
扩展性
对于互联⽹产品来说,这是个必选项!
以前在⽹上看到过⼀句话,⼤意是:「当你有⼀个想法的时候,世界上可能有1万个⼈也有这个想法!其中1000个⼈已经开始做了!100个⼈已经做完了!10个⼈已经运营了!1个已经盈利了!」
也就是说,相同的产品千千万。⽤户为何就偏爱你这款?
你的系统需要有核⼼竞争⼒,来吸引新⽤户!同时还需要不断的加⼊新功能,保持⽤户不流失!
可维护性
服务的数量增加了,维护的成本也就相应的增加了。除了上⾯提到的通过降低沟通成本来提⾼可维护性外,微服务还通过「基础设施⾃动化」来降低维护难度!
基础设施⾃动化有如下⼏个原因:
由于微服务的服务较单体应⽤会多了很多,这就导致了部署微服务较部署单体应⽤来说要复杂得多。单纯的靠运维来⼿动部署不现实部署的服务较多,且是⽹状通信,导致了⼀个请求可能会调⽤多个服务,对于请求的追踪不能像单体应⽤⼀样,靠⽇志来跟踪。需要追踪请求。
当请求异常时,或服务异常时,需要能⾃动的处理⼀些常见情况(也涉及上⾯的「容错性」)
参考资料
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论