关于微服务平滑发布机制,LoadBalancer与nacos和openfeign的那些事

背景:

当我们更新微服务时,停止服务,然后再启动服务,这个时间内,服务是不可用的,但是nacos并不能立马感知到我们的微服务已经下线了,nacos是定时轮询当前的服务是否健康,当检测到服务不健康时,会移除当前服务,这个时间可以再nacos中进行设置检查时间,但是无论怎么设置,都会存在这种服务不可用的状态,尤其再访问高时。

解决方案:

服务滚动发布,当微服务下线时,使用钩子ShutdownHook函数来通知nacos下线。

 具体实现:

首先当我们请求我们的网关时,网关会选择一个服务实例进行转发,那他这个实例是从哪里来的呢,这个关乎到我们的版本,我们使用的是springcloud alibaba 、openfeign,spingcloud已经自己研制了负载均衡组件,loadbalancer,这个loadbalancer目前有两种默认的负载均衡算法分别是

RandomLoadBalancer、
RoundRobinLoadBalancer

他们都实现了

ReactorServiceInstanceLoadBalancer接口,包括nacos也实现了这个接口
NacosLoadBalancer。关于这几个负载均衡器可自行了解

我们今天聊一下他的原理

首先,是从网关转发,网关根据自己的设置去找微服务实例,这个设置会判定是走本地缓存还是走实时读取nacos上的实例,如果是缓存,那么就存在服务下线延迟的问题,因为他需要根据时间去调度来更新缓存。所以我们的解决方案是,当我们服务下线时,将本地缓存清理,然后让服务去nacos上拉取最新的实例列表,这样就可以实现服务下线,也不会导致服务不可用的问题。

@Slf4j
@Component
public class ServiceChangeNotifier extends Subscriber<InstancesChangeEvent> {

    @Autowired
    private ApplicationContext context;

    @PostConstruct
    public void init() {
        // 注册当前自定义的订阅者以获取通知
        NotifyCenter.registerSubscriber(this);
    }

    @Override
    public void onEvent(InstancesChangeEvent event) {
        String serviceName = event.getServiceName();
        if (serviceName.contains(":")) {
            return;
        }
        String split = Constants.SERVICE_INFO_SPLITER;
        if (serviceName.contains(split)) {
            serviceName = serviceName.substring(serviceName.indexOf(split) + split.length());
        }
        log.info("服务上下线: {}", serviceName);
        ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider = context.getBeanProvider(LoadBalancerCacheManager.class);
        Cache cache = cacheManagerProvider.getIfAvailable().getCache(CachingServiceInstanceListSupplier.SERVICE_INSTANCE_CACHE_NAME);
        if (cache != null) {
            boolean present = cache.evictIfPresent(serviceName);
            log.info("本地缓存处理结果:{}",present);
        }
    }

    @Override
    public Class<? extends Event> subscribeType() {
        return InstancesChangeEvent.class;
    }

}
NotifyCenter这个类,在初始化时,会将服务注册到nacos服务端,并且会触发关闭钩子(关键),具体看代码

这样,我们监听到nacos发布通知,然后直接执行本地缓存清理,即可完成缓存内的服务实例进行实时更新,完结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值