dubbo 机器多IP问题的解决

承载dubbo服务的机器多IP时,需要指定dubbo服务需要绑定到的IP(dubbo.protocol.host),确保登记到注册中心的提供者或者消费者的IP之间可以互相ping通

此IP与具体环境有关,上生产环境时,需要进行增量配置


dubbo 机器多IP问题的解决_第1张图片
 

 

=========================

绑定IP,DUBBO 怎么做的

 

通常绑定本机ip地址 一般如下

 

Java代码   收藏代码
  1. InetSocketAddress address = new InetSocketAddress(port);  
  2. Channel serverChannel = bootstrap.bind(address);  

 

 

InetSocketAddress默认使用的是什么ip呢?看看内部代码就明白了:

Java代码   收藏代码
  1. public InetSocketAddress(int port) {  
  2.    this(InetAddress.anyLocalAddress(), port);  
  3. }  

 

InetAddress.anyLocalAddress()一般就是0.0.0.0/0.0.0.0,如果我们有两块网卡,一块内网,一块外网,那么都能访问这个socket,这通常是不安全的。那么通过InetAddress.getLocalHost().getHostAddress()呢?

结果悲剧了,使用上面的代码取回的是127.0.0.1。

 

好了,看看dubbo是怎么解决,dubbo获取本机ip地址的方法封装在com.alibaba.dubbo.common.utils.NetUtils类里面。

Java代码   收藏代码
  1. import java.net.InetAddress;  
  2. import java.net.NetworkInterface;  
  3. import java.util.Enumeration;  
  4. import java.util.regex.Pattern;  
  5.   
  6. import org.slf4j.Logger;  
  7. import org.slf4j.LoggerFactory;  
  8.   
  9. public class NetUtils {  
  10.   
  11.     private static final Logger  logger           = LoggerFactory.getLogger(NetUtils.class);  
  12.   
  13.     private static final Pattern IP_PATTERN       = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");  
  14.   
  15.     private static final Pattern LOCAL_IP_PATTERN = Pattern.compile("127(\\.\\d{1,3}){3}$");  
  16.   
  17.     public static final String   ANYHOST          = "0.0.0.0";  
  18.   
  19.     public static final String   LOCALHOST        = "127.0.0.1";  
  20.   
  21.     private static boolean isValidAddress(InetAddress address) {  
  22.         if (address == null || address.isLoopbackAddress()) return false;  
  23.         String name = address.getHostAddress();  
  24.         return (name != null && !ANYHOST.equals(name) && !LOCALHOST.equals(name) && IP_PATTERN.matcher(name).matches());  
  25.     }  
  26.   
  27.     public static boolean isLocalHost(String host) {  
  28.         return host != null && (LOCAL_IP_PATTERN.matcher(host).matches() || host.equalsIgnoreCase("localhost"));  
  29.     }  
  30.   
  31.     public static boolean isAnyHost(String host) {  
  32.         return "0.0.0.0".equals(host);  
  33.     }  
  34.   
  35.     private static volatile InetAddress LOCAL_ADDRESS = null;  
  36.   
  37.     /** 
  38.      * 遍历本地网卡,返回第一个合理的IP。 
  39.      *  
  40.      * @return 本地网卡IP 
  41.      */  
  42.     public static InetAddress getLocalAddress() {  
  43.         if (LOCAL_ADDRESS != null) {  
  44.             return LOCAL_ADDRESS;  
  45.         }  
  46.         InetAddress localAddress = getLocalAddress0();  
  47.         LOCAL_ADDRESS = localAddress;  
  48.         return localAddress;  
  49.     }  
  50.   
  51.     private static InetAddress getLocalAddress0() {  
  52.         InetAddress localAddress = null;  
  53.         try {  
  54.             localAddress = InetAddress.getLocalHost();  
  55.             if (isValidAddress(localAddress)) {  
  56.                 return localAddress;  
  57.             }  
  58.         } catch (Throwable e) {  
  59.             logger.warn("Failed to retriving ip address, " + e.getMessage(), e);  
  60.         }  
  61.         try {  
  62.             Enumeration interfaces = NetworkInterface.getNetworkInterfaces();  
  63.             if (interfaces != null) {  
  64.                 while (interfaces.hasMoreElements()) {  
  65.                     try {  
  66.                         NetworkInterface network = interfaces.nextElement();  
  67.                         Enumeration addresses = network.getInetAddresses();  
  68.                         if (addresses != null) {  
  69.                             while (addresses.hasMoreElements()) {  
  70.                                 try {  
  71.                                     InetAddress address = addresses.nextElement();  
  72.                                     if (isValidAddress(address)) {  
  73.                                         return address;  
  74.                                     }  
  75.                                 } catch (Throwable e) {  
  76.                                     logger.warn("Failed to retriving ip address, " + e.getMessage(), e);  
  77.                                 }  
  78.                             }  
  79.                         }  
  80.                     } catch (Throwable e) {  
  81.                         logger.warn("Failed to retriving ip address, " + e.getMessage(), e);  
  82.                     }  
  83.                 }  
  84.             }  
  85.         } catch (Throwable e) {  
  86.             logger.warn("Failed to retriving ip address, " + e.getMessage(), e);  
  87.         }  
  88.         logger.error("Could not get local host ip address, will use 127.0.0.1 instead.");  
  89.         return localAddress;  
  90.     }  
  91.   
  92. }  

 简单的说就是通过NetworkInterface遍历网卡address,然后通过isValidAddress校验ip是否正常即可。需要注意的一点是,dubbo通过Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$")判断ip是否合法,也就是说不能保证只返回内网ip!

 

=====================================

 

 http://curious.iteye.com/blog/2286476

你可能感兴趣的:(dubbo)