91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何開啟Dubbo框架不重復可用端口功能

發布時間:2021-06-25 17:48:10 來源:億速云 閱讀:297 作者:chen 欄目:大數據

本篇內容主要講解“如何開啟Dubbo框架不重復可用端口功能”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何開啟Dubbo框架不重復可用端口功能”吧!

業務場景

當前我們基本上一臺服務器部署一個應用,所以dubbo協議端口提前配置好,例如:dubbo協議使用20880,rest協議使用20889;但是如果需要在同一臺主機部署多個實例節點時,會出現端口沖突,解決方法有兩種:

  1. 手工分配并修改端口;(很明顯不優雅,且后期運維成本很高)

  2. 系統支持自動分配端口;(優選方案)

本文就是通過dubbo源碼解讀,說明如何配置才能實現第二種方案.

開啟自動分配端口

此處以dubbox中dubbo.xml配置

<dubbo:protocol name="rest" port="-1" />
<dubbo:protocol name="dubbo" port="-1" />

如果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<String, String> 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:protocol標簽中的port端口
            portToBind = protocolConfig.getPort();
            if (provider != null && (portToBind == null || portToBind == 0)) {
                portToBind = provider.getPort();
            }
			//獲取默認端口:dubbo:20880,http:80(與老版本一致)
            final int defaultPort = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).getDefaultPort();
			//如果標簽中配置端口為null或者0,則使用默認端口
            if (portToBind == null || portToBind == 0) {
                portToBind = defaultPort;
            }
			//如果配置是負數,則隨機獲取或按順序獲取可用端口
            if (portToBind <= 0) {
				//獲取隨機邏輯與最近可用端口邏輯(與老版本一致)
                portToBind = getRandomPort(name);
                if (portToBind == null || portToBind < 0) {
                    portToBind = getAvailablePort(defaultPort);
                    putRandomPort(name, portToBind);
                }
            }
        }

        // save bind port, used as url's key later
        map.put(Constants.BIND_PORT_KEY, String.valueOf(portToBind));

        // registry port, not used as bind port by default
        String portToRegistryStr = getValueFromConfig(protocolConfig, DUBBO_PORT_TO_REGISTRY);
        Integer portToRegistry = parsePort(portToRegistryStr);
        if (portToRegistry == null) {
            portToRegistry = portToBind;
        }

        return portToRegistry;
    }

到此,相信大家對“如何開啟Dubbo框架不重復可用端口功能”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

西峡县| 云梦县| 松阳县| 齐齐哈尔市| 张北县| 中方县| 南召县| 合肥市| 巴林左旗| 页游| 孟连| 昭通市| 上思县| 呼和浩特市| 太原市| 琼结县| 丽水市| 汶川县| 清流县| 安宁市| 贵南县| 平湖市| 通城县| 环江| 建昌县| 临海市| 新乡市| 惠东县| 冷水江市| 大英县| 三门县| 牙克石市| 依兰县| 杨浦区| 南投市| 铁岭市| 喀什市| 晴隆县| 咸丰县| 丰镇市| 乌恰县|