本帖最后由 FYIRH 于 2021-12-25 17:10 编辑
c5 c3 {3 p+ E0 C/ u) [0 E' \' j8 L+ X) z' v
这几年在 Java 工程师招聘时,会看到很多人的简历都写着使用了Spring Cloud做微服务实现,使用 Docker 做自动化部署,并且也会把这些做为自己的亮点。' ?$ V# T, I' e6 e" \! z
: W' S2 a3 G3 h3 k! x1 S
而比较有趣的这其中以小公司出来的人为绝大多数,大的公司出来的人简历上倒是很少提这些东西。! @, y( o4 _. g2 S# X+ y4 q7 D$ g
- y, R* E+ J7 F5 ]对于我自己来说,从15年就开始关注这一块,看过马丁· 福勒最开始的关于微服务的论文、也看过不少对微服务的论证的英文文章和书,也研究过 Spring Cloud、Sofa 等开源实现以及 Service mesh。考虑到我们公司研发团队人力不足、基础设施不完善,当初是没有推行微服务的。; a2 h5 y5 t+ r
4 a4 `6 J/ g5 c" @5 q2 w2 q
但随着看到上述的那种简历越来越多,有时候我也会疑问:难道真的不用微服务就落后了吗?公司的同事如果不掌握这些就真的没有竞争力了吗。8 ~ U3 K1 z' L, j5 Y! w7 D+ l
( u U$ Y, f9 o* b0 c6 @6 l% y
而随着最近公司业务的逐步提升,研发人员越来越多,借着在梳理公司的微服务落地计划时,也梳理了一下微服务的相关知识点,也是本文的主要内容。
5 S) O% O- o# U8 y# A2 m2 ]! X- @! c4 S' Z/ i0 ?+ O/ b
菜单: 微服务是什么 为什么要采用微服务 微服务架构 架构设计模式 服务拆分 微服务框架 + a; ?3 t7 Y4 k$ X) W
/ [( S( w q4 ]8 b2 T8 `
开篇之前先声明我对微服务的几点态度: 架构模式有很多,微服务不是唯一的选择也不是什么银弹。国内绝大多数中小公司引入微服务都是在盲目追新,也能看出做此种技术选型的工程师基础架构素质的不足。 “你必须长的足够高才能使用微服务”。微服务基础设施,尤其是容器技术、自动化部署、自动化测试这些不完备,微服务形同虚设,不会带来什么质的提升。 微服务架构的关键不在于具体的实现,而在于如何合理地划分服务边界以及组织架构是否相匹配。不考虑研发团队的规模和组成就盲目上微服务是不良的技术选型。 Spring Boot是Spring全家桶的上层封装,并不是什么崭新的技术,也不是什么值得觉得成为自己杀手锏的技术。 Spring Cloud中Spring Cloud Netflix的组件是经过生产环境验证的,其他的则建议慎重选择 + j. N; H$ e9 q5 c
8 n* U' O+ G" y6 g8 j
一、微服务是什么微服务起源于2005年Peter Rodgers博士在云端运算博览会提出的微Web服务(Micro-Web-Service),根本思想类似于Unix的管道设计理念。2014年,由Martin Fowler 与 James Lewis共同提出了微服务的概念,定义了微服务架构风格是一种通过一套小型服务来开发单个应用的方法,每个服务运行在自己的进程中,并通过轻量级的机制进行通讯(HTTP API)。关键的三点是small、automated以及lightweight。 对比SOA,微服务可以看做是SOA的子集,是轻量级的SOA,粒度更细的服务,独立进程、数据分离,更注重敏捷、持续交付、DevOps以及去中心化实践。其共同的架构原理: 单一职责 关注分离:控制与逻辑相分离 模块化和分而治之
3 o3 z8 [2 u5 I7 {$ q
" x& g5 t/ t; x, f
特点: 综合来看,其优缺点如下: ' A; u( l; Q! z# N6 N6 E/ X
优点: 模块的强边界 独立部署 技术选型的多样性
( b) @" F! ~* m; h" o
6 Y: ] y) I" u& m' w缺点:
$ s. z( x# X$ K8 c4 {' |二、为什么要采用微服务2 J' f' N5 v- w3 l/ c. j: @ H& r
是否选择微服务取决于你要设计的系统的复杂度。微服务是用来把控复杂系统的,但是随之而来的就是引入了微服务本身的复杂度。需要解决包括自动化部署、监控、容错处理、最终一致性等其他分布式系统面临的问题。即使已经有一些普遍使用的解决方案,但是仍然是有不小的成本的。
) M4 k5 p5 n# j/ r0 K& t3 i! T! G
生产力和复杂度的关系如图所示,可见系统越复杂,微服务带来的收益越大。此外,无论是单体应用还是微服务,团队的技能都需要能够把控住。 $ b( m0 b8 L- R H- K
马丁.福勒的一个观点是:除非管理单体应用的成本已经太复杂了(太大导致很难修改和部署),否则都不要考虑微服务。大部分应用都应该选择单体架构,做好单体应用的模块化而不是拆分成服务。
# M! F! z# z9 X1 q+ d0 p, O
因此,系统一开始采用单体架构,做好模块化,之后随着系统变得越来越复杂、模块/服务间的边界越来越清晰,再重构为微服务架构是一个合理的架构演化路径。 ' Z& ^+ e/ J" R: w, K
四个可以考虑上微服务的情况: 微服务的三个阶段: 微服务1.0:仅使用注册发现,基于SpringCloud或者Dubbo进行开发。 微服务2.0:使用了熔断、限流、降级等服务治理策略,并配备完整服务工具和平台。 微服务3.0:Service Mesh将服务治理作为通用组件,下沉到平台层实现,应用层仅仅关注业务逻辑,平台层可以根据业务监控自动调度和参数调整,实现AIOps和智能调度。
( G. e: P1 m5 Q6 M3 g' `* \$ b* U% |
三、微服务架构
2 R5 n; H8 j. y( }& X; w先决条件 ( p E% D# v; F0 `- C g
此外,根据康威定律和逆康威定律(技术架构倒逼组织架构改进),组织架构也是一个很关键的因素。对应于微服务架构,组织架构需要遵循以下原则: 一个微服务由一个团队维护,团队成员以三人为宜。 单个团队的任务和发展是独立的,不受其他因素影响。 团队是功能齐全、全栈、自治的,扁平、自我管理。 6 @2 I8 Q! C. Q" p+ b5 V% `. y
( l' z M( m3 A3 s
基础设施 微服务的推行需要依赖于很多底层基础设施,包括提供微服务的编译、集成、打包、部署、配置等工作,采用PaaS平台解决微服务从开发到运行的全生命周期管理,同时提供异构环境管理、容器资源隔离与互通、服务伸缩漂移、服务升级与回退、服务熔断与降级、服务注册与发现。
( X+ y- S/ k% C6 d. B9 U1. 最基本的基础设施
- S7 \: o& \8 h! w) h$ [- 进程间通讯机制:微服务是独立进程的,需要确定之间的通讯方式。
- 服务发现+服务路由: 提供服务注册中心,服务提供者和消费者通过服务发现获取服务的信息从而调用服务,实现服务的负载均衡等。
- 服务容错:微服务架构中,由于服务非常多,往往是一个服务挂了,整个请求链路的服务都受到影响,因此需要服务容错,在服务调用失败的时候能够处理错误或者快速失败,包括熔断、fallback、重试、流控和服务隔离等。
- 分布式事务支持:随着业务拆分为服务,那么有时候不开避免的就是跨服务的事务,即分布式事务的问题。原则是尽量避免分布式事务,如果无法避免那么可以使用消息系统或者CQRS和Event Sourcing方案来实现最终一致性。如果需要强一致性,则有两阶段提交、三阶段提交、TCC等分布式事务解决方案。
/ M* a1 c) M6 L* ~6 f
# T& b4 j0 ], z7 e( m- L
, i+ ?3 a7 f' r2 W2. 提升外部服务对接效率和内部开发效率 - API网关: 负责外部系统的访问,负责跨横切面的公共层面的工作,包括安全、日志、权限控制、传输加密、请求转发、流量控制等。典型的网关功能即对外暴露一个域名xx.com,根据第一级目录做反向路由xx.com/user,xx.com/trade。每一级目录,如user、trade对应一个服务的域名。此外,API网关也可以有服务编排的功能(不推荐)。
- 接口框架: 规范服务之间通讯使用的数据格式、解析包、自解释文档,便于服务使用方快速上手等。+ ]/ ~: s* u4 {$ ~# T3 Q" c% k
& Z& V5 X! S* `) `' V
- h3 }/ ^' `( f6 r& i& W( }3. 提升测试和运维效率
# Y2 \1 X) Q: s- l! h- 持续集成:这一部分并非是微服务特定的,对于之前的单体应用,此部分一般来说也是必要的。主要是指通过自动化手段,持续地对代码进程编译构建、自动化测试,以得到快速有效的质量反馈,从而保证代码的顺利交付。自动化测试包括代码级别的单元测试、单个系统的集成测试、系统间的接口测试。
- 自动化部署:微服务架构,节点数动辄上百上千,自动化部署能够提高部署速度和部署频率,从而保证持续交付。包括版本管理、资源管理、部署操作、回滚操作等功能。而对于微服务的部署方式,包括蓝绿部署、滚动部署以及金丝雀部署。
- 配置中心: 运行时配置管理能够解决动态修改配置并批量生效的问题。包括配置版本管理、配置项管理、节点管理、配置同步等。
- 持续交付:包括持续集成、自动化部署等流程。目的就是小步迭代,快速交付。
2 `3 ?7 h7 I. I2 ]" Z
0 h& f6 Q' B) M3 j" n, H4. 进一步提升运维效率# Q+ x( W! J! M5 T, r5 S' a$ ^1 G
- 服务监控: 微服务架构下节点数目众多,需要监控的机器、网络、进程、接口等的数量大大增加,需要一个强大的监控系统,能够提供实时搜集信息进行分析以及实时分析之上的预警。包括监控服务的请求次数、响应时间分布、最大/最小响应值、错误码分布等: R2 Y( P& t) o; C
- 服务跟踪:跟踪一个请求的完整路径,包括请求发起时间、响应时间、响应码、请求参数、返回结果等信息,也叫做全链路跟踪。通常的服务监控可以和服务监控做在一起,宏观信息由服务跟踪呈现,微观单个服务/节点的信息由服务监控呈现。服务跟踪目前的实现理论基本都是Google的Dapper论文。
- 服务安全:内网之间的微服务调用原则上讲应该是都可以互相访问写,一般并不需要权限控制,但有时候限于业务要求,会对接口、数据等方面有安全控制的要求。此部分可以以配置的方式存在于服务注册中心中,和服务绑定,在请求时由做为服务提供者的服务节点进行安全策略控制。配置则可以存储在配置中心以方便动态修改。. w; z6 _. W' O+ H
. S ]/ X# q* F- E8 z
; l" l! u6 }0 F5 S# w& x; W5 q在微服务数量很少的情况下,以上基础设施的优先级自上而下降低。否则,仅仅依赖人工操作,则投入产出比会很低。 ; E+ }5 V; D0 B, K* d( C2 J
还需要提到的是Docker容器技术。虽然这个对于微服务并不是必须的,但是容器技术轻量级、灵活、与应用依存、屏蔽环境差异的特性对于持续交付的实现是至关重要的,即使对于传统的单体应用也能够给其带来交付效率的大幅提升。* G% R& L) {$ V; i* o0 a
D1 {# A( m' [
四、架构设计模式6 K6 o* C" x, J7 ?, _, j
在引入微服务之后,传统的单体应用变为了一个一个服务,之前一个应用直接提供接口给客户端访问的架构不再适用。微服务架构下,针对不同设备的接口做为BFF层(Backend For Frontend),也叫做用户体验适配层,负责聚合、编排微服务的数据转换成前端需要的数据。服务之间的调用则在允许的情况下(允许延迟)尽可能使用异步消息传递方式,如此形成面向用户体验的微服务架构设计模式。如下图所示: ; N5 X9 X+ M# p% H
) I% _2 o9 w! h* L6 J
u2 Y, H0 `; [- I
Client -> API Gateway -> BFF(Backend For Frontend) -> Downstream Microservices 后台采用微服务架构,微服务可以采用不同的编程语言和不同的存储机制。 前台采用BFF模式对不同的用户体验(如桌面浏览器,Native App,平板响应式Web)进行适配。 BFF、API Orchestration Layer,Edge Service Layer,Device Wrapper Layer是相同的概念。 BFF不能过多,过多会造成代码逻辑重复冗余。 可以将网关承担的功能,如Geoip、限流、安全认证等跨横切面功能和BFF做在同一层,虽然增加了BFF层的复杂性,但能够得到性能优势。 w4 w; n6 ]9 k& i
+ m$ ]7 @$ h+ a7 o) }& c6 G 五、服务拆分
2 f6 b9 c* b! `$ z7 C; n微服务架构最核心的环节,主要是对服务的横向拆分。服务拆分就是讲一个完整的业务系统解耦为服务,服务需要职责单一,之间没有耦合关系,能够独立开发和维护。 服务拆分不是一蹴而就的,需要在开发过程中不断地理清边界。在完全理清服务之前,尽量推迟对服务的拆分,尤其是对数据库的拆分。 * N7 u& c q' L8 g
拆分方法如下: 基于业务逻辑拆分 基于可扩展拆分 基于可靠性拆分 基于性能拆分 5 n# ]% e: t3 |; W! Y/ n, P: H3 ?. Y9 |
1 T X" Y5 N% `, p8 A- l
其中,对于无法修改的遗留系统,采用绞杀者模式:在遗留系统外面增加新的功能做成微服务方式,而不是直接修改原有系统,逐步的实现对老系统替换。
/ l" R, N6 v( j
拆分过程需要遵守的规范如下: 六、微服务框架
- d" W7 u$ r9 z* E上面讲述了微服务架构的众多基础设施,如果每一个基础设施都需要自己开发的话是非常巨大的开发工作。目前市面上已经有不少开源的微服务框架可以选择。 W1 S( V* S1 Z$ i( {- K
Spring Boot
# @( F% U: ]& h+ S3 KSpring Boot是用来简化新Spring应用的初始搭建以及开发过程的。其虽然不是微服务框架,但其设计的初衷本质就是微应用的底层框架,因此非常适合用于微服务基础设施的开发以及微服务的应用开发。尤其对于Spring技术栈的团队来说,基于Spring Boot开发微服务框架和应用是自然而然的一个选择。 Dubbo&&Motan
: }. |3 a! b" y- NDubbo阿里开源的服务治理框架。其出现在微服务理念兴起之前,可以看做是SOA框架的集大成之作。但其仅仅包含了微服务基础设施的部分功能,诸如熔断、服务跟踪、网关等都没有实现 Motan则是微博开源的类似Dubbo的RPC框架,与Dubbo相比更轻量级。
; `+ p% w. E- |& A/ W- w! |% x4 F
% E0 @2 f" N: u$ \9 Z, E# G" r
Spring Cloud
: q1 a# ?' I5 j* }! O) z: w4 TSpring Cloud是基于Spring Boot实现的微服务框架,也可以看做一套微服务实现规范。基本涵盖了微服务基础设施的方方面面,包括配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等。其基于Spring生态,社区支持非常好。但其很多组件都没有经过生产环境验证,需要慎重选择。 Spring Cloud Netflix是Spring Cloud的一个子项目,是Spring对Netflix OSS的集成实现。基于Netflix的大规模使用,其中的已经被广泛使用的组件包括: 此外,另一个子项目Spring Cloud Alibaba则是Alibaba开源的基于Spring Boot的微服务框架,主要是对阿里云服务的支持。 4 c' x0 J/ }6 O
1 x4 O2 h3 P# W: c3 H+ L8 \ " G) R3 H% Y/ t/ w
. Y; Z4 H% z2 i4 U/ s2 {7 ~
: s8 m" x8 w+ u; x3 Z7 x
0 w$ d9 P0 [2 C) X
目前主流的开源实现包括:
2 w7 F% X# K* c% [" } d, x
限于Service Mesh带来的性能延迟的开销以及sidecar对分布复杂性的增加,其对大规模部署(微服务数目多)、异构复杂(交互协议/开发语言类型多)的微服务架构带来的收益会更大。
* n* V! ~% k. T1 M4 a5 ] R- {+ {( g / Z# w; `( c7 U; k
- Sofastack
5 x9 A# `6 |. O4 G* r( K( E! N# W蚂蚁金服开源的构建金融级分布式架构的一套中间件。包括微服务开发框架、RPC框架、服务注册中心、全链路追踪、服务监控、Service Mesh 等一整套分布式应用开发工具。1 z# b9 [5 L8 z, F4 C, |
. K3 v* \! s8 D! ] b' Z) `$ t
特别值得一提的是 SOFAMesh。其实对下一代微服务架构 Service Mesh 的大规模落地方案实践,基于 Istio 改进和扩展而来,应该是国内最为成熟的开源Service Mesh方案。( k; m6 @1 C# x/ ^) W c# B
, Q s; Q x. g. p( W7 L: l0 N
此外,需要提到 Kubernetes(K8s),其本身提供了部分的微服务特性支持(通过域名做服务发现),对代码无侵入。但服务调用、熔断这些都需要自己实现。
# v( {, p) v' Y* {; b
% A* y( E" G& o/ x& D& F p综上,目前公司技术团队技术栈是 Spring,并且已有服务的实现都是基于 Dubbo,因此选择 Spring Cloud Netflix 做为基础的微服务框架,对其中不成熟或者缺乏的组件,选择业界更为成熟的组件替代即可。
5 q3 |& Y# Y4 x' B/ p6 y
`" p' c, Y/ N) M1 R9 k2 x- n y
+ |4 @. G* u# y, ?, R2 O4 w! |3 e( j# y \2 h# q m- q8 k
5 B- Y6 U, @: W( ^! `9 w3 F
API网关:Zuul 服务注册中心:Dubbo 配置中心:disconf 服务监控&&全链路追踪:CAT 服务开发框架:Spring Boot 日志监控、告警:ELK + Elasalert 流量控制:Sentinel 消息队列:Kafka(转自飒然Hang) ) [6 Q" z2 U9 Y7 u. a7 A
) }* H. B8 Q; M0 @
8 i, j) h, X6 ~0 W# }9 z5 E# W( U. m! M8 u2 @% ]9 x
; V/ V, H( Z$ Z+ V M
, d# O% y& O( g# w5 g |