zoukankan      html  css  js  c++  java
  • Dubbo Qos端口占用问题

    前几天部署环境的时候,启动几个dubbo服务的时候,报了qos端口22222被占用。

    貌似以前没遇到过这个错呢?

    Qos是啥?

    qos是dubbo的在线运维命令。

    dubbo2.5.8新版本重构了telnet模块,提供了新的telnet命令支持,新版本的telnet端口与dubbo协议的端口是不同的端口,默认为22222。可以对dubbo服务上/下线。

    qos使用示例参考

    QoS参数配置

    可以通过如下方式进行配置

    • JVM系统属性
    • dubbo.properties(在项目的src/main/resources目录下添加dubbo.properties文件)
    • XML方式
    • Spring-boot自动装配方式

    其中,上述方式的优先顺序为 JVM系统属性 > dubbo.properties > XML/Spring-boot自动装配方式。

    dubbo 2.5.9 版本

    如果要修改qos.port,可以通过如下方式达到目的:【类QosProtocolWrapper】

    方法一:在spring-dubbo.xml中配置如下

    <dubbo:application name="${project.name}">
        <!-- 关闭qos -->
        <dubbo:parameter key="qos.enable" value="false"/>
        <dubbo:parameter key="qos.port" value="22223"/>
    </dubbo:application>
    

    方法二:配置启动参数

    -Ddubbo.application.qos.port=33333 -Ddubbo.application.qos.enable=false

    dubbo 2.6.0版本

    取qos.port 是 【-Ddubbo.qos.port=33333】, 且无法通过配置关闭。

    在com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper中有启动qos

    public class ProtocolListenerWrapper implements Protocol {
        static {
            try {
                Class serverClass = Protocol.class.getClassLoader().loadClass("com.alibaba.dubbo.qos.server.Server");
                Method serverGetInstanceMethod = serverClass.getMethod("getInstance");
                Object serverInstance = serverGetInstanceMethod.invoke(null);
                Method startMethod = serverClass.getMethod("start");
                // 这里没有判断配置,直接反射调用start了
                startMethod.invoke(serverInstance);
            }catch (Throwable throwable){
    
            }
        }
        // ...
    }
    

    不过可以在qos-server启动之后,再关掉它。

    // 关闭dubbo qos service
    com.alibaba.dubbo.qos.server.Server.getInstance().stop();
    

    在com.alibaba.dubbo.qos.server.Server中,有如下代码段:

    public class Server {
        private static final Logger logger = LoggerFactory.getLogger(Server.class);
        private static final Server INSTANCE = new Server();
    
        public static final Server getInstance() {
            return INSTANCE;
        }
    	// 这里直接取端口号
        private int port = Integer.parseInt(ConfigUtils.getProperty(Constants.QOS_PORT, Constants.DEFAULT_PORT + ""));
    
        // ...略部分代码...
        
       /**
         * start server, bind port
         */
        public void start() throws Throwable {
            if (!hasStarted.compareAndSet(false, true)) {
                return;
            }
            boss = new NioEventLoopGroup(0, new DefaultThreadFactory("qos-boss", true));
            worker = new NioEventLoopGroup(0, new DefaultThreadFactory("qos-worker", true));
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(boss, worker);
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.childOption(ChannelOption.TCP_NODELAY, true);
            serverBootstrap.childOption(ChannelOption.SO_REUSEADDR, true);
            serverBootstrap.childHandler(new ChannelInitializer<Channel>() {
                @Override
                protected void initChannel(Channel ch) throws Exception {
                    ch.pipeline().addLast(new QosProcessHandler(welcome));
                }
            });
            try {
                serverBootstrap.bind(port).sync();
                logger.info("qos-server bind localhost:" + port);
            } catch (Throwable throwable) {
                // 这里会打印端口冲突错误
                logger.error("qos-server can not bind localhost:" + port, throwable);
                throw throwable;
            }
        }
    }
    

    为什么以前没遇到22222端口占用问题

    之前依赖的是dubbo-2.5.9。在这个版本的QosProtocolWrapper中,可以看到:

    private void startQosServer(URL url) {
            if (!hasStarted.compareAndSet(false, true)) {
                return;
            }
    
            try {
                boolean qosEnable = Boolean.parseBoolean(url.getParameter(QOS_ENABLE,"true"));
                if (!qosEnable) {
                    return;
                }
    
                int port = Integer.parseInt(url.getParameter(QOS_PORT,"22222"));
                boolean acceptForeignIp = Boolean.parseBoolean(url.getParameter(ACCEPT_FOREIGN_IP,"true"));
                // 如果没有netty4,下面这行代码就会报错
                Server server = com.alibaba.dubbo.qos.server.Server.getInstance();
                server.setPort(port);
                server.setAcceptForeignIp(acceptForeignIp);
                server.start();
            } catch (Throwable throwable) {
                // 这里错误直接吃掉了,没往外部抛出来
                //throw new RpcException("fail to start qos server", throwable);
            }
        }
    

    qos-server 需要netty4版本的支持,默认情况下dubbo不会引用netty4的依赖包。

    而最近新加的功能确实间接引入了netty4。

    关闭qos

    对于2.5.9的版本,可以通过如下方式关闭qos

    <dubbo:parameter key="qos.enable" value="false"/>

    或者

    -Ddubbo.application.qos.enable=false

    对于2.6.0的版本,没办法通过配置关闭,只能是Server有stop方法了

  • 相关阅读:
    ios开发常用工具集合网站
    xib自定义UIView报错误 "forUndefinedKey:]: this class is not key value coding-compliant for the key"
    IOS MJExtension json转模型的轻量级框架的使用(转载)
    升级Xcode之后VVDocumenter-Xcode不能用的解决办法
    iOS开发系列--并行开发其实很容易
    通讯录开发
    UIGestureRecognizer手势
    UIScrollView
    UIStepper
    UIPickerView
  • 原文地址:https://www.cnblogs.com/yejg1212/p/14794042.html
Copyright © 2011-2022 走看看