基本模型
服务注册与发现:
- 服务端启动的时候,需要往注册中心里注册自身的信息,主要是定位信息。(非主要数据取决于微服务框架的功能特性。例如常见的分组功能,就是依赖于服务端在注册的时候同时注册自己的分组信息。)
- 注册成功之后,注册中心和服务端要保持心跳。
- 客户端第一次发起对某个服务的调用之前,要先找注册中心获得所有可用服务节点列表,随后客户端会在本地缓存每个服务对应的可用节点列表。
- 客户端和注册中心要保持心跳和数据同步,后续服务端有任何变动,注册中心都会通知客户端,客户端会更新本地的可用节点列表。
- 客户端发送请求。
服务下线:
- 服务端通知注册中心自己准备下线了。
- 注册中心通知客户端某个服务端下线了。
- 客户端收到通知之后,新来的请求就不会再给该服务端发过去。
- 服务端等待一段时间之后,暂停服务并下线。
高可用
高可用的服务注册与发现要围绕注册服务端崩溃检测、客户端容错和注册中心选型三个方面进行。
服务端崩溃检测
问题的关键就在于注册中心怎么判断服务端已经崩溃了。
一方面,注册中心在和服务端进行心跳的时候失败了,就要立刻通知客户端该服务端已经不可用了,那么客户端就不会再发请求过来。
另外一方面,注册中心还要继续往服务端发心跳。如果只是偶发性的心跳失败,那么注册中心后面心跳是肯定能够连上的,这时候注册中心再通知客户端这个服务端是可用的。
如果不考虑重试间隔的话,就难以避开偶发性的失败。比如说注册中心和服务端之间网络抖动,那么第一次心跳失败之后,你立刻重试多半也是失败的,因为此时网络很可能还是不稳定。所以比较好的策略是立刻重试几次,如果都失败了就再间隔一段时间继续重试。所有的重试机制实际上也是要谨慎考虑重试次数和重试间隔的,确保在业务可以接受的范围内重试成功。不过再怎么样,从服务端崩溃到客户端知道,中间总是存在一个时间误差的,这时候就需要客户端来做容错了。
客户端容错
客户端容错是指尽量在注册中心或者服务端节点出现问题的时候,依旧保证请求能够发送到正确的服务端节点上。
客户端容错第一个要考虑的是如果某个服务端节点崩溃了该怎么办。在服务端节点崩溃之后,到注册中心发现,再到客户端收到通知,是存在一段延时的,这个延时是能算出来的。在这段延时内,客户端发送请求给这个服务端节点都会失败。
一般的策略是客户端在发现调不通之后,应该尝试换另外一个节点进行重试。如果客户端上的服务发现组件或者负载均衡器能够根据调用结果来做一些容错的话,那么它们应该要尝试将这个节点挪出可用节点列表,在短时间内不要再使用这个节点了。后面再考虑将这个节点挪回去。
最坏的情况下,延时等于服务端和注册中心心跳间隔加上注册中心通知客户端的时间。大多数时候,注册中心通知客户端都是很快的,在毫秒级以内。因此可以认为服务端和注册中心的心跳间隔就是这个延时。
如果注册中心最终发现服务端崩溃,然后通知了客户端,那么客户端就不用放回去了。等到注册中心发现服务端再次恢复了,那么注册中心会通知客户端,此时客户端更新可用节点列表就可以了。
客户端也要朝着那个疑似崩溃的服务端节点继续发送心跳。如果心跳成功了,就将节点放回可用列表。如果连续几次心跳都没有成功,那么就不用放回去了,直接认为这个节点已经崩溃了。
注册中心选型
在注册中心选型上,重要的是 CAP 原理中应该选择 AP,比如说 Eureka,又或者 Nacos 启用 AP 模式。
此文章为9月Day21学习笔记,内容来源于极客时间《后端工程师的高阶面经》