|
23 | 23 | import com.alibaba.dubbo.common.utils.ClassHelper; |
24 | 24 | import com.alibaba.dubbo.common.utils.ConfigUtils; |
25 | 25 | import com.alibaba.dubbo.common.utils.NamedThreadFactory; |
26 | | -import com.alibaba.dubbo.common.utils.NetUtils; |
27 | 26 | import com.alibaba.dubbo.common.utils.StringUtils; |
28 | 27 | import com.alibaba.dubbo.config.annotation.Service; |
29 | 28 | import com.alibaba.dubbo.config.support.Parameter; |
|
52 | 51 | import java.util.concurrent.ScheduledExecutorService; |
53 | 52 | import java.util.concurrent.TimeUnit; |
54 | 53 |
|
| 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 | + |
55 | 60 | /** |
56 | 61 | * ServiceConfig |
57 | 62 | * |
@@ -347,72 +352,151 @@ private void doExportUrls() { |
347 | 352 | } |
348 | 353 | } |
349 | 354 |
|
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; |
355 | 366 |
|
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); |
359 | 370 | } |
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(); |
367 | 377 | } |
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) { |
373 | 388 | 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(); |
379 | 390 | 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 | + } |
382 | 400 | } |
| 401 | + } catch (Exception e) { |
| 402 | + logger.warn(e.getMessage(), e); |
383 | 403 | } |
384 | | - } catch (Exception e) { |
385 | | - logger.warn(e.getMessage(), e); |
386 | 404 | } |
387 | 405 | } |
388 | | - } |
389 | | - if (NetUtils.isInvalidLocalHost(host)) { |
390 | | - host = NetUtils.getLocalHost(); |
| 406 | + if (isInvalidLocalHost(hostToBind)) { |
| 407 | + hostToBind = getLocalHost(); |
| 408 | + } |
391 | 409 | } |
392 | 410 | } |
393 | 411 | } |
394 | 412 |
|
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 | + } |
398 | 462 | } |
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; |
402 | 472 | } |
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); |
408 | 488 | } |
409 | | - logger.warn("Use random available port(" + port + ") for protocol " + name); |
410 | 489 | } |
| 490 | + return port; |
| 491 | + } |
411 | 492 |
|
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"; |
415 | 497 | } |
| 498 | + |
| 499 | + Map<String, String> map = new HashMap<String, String>(); |
416 | 500 | map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE); |
417 | 501 | map.put(Constants.DUBBO_VERSION_KEY, Version.getVersion()); |
418 | 502 | map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis())); |
@@ -513,6 +597,9 @@ private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> r |
513 | 597 | if ((contextPath == null || contextPath.length() == 0) && provider != null) { |
514 | 598 | contextPath = provider.getContextpath(); |
515 | 599 | } |
| 600 | + |
| 601 | + String host = this.findConfigedHosts(protocolConfig, registryURLs, map); |
| 602 | + Integer port = this.findConfigedPorts(protocolConfig, name, map); |
516 | 603 | URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map); |
517 | 604 |
|
518 | 605 | if (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class) |
@@ -566,7 +653,7 @@ private void exportLocal(URL url) { |
566 | 653 | if (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) { |
567 | 654 | URL local = URL.valueOf(url.toFullString()) |
568 | 655 | .setProtocol(Constants.LOCAL_PROTOCOL) |
569 | | - .setHost(NetUtils.LOCALHOST) |
| 656 | + .setHost(LOCALHOST) |
570 | 657 | .setPort(0); |
571 | 658 | Exporter<?> exporter = protocol.export( |
572 | 659 | proxyFactory.getInvoker(ref, (Class) interfaceClass, local)); |
|
0 commit comments