您好,登錄后才能下訂單哦!
本篇內容主要講解“如何開啟Dubbo框架不重復可用端口功能”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何開啟Dubbo框架不重復可用端口功能”吧!
當前我們基本上一臺服務器部署一個應用,所以dubbo協議端口提前配置好,例如:dubbo協議使用20880,rest協議使用20889;但是如果需要在同一臺主機部署多個實例節點時,會出現端口沖突,解決方法有兩種:
手工分配并修改端口;(很明顯不優雅,且后期運維成本很高)
系統支持自動分配端口;(優選方案)
本文就是通過dubbo源碼解讀,說明如何配置才能實現第二種方案.
開啟自動分配端口
此處以dubbox中dubbo.xml配置
<dubbo:protocol name="rest" port="-1" /> <dubbo:protocol name="dubbo" port="-1" />
如果port不填或者直接設置成null,將會使用系統默認的端口;如果設置成小于0(例如-1),則隨機分配未被使用的端口。
其中dubbo協議從20880開始編起,rest協議則從80端口開始編起;
方法源碼: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框架中,從環境變量可以配置端口(優先級最高)
獲取端口源碼地址:
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框架不重復可用端口功能”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。