单体地狱
单体架构的好处:
应用的开发很简单
易于对应用程序进行大规模的更改
测试相对简单直观
部署简单明了
横向扩展不费吹灰之力
什么是单体地狱:
过度的复杂性 系统过于庞大、复杂,任何一个开发者很难理解它的全部,修复问题,实现功能变得困难耗时,开发者更改时容易出错。
开发速度缓慢 如此庞大的项目,构建、启动变得缓慢,严重影响团队工作效率。
从代码提交道实际部署的周期很长,而且容易出问题 众多开发人员向同一个代码库提交代码更改,这使得代码库构建结果处于无法交付的状态,功能分支的解决方案又会带来漫长而痛苦的合并过程。一个更改可能牵一发而动全身,运行测试需要很长时间。
难以扩展 有时候应用的不同模块对资源的需求是相互冲突的,有些数据保存需要较大容量内存,有些图片处理模块需要高性能CPU,单体架构下服务器必须满足所有模块的需求。
缺乏可靠性 由于程序庞大无法进行全面彻底的测试,代码中的错误会进入生产环境;模块之间缺乏故障隔离。
需要长期依赖某个可能已经过时的技术栈 在单体上采用、尝试新技术是极其昂贵,高风险的,而尝试其他语言也做不到。
拯救之道:微服务架构
软件架构对功能性需求影响并不大,它影响非功能性需求,即质量属性或者其他能力,如交付速度的可维护性、可扩展性和可测试性。
优秀的团队可以减缓陷入单体地狱的速度,但无法避免大型团队在单体应用上协同合作的问题,不能解决日益过时的技术栈问题。
扩展立方体和服务
X轴扩展在负载均衡器之后运行多个相同的单体应用程序实例
Z轴扩展在路由器后面运行单个应用程序的多个相同实例,路由器根据请求属性进行路由,每个实例负责数据的一部分子集
X轴与Z轴有效提升了应用的吞吐量和可用性,但没有解决日益增长的开发问题和应用复杂性。Y轴扩展将应用程序拆分为一组服务,每项服务都负责特定的功能。使用X轴扩展以及可能的Z轴扩展来扩展这些服务。
微服务架构的定义:把应用程序功能性分解为一组服务的架构风格。
微服务架构作为模块化的一种形式
模块化是开发大型、复杂应用的基础。单体应用中可以通过包等形式来定义模块,但随着时间推移,单体应用往往蜕变为一个大泥球。微服务架构中,服务的API构筑了一个不可逾越的边界,使模块化服务更容易随时间推移而演化。另外每个服务可以独立部署、扩展。
每个服务都拥有自己的数据库
开发者可以修改自己的服务的数据库模式,不必同其他服务的开发者协调。运行时,服务实现了相互之间的独立,不会因为其他服务锁住了数据库而进入堵塞状态。
微服务与SOA的异同:
SOA | 微服务 | |
---|---|---|
服务间通信 | 智能管道,采用重量级协议,如SOAP或其他WS*标准 | 使用用哑管道,如消息代理,服务间的点对点通信,使用REST或gRPC等轻量级协议 |
数据管理 | 全局数据模型共享数据库 | 每个服务都有自己的数据模型或数据库 |
典型服务规模 | 较大的单体应用 | 较小的服务 |
服务微服务架构的好处与弊端
微服务架构的好处
-
使大型的复杂应用程序可以持续交付和持续部署
具有可测试性、可部署性、开发团队能够自主且松散耦合
每个服务都相对较小且容易维护
服务可以独立扩展
更好的容错性
更容易实验且采纳新的技术
微服务架构的弊端
服务的拆分和定义是一项挑战。
分布式系统带来的各种复杂性,如服务间必须使用进程间通信机制,必须设计服务处理局部故障,处理远程服务不可用或出现高延迟的各种情况。它还引入了运维复杂性。
当部署多个服务的功能时需要谨慎地协调更多开发团队。
开发者需要思考到底应该在什么阶段使用微服务架构。初创公司几乎肯定要从单体应用程序开始,但问题变为如何处理复杂性时,就是将应用功能性分解为服务的时候了。
微服务架构的模式语言
微服务架构并不是“银弹”
模式和模式语言
模式是针对特定上下文中发生的问题的可重用性解决方案。
软件模式通过定义一组互相协作的软件元素来解决软件架构或设计问题。
模式必须描述它所使用的上下文场景。
常用的模式结构包括三个重要部分:
需求
描述了必须解决的问题和围绕问题的特定上下文环境,需求的重要性取决于上下文环境,必须把需求按优先级排序
-
结果上下文
好处、弊端和引入的新问题
-
相关模式
五种不同类型的关系
前导模式:是催生这个模式的需求的模式,如微服务架构是除单体架构模式外整个模式语言中所有模式的前导模式
后续模式:用来解决当前模式引入的新问题的模式
替代模式:提供替代当前模式的解决方案
泛化模式:针对一个问题的一般性解决方案。如某个模式存在多种不同的解决方案
特化模式:针对特定模式的具体解决方案。
微服务架构的模式语言概述
服务拆分的相关模式:
围绕业务功能组织服务,或根据子域分解,子域围绕DDD来组织服务
通信的相关模式:
通信风格:使用哪一类进程间通信机制?
服务发现:客户端如何获得服务具体实例的IP地址?
可靠性:服务不可用情况下,如何确保服务间的可靠通信?
事务性消息:如何将消息发送、事件发布这样的动作与更新业务数据的数据库事务集成?
外部API:应用程序的客户端如何与服务进行通信?
实现事务管理的数据一致性相关模式
每个服务拥有自己的数据库,原来的2PC分布式事务机制不再适用,可使用Saga模式确保数据一致性
查询数据的相关模式
有时候可以使用API组合模式,逐一调用聚合服务的API,多数情况下需要使用CQRS.
服务部署的相关模式
传统(手工)方式不再适用,需要一个部署平台,它往往基于虚拟机、容器或Serverless技术
可观测行的相关模式:
健康检查API:可以返回服务健康状态的API
日志聚合:日志写入一个集中式的日志服务器,可以搜索,报警触发
分布式追踪:为每个外部请求分配一个唯一ID,用于各个服务间追踪外部请求
异常追踪:把程序异常发送到异常追踪服务,这个服务会排除重复异常,告警,并追踪异常解决
应用指标:供维护使用的指标,如计数器
审计日志:记录用户行为
实现服务自动化测试的相关模式
重要的是测试不同的服务是否协同,同时避免使用复杂、缓慢和脆弱的端到端测试
解决基础设施和边界问题的相关模式
需实现许多和基础设施相关的功能,如可观测模式、外部化配置模式,可以在现有成熟基底框架上构建服务
安全相关的模式
用户身份验证通常由API Gateway完成. 常见的解决方案是应用访问令牌模式(如JWT)
微服务之上:流程和组织
大型复杂应用程序快速、频繁和可靠地交付软件需要几项DevOps关键能力,包括持续交付和持续部署,小型跨功能性自治团队,微服务架构
进行软件开发和交付的组织
沟通成本会随着团队规模呈 O(n^2)增长.反向使用康威定律(应用程序的架构往往反映了开发它的组织的结构),拆分大团队为独立开发测试部署的小团队,减少沟通协调成本,明确责任,提高组织可扩展性.
进行软件开发和交付的流程
要充分利用微服务的便利,采用Scrum或Kanban这类敏捷开发和部署实践,同时积极实践持续交付和持续部署
持续交付的关键特征是软件总是随时可以交付,它依赖于高度的自动化.
实施持续部署的高绩效组织每天多次部署到生产环境,生产中断的次数要少得多,并且可以从发生的任何事情中快速恢复.
采用微服务架构时的人为因素
转换到微服务架构,需要考虑到员工情绪变化
java达人
ID:drjava
(长按或扫码识别)
感谢你的阅读,下面是一个抽奖链接按钮,10月06日晚上开奖,共6个红包,写文不易,感谢大家支持。
感谢大家一直以来的阅读、在看和转发,点我参与抽奖!点我参与抽奖!