傳統SSM項目集成Eureka


由於公司一些老的項目要對接新項目,而新項目是springCloud框架,需要在老項目里面集成下Eureka,(當然,如果新項目提供IP的調用方式,就可以用傳統的HTTP調用方式來調用)

注意:此次只是集成Eureka,並不涉及到Feign

項目依賴

<dependency>
            <groupId>com.netflix.eureka</groupId>
            <artifactId>eureka-client</artifactId>
            <version>1.7.0</version>
        </dependency>
        <!-- Ribbon 負載均衡 -->
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-eureka</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon</artifactId>
            <version>2.2.5</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-core</artifactId>
            <version>2.2.5</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-httpclient</artifactId>
            <version>2.2.5</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-loadbalancer</artifactId>
            <version>2.2.5</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.archaius</groupId>
            <artifactId>archaius-core</artifactId>
            <version>0.7.4</version>
        </dependency>

 

配置文件

ribbon.properties  

注意:ribbon由於配置是customer-svc服務名,所以只能獲取到customer-svc服務對應的ip地址,如果還要獲取其他服務,就需要把下面的ribbon的三行配置copy一下,把customer-svc改成你需要調用的其他服務名即可

# customer-svc:微服務Eureka上對應的服務名
customer-svc.ribbon.DeploymentContextBasedVipAddresses=customer-svc

# 固定寫法,customer-svc使用的ribbon負載均衡器
customer-svc.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList

# 每分鍾更新customer-svc對應服務的可用地址列表
customer-svc.ribbon.ServerListRefreshInterval=60000


# 控制是否注冊自身到eureka中 eureka.registration.enabled=false # eureka相關配置 eureka.preferSameZone=true eureka.shouldUseDns=false eureka.serviceUrl.default=http://10.0.0.0:8671/eureka eureka.decoderName=JacksonJson

初始化Ribbon

package com.movitech.mbox.modules.feign;

import com.netflix.appinfo.MyDataCenterInstanceConfig;
import com.netflix.config.ConfigurationManager;
import com.netflix.discovery.DefaultEurekaClientConfig;
import com.netflix.discovery.DiscoveryManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.IOException;

public class EurekaInitAndRegisterListener implements ServletContextListener {

    /**
     * 默認的ribbon配置文件名, 該文件需要放在classpath目錄下
     */
    public static final String RIBBON_CONFIG_FILE_NAME = "ribbon.properties";
    private static Logger log = LoggerFactory.getLogger(EurekaInitAndRegisterListener.class);

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("開始初始化ribbon");
        try {
            // 加載ribbon配置文件
            ConfigurationManager.loadPropertiesFromResources(RIBBON_CONFIG_FILE_NAME);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("ribbon初始化失敗");
            throw new IllegalStateException("ribbon初始化失敗");
        }
        // 初始化Eureka Client
        DiscoveryManager.getInstance().initComponent(new MyDataCenterInstanceConfig(), new DefaultEurekaClientConfig());
        log.info("ribbon初始化完成");

    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        DiscoveryManager.getInstance().shutdownComponent();
    }
}

web.xml

<listener>
        <listener-class>xx.xx.modules.feign.EurekaInitAndRegisterListener</listener-class>
    </listener>

獲取服務地址

package com.movitech.mbox.modules.feign;

import com.movitech.mbox.modules.feign.vo.AlanServiceAddress;
import com.netflix.client.ClientFactory;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.loadbalancer.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class AlanServiceAddressSelector {
    private static Logger log = LoggerFactory.getLogger(AlanServiceAddressSelector.class);
    private static RoundRobinRule chooseRule = new RoundRobinRule();

    /**
     * 根據輪詢策略選擇一個地址
     *
     * @param clientName
     *            ribbon.properties配置文件中配置項的前綴名, 如myclient
     * @return null表示該服務當前沒有可用地址
     */
    public static AlanServiceAddress selectOne(String clientName) {
        // ClientFactory.getNamedLoadBalancer會緩存結果, 所以不用擔心它每次都會向eureka發起查詢
        DynamicServerListLoadBalancer lb = (DynamicServerListLoadBalancer) ClientFactory
                .getNamedLoadBalancer(clientName);
        Server selected = chooseRule.choose(lb, null);
        if (null == selected) {
            log.warn("服務{}沒有可用地址", clientName);
            return null;
        }
        log.debug("服務{}選擇結果:{}", clientName, selected);
        return new AlanServiceAddress(selected.getPort(), selected.getHost());
    }

    /**
     * 選出該服務所有可用地址
     *
     * @param clientName
     * @return
     */
    public static List<AlanServiceAddress> selectAvailableServers(String clientName) {
        DynamicServerListLoadBalancer lb = (DynamicServerListLoadBalancer) ClientFactory
                .getNamedLoadBalancer(clientName);
        List<Server> serverList = lb.getReachableServers();
        if (serverList.isEmpty()) {
            log.warn("服務{}沒有可用地址", clientName);
            return Collections.emptyList();
        }
        log.debug("服務{}所有選擇結果:{}", clientName, serverList);
        return serverList.stream().map(server -> new AlanServiceAddress(server.getPort(), server.getHost()))
                .collect(Collectors.toList());
    }

}

地址實體類:

package com.movitech.mbox.modules.feign.vo;

public class AlanServiceAddress {

    private int port;
    private String host;

    public AlanServiceAddress() {
    }

    public AlanServiceAddress(int port, String host) {
        this.port = port;
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    /**
     * 將服務地址轉換為 http://主機名:端口/ 的格式
     * @return
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(15 + host.length());
        sb.append("http://").append(host).append(":").append(port).append("/");
        return sb.toString();
    }
}

使用方法

JSONObject param = (JSONObject) JSON.toJSON(feignVO);
        AlanServiceAddress addr = AlanServiceAddressSelector.selectOne("customer-svc");
        String response = HttpUtil.httpPost(addr+"v1/createRecommend",param,null);

借鑒https://www.cnblogs.com/xandersu/p/8504740.html

 

 

踩坑

項目集成后,測試環境tomcat一直啟動報錯

錯誤信息報的是這個:Failed to initalize discoveryClient!  這個一看就可能是HTTPCLient的問題,看了下初始化EurekaClient的底層代碼,把pom文件里面的HTTPCLient版本升級成

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.1</version>
        </dependency>

然后重新啟動就可以了,至於為什么低版本的不行,還不是很清楚


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM