如何开启Dubbo框架不重复可用端口功能

本篇内容主要讲解“如何开启Dubbo框架不重复可用端口功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何开启Dubbo框架不重复可用端口功能”吧!

创新互联建站专注于西乡塘企业网站建设,响应式网站开发,商城网站开发。西乡塘网站建设公司,为西乡塘等地区提供建站服务。全流程按需求定制设计,专业设计,全程项目跟踪,创新互联建站专业和态度为您提供的服务

业务场景

当前我们基本上一台服务器部署一个应用,所以dubbo协议端口提前配置好,例如:dubbo协议使用20880,rest协议使用20889;但是如果需要在同一台主机部署多个实例节点时,会出现端口冲突,解决方法有两种:

  1. 手工分配并修改端口;(很明显不优雅,且后期运维成本很高)

  2. 系统支持自动分配端口;(优选方案)

本文就是通过dubbo源码解读,说明如何配置才能实现第二种方案.

开启自动分配端口

此处以dubbox中dubbo.xml配置


如果port不填或者直接设置成null,将会使用系统默认的端口;如果设置成小于0(例如-1),则随机分配未被使用的端口。

其中dubbo协议从20880开始编起,rest协议则从80端口开始编起;

老版本dubbo框架源码

方法源码:com.alibaba.dubbo.config.ServiceConfig.doExportUrlsFor1Protocol()

该方法在dubbo容器启动,进行provider export初始化时调用,其中包括IP地址以及端口获取的逻辑,下面是端口处理的源码:

//从dubbo:protocol标签中读取port配置
Integer port = protocolConfig.getPort();
//如果有provider标签配置,且protocol中port配置为null 或者 0,则直接使用provider中的port端口
if (provider != null && (port == null || port == 0)) {
	port = provider.getPort();
}
//根据协议类型获取默认端口号(dubbo协议的端口为20880,源码在下面有说明)
final int defaultPort = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).getDefaultPort();
//如果配置port为null或者0,则会使用默认端口
if (port == null || port == 0) {
	port = defaultPort;
}
//如果经过默认端口处理后,port为null(例如没有协议中配置默认端口)或者负数,则随机生成一个端口
if (port == null || port <= 0) {
	//获取随机端口,从缓存中取
	port = getRandomPort(name);
	//如果获取端口为空,则以默认端口为基准,按顺序取最近一个可用的端口
	if (port == null || port < 0) {
		port = NetUtils.getAvailablePort(defaultPort);
		//添加到缓存中
		putRandomPort(name, port);
	}
	logger.warn("Use random available port(" + port + ") for protocol " + name);
}

下面是dubbo协议的默认端口配置:

com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol

核心源码:

public static final int DEFAULT_PORT = 20880;

获取顺序可用端口源码

public static int getAvailablePort(int port) {
    	if (port <= 0) {
    		return getAvailablePort();
    	}
    	for(int i = port; i < MAX_PORT; i ++) {
    		ServerSocket ss = null;
            try {
                ss = new ServerSocket(i);
                return i;
            } catch (IOException e) {
            	// continue
            } finally {
                if (ss != null) {
                    try {
                        ss.close();
                    } catch (IOException e) {
                    }
                }
            }
    	}
    	return port;
    }

新版dubbo框架源码(Apache)

在新版dubbo框架中,从环境变量可以配置端口(优先级最高)

获取端口源码地址:

org.apache.dubbo.config.ServiceConfig.doExportUrlsFor1Protocol()

// export service
String host = this.findConfigedHosts(protocolConfig, registryURLs, map);
Integer port = this.findConfigedPorts(protocolConfig, name, map);
URL url = new URL(name, host, port, getContextPath(protocolConfig).map(p -> p + "/" + path).orElse(path), map);

org.apache.dubbo.config.ServiceConfig.findConfigedPorts()

/**
     * Register port and bind port for the provider, can be configured separately
     * Configuration priority: environment variable -> java system properties -> port property in protocol config file
     * -> protocol default port
     *
     * @param protocolConfig
     * @param name
     * @return
     */
    private Integer findConfigedPorts(ProtocolConfig protocolConfig, String name, Map map) {
        Integer portToBind = null;
		
		//支持从环境变量中获取端口
        // parse bind port from environment
        String port = getValueFromConfig(protocolConfig, DUBBO_PORT_TO_BIND);
        portToBind = parsePort(port);

		//如果环境变量没有配置绑定端口,走下面逻辑
        // if there's no bind port found from environment, keep looking up.
        if (portToBind == null) {
			//

到此,相信大家对“如何开启Dubbo框架不重复可用端口功能”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!


本文名称:如何开启Dubbo框架不重复可用端口功能
转载注明:http://pwwzsj.com/article/jijphs.html