乐趣区

关于后端:发布稳定性优雅上线

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

优雅上线也叫:「无损上线」,「提早公布」,「提早裸露」。与之对抗的天然是:「有损上线」,「间接公布」

什么是优雅上线

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

  • 利用启动时,Service 还没加载完,零碎就开始对外提供服务,导致失败调用。
  • 利用启动时,没有查看零碎衰弱状态,导致失败调用

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

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

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

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

过程如下图

最佳实际

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

  • 提早公布(delay=5000)
  • 不公布 + QOS 指令公布(register=false)

在理论的企业应用中,须要联合具体场景应用。大型利用 Service 较多时,通常可用 QOS 命令分层公布 Service,即每次公布肯定数量的接口,而不是一次全发。

总结:服务公布的稳定性已讲了优雅高低线,然而理论工作中不是做好这两样就行了,具体情况须要具体分析,下篇文章持续讲稳定性的内容:流量预热。

退出移动版