最近在本地搭了个docker后,然后某个dubbo服务启动失败了,其他dubbo服务启动是正常的;看了下其他同事及测试环境,均运行正常;本地错误信息如下

com.alibaba.dubbo.rpc.RpcException: Fail to start server(url: dubbo://192.168.3.184:20880/
 Failed to bind NettyServer on /192.168.3.184:20880, cause: Failed to bind to: /0.0.0.0:20880
	at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol.createServer(DubboProtocol.java:331)
	at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol.openServer(DubboProtocol.java:308)
Caused by: com.alibaba.dubbo.remoting.RemotingException: Failed to bind NettyServer on /192.168.3.184:20880, cause: Failed to bind to: /0.0.0.0:20880
	at com.alibaba.dubbo.remoting.transport.AbstractServer.<init>(AbstractServer.java:74)
	at com.alibaba.dubbo.remoting.transport.netty.NettyServer.<init>(NettyServer.java:67)
	at com.alibaba.dubbo.remoting.transport.netty.NettyTransporter.bind(NettyTransporter.java:33)
	at com.alibaba.dubbo.remoting.Transporter$Adpative.bind(Transporter$Adpative.java)
	at com.alibaba.dubbo.remoting.Transporters.bind(Transporters.java:48)
	at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchanger.bind(HeaderExchanger.java:41)
	at com.alibaba.dubbo.remoting.exchange.Exchangers.bind(Exchangers.java:63)
	at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol.createServer(DubboProtocol.java:329)
	... 71 common frames omitted
Caused by: org.jboss.netty.channel.ChannelException: Failed to bind to: /0.0.0.0:20880
	at org.jboss.netty.bootstrap.ServerBootstrap.bind(ServerBootstrap.java:272)
	at com.alibaba.dubbo.remoting.transport.netty.NettyServer.doOpen(NettyServer.java:100)
	at com.alibaba.dubbo.remoting.transport.AbstractServer.<init>(AbstractServer.java:68)
	... 78 common frames omitted
Caused by: java.net.BindException: Address already in use
	at sun.nio.ch.Net.bind0(Native Method)

,当时也没想到与docker有关(准确来说和网卡有关),
有问题就Debug,首先看了下端口占用情况,完全正常,然后断点debug, 发现com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol.createServer方法调用了两次,两次都是相同的端口,但ip不同,一个是172.17.0.1,一个是192.168.3.184,然后通过ifconfig(windows ipconfig)看了下本地ip情况,也就是两次分别配置
没什么好说的
刚好是本地两个网卡的ip,192.168.3.184,
因为配置了<dubbo:registry address="zookeeper://192.168.3.184:2181"/>,所以出现192.168.3.184一点也不奇怪,
为什么会出现172.17.0.1呢? 继续debug,发现两次走了不同的逻辑

    if (NetUtils.isInvalidLocalHost(host)) {
                if (registryURLs != null && registryURLs.size() > 0) {
                    for (URL registryURL : registryURLs) {
                        try {
                            Socket socket = new Socket();
                            try {
                                SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
                                socket.connect(addr, 1000);
                                host = socket.getLocalAddress().getHostAddress();
                                break;
                            } finally {
                                try {
                                    socket.close();
                                } catch (Throwable e) {}
                            }
                        } catch (Exception e) {
                            logger.warn(e.getMessage(), e);
                        }
                    }
                }
                if (NetUtils.isInvalidLocalHost(host)) {
                    host = NetUtils.getLocalHost();
                }
            }

其中一次host走的是

SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
socket.connect(addr, 1000);
host = socket.getLocalAddress().getHostAddress();

另一次是

                if (NetUtils.isInvalidLocalHost(host)) {
                    host = NetUtils.getLocalHost();
                }

也就是一次走的是dubbo:registry配置的局域网地址,另一次是第一个局域网地址(127.0.0.1被dubbo排除在外了),最后本地不同局域网域名走了两次,端口相同,所以出现以上错误.
同样是dubboServiceBean,为什么走不同逻辑,检查了下配置差异,然后发现

<dubbo:service interface="com.hqjl.common.session.ISessionService" ref="sessionService" delay="-1" register="false"/> 
<dubbo:service interface="com.hqjl.base.school.service.ISchoolBaseDataService" ref="schoolBaseDataServiceImpl" delay="-1" register="true"/>

有一个serviceregisterfalse,不注册也就不会使用dubbo:registry配置的地址.

解决方案:
<dubbo:protocol/> 中加入 配置 host="192.168.3.184"

也可移除不注册的服务,或是将注册地址改成第一个局域网ip.

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐