阿里二面:使用 Nacos 做注册中心怎么做优雅发布?

网站建设1年前发布
10 00

大家好,我是君哥。,今天来聊一聊使用 Nacos 做注册中心怎么做优雅发布。,跟其他的注册中心一样,Nacos 作为注册中心的使用如下图:,阿里二面:使用 Nacos 做注册中心怎么做优雅发布?,Service Provider 启动后注册到 Nacos Server,Service Consumer 则从 Nacos Server 拉取服务列表,根据一定算法选择一个 Service Provider 来发送请求。,对于优雅发布,要求是 Service Provider 上线(注册到 Nacos)后,服务能够正常地接收和处理请求,而 Service Provider 停服后,则不会再收到请求。这就有两个要求:,解决了这两个问题,优雅发布就可以做到了。,搭建环境是为了看 Nacos 日志,通过日志找到对应的源代码。本文搭建的环境如下图:,阿里二面:使用 Nacos 做注册中心怎么做优雅发布?,启动 springboot-provider 的应用,注册到 Nacos,启动日志如下:,我们再看下 Nacos 的日志,这里看的文件 naming-server.log,日志如下:,springboot-provider 启动成功后,从Nacos 管理后台可以看到下图:,阿里二面:使用 Nacos 做注册中心怎么做优雅发布?,服务下线后,Nacos 日志如下:,在 springboot-consumer 上跑一个单元测试的用例,用 FeignClient 调用下面的方法:,日志如下:,注意,这里使用了 OpenFeign,其中用到了 Ribbon 做负载均衡,那就需要考虑到 Ribbon 的刷新本地服务列表的时间,从源代码中看,刷新周期是 30s。如下图:,阿里二面:使用 Nacos 做注册中心怎么做优雅发布?,Ribbon 刷新缓存的逻辑参考下面代码:,前面第一节提到过,优雅发布有两个要求:优雅上线和优雅下线。,Nacos 客户端和服务端的交互采用长轮询的方式,服务端收到客户端的请求后,首先会判断服务端本地的服务列表是否跟客户端的相比是否发生变化(比较 MD5),如果发生变化则立即通知客户端,否则放入长轮询队列挂起,如果这段时间内服务列表发生变化,则立刻通知客户端,否则等到超时后再通知客户端。代码如下:,从上面服务端源代码可以看到,这里超时时间是 30s,其中 29.5s 用于挂起等待,0.5s 检查服务列表是否发生变化。这里使用了长轮询,如果服务端列表发生变化,会立刻通知客户端,所以对优雅发布影响非常小。,服务列表发生变化后,客户端用单独的线程通知监听的 listener,代码如下:,优雅上线存在的问题主要在于 Service Provider 注册到 Nacos 后,服务还没有完成初始化,请求已经到来。这种情况主要原因是 Service Provider 启动后立刻注册 Naocs,而本身提供的接口可能还没有初始化完成。,这种情况的解决方法是关闭自动注册:,在服务初始化后使用代码手动注册,代码如下:,服务下线分两种情况,一个是正常停服,一个是服务故障。,对于正常停服,Nacos 采用心跳检测来实现服务在线。心跳周期是 5s,Nacos Server 如果 15s 没收到心跳就会将实例设置为不健康,在 30s 没收到心跳才会讲这个服务删除。当然这个时间可以设置:,但这样并不能保证服务停止后能够立刻从 Nacos Server 下线,很有可能服务停止后还能再收到请求,最好的方式是手动下线,比如增加一个 API 接口,服务下线之前增加 preStopHook 函数调用这个 API 接口来实现下线。API 接口示例代码如下:,在使用 Ribbon 的场景,也需要考虑 Ribbon 更新本地缓存服务列表的机制,手动下线后,可以再等待 30s 再关闭服务。,第二种情况是服务故障,但是并没有停服,这种情况是很难避免外部请求再发送过来的。处理方式是对这个服务本身的健康检查结果进行处理,比如连续三次健康检查失败,可以调用上面的 API 接口让服务下线。,无论是哪一款注册中心,优雅发布要解决的问题都是优雅上线和优雅下线。本文结合 Nacos 的原理讲解了 Nacos 的优雅发布,希望对你有所帮助。

© 版权声明

相关文章