基于nacos的服务平滑上下线方案
所谓平滑上下线简单说就是系统发版升级过程对用户无感知,不至于等到夜深人静的时候偷偷去搞,某些请求时间可以长点,但不能失败。
主要是基于naocs提供的SDK接口进行服务的注销和注册。
在对应服务中新增注销服务的接口和注册服务的接口。
代码如下:
package com.gaopeng.cloud.controller; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; import com.alibaba.cloud.nacos.registry.NacosRegistration; import com.alibaba.nacos.api.exception.NacosException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class NacosController { protected final transient Logger log = LoggerFactory.getLogger(getClass()); @Autowired NacosDiscoveryProperties nacosDiscoveryProperties; @Autowired NacosRegistration nacosRegistration; /** * 服务注册接口 * * @return */ @GetMapping(value = "/api/nacos/register") public String registerInstance() { String serviceName = nacosDiscoveryProperties.getService(); String groupName = nacosDiscoveryProperties.getGroup(); String clusterName = nacosDiscoveryProperties.getClusterName(); String ip = nacosDiscoveryProperties.getIp(); int port = nacosDiscoveryProperties.getPort(); log.info("register from nacos, serviceName:{}, groupName:{}, clusterName:{}, ip:{}, port:{}", serviceName, groupName, clusterName, ip, port); try { nacosRegistration.getNacosNamingService().registerInstance(serviceName, groupName, ip, port, clusterName); } catch (NacosException e) { log.error("register from nacos error", e); return "error"; } return "success"; } /** * 服务注销接口 * * @return */ @GetMapping(value = "/api/nacos/deregister") public String deregisterInstance() { String serviceName = nacosDiscoveryProperties.getService(); String groupName = nacosDiscoveryProperties.getGroup(); String clusterName = nacosDiscoveryProperties.getClusterName(); String ip = nacosDiscoveryProperties.getIp(); int port = nacosDiscoveryProperties.getPort(); log.info("deregister from nacos, serviceName:{}, groupName:{}, clusterName:{}, ip:{}, port:{}", serviceName, groupName, clusterName, ip, port); try { nacosRegistration.getNacosNamingService().deregisterInstance(serviceName, groupName, ip, port, clusterName); } catch (NacosException e) { log.error("deregister from nacos error", e); return "error"; } return "success"; } }
系统升级步骤:
a、在系统升级前先调用注销接口将目标服务实例注销,服务实例列表中将会删除该实例
b、注销之后将这个实例服务进行打包部署
c、部署后,调用服务注册接口将该服务重新注册
d、重复a、b、c完成服务的平滑升级过程
缺点:
1、需要开发人员手动增加服务注销和注册的接口
2、存在时间窗口,服务实例状态变化感知不实时