tomcat部署多个dubbo服务提供者,tomcat启动报20880端口占用

报错的主要内容节选

Caused by: com.alibaba.dubbo.remoting.RemotingException: Failed to bind NettyServer on /xxx.xxx.x.xxx:20880, cause: Failed to bind to: /0.0.0.0:20880
Caused by: org.jboss.netty.channel.ChannelException: Failed to bind to: /0.0.0.0:20880
Caused by: java.net.BindException: Address already in use

由于需求要求dubbo的服务提供者(例如:用户模块,产品模块,订单模块等),每个服务提供者为独立的服务,在开发的时候,maven父模块下,每个子项目模块为独立的war包,每个子模块内有各自的dubbo配置文件如下,在配置文件未修改之前是这样的每次启动都会报端口占用,修改成什么端口都一样报端口占用(这里已排除tomcat配置文件加载两次的问题,配置文件是只加载了一次的),后来各种查找,找到这样一种解决办法,配置文件里端口-1,启动时使用随机端口,问题解决!
非常感谢https://blog.csdn.net/typ1805/article/details/81065990此同学无私奉献提供的博文!

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans          
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd          
        http://code.alibabatech.com/schema/dubbo          
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
        
    <!--配置SpringBean-->
    <bean id="xxxService" class="com.xxx.service.impl.xxxServiceImpl"/>
    
	<!-- 消费方应用名,需要保证应用名唯一,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
	<dubbo:application name="xxx.provider" />
	<!-- 暴露发现服务地址 -->
 	<dubbo:registry protocol="zookeeper" address="zookeeper://192.168.0.160:2181" />
	<!-- 用dubbo协议不使用20880端口暴露服务,而使用随机端口,见代码里实现 -->
	<!-- name 指定的是传输协议的名称:dubbo rmi hessian webservic -->
    <dubbo:protocol name="dubbo" port="-1" accesslog="true"/>
    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.xxx.facade.xxxService" ref="xxxService" timeout="600000"/>
</beans>

package com.xxx.dubbo;

import java.util.Map;
import javax.annotation.PostConstruct;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.Map.Entry;
import com.alibaba.dubbo.common.utils.NetUtils;
import com.alibaba.dubbo.config.ProtocolConfig;

/**
 * 一个机器部署两个dubbo生产者服务会产生端口占用问题,为了解决这个问题,在加载dubbo配置文件之前,先设置没被占用的端口
 * @author typ
 */
public class DynamicDubboPortReader implements ApplicationContextAware{

	@Autowired
    private ApplicationContext applicationContext;

    private int port = 20880;

    @PostConstruct
    public void init(){
        Map<String, ProtocolConfig> map = applicationContext.getBeansOfType(ProtocolConfig.class);
        for(Entry<String,ProtocolConfig> con: map.entrySet()){
            port = NetUtils.getAvailablePort();
            System.out.println("=========="+port);
            con.getValue().setPort(port);
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = (ConfigurableApplicationContext)applicationContext;
    }

}

你可能感兴趣的:(java,java)