再谈微服务
微服务架构:单独的应用程序对应一个独立模块的小服务,每个服务运行在自己的进程中,并且使用类似http的轻量级通信机制。这些服务围绕业务来构建和关联,独立部署,数据私有。
微服务通常具备以下特点:
- 围绕业务构建团队:团队是跨职能的,设计系统架构受制于产生这些设计的组织的沟通结构
- 去中心化的数据管理:数据与业务绑定
微服务架构下,团队内聚,沟通高效。但是随着服务数量的增多,服务间的网络通信会变的很复杂,服务的依赖关系也变的不可维护。此时就需要解决一些通用的问题:
- 服务注册
- 服务发现
- 负载均衡
- 熔断
- 限流
- 降级
- 超时、重试
- 安全
- 可观测性,trace等
Service Mesh 发展史
Service mesh,中文名叫“服务网格”,是一组用于处理服务间通讯的网络代理。现代的服务有复杂的拓扑结构,服务网格负责在这些结构中实现请求的可靠传递,实践中通常实现为一组轻量级的网络代理,他们与应用程序部署在一起,同时对应用程序透明。 在分布式的网络环境下,为了提高系统的可用性,我们引入了服务注册和发现、负载均衡、熔断、降级、限流等等和通信相关的能力,service mesh也目标解决这些问题。
服务通信的演变过程大致如下图所示:
- 远古时代:应用代码中包含网络通信细节,如流量控制。后来出现了TCP/IP并沉淀了通用能力,流量控制等代码从应用代码中分离开,最终形成网络层的一部分
- 微服务时代-公共库:微服务初期也需要处理比较多的基础事项,主要包含服务发现、负载均衡、熔断降级等。为了避免与应用程序融合,我们选择框架或者抽象好的类库。以spring cloud/dubbo为例,他们以类库的方式存在,编码时重用类库来减少重复开发,但在运行期,这些类库仍然进入了打包部署后的业务应用程序,和业务程序运行在统一进程内,因此也被称为“侵入式框架”。面临的痛点包含(业务无关、本质是服务通讯问题):
- 学习门槛高
- 功能不全:实践中各个公司会各自做定制化
- 跨语言:框架类库和语言是强相关的,执行层面会变为可能是统一语言,可能是对每种语言单独考虑一套解决方案
- sdk升级维护困难:随着时间推移,容易出现版本碎片化,版本的兼容性也变得比较复杂,中间件演进也会比较困难
- 基础服务和应用服务故障不分离:功能层面的故障可以由业务团队来维护,性能层面的故障可能更适合基础设施团队。比如使用proxy代替代码中自行维护redis
- proxy模式: 在服务端和客户端之间增加一个中间层,负责请求的转发,避免微服务之间直接通信。proxy也需要负责负载均衡等基础能力
- sidecar模式:在参考proxy模式的基础上,对齐了侵入式框架的功能,粒度上也更细。局限性在于sidecar本身有很多原有体系带来的限制,为特定的基础设施而配套设计,不太能大规模通用
- service mesh:
- 第一代:在sidecar的基础上,解决了通用性问题,不受限于原有的环境。同时要求所有的请求都经过网格转发
- 第二代:和第一代相比,增加了控制平面,用于控制系统中所有的sidecar,进一步控制所有的请求
- 控制平面:从全局的维度控制sidecar,相当于 service mesh的大脑,控制sidecar来实现服务治理的各种功能
Service Mesh 的优势
服务网格功能层面可以大致归纳为以下几种:
- 流量控制:提供智能路由、超时重试、熔断、流量镜像等多种控制能力
- 安全:授权和身份认证
- 策略:流量配额,黑白名单
- 可观察性:指标数据、日志、追踪
业务价值
最大的价值就是解放业务研发,开发者不需要关心通信细节,像本地服务一样使用微服务,主要的优点包含:
- 无需关注sdk升级:基础团队可以自行升级,无需业务方参与
- 异构系统的统一治理:服务网格提供统一的类库、框架,多种语言之间不必关心这部分的交互,只需要关注自身的业务发挥对应的优势
- 减少业务&运维的沟通成本,明确边界