微服务架构(microservicearchitecture)是一种架构设计理念,旨在通过将功能分解到各个分散的服务中来实现对解决方案的解耦。服务化是将企业资源以业务能力的形式组织起来,通过一定的技术架构对这些业务能力进行封装,形成易于消费的服务,从而实现业务能力粒度的复用、组装、维护和管理,以灵活迅捷地构筑特定业务目的的企业应用,助力企业实现数字化转型。
技术架构的目标是实现对业务发展提供有力支持,比如业务敏捷、应用弹性、持续交付。相比单体架构,微服务架构具有如下特点。
微服务设计以服务识别出的服务目录为基础,针对服务粒度、依赖组合关系做合理调整(更新服务目录和服务关联),并对服务接口(输入/输出异常)、服务应用分组以及部署方式,采用契约先行的方式并更好地支持可伸缩高可用(如无状态原则),为目标做进一步的设计,同时在性能、管控、安全等非功能性需求方面对接下来的服务实现阶段提出明确的要求(服务定义)。
在服务设计阶段,针对服务模型(服务目录+服务关联+服务定义)的设计是自上而下、由粗到细的,微服务设计有以下一些参考原则。
建议使用服务使用者专业领域内有意义的名称,优先选用业务概念,而不是技术概念。应使用名词对服务进行命名,使用动词对操作进行命名。
综合考虑复用性以及功能完整性,尽量保持一个团队内部对于服务粒度的一致理解。服务应该是内聚而完整的。
无状态的服务可以轻易地被替代,如果一个服务出现异常,系统可以随时拉起一个新的服务来接管原有服务的工作;而有状态的服务伸缩起来非常复杂,可以通过将服务的状态外置到数据库、分布式缓存中,从而使服务变成无状态的。
应逐步划分、持续演进,避免服务数量的爆发性增长。这就类似于应用的灰度发布效果,先将几个不太重要的功能拆分到一个服务做实验,万一有问题也可以缩小故障影响范围。另外,除了业务服务数量的增加,还需要准备持续交付的工具、微服务框架等。随着分布式微服务的改造,系统的全链路追踪监控也要及时跟上,以便出问题时进行快速定位排查。
微服务治理的好坏决定了企业实施分布式微服务架构的成败。总体来说,微服务治理包括服务目录、服务路由、服务管控、服务监控 4 个部分的内容。服务治理的手段是从不同角度来确保服务调用的成功率。
服务治理领域最重要的问题就是服务发现与注册。绝大部分微服务框架中引入了一个服务注册中心的概念,服务的注册与发现主要依赖这个服务注册中心。服务注册中心还需实时监听所有服务节点的健康状态,以及节点的上下线消息,及时更新推送服务地址信息。
根据配置中心配置的路由规则进行服务的路由指向,既可以在调用方本地路由,也可以由专门的组件(如负载均衡)进行路由处理。服务调用并不总是一定成功的,可能的原因包括服务提供者节点自身死机、进程异常退出或者服务消费者与提供者之间的网络出现故障等。对于服务调用失败的情况,需要有手段自动恢复,来确保调用成功。
提供不同环境(如开发、测试、生产)的服务隔离机制,以及不同租户之间的服务隔离。限流和降级是保护自身服务正常运行的两方面的手段。限流指的是当外部请求量太大时,进行主动拒绝(或者放入缓冲队列),确保系统不被压垮;降级指的是当依赖的第三方系统性能异常(或不可用)时,为了不被第三方系统拖垮。
记录每一次服务请求的审计日志,以不同维度生成服务报表(调用量、调用时长、状态分布、错误率等)。服务追踪系统可以跟踪记录一次用户请求发起了哪些调用,经过哪些服务处理,并且记录每一次调用所涉及的服务的详细信息,通过日志快速定位是调用失败的环节。
HSF 是一个分布式 RPC 框架,联通各种不同的分布式系统,以服务的方式调用。其核心有服务注册中心(ConfigServer)、RPC 框架和服务治理(包括服务寻址、路由、限流等)。图 6-5 所示是 HSF 微服务框架,以及各个核心模块之间的交互流程。
HSF 底层的通信基于 Netty 设计实现高性能的服务器之间远程调用,支持多种序列化方式(java、hessian1、hessian2、kryo、fastjson 和 customized 等)和多种 RPC 协议(HSF、Dubbo 等),高性能得益于快速高效的二进制协议,包括二进制序列化和 TCP。
HSF 对开发最大的价值是透明地将本地调用转换为远程调用,而无须改动业务代码,客户端通过代理模式,支持多种调用方式,分别是同步调用、future 并行调用、callback 异步回调、泛化调用,以及 HTTP 调用。
HSF 服务治理包括服务发布和寻址,以及通过各种规则来实现诸如限流、白名单、授权、路由、同机房优先、单元化、动态分组、权重路由、降级等功能,配置和规则放在 Diamond 集中管理,有专门的 ops 页面进行维护,所有客户端和服务器端都会订阅这些配置和规则。
Dubbo 是一款高性能、轻量级的开源 Java RPC 框架。它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
Dubbo 最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo 采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务。
Dubbo 采用的是 JavaDevelopment Kit(JDK)标准的串行外设接口(Serial Peripheral Interface,SPI)扩展机制,微核心+插件式,平等对待所有的第三方插件,扩展性极佳。
Spring Cloud 为最常见的分布式系统模式提供了简单易用的编程模型,帮助开发人员构建弹性、可靠和协调的应用程序。
Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,比如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控、链路追踪等。
Spring Cloud 采用的是基于 HTTP 的 REST 方式。RPC 一般面向接口引用来调用远端服务,对开发人员更加友好,且 RPC 主要是基于 TCP/IP 的,调用参数采用二进制进行序列化,网络传输更加精简高效;RPC 的缺点是调用双方存在技术栈的强绑定。REST 比 RPC 更灵活,天然具有跨语言的优势,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级的强依赖,这在强调快速演进的微服务环境下,显得更加合适。
gRPC 是一个基于 HTTP/2 通信协议和 Protobuf 序列化的 RPC 实现,其前身是谷歌内部大量使用的 Stubby 服务间通信产品。gRPC 已被 CNCF 所收录,作为云原生架构的一个进程之间服务调用参考。
在 gRPC 中,客户端应用可以像调用本地对象的方法一样直接调用部署在其他机器上的服务器端应用的方法。gRPC 降低了构建分布式应用和服务的难度。和其他 RPC 系统一样,gRPC 的核心也是服务定义,定义可以被远程调用的方法的入参和返回值。gRPC 客户端和服务器端既可以在多种不同的环境下运行并相互通信,也可以使用 gRPC 支持的语言实现。
gRPC 并不算是一个完整的微服务框架,而只是一个轻量级远程服务调用技术。通常我们不会单独使用 gRPC,而是将 gRPC 作为一个组件进行使用。这是因为生产环境中在面对大并发的情况时,需要使用分布式系统来处理,而 gRPC 并没有提供分布式系统相关的一些必要组件。
service mesh 是一种非侵入式架构,用于处理服务到服务通信的专用基础设施层。它负责通过复杂的服务拓扑来可靠地传递请求。
service mesh 帮助应用程序在海量服务、复杂的架构和网络中建立稳定的通信机制。业务所有的流量都转发到 service mesh 的代理服务中,支撑应用之间透明的网络调用,可以确保应用的调用请求在复杂的微服务应用拓扑中可靠地穿梭。
service mesh 通常由一系列轻量级的网络代理组成,这通常被形象地称为边车(sidecar)模式,与应用程序部署在一起,但应用程序不需要知道它们的存在。以旁路的方式为应用系统提供服务发现、路由、负载均衡、健康检查和可观察性来帮助管理流量。
service mesh 承担了微服务框架的所有功能,包括服务注册发现、负载均衡、熔断限流、认证鉴权、缓存加速、运行监控等。可以说,service mesh 是云原生下的微服务治理方案。微服务架构强调去中心化、独立自治、跨语言,service mesh 通过独立进程的方式进行了隔离,可以低成本实现微服务框架这些特性。
当下主流的 service mesh 框架有:Linkerd、Envoy、Istio、SOFAMesh。有兴趣的读者可以去各个官网上查看相关信息。
一个完整的微服务调用框架包含 3 个部分。
1)通信框架:主要解决客户端和服务器端如何建立连接、管理连接以及服务器端如何处理请求的问题。2)通信协议:主要解决客户端和服务器端采用哪种数据传输协议的问题。
3)序列化和反序列化:主要解决客户端和服务器端采用哪种数据编解码的问题。
远程服务调用是分布式服务框架的基础和核心功能。目前主流的分布式服务框架使用两种传输协议。
1)RPC 协议:以 HSF、Dubbo、Thrift、gRPC、Motan 为代表的框架使用的协议。
2)HTTP REST 协议:以 Spring Cloud 为代表的框架使用的协议。
远程过程调用(Remote Procedure Call,RPC)框架作为架构微服务化的基础组件,能大大降低架构微服务化的成本,提高服务调用方与服务提供方的开发效率,屏蔽跨进程调用函数(服务)的各类复杂细节。
RPC 调用的四个关键细节
多数 RPC 产品采用本地负载均衡策略,即调用方启动时从注册中心拉取服务地址信息后,在本地缓存,运行过程中真正发起调用时,直接从本地缓存读取服务地址信息,根据一定的负载均衡算法选取某一个地址,发起点对点的直接调用。当服务器端地址信息发生变更时(如节点上下线),由注册中心实时推送变更信息到所有的调用方同步更新。
服务器端 I/O 的方式通常分为 3 种处理方式:
同步阻塞(Blocking I/O,BIO)方式—— 一次请求需要创建一个线程处理。
同步非阻塞(Non-blocking I/O,NIO)方式——多个连接共用一个线程。
异步非阻塞(Asynchronous I/O,AIO)方式——当进行读写操作时,AIO 只需直接调用 API 的 read 或 write 方法。
客户端和服务器端交互时将参数或结果转化为字节流在网络中传输,那么将数据转化为字节流或者将字节流转换成能读取的固定格式时,就需要进行序列化(数据编码)和反序列化(数据解码),序列化和反序列化的速度也会影响远程调用的效率。
常用的序列化方式分为两类:文本类(如 XML、json 等)、二进制类(如 Hessian、Thrift 等)。而具体采用哪种序列化方式。主要取决于 3 个方面的因素:支持数据结构种类的丰富度、跨语言支持、性能。
多数 RPC 框架会选择 TCP 作为传输协议,也有部分会选择 HTTP(如 gRPC 使用 HTTP/2)。不同的协议各有利弊,TCP 更加高效,而 HTTP 在实际应用中更加灵活。
RPC 的优点:
RPC 的缺点:
RESTful 是一种网络应用程序 API 的设计风格和开发方式,基于 HTTP,可以使用 XML 格式定义或 json 格式定义。最常用的数据格式是 json。由于 json 能直接被 JavaScript 读取,因此以 json 格式编写的 REST 风格的 API 具有简单、易读、易用的特点。
REST 风格协议的特点如下:
1)每个统一资源标识符(Uniform Resource Identifier,URI)代表一种资源。任何事物只要有被引用的必要,它就是一个资源;要让一个资源可以被识别,需要有一个唯一标识,在 Web 中这个唯一标识就是 URI。2)客户端使用 GET、POST、PUT、DELETE 这 4 个表示操作方式的动词对服务器端资源进行操作:GET 用来获取资源,POST 用来新建资源(也可以用于更新资源),PUT 用来更新资源,DELETE 用来删除资源。3)通过操作资源的表述形式来操作资源,资源在外部的具体呈现可以有多种表述形式(例如文本资源可以采用 HTML、XML、json 等格式,图片可以使用 PNG 或 JPG 格式展现出来),在客户端和服务器端之间传送的也是资源的表述,而不是资源本身。
4)客户端与服务器端之间的交互在请求之间是无状态的,从客户端到服务器端的每个请求都必须包含理解请求所必需的信息。这里说的无状态通信原则,并不是说客户端应用不能有状态,而是指服务器端不应该保存客户端状态。
RESTful API 的优点:
RESTful API 的缺点:
领取专属 10元无门槛券
私享最新 技术干货