发布稳定性-优雅上线

简介: 之前的文章讲了优雅下线,今天讲优雅上线

之前的文章讲了优雅下线发布稳定性-优雅下线,今天讲优雅上线

优雅上线也叫:「无损上线」,「延迟发布」,「延迟暴露」。与之对立的自然是:「有损上线」,「直接发布」

什么是优雅上线

先说说什么情况不是优雅上线

  • 应用启动时,Service还没加载完,系统就开始对外提供服务,导致失败调用。

  • 应用启动时,没有检查系统健康状态,导致失败调用

这些情况都会影响到用户,即不优雅的上线。

对于任何一个线上应用来说,发布、扩容、缩容、重启等操作不可避免,这时候服务不可用,就必须把流量弄走,比如分批发布时,放到别的机器上。等到应用恢复正常后,再把流量弄回来,让应用继续提供服务,这就是优雅上线。

无论是HTTP应用还是RPC应用,在发布上线时,优雅上线逻辑都是一样的,如下图,服务发布过程中不可用,进行摘流。待到服务发布完成,重新分配流量

1_1.png

Dubbo的优雅上线

Dubbo的优雅上线有2种方式:延迟发布 和 Qos命令

1.延迟发布

即延迟暴露Dubbo服务,比如你的服务需要一些初始化操作后才能对外提供服务,如初始化缓存,redis连接池等相关资源就位,可以使用 delay 进行延迟暴露。 Dubbo 2.6.5 之后的版本中所有的Dubbo服务都会在Spring初始化完成后进行暴露,可自行配置延迟暴露的时间,配置如下:

Dubbo官方文档的延迟暴露:延迟暴露

# 延迟暴露5s
dubbo.provider.delay=5000

源码分析

Dubbo实现了Spring的ApplicationListener接口,监听ContextRefreshedEvent事件,即在Spring容器启动完毕后再开始暴露服务,源码分析如下:

ServiceBean:

//监听ContextRefreshedEvent事件,再执行export暴露服务    
        @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
   
   
        if (!isExported() && !isUnexported()) {
   
   
            if (logger.isInfoEnabled()) {
   
   
                logger.info("The service ready on spring started. service: " + getInterface());
            }
            export();
        }
    }

ServiceConfig类:

  //暴露Service
  public synchronized void export() {
   
   
        checkAndUpdateSubConfigs();

        if (!shouldExport()) {
   
   
            return;
        }
                //判断是否配置了延迟发布时间,如有,则单起一个线程,等待相应时间后再执行doExport方法
        if (shouldDelay()) {
   
   
            DELAY_EXPORT_EXECUTOR.schedule(this::doExport, getDelay(), TimeUnit.MILLISECONDS);
        } else {
   
   
            doExport();
        }
    }

    private boolean shouldExport() {
   
   
        Boolean export = getExport();
        // default value is true
        return export == null ? true : export;
    }


    @Override
    public Boolean getExport() {
   
   
        return (export == null && provider != null) ? provider.getExport() : export;
    }
    //判断是否需要延迟暴露
    private boolean shouldDelay() {
   
   
        Integer delay = getDelay();
        return delay != null && delay > 0;
    }
    //获取配置的延迟暴露时间
    @Override
    public Integer getDelay() {
   
   
        return (delay == null && provider != null) ? provider.getDelay() : delay;
    }

2. QOS命令上线

Dubbo官方文档QOS命令操作手册:QOS操作手册

配置以下,启动时不向注册中心发布服务

# 延迟暴露5s
dubbo.provider.delay=5000
# provider服务启动后不注册到注册中心
#dubbo.registry.register=false
#dubbo.registry.default=false
dubbo.provider.register=false

dubbo.application.qos-port=22223
dubbo.application.qos-enable=true
dubbo.application.qos-accept-foreign-ip-compatible=true

这里配置的时候遇到个问题:

按网上的方法配置dubbo.registry.register=false就能让服务不发布到注册中心,但是Qos命令也用不了了。按我上面的配置,Qos还是可用的啊

因为此时服务未发布,就不会有请求过来。我们可以在服务健康检查完之后在手动发布Service,可通过telnet命令或是http请求方式online

HTTP方式发布所有服务

curl localhost:22223/online

过程如下图

1_2.png

最佳实践

本文介绍了两种 Dubbo 优雅上线的方法:

  • 延迟发布(delay=5000)
  • 不发布 + QOS 指令发布(register=false)

在实际的企业应用中,需要结合具体场景使用。大型应用Service较多时,通常可用QOS命令分层发布Service,即每次发布一定数量的接口,而不是一次全发。

总结:服务发布的稳定性已讲了优雅上下线,但是实际工作中不是做好这两样就行了,具体情况需要具体分析,下篇文章继续讲稳定性的内容:流量预热。

相关文章
|
9月前
|
存储 缓存 NoSQL
分布式系统架构8:分布式缓存
本文介绍了分布式缓存的理论知识及Redis集群的应用,探讨了AP与CP的区别,Redis作为AP系统具备高性能和高可用性但不保证强一致性。文章还讲解了透明多级缓存(TMC)的概念及其优缺点,并详细分析了memcached和Redis的分布式实现方案。此外,针对缓存穿透、击穿、雪崩和污染等常见问题提供了应对策略,强调了Cache Aside模式在解决数据一致性方面的作用。最后指出,面试中关于缓存的问题多围绕Redis展开,建议深入学习相关知识点。
600 8
|
持续交付
2分钟教你部署2048小游戏到云服务器上
2分钟教你部署2048小游戏到云服务器上
466 0
2分钟教你部署2048小游戏到云服务器上
|
9月前
|
NoSQL 关系型数据库 MySQL
分布式系统学习9:分布式锁
本文介绍了分布式系统中分布式锁的概念、实现方式及其应用场景。分布式锁用于在多个独立的JVM进程间确保资源的互斥访问,具备互斥、高可用、可重入和超时机制等特点。文章详细讲解了三种常见的分布式锁实现方式:基于Redis、Zookeeper和关系型数据库(如MySQL)。其中,Redis适合高性能场景,推荐使用Redisson库;Zookeeper适用于对一致性要求较高的场景,建议基于Curator框架实现;而基于数据库的方式性能较低,实际开发中较少使用。此外,还探讨了乐观锁和悲观锁的区别及适用场景,并介绍了如何通过Lua脚本和Redis的`SET`命令实现原子操作,以及Redisson的自动续期机
946 7
|
12月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
9月前
|
负载均衡 Kubernetes 网络协议
注册中心如何选型?Eureka、Zookeeper、Nacos怎么选
这是小卷对分布式系统架构学习的第9篇文章,继续探讨注册中心的原理及选型。文章详细介绍了Eureka、Nacos的工作机制与特点,并对比了Eureka、Nacos、Consul和Zookeeper在一致性协议、健康检查、负载均衡等方面的差异。最后根据不同的应用场景给出了注册中心的选型建议,帮助读者理解如何选择最适合的注册中心。
696 100
|
9月前
|
人工智能 数据可视化 IDE
AI编程:cursor使用教程
这是小卷对AI编程工具学习的首篇文章,以Cursor为例,介绍其安装与基本功能。Cursor分为狭义和广义两类,前者辅助程序员高效编程,后者让无基础用户也能创建应用。文章详细讲解了Cursor的安装、快捷键、代码生成、修改、补全及项目理解等功能,并展示了如何通过提示词实现需求,帮助小白轻松上手编程。
1846 77
|
10月前
|
自然语言处理 负载均衡 Kubernetes
分布式系统架构2:服务发现
服务发现是分布式系统中服务实例动态注册和发现机制,确保服务间通信。主要由注册中心和服务消费者组成,支持客户端和服务端两种发现模式。注册中心需具备高可用性,常用框架有Eureka、Zookeeper、Consul等。服务注册方式包括主动注册和被动注册,核心流程涵盖服务注册、心跳检测、服务发现、服务调用和注销。
395 13
|
9月前
|
Shell 网络安全
2024年终总结:选择错误、加班三月、降薪、面试无果...
卷福同学回顾2024年,反思“选择大于努力”的重要性。年初因错误选择,导致一年都在调整。从阿里离职回到武汉国企后,发现二线城市工作机会有限,成长空间小,且加班严重、降薪明显。尽管尝试副业和面试大厂,但进展不顺。最终意识到选择至关重要,未来将继续努力提升专业技能,寻找更好的发展机会。
239 70
|
7月前
|
算法
面试场景题:如何设计一个抢红包随机算法
本文详细解析了抢红包随机算法的设计与实现,涵盖三种解法:随机分配法、二倍均值法和线段切割法。随机分配法通过逐次随机分配金额确保总额不变,但易导致两极分化;二倍均值法优化了金额分布,使每次抢到的金额更均衡;线段切割法则将总金额视为线段,通过随机切割点生成子金额,手气最佳金额可能更高。代码示例清晰,结果对比直观,为面试中类似算法题提供了全面思路。
1231 16
|
7月前
|
缓存 监控 NoSQL
场景题:线上接口响应慢,应该如何排查问题?
面试中常见的接口响应慢排查题旨在考察研发人员的系统性解决问题的能力。回答时需结合业务场景(如大促、高峰期),并运用工具(Arthas、SkyWalking等)进行监控告警、链路追踪和日志分析,明确问题范围及原因。具体步骤包括:1. 定位问题(确认单个接口或整体系统、查看APM指标、分析链路和日志);2. 排查网络、中间件及外部依赖(检测延迟、检查Redis、RocketMQ、MySQL等);3. 服务端性能分析(CPU、内存、磁盘IO、JVM调优)。最后提出优化方案,如代码逻辑、数据库、缓存策略及资源扩容等。总结时可结合实际案例,展示完整的排查与优化流程。
1008 3