目录
一、服务发现
服务注册和发现不是一个新的概念。Nginx是一个反向代理组件,那么Nginx需要知道应用服务器的地址是什么,这样才能够将流量透传到应用服务器上,这就是服务发现的过程,使用Nginx作为服务发现有几个问题
- 首先在紧急扩容的时候,就需要修改客户端配置后,重启所有的客户端进程,操作时间比较长;
- 其次,一旦某一个服务器出现故障时,也需要修改所有客户端配置后重启,无法快速修复,更无法做到自动恢复;
- 最后,RPC服务端上线无法做到提前摘除流量,这样在重启服务端的时候,客户端发往被重启服务端的请求还没有返回,会造成慢请求甚至请求失败
使用注册中心来解决这些问题,比如说老派的ZooKeeper、Kubernetes使用的ETCD、阿里的微服务注册中心Nacos、Spring Cloud的Eureka等。基本功能有两点:
- 其一是提供了服务地址的存储;
- 其二是当存储内容发生变化时,可以将变更的内容推送给客户端。
无论是当我们需要紧急扩容,还是在服务器发生故障时需要快速摘除节点,都不用重启服务器就可以实现了。使用了注册中心组件之后,RPC的通信过程就变成了下面这个样子
- 客户端会与注册中心建立连接,并且告诉注册中心,它对哪一组服务感兴趣;
- 服务端向注册中心注册服务后,注册中心会将最新的服务注册信息通知给客户端;
- 客户端拿到服务端的地址之后就可以向服务端发起调用请求了
有了注册中心之后,服务节点的增加和减少对于客户端就是透明的。
优雅关闭
如果暴力地停止服务,那么已经发送给服务端的请求,来不及处理服务就被删掉了,就会造成这部分请求失败,服务就会有波动。所以服务在退出的时候,都需要先停掉流量再停止服务,这样服务的关闭才会更平滑。比如,消息队列处理器就是要将所有已经从消息队列中读出的消息,处理完之后才能退出。
对于RPC服务来说, 我们可以先将RPC服务从注册中心的服务列表中删除掉,然后观察RPC服务端没有流量之后,再将服务端停掉。有了优雅关闭之后,RPC服务端再重启的时候,就会减少对客户端的影响。
二、服务状态管理如何来做
1.主动探测
你的RPC服务要打开一个端口,然后由注册中心每隔一段时间(比如30秒)探测这些端口是否可用,如果可用就认为服务仍然是正常的,否则就可以认为服务不可用,那么注册中心就可以把服务从列表里面删除了
如果RPC服务端部署的实例比较多,那么每次探测的成本也会比较高,探测的时间也比较长,这样当一个服务不可用时,可能会有一段时间的延迟,才会被注册中心探测到。
2.心跳模式
RPC服务节点在启动注册到注册中心后,就按照一定的时间间隔(比如30秒),向注册中心发送心跳包。注册中心在接收到心跳包之后,会更新这个节点的最近续约时间。然后,注册中心会启动一个定时器定期检测当前时间和节点最近续约时间的差值,如果达到一个阈值(比如说90秒),那么认为这个服务节点不可用。
三、总结
如果你新建了一条街道(相当于启动了一个新的服务节点),那么就要通知所有的车辆(流量)有新的道路可以走了;你关闭了一条街道,你也要通知所有车辆不要从这条路走了,这就是服务的注册和发现
在道路上安装监控,监视每条道路的流量情况,这就是服务的监控
道路一旦出现拥堵或者道路需要维修,那么就需要暂时封闭这条道路,由城市来统一调度车辆,走不堵的道路,这就是熔断以及引流
道路之间纵横交错四通八达,一旦在某条道路上出现拥堵,但是又发现这条道路从头堵到尾,说明事故并不是发生在这条道路上,那么就需要从整体链路上来排查事故究竟处在哪个位置,这就是分布式追踪。
不同道路上的车辆有多有少,那么就需要有一个警察来疏导,在某一个时间走哪一条路会比较快,这就是负载均衡。