Skip to content

Commit 25b906f

Browse files
authored
Merge pull request apache#778 from chickenlj:specify_registry_ip&port
Feature: support specify ip & port registered to registry from environment properties
1 parent b27e1ff commit 25b906f

File tree

12 files changed

+213
-65
lines changed

12 files changed

+213
-65
lines changed

dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,20 @@ public class Constants {
582582

583583
public static final String GENERIC_SERIALIZATION_BEAN = "bean";
584584

585+
public static final String DUBBO_IP_TO_REGISTRY = "DUBBO_IP_TO_REGISTRY";
586+
587+
public static final String DUBBO_PORT_TO_REGISTRY = "DUBBO_PORT_TO_REGISTRY";
588+
589+
public static final String DUBBO_IP_TO_BIND = "DUBBO_IP_TO_BIND";
590+
591+
public static final String DUBBO_PORT_TO_BIND = "DUBBO_PORT_TO_BIND";
592+
593+
public static final String BIND_IP_KEY = "bind.ip";
594+
595+
public static final String BIND_PORT_KEY = "bind.port";
596+
597+
public static final String REGISTER_IP_KEY = "register.ip";
598+
585599
/*
586600
* private Constants(){ }
587601
*/

dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/ConfigUtils.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,20 @@ public static String getProperty(String key, String defaultValue) {
186186
return replaceProperty(properties.getProperty(key, defaultValue), (Map) properties);
187187
}
188188

189+
/**
190+
*  系统环境变量 -> java命令参数-D
191+
*
192+
* @param key
193+
* @return
194+
*/
195+
public static String getSystemProperty(String key) {
196+
String value = System.getenv(key);
197+
if (value == null || value.length() == 0) {
198+
value = System.getProperty(key);
199+
}
200+
return value;
201+
}
202+
189203
public static Properties loadProperties(String fileName) {
190204
return loadProperties(fileName, false, false);
191205
}

dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ReferenceConfig.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
import java.util.Map;
5151
import java.util.Properties;
5252

53+
import static com.alibaba.dubbo.common.utils.NetUtils.isInvalidLocalHost;
54+
5355
/**
5456
* ReferenceConfig
5557
*
@@ -315,6 +317,16 @@ private void init() {
315317
checkAndConvertImplicitConfig(method, map, attributes);
316318
}
317319
}
320+
321+
//
322+
String hostToRegistry = ConfigUtils.getSystemProperty(Constants.DUBBO_IP_TO_REGISTRY);
323+
if (hostToRegistry == null || hostToRegistry.length() == 0) {
324+
hostToRegistry = NetUtils.getLocalHost();
325+
} else if (isInvalidLocalHost(hostToRegistry)) {
326+
throw new IllegalArgumentException("Specified invalid registry ip from property:" + Constants.DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
327+
}
328+
map.put(Constants.REGISTER_IP_KEY, hostToRegistry);
329+
318330
//attributes通过系统context进行存储.
319331
StaticContext.getSystemContext().putAll(attributes);
320332
ref = createProxy(map);

dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ServiceConfig.java

Lines changed: 136 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import com.alibaba.dubbo.common.utils.ClassHelper;
2424
import com.alibaba.dubbo.common.utils.ConfigUtils;
2525
import com.alibaba.dubbo.common.utils.NamedThreadFactory;
26-
import com.alibaba.dubbo.common.utils.NetUtils;
2726
import com.alibaba.dubbo.common.utils.StringUtils;
2827
import com.alibaba.dubbo.config.annotation.Service;
2928
import com.alibaba.dubbo.config.support.Parameter;
@@ -52,6 +51,12 @@
5251
import java.util.concurrent.ScheduledExecutorService;
5352
import java.util.concurrent.TimeUnit;
5453

54+
import static com.alibaba.dubbo.common.utils.NetUtils.LOCALHOST;
55+
import static com.alibaba.dubbo.common.utils.NetUtils.getAvailablePort;
56+
import static com.alibaba.dubbo.common.utils.NetUtils.getLocalHost;
57+
import static com.alibaba.dubbo.common.utils.NetUtils.isInvalidLocalHost;
58+
import static com.alibaba.dubbo.common.utils.NetUtils.isInvalidPort;
59+
5560
/**
5661
* ServiceConfig
5762
*
@@ -347,72 +352,151 @@ private void doExportUrls() {
347352
}
348353
}
349354

350-
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
351-
String name = protocolConfig.getName();
352-
if (name == null || name.length() == 0) {
353-
name = "dubbo";
354-
}
355+
/**
356+
* provider注册&监听ip地址,注册与监听ip可独立配置
357+
* 配置优先级:系统环境变量 -> java命令参数-D -> 配置文件host属性 -> /etc/hosts中hostname-ip映射关系 -> 默认联通注册中心地址的网卡地址 -> 第一个可用的网卡地址
358+
*
359+
* @param protocolConfig
360+
* @param registryURLs
361+
* @param map
362+
* @return
363+
*/
364+
private String findConfigedHosts(ProtocolConfig protocolConfig, List<URL> registryURLs, Map<String, String> map) {
365+
boolean anyhost = false;
355366

356-
String host = protocolConfig.getHost();
357-
if (provider != null && (host == null || host.length() == 0)) {
358-
host = provider.getHost();
367+
String hostToBind = ConfigUtils.getSystemProperty(Constants.DUBBO_IP_TO_BIND);
368+
if (hostToBind != null && hostToBind.length() > 0 && isInvalidLocalHost(hostToBind)) {
369+
throw new IllegalArgumentException("Specified invalid bind ip from property:" + Constants.DUBBO_IP_TO_BIND + ", value:" + hostToBind);
359370
}
360-
boolean anyhost = false;
361-
if (NetUtils.isInvalidLocalHost(host)) {
362-
anyhost = true;
363-
try {
364-
host = InetAddress.getLocalHost().getHostAddress();
365-
} catch (UnknownHostException e) {
366-
logger.warn(e.getMessage(), e);
371+
372+
// 如果没通过环境变量设置bind ip,则继续按优先级查找
373+
if (hostToBind == null || hostToBind.length() == 0) {
374+
hostToBind = protocolConfig.getHost();
375+
if (provider != null && (hostToBind == null || hostToBind.length() == 0)) {
376+
hostToBind = provider.getHost();
367377
}
368-
if (NetUtils.isInvalidLocalHost(host)) {
369-
if (registryURLs != null && registryURLs.size() > 0) {
370-
for (URL registryURL : registryURLs) {
371-
try {
372-
Socket socket = new Socket();
378+
if (isInvalidLocalHost(hostToBind)) {
379+
anyhost = true;
380+
try {
381+
hostToBind = InetAddress.getLocalHost().getHostAddress();
382+
} catch (UnknownHostException e) {
383+
logger.warn(e.getMessage(), e);
384+
}
385+
if (isInvalidLocalHost(hostToBind)) {
386+
if (registryURLs != null && registryURLs.size() > 0) {
387+
for (URL registryURL : registryURLs) {
373388
try {
374-
SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
375-
socket.connect(addr, 1000);
376-
host = socket.getLocalAddress().getHostAddress();
377-
break;
378-
} finally {
389+
Socket socket = new Socket();
379390
try {
380-
socket.close();
381-
} catch (Throwable e) {
391+
SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
392+
socket.connect(addr, 1000);
393+
hostToBind = socket.getLocalAddress().getHostAddress();
394+
break;
395+
} finally {
396+
try {
397+
socket.close();
398+
} catch (Throwable e) {
399+
}
382400
}
401+
} catch (Exception e) {
402+
logger.warn(e.getMessage(), e);
383403
}
384-
} catch (Exception e) {
385-
logger.warn(e.getMessage(), e);
386404
}
387405
}
388-
}
389-
if (NetUtils.isInvalidLocalHost(host)) {
390-
host = NetUtils.getLocalHost();
406+
if (isInvalidLocalHost(hostToBind)) {
407+
hostToBind = getLocalHost();
408+
}
391409
}
392410
}
393411
}
394412

395-
Integer port = protocolConfig.getPort();
396-
if (provider != null && (port == null || port == 0)) {
397-
port = provider.getPort();
413+
map.put(Constants.BIND_IP_KEY, hostToBind);
414+
415+
// registry ip,默认不作为bind ip
416+
String hostToRegistry = ConfigUtils.getSystemProperty(Constants.DUBBO_IP_TO_REGISTRY);
417+
if (hostToRegistry != null && hostToRegistry.length() > 0 && isInvalidLocalHost(hostToRegistry)) {
418+
throw new IllegalArgumentException("Specified invalid registry ip from property:" + Constants.DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
419+
} else if (hostToRegistry == null || hostToRegistry.length() == 0) {
420+
// bind ip默认作为registry ip
421+
hostToRegistry = hostToBind;
422+
}
423+
424+
map.put(Constants.ANYHOST_KEY, String.valueOf(anyhost));
425+
426+
return hostToRegistry;
427+
}
428+
429+
/**
430+
* provider注册&监听端口,注册与监听port可独立配置
431+
* 配置优先级:启动环境变量 -> java命令参数-D -> protocol配置文件port属性配置 -> 协议默认端口
432+
*
433+
* @param protocolConfig
434+
* @param name
435+
* @return
436+
*/
437+
private Integer findConfigedPorts(ProtocolConfig protocolConfig, String name, Map<String, String> map) {
438+
Integer portToBind = null;
439+
440+
// 解析环境变量配置的bind port
441+
String port = ConfigUtils.getSystemProperty(Constants.DUBBO_PORT_TO_BIND);
442+
portToBind = parsePort(port);
443+
444+
// 如未通过环境变量配置bind port,则继续按优先级查找
445+
if (portToBind == null) {
446+
portToBind = protocolConfig.getPort();
447+
if (provider != null && (portToBind == null || portToBind == 0)) {
448+
portToBind = provider.getPort();
449+
}
450+
final int defaultPort = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).getDefaultPort();
451+
if (portToBind == null || portToBind == 0) {
452+
portToBind = defaultPort;
453+
}
454+
if (portToBind == null || portToBind <= 0) {
455+
portToBind = getRandomPort(name);
456+
if (portToBind == null || portToBind < 0) {
457+
portToBind = getAvailablePort(defaultPort);
458+
putRandomPort(name, portToBind);
459+
}
460+
logger.warn("Use random available port(" + portToBind + ") for protocol " + name);
461+
}
398462
}
399-
final int defaultPort = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).getDefaultPort();
400-
if (port == null || port == 0) {
401-
port = defaultPort;
463+
464+
// 记录bind port,作为url的key
465+
map.put(Constants.BIND_PORT_KEY, String.valueOf(portToBind));
466+
467+
// registry ip,默认不作为bind ip
468+
String portToRegistryStr = ConfigUtils.getSystemProperty(Constants.DUBBO_PORT_TO_REGISTRY);
469+
Integer portToRegistry = parsePort(portToRegistryStr);
470+
if (portToRegistry == null) {
471+
portToRegistry = portToBind;
402472
}
403-
if (port == null || port <= 0) {
404-
port = getRandomPort(name);
405-
if (port == null || port < 0) {
406-
port = NetUtils.getAvailablePort(defaultPort);
407-
putRandomPort(name, port);
473+
474+
return portToRegistry;
475+
}
476+
477+
private Integer parsePort(String configPort) {
478+
Integer port = null;
479+
if (configPort != null && configPort.length() > 0) {
480+
try {
481+
Integer intPort = Integer.parseInt(configPort);
482+
if (isInvalidPort(intPort)) {
483+
throw new IllegalArgumentException("Specified invalid port from env value:" + configPort);
484+
}
485+
port = intPort;
486+
} catch (Exception e) {
487+
throw new IllegalArgumentException("Specified invalid port from env value:" + configPort);
408488
}
409-
logger.warn("Use random available port(" + port + ") for protocol " + name);
410489
}
490+
return port;
491+
}
411492

412-
Map<String, String> map = new HashMap<String, String>();
413-
if (anyhost) {
414-
map.put(Constants.ANYHOST_KEY, "true");
493+
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
494+
String name = protocolConfig.getName();
495+
if (name == null || name.length() == 0) {
496+
name = "dubbo";
415497
}
498+
499+
Map<String, String> map = new HashMap<String, String>();
416500
map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE);
417501
map.put(Constants.DUBBO_VERSION_KEY, Version.getVersion());
418502
map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
@@ -513,6 +597,9 @@ private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> r
513597
if ((contextPath == null || contextPath.length() == 0) && provider != null) {
514598
contextPath = provider.getContextpath();
515599
}
600+
601+
String host = this.findConfigedHosts(protocolConfig, registryURLs, map);
602+
Integer port = this.findConfigedPorts(protocolConfig, name, map);
516603
URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map);
517604

518605
if (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
@@ -566,7 +653,7 @@ private void exportLocal(URL url) {
566653
if (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
567654
URL local = URL.valueOf(url.toFullString())
568655
.setProtocol(Constants.LOCAL_PROTOCOL)
569-
.setHost(NetUtils.LOCALHOST)
656+
.setHost(LOCALHOST)
570657
.setPort(0);
571658
Exporter<?> exporter = protocol.export(
572659
proxyFactory.getInvoker(ref, (Class) interfaceClass, local));

dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/integration/RegistryProtocol.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.alibaba.dubbo.common.extension.ExtensionLoader;
2121
import com.alibaba.dubbo.common.logger.Logger;
2222
import com.alibaba.dubbo.common.logger.LoggerFactory;
23-
import com.alibaba.dubbo.common.utils.NetUtils;
2423
import com.alibaba.dubbo.common.utils.StringUtils;
2524
import com.alibaba.dubbo.common.utils.UrlUtils;
2625
import com.alibaba.dubbo.registry.NotifyListener;
@@ -37,6 +36,7 @@
3736
import com.alibaba.dubbo.rpc.protocol.InvokerWrapper;
3837

3938
import java.util.ArrayList;
39+
import java.util.HashMap;
4040
import java.util.List;
4141
import java.util.Map;
4242
import java.util.concurrent.ConcurrentHashMap;
@@ -210,7 +210,10 @@ private Registry getRegistry(final Invoker<?> originInvoker) {
210210
private URL getRegistedProviderUrl(final Invoker<?> originInvoker) {
211211
URL providerUrl = getProviderUrl(originInvoker);
212212
//注册中心看到的地址
213-
final URL registedProviderUrl = providerUrl.removeParameters(getFilteredKeys(providerUrl)).removeParameter(Constants.MONITOR_KEY);
213+
final URL registedProviderUrl = providerUrl.removeParameters(getFilteredKeys(providerUrl))
214+
.removeParameter(Constants.MONITOR_KEY)
215+
.removeParameter(Constants.BIND_IP_KEY)
216+
.removeParameter(Constants.BIND_PORT_KEY);
214217
return registedProviderUrl;
215218
}
216219

@@ -276,7 +279,9 @@ private <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type
276279
RegistryDirectory<T> directory = new RegistryDirectory<T>(type, url);
277280
directory.setRegistry(registry);
278281
directory.setProtocol(protocol);
279-
URL subscribeUrl = new URL(Constants.CONSUMER_PROTOCOL, NetUtils.getLocalHost(), 0, type.getName(), directory.getUrl().getParameters());
282+
// REFER_KEY的所有属性
283+
Map<String, String> parameters = new HashMap<String, String>(directory.getUrl().getParameters());
284+
URL subscribeUrl = new URL(Constants.CONSUMER_PROTOCOL, parameters.remove(Constants.REGISTER_IP_KEY), 0, type.getName(), parameters);
280285
if (!Constants.ANY_VALUE.equals(url.getServiceInterface())
281286
&& url.getParameter(Constants.REGISTER_KEY, true)) {
282287
registry.register(subscribeUrl.addParameters(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY,

dubbo-remoting/dubbo-remoting-api/src/main/java/com/alibaba/dubbo/remoting/transport/AbstractServer.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,13 @@ public abstract class AbstractServer extends AbstractEndpoint implements Server
5252
public AbstractServer(URL url, ChannelHandler handler) throws RemotingException {
5353
super(url, handler);
5454
localAddress = getUrl().toInetSocketAddress();
55-
String host = url.getParameter(Constants.ANYHOST_KEY, false)
56-
|| NetUtils.isInvalidLocalHost(getUrl().getHost())
57-
? NetUtils.ANYHOST : getUrl().getHost();
58-
bindAddress = new InetSocketAddress(host, getUrl().getPort());
55+
56+
String bindIp = getUrl().getParameter(Constants.BIND_IP_KEY, getUrl().getHost());
57+
int bindPort = getUrl().getParameter(Constants.BIND_PORT_KEY, getUrl().getPort());
58+
if (url.getParameter(Constants.ANYHOST_KEY, false) || NetUtils.isInvalidLocalHost(bindIp)) {
59+
bindIp = NetUtils.ANYHOST;
60+
}
61+
bindAddress = new InetSocketAddress(bindIp, bindPort);
5962
this.accepts = url.getParameter(Constants.ACCEPTS_KEY, Constants.DEFAULT_ACCEPTS);
6063
this.idleTimeout = url.getParameter(Constants.IDLE_TIMEOUT_KEY, Constants.DEFAULT_IDLE_TIMEOUT);
6164
try {

dubbo-remoting/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/jetty/JettyHttpServer.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class JettyHttpServer extends AbstractHttpServer {
3838

3939
public JettyHttpServer(URL url, final HttpHandler handler) {
4040
super(url, handler);
41-
DispatcherServlet.addHttpHandler(url.getPort(), handler);
41+
DispatcherServlet.addHttpHandler(url.getParameter(Constants.BIND_PORT_KEY, url.getPort()), handler);
4242

4343
int threads = url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS);
4444
QueuedThreadPool threadPool = new QueuedThreadPool();
@@ -47,10 +47,12 @@ public JettyHttpServer(URL url, final HttpHandler handler) {
4747
threadPool.setMinThreads(threads);
4848

4949
SelectChannelConnector connector = new SelectChannelConnector();
50-
if (!url.isAnyHost() && NetUtils.isValidLocalHost(url.getHost())) {
51-
connector.setHost(url.getHost());
50+
51+
String bindIp = url.getParameter(Constants.BIND_IP_KEY, url.getHost());
52+
if (!url.isAnyHost() && NetUtils.isValidLocalHost(bindIp)) {
53+
connector.setHost(bindIp);
5254
}
53-
connector.setPort(url.getPort());
55+
connector.setPort(url.getParameter(Constants.BIND_PORT_KEY, url.getPort()));
5456

5557
server = new Server();
5658
server.setThreadPool(threadPool);
@@ -65,7 +67,7 @@ public JettyHttpServer(URL url, final HttpHandler handler) {
6567
try {
6668
server.start();
6769
} catch (Exception e) {
68-
throw new IllegalStateException("Failed to start jetty server on " + url.getAddress() + ", cause: "
70+
throw new IllegalStateException("Failed to start jetty server on " + url.getParameter(Constants.BIND_IP_KEY) + ":" + url.getParameter(Constants.BIND_PORT_KEY) + ", cause: "
6971
+ e.getMessage(), e);
7072
}
7173
}

0 commit comments

Comments
 (0)