微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

优雅停机-dubbo篇

dubbo中使用了netty,但是它修改了netty的代码,其中有个bug,导致无法优雅停机。
下面的代码用于解决这个问题。

package org.j@R_263_5404@ia.dubbo;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import javax.annotation.PreDestroy;

import org.jboss.netty.channel.ChannelFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

/**
 * 依赖dubbo2.5.3
 * 解决优雅停机的问题(dubbo间接创建的非守护线程导致的不能优雅停机) 参考文章
 * https://jeremy-xu.oschina.io/2016/12/%E8%A7%A3%E5%86%B3dubbo%E5%AF%BC%E8%87%B4tomcat%E6%97%A0%E6%B3%95%E4%BC%98%E9%9B%85shutdown%E7%9A%84%E9%97%AE%E9%A2%98/
 * 解决方案:
 * 在停掉应用的回调里面,比如spring的PreDestroy,比如servletcontextlistener的contextDestroyed,
 * 获取NettryClient的静态属性 channelFactory,调用其releaseExternalResource方法。
 * 
 */
public class dubboNettyClientResourceReleaser {
	private Logger logger = LoggerFactory.getLogger(this.getClass());

	// 最低优先级
	@PreDestroy
	@Order(Ordered.LOWEST_PRECEDENCE)
	public void destroy() {
		try {
			// 先释放dubbo所占用的资源
			Class<?> protocolConfigClass = Class.forName("com.alibaba.dubbo.config.ProtocolConfig");
			Method destroyAllMethod = protocolConfigClass.getmethod("destroyAll");
			destroyAllMethod.invoke(protocolConfigClass);
			//ProtocolConfig.destroyAll();
			logger.info("ProtocolConfig destroyAll success");
		} catch (Exception e) {
			logger.error("ProtocolConfig destroyAll error", e);
		}
		try {
			// 用反射释放NettyClient所占用的资源, 以避免不能优雅shutdown的问题
			releaseNettyClientExternalResources();
			logger.info("Release NettyClient's external resources");
		} catch (Exception e) {
			logger.error("Release NettyClient's external resources error", e);
		}
	}

	private void releaseNettyClientExternalResources() throws NoSuchFieldException, SecurityException, IllegalArgumentException, illegalaccessexception, ClassNotFoundException {
		Class<?> nettyClientClass = Class.forName("com.alibaba.dubbo.remoting.transport.netty.NettyClient");
		Field field = nettyClientClass.getDeclaredField("channelFactory");
		field.setAccessible(true);
		ChannelFactory channelFactory = (ChannelFactory) field.get(nettyClientClass);
		channelFactory.releaseExternalResources();
		field.setAccessible(false);
	}
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐