如何发布和引用服务
服务提供者如何发布一个服务,服务消费者如何引用这个服务。具体来说,就是这个服务的接口名是什么?调用这个服务需要传递哪些参数?接口的返回值是什么类型?以及一些其他接口描述信息
最常见的服务发布和引用的方式有三种:
RESTful API (一般对外)
XML 配置(对内)
IDL 文件(跨语言,Thrift, gRPC)
如何注册和发现服务
在微服务架构下,主要有三种角色:服务提供者(RPC Server)、服务消费者(RPC Client)和服务注册中心(Registry)。
RPC Server 提供服务,在启动时,根据服务发布文件 server.xml 中的配置的信息,向 Registry 注册自身服务,并向 Registry 定期发送心跳汇报存活状态。
RPC Client 调用服务,在启动时,根据服务引用文件 client.xml 中配置的信息,向 Registry 订阅服务,把 Registry 返回的服务节点列表缓存在本地内存中,并与 RPC Sever 建立连接。
当 RPC Server 节点发生变更时,Registry 会同步变更,RPC Client 感知后会刷新本地内存中缓存的服务节点列表。
RPC Client 从本地缓存的服务节点列表中,基于负载均衡算法选择一台 RPC Sever 发起调用。
注册中心实现方式
注册中心的实现主要涉及几个问题:注册中心需要提供哪些接口,该如何部署;如何存储服务信息;如何监控服务提供者节点的存活;如果服务提供者节点有变化如何通知服务消费者,以及如何控制注册中心的访问权限。
注册中心必须提供以下最基本的 API
- 服务注册接口:服务提供者通过调用服务注册接口来完成服务注册。
- 服务反注册接口:服务提供者通过调用服务反注册接口来完成服务注销。
- 心跳汇报接口:服务提供者通过调用心跳汇报接口完成节点存活状态上报。
- 服务订阅接口:服务消费者通过调用服务订阅接口完成服务订阅,获取可用的服务提供者节点列表。
- 服务变更查询接口:服务消费者通过调用服务变更查询接口,获取最新的可用服务节点列表。
除此之外,为了便于管理,注册中心还必须提供一些后台管理的 API,例如:
- 服务查询接口:查询注册中心当前注册了哪些服务信息。
- 服务修改接口:修改注册中心中某一服务的信息。
如何实现 RPC 远程服务调用
在进行服务化拆分之后,服务提供者和服务消费者运行在两台不同物理机上的不同进程内,它们之间的调用相比于本地方法调用,可称之为远程方法调用,简称 RPC。
想要完成远程调用,你需要解决四个问题:
- 客户端和服务端如何建立网络连接?
- 服务端如何处理请求?
- 数据传输采用什么协议?
- 数据该如何序列化和反序列化?
客户端和服务端如何建立网络连接
客户端和服务端之间基于 TCP 协议建立网络连接最常用的途径有两种
- HTTP 通信
- Socket 通信
服务端如何处理请求
- 同步阻塞方式 (适用于连接数比较小的业务场景)
- 同步非阻塞方式 (用于连接数比较多并且请求消耗比较轻的业务场景,比如聊天服务器)
- 异步非阻塞方式 (用于连接数比较多而且请求消耗比较重的业务场景)
数据传输采用什么协议
最常用的有 HTTP 协议,它是一种开放的协议,各大网站的服务器和浏览器之间的数据传输大都采用了这种协议。还有一些定制的私有协议,比如阿里巴巴开源的 Dubbo 协议等。
数据该如何序列化和反序列化
常用的序列化方式分为两类:
- 文本类如 XML/JSON 等
- 二进制类如 PB/Thrift 等
如何监控微服务调用
监控对象
- 用户端监控。提供给用户的功能监控
- 接口监控。依赖的具体 RPC 接口的监控
- 资源监控。依赖的 redis,mysql 等
- 基础监控。服务器本身的健康状况的监控
监控指标
- 请求量,请求量一般有二个维度,一个是实时请求量即 QPS, 还一个是统计请求量即 PV。
- 响应时间,可以用一段时间内所有调用的平均耗时来反映请求的响应时间
- 错误率,通常用一段时间内调用失败的次数占调用总次数的比率来衡量
监控维度
- 全局维度
- 分机房维度
- 单机维度
- 时间维度
- 核心维度
监控系统的步骤
1. 数据采集
通常有两种数据收集方式:
- 服务主动上报,这种处理方式通过在业务代码或者服务框架里加入数据收集代码逻辑,在每一次服务调用完成后,主动上报服务的调用信息。
- 代理收集,这种处理方式通过服务调用后把调用的详细信息记录到本地日志文件中,然后再通过代理去解析本地日志文件,然后再上报服务的调用信息。
2. 数据传输
数据传输最常用的方式有两种:
- UDP 传输,这种处理方式是数据处理单元提供服务器的请求地址,数据采集后通过 UDP 协议与服务器建立连接,然后把数据发送过去。
- Kafka 传输,这种处理方式是数据采集后发送到指定的 Topic,然后数据处理单元再订阅对应的 Topic,就可以从 Kafka 消息队列中读取到对应的数据。
3. 数据处理
数据处理是对收集来的原始数据进行聚合并存储。数据聚合通常有两个维度:
- 接口维度聚合,这个维度是把实时收到的数据按照接口名维度实时聚合在一起,这样就可以得到每个接口的实时请求量、平均耗时等信息。
- 机器维度聚合,这个维度是把实时收到的数据按照调用的节点维度聚合在一起,这样就可以从单机维度去查看每个接口的实时请求量、平均耗时等信息。
4. 数据展示
数据展示是把处理后的数据以 Dashboard 的方式展示给用户。数据展示有多种方式,比如曲线图、饼状图、格子图展示等。
如何追踪微服务调用
在微服务架构下,由于进行了服务拆分,一次请求涉及到多个服务调用,如果请求失败,就很难定位是在哪个环节出错,所以我们需要服务调用链的追踪。
服务追踪的作用
- 优化系统瓶颈
- 优化链路调用
- 生成网络拓扑
- 透明传输数据
服务追踪系统原理
它的核心理念就是调用链:通过一个全局唯一的 ID 将分布在各个服务节点上的同一次请求串联起来,从而还原原有的调用关系,可以追踪系统问题、分析调用数据并统计各种系统指标。
服务追踪系统可以分为三层
- 数据采集层,负责各个节点数据埋点并上报数据处理层。
- 数据处理层,负责数据的存储与计算。
- 数据展示层,负责数据的图形化展示。
微服务治理的手段有哪些
一次服务调用,服务提供者、注册中心、网络这三者都可能会有问题,此时服务消费者应该如何处理才能确保调用成功呢?这就是服务治理要解决的问题。
常用的服务治理手段
节点管理
服务调用失败一般是由两类原因引起的,一类是服务提供者自身出现问题,如服务器宕机、进程意外退出等;一类是网络问题,如服务提供者、注册中心、服务消费者这三者任意两者之间的网络出现问题。
无论是服务提供者自身出现问题还是网络发生问题,都有两种节点管理手段。
- 注册中心主动摘除机制
这种机制要求服务提供者定时的主动向注册中心汇报心跳,注册中心根据服务提供者节点最近一次汇报心跳的时间与上一次汇报心跳时间做比较,如果超出一定时间,就认为服务提供者出现问题,继而把节点从服务列表中摘除,并把最近的可用服务节点列表推送给服务消费者。
- 服务消费者摘除机制
虽然注册中心主动摘除机制可以解决服务提供者节点异常的问题,但如果是因为注册中心与服务提供者之间的网络出现异常,最坏的情况是注册中心会把服务节点全部摘除,导致服务消费者没有可用的服务节点调用,但其实这时候服务提供者本身是正常的。所以,将存活探测机制用在服务消费者这一端更合理,如果服务消费者调用服务提供者节点失败,就将这个节点从内存中保存的可用服务提供者节点列表中移除。
负载均衡
常用的负载均衡算法主要包括以下几种。
- 随机算法
- 轮训算法
- 最少活跃调用算法
- 一致性 Hash 算法
服务路由
对于服务消费者而言,在内存中的可用服务节点列表中选择哪个节点不仅由负载均衡算法决定,还由路由规则确定。所谓的路由规则,就是通过一定的规则如条件表达式或者正则表达式来限定服务节点的选择范围。
为什么要制定路由规则呢?主要有两个原因。
- 业务存在灰度发布的需求
- 多机房就近访问的需求
服务容错
服务调用并不总是一定成功的, 对于服务调用失败的情况,需要有手段自动恢复,来保证调用成功。
服务容错常用的手段主要有以下几种。
- FailOver:失败自动切换。就是服务消费者发现调用失败或者超时后,自动从可用的服务节点列表总选择下一个节点重新发起调用,也可以设置重试的次数。
- FailBack:失败通知。就是服务消费者调用失败或者超时后,不再重试,而是根据失败的详细信息,来决定后续的执行策略。
- FailCache:失败缓存。就是服务消费者调用失败或者超时后,不立即发起重试,而是隔一段时间后再次尝试发起调用。
- FailFast:快速失败。就是服务消费者调用一次失败后,不再重试。
一般情况下对于幂等的调用,可以选择 FailOver 或者 FailCache,非幂等的调用可以选择 FailBack 或者 FailFast。
参考资料
极客专栏: 从 0 开始学微服务
本文亦在微信公众号【小道资讯】发布,欢迎扫码关注!