《分布式配置管理平台与优雅停机》
分布式配置管理平台与优雅停机存在什么必然联系?假设配置在配置中心的数据信息发生改变后,客户端感知并订阅到后,必然需要reset来及时响应,最典型的场景就是服务降级(开关)。
一些根据配置信息生成的对象实例(比如JDBC对象实例、Jedis对象实例),则需要重新生成新的对象实例,而不是简单的对目标值做reset。针对这种对象,本文提供2种方案可供参考:
1、动态注册Bean实例方案;
2、优雅停机实现restart方案。
如果项目中采用了Spring,那么可以选择对IOC容器中的那些Bean实例进行“剔除”后重新注册,这其实就是不重启状态下的动态注册。但这种方案却存在一个较为致命的缺陷,生产环境中,尤其是用户流量较大的网站,假设配置中心的数据源信息发生了变更,客户端感知并订阅后需要立马释放之前的资源连接,也不管之前的连接上是否还有未执行完成的任务,那么这对业务肯定会产生较为严重的影响。
那么我们来看第2种方案,优雅停机后restart。在Linux上,相信大家都使用过kill命令,在生产环境中,笔者最长用的就是kill(即kill -15 )PID和kill -9 PID,无论执行哪一个命令,最终程序进程都会停止,但是仍然存在区别。我们可以先来看一下信号变量,执行命令“kill -l”,如下所示:
简单来说,假设执行的是kill -15命令,那么操作系统会发送一个SIGTERM的信号对应用程序,应用程序收到SIGTERM信号后,会对当前所占用的资源进行释放,然后才会相对安全优雅的结束进程。而kill -9命令则恰恰相反,强制结束进程,可能会造成资源无法释放等问题。
谈到了kill,那么接下来要谈的就是如何让程序实现优雅停机,也就是说,假设数据源信息发生变化,应用系统要首先拒绝新的任务请求,并且等待那些还未执行完成的线程处理完成后,再restart,相对于第1种方案,采用此方案会更加安全可靠。
假设我们采用dubbo实施服务化后,那么dubbo原生是支持优雅停机的,其实也就是采用JDK的ShudownHook来实现,当然仅限kill -15 PID。这里也顺带说一下dubbo优雅停机的原理,如下所示:
服务提供方
· 停止时,先标记为不接收新请求,新请求过来时直接报错,让客户端重试其它机器。
· 然后,检测线程池中的线程是否正在运行,如果有,等待所有线程执行完成,除非超时,则强制关闭。
服务消费方
· 停止时,不再发起新的调用请求,所有新的调用在客户端即报错。
· 然后,检测有没有请求的响应还没有返回,等待响应返回,除非超时,则强制关闭。
接下来,我们再来尝试通过ShudownHook模拟优雅停机,如下所示:
public class ShutdownHookDemo {
public ThreadPoolExecutor tPool = new ThreadPoolExecutor(10, 100, 1, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(2), new CallerRunsPolicy());
public ShutdownHookDemo() {
init();
int threadSize = tPool.getCorePoolSize();
final CountDownLatch latch = new CountDownLatch(threadSize);
for (int i = 0; i < threadSize; i++) {
tPool.execute(new Thread() {
public void run() {
try {
/* 休眠10s */
TimeUnit.SECONDS.sleep(((int) (Math.random() * 15)));
} catch (Exception e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}
});
}
try {
latch.await();
System.out.println("所有任务执行结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void init() {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
/* 尝试中断线程,且不再接收新请求 */
tPool.shutdownNow();
while (true) {
int activeCount = tPool.getActiveCount();
System.out.println("活跃线程-->" + activeCount);
if (0 == activeCount)
break;
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
public static void main(String[] args) {
new ShutdownHookDemo();
}
}
上述程序示例中,总共会有10条线程分别“处理”任务,耗时都在<=15S内,那么假设使用kill -15 PID命令终止进程后,通过ShutdownHook注册的钩子就会发生作用,一般来说,开发人员可以通过ShutdownHook来完成一些释放资源的操作,这里笔者选择拒绝新任务,且等待当前线程处理完当前任务,如果线程池中的所有线程都非活跃的情况,则代表程序可以安全的结束进程。
未经许可,不可转载
相关推荐
DCMP是分布式配置管理平台。提供了一个etcd的管理界面,可通过界面修改配置信息,借助confd可实现配置文件的同步。
Disconf分布式配置管理平台 v2.6.36.zip
xxl-conf分布式配置管理平台 v1.6.1.zip
XXL-CONF 是一个分布式配置管理平台,拥有"毫秒级动态推送、多环境、多语言、配置监听、权限控制、版本版本回滚"等特性。现已开放源代码,开箱即用。
GIT 分布式配置管理工具 开源工具,与SVN类同,分布式管理。
SpringCloud——分布式配置中心(Spring Cloud Config)之高可用的分布式配置中心
为您提供Disconf分布式配置管理平台下载,Disconf(Distributed Configuration Management Platform)分布式配置管理平台,专注于为各种「分布式系统配置管理」的「通用组件」和「通用平台」提供统一的「配置管理...
分布式配置文件
基于.NET Core开发的轻量级分布式配置中心.zip
Apollo分布式配置中心
Linux Hadoop 伪分布式配置 一个节点,线程模仿分布式
Hadoop安装教程_单机_伪分布式配置
但实际中会有某些配置信息变化有一定频率和规律,并且希望能够做到尽量实时,比如一些营销类,或活动类应用系统,若使用传统的配置文件,加上重新发布应用可能会有些不方便,因此,才有了分布式配置管理平台,旨在能...
QConf 是奇虎 360 内部分布式配置管理工具。用来替代传统的配置文件,使得配置信息和程序代码分离,同时配置变化能够实时同步到客户端,而且保证用户高效读取配置,这使的工程师从琐碎的配置修改、代码提交、配置...
Disconf(Distributed Configuration Management Platform)分布式配置管理平台,专注于为各种「分布式系统配置管理」的「通用组件」和「通用平台」提供统一的「配置管理服务」。包括百度、滴滴出行、银联、网易、...
分布式数据库管理综述,快速学会分布式数据库管理的应用
分布式配置中心架构设计,李迪,詹舒波,随着程序功能的日益复杂,程序的配置也日益增多,同一程序对应不同的业务时需要不同的配置,同时,分布式应用也越来越多,在不同
分布式库存管理系统的设计与实现 分布式库存管理系统的设计与实现
rabbitMQ安装与配置(分布式配置)