之前的文章讲了优雅下线公布稳定性 - 优雅下线,明天讲优雅上线
优雅上线也叫:「无损上线」,「提早公布」,「提早裸露」。与之对抗的天然是:「有损上线」,「间接公布」
什么是优雅上线
先说说什么状况不是优雅上线
- 利用启动时,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,即每次公布肯定数量的接口,而不是一次全发。
总结:服务公布的稳定性已讲了优雅高低线,然而理论工作中不是做好这两样就行了,具体情况须要具体分析,下篇文章持续讲稳定性的内容:流量预热。