定义
Microservices 是一种服务组织形式,很难有一个特别明确的定义,更多的是技术开发人员总结出来的一些共识。通常来说微服务架构包含一组「独立部署」的小服务,共同完成一个应用。
接下来我们通过微服务的历史、特点和遇到的问题来进一步了解微服务。
一点历史
早在 2005 年,Peter Rodgers 在 Web Services Edge 会议上的一次演讲中介绍了“Micro-Web-Services”这个术语。他主张 :Micro-Services 应该类似 Unix 系统的 Pipelines ;服务在运行时是多语言的,它们可以互相调用;复杂的业务逻辑应该隐藏在服务内部,对外只暴露简单的 api ;任何粒度的服务都可以对外提供服务。
在2007年, Juval Löwy 在他的著作中呼吁构建每一个 class 都是一个服务的系统。
2011 年5月在威尼斯附近举行的软件架构师研讨会使用术语 「micorservice」 来描述参与者最近一直在探索这种常见的架构风格。在2012年5月这个小组认为 「microservices」 是更合适的名字。
2012年3月,James Lewis 在克拉科夫的会议上也提出了要把一些相似的想法作为研究课题。Netflix 前云系统总监 Adrian Cockcroft 将这种方法描述为 「细粒度 SOA 。」
我个人感觉把微服务理解成一种极致的 SOA 架构是非常合理的。
特点
微服务具有以下特点:
- 服务体量小,可以有少数人开发和维护。
- 每一个服务最好是单独的代码仓库。
- 服务可以独立部署。
- 自己维护自己的业务数据,不直接对外暴露数据的存储逻辑。
- 服务之间通过 api 通信,服务的内部实现细节对外是隐藏的。
- 支持多语言。
好处
微服务的这些特点带来了很多好处:
- 单个服务逻辑简单,便于快速开发、迭代。
- 服务独立部署,可以针对不同特点的服务分配合适的资源,能有效提高资源利用率。
- 灵活扩展,方便增加新的服务,而不用过多地考虑原有逻辑。
- 技术自由,对应不同的业务使用合适的技术,方便技术选型。
- 提高系统的吞吐量。
如何实现
我认为实现微服务架构可以分两步进行:
- 服务拆分
- 服务治理
服务拆分
服务拆分分为垂直拆分(业务拆分)和水平拆分(分层)。
垂直拆分可以先按照大的领域拆分,然后在领域的内部再按照 api 拆分。比如说我们可以把公司先分成用户、搜索、评论、推荐几个大业务领域。
对于用户领域我们可以按照 api 的粒度进行具体服务的拆分。比如分为:注册服务、登录服务、会员管理服务等。
业务领域的垂直拆分往往需要根据业务的领域模型,对不同的模块进行拆分,很难有统一的标准;而且拆分的粒度还要结合团队规模,基础设施、访问量等维度统一考量。相对于水平拆分,垂直拆分往往更加考验架构师的综合能力。
水平拆分其实就是对整个业务流程进行分层,业界反倒是有一些通用的分层规则可以参考。总结了一个相对完善的微服务架构的示意图。
上图左侧代表静态资源服务,相对简单,采用 CDN 做缓存加速,后面连的是静态资源的存储地址。
上图右侧代表动态资源的访问链路。主要分为:网关层、业务逻辑层、数据逻辑层、存储层。网关层中 LVS 用来实现四层网络负载、Nginx 用来实现7层网络。业务网关用来实现鉴权、限流、生成 session 、协议转换等工作。BFF 层用来实现对业务模块进行数据组装和 SSR 。业务逻辑层以单个或多个 api 的粒度部署各服务,对于一些需要聚合的服务我们可以做一些服务包装,通过服务之间的分层把通用逻辑收敛起来。数据访问层把数据的存储逻辑封装起来,让业务模块不用关心底层数据库。存储层实现数据的最终存储。
通过水平分层可以在通用功能维度拆分服务,使各层的服务关心自己的功能。
服务治理
通过服务拆分,降低了单个服务的复杂性,但是同时也带来了很多问题:
- 服务数量变多了,不容易维护。
- 服务发布次数变多了。
- 请求链路变长了,RT时间变长。
- 服务出现故障不容易发现。
- 线上问题不方便排查。
- 服务之间出现依赖关系时不方便测试。
等等。
为了保障微服务架构下整个系统的高可用性,需要有一系列工具来解决上面这些问题。
我把常见问题及解决方案总结了一张思维导图:
我对图中的部分内容做一些解释:
我们的每一个服务都可能存在多个副本,也有可能分布在不同的机房里,上游服务调用下游服务时就需要知道每一个副本的调用信息,此时就需要注册中心来完成服务的注册和上游服务对下游服务的发现。
微服务之间通常会使用内网通信,此时可以采用 RPC 框架完成服务之间的调用。在微服务发展的中间阶段,网络延迟可接受的情况下直接通过 HTTP 调用也是可以的。
大量细小的服务,每一个都有可能出现故障,为了能比客户先发现问题并及时止损,所以需要有故障检测、故障处理、故障恢复。
微服务的可观测性也非常重要。随着请求链路变长,线上问题难以排查。在网关层给每一个请求添加 traceID,通过日志追踪系统,可以方便的追踪请求出现问题的模块及上下文信息。
服务之间的调用需要合理地选择集群、解决并行串行调用、解决流量均衡等问题。
需要有一个发布平台,方便服务快速发布,并能支持在发布时设置副本数量、资源分配、服务回滚等功能。
需要有多套测试方案,能完成线上的各种测试要求。
现在还没有一个大而全的架构能解决上述的所有问题,不过有很多开源的组件,可以在一些开源组件的基础上做封装或二次开发。图中的每一个问题都牵扯到很多技术细节,一个人很难搞定,需要有一个开发 运维的团队去协作完成任务。
其它
微服务架构并不适合所有业务场景,它适合快速迭代开发、追求吞吐量对响应延迟没有那么敏感的业务。
微服务架构的实现成本比较高,公司在转型时并不需要从单体架构一步到位,达到最终的完整微服务形态。比如说一个单体架构可以先在单体架构内部进行模块拆分,对表结构做拆分,这样再拆分为单个服务时就容易了很多。再比如,数据访问层和和业务逻辑层在初级阶段也可以放到一个项目中,在一个项目中我们可以通过 Dao 层分离数据和业务逻辑,这样在需要抽离数据逻辑层时就变得轻而易举。
最后,欢迎私信交流,指出文章的不足之处或提出您的疑虑。
相关链接
https://microservices.io/
https://en.wikipedia.org/wiki/Microservices
https://en.wikipedia.org/wiki/Service-oriented_architecture
https://docs.microsoft.com/en-us/azure/architecture/guide/architecture-styles/microservices
https://aws.amazon.com/cn/microservices/
https://e.naixuejiaoyu.com/detail/term_60641ec5c73b2_8TIxMm/25