启动rocketmq控制台后报错如下:
[2018-12-18 11:02:28.574] ERROR op=global_exception_handler_print_error
java.lang.RuntimeException: org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to <10.16.100.41:10909> failed
at com.google.common.base.Throwables.propagate(Throwables.java:160)
at org.apache.rocketmq.console.service.impl.ClusterServiceImpl.list(ClusterServiceImpl.java:63)
at org.apache.rocketmq.console.controller.ClusterController.list(ClusterController.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:220)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
仔细看了一下这个报错的地址10.16.100.41:10909,刚好是我那台linux服务器上的内网地址,于是百度了一下,
在conf下的broker-x.properties(我用的是2m-noslave配置,所以在两台主节点配置就好了,配各自的外网地址)配置brokerIP1就可以了,配置后,果然没错了。
加类似如下代码:
brokerIP1=172.27.xx.xx
-----------------------------------------------------------------------------------------------
分析一下原理:
参考了这篇文章,https://my.oschina.net/u/3476125/blog/897429。这篇文章言简意赅,我跟随着找到了源码。
报错的本质还是broker处理的时候出现的问题,所以找到了 BrokerStartup类->启动方法createBrokerController
public static BrokerController createBrokerController(String[] args) {
。。。。。
try {
。。。。。
// 这三行重点
// 初始化broker相关配置是第一个final变量的定义,下面详细看BrokerConfig的代码
final BrokerConfig brokerConfig = new BrokerConfig();
final NettyServerConfig nettyServerConfig = new NettyServerConfig();
final NettyClientConfig nettyClientConfig = new NettyClientConfig();
nettyClientConfig.setUseTLS(Boolean.parseBoolean(System.getProperty(TLS_ENABLE,
String.valueOf(TlsSystemConfig.tlsMode == TlsMode.ENFORCING))));
nettyServerConfig.setListenPort(10911);
final MessageStoreConfig messageStoreConfig = new MessageStoreConfig();
.......
.......
return controller;
} catch (Throwable e) {
e.printStackTrace();
System.exit(-1);
}
return null;
}
BrokerConfig的初始化:
public class BrokerConfig {
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
private String rocketmqHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV));
@ImportantField
private String namesrvAddr = System.getProperty(MixAll.NAMESRV_ADDR_PROPERTY, System.getenv(MixAll.NAMESRV_ADDR_ENV));
// 这段是默认情况下,不读取配置时,取到的brokerIP1的值。进去看就知道,ip是怎么取得了
@ImportantField
private String brokerIP1 = RemotingUtil.getLocalAddress();
private String brokerIP2 = RemotingUtil.getLocalAddress();
@ImportantField
private String brokerName = localHostName();
.......
.......
}
RemotingUtil的getLocalAddress方法
public static String getLocalAddress() {
try {
。。。。。。
// prefer ipv4
if (!ipv4Result.isEmpty()) {
// 这块代码就比较清晰了,取到ipv4地址后,过滤掉127.0和192.168开头的,然后找到的第一块网卡信息就返回了
for (String ip : ipv4Result) {
if (ip.startsWith("127.0") || ip.startsWith("192.168")) {
continue;
}
return ip;
}
return ipv4Result.get(ipv4Result.size() - 1);
} else if (!ipv6Result.isEmpty()) {
return ipv6Result.get(0);
}
//If failed to find,fall back to localhost
final InetAddress localHost = InetAddress.getLocalHost();
return normalizeHostAddress(localHost);
} catch (Exception e) {
log.error("Failed to obtain local address", e);
}
return null;
}