SpringCloud之實現客戶端的負載均衡Ribbon(二)


 

一 Ribbon簡介

Ribbon是Netflix發布的負載均衡器,它有助於控制HTTP和TCP的客戶端的行為。為Ribbon配置服務提供者地址后,Ribbon就可基於某種負載均衡算法,自動地幫助服務消費者去請求。Ribbon默認為我們提供了很多負載均衡算法,例如輪詢、隨機等。當然,我們也可為Ribbon實現自定義的負載均衡算法。

在Spring Cloud中,當Ribbon與Eureka配合使用時,Ribbon可自動從Eureka Server獲取服務提供者地址列表,並基於負載均衡算法,請求其中一個服務提供者實例。

下圖展示了Ribbon與Eureka配合使用時的架構

 

搭建負載均衡Ribbon (ribbon-consumer)

接到上篇 “SpringCloud之服務注冊與發現Eureka(一)

繼續在springcloud工程中添加模塊ribbon-consumer,也是通過start.spring.io提供的模板創建

 

新的目錄

 

生成的pom.xml文件為

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xuan</groupId>
    <artifactId>ribbon-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>ribbon-consumer</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

 

修改啟動文件RibbonConsumerApplication.java,注意增加RestTemplate 的bean注解。

package com.xuan.ribbonconsumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@EnableDiscoveryClient
@SpringBootApplication
public class RibbonConsumerApplication {
    @Bean
    @LoadBalanced
    RestTemplate restTemplate () {
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(RibbonConsumerApplication.class, args);
    }
}

增加測試的消費接口ConsumerController.java

package com.xuan.ribbonconsumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class ConsumerController {
    @Autowired
    RestTemplate restTemplate;

    @RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET)
    public String helloConsumer() {
        return restTemplate.getForEntity("http://eureka-client/hello",
                String.class).getBody();
    }
}

注意要去實現提供者的“hello”接口,在后面在描述具體實現過程。

修改配置文件”application.properties“,讓消費者注冊中心注冊,並且通過注冊中心找到服務提供者。

spring.application.name=ribbon-consumer
server.port=9000
eureka.client.serviceUrl.defaultZone=http://localhost:8080/eureka/

 

為了觀察是否進行了負載均衡,在eureka-client模塊,增加一個服務提供者接口HelloController.java實現hello接口。

package com.xuan.eurekaclient;

import com.netflix.appinfo.InstanceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class HelloController {
    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);

    @Autowired
    private DiscoveryClient client;

    @Value("${server.port}")
    String port;

    @RequestMapping(value = "hello", method = RequestMethod.GET)
    public String index() {
    StringBuffer uriList = new StringBuffer("Hello World " + port + " 端口為您服務!<br>");

    return uriList.toString();
 } }

如果需要打印服務端的詳細明細可以修改為:

package com.xuan.eurekaclient;

import com.netflix.appinfo.InstanceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class HelloController {
    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);

    @Autowired
    private DiscoveryClient discoveryClient;

    @Value("${server.port}")
    String port;

    @RequestMapping(value = "hello", method = RequestMethod.GET)
    public String index() {
StringBuffer uriList = new StringBuffer("Hello World " + port + " 端口為您服務!<br>"); List<ServiceInstance> list = discoveryClient.getInstances("eureka-client"); uriList.append("<br>discoveryClient.getServices().size() = " + discoveryClient.getServices().size()); for( String s : discoveryClient.getServices()){ List<ServiceInstance> serviceInstances = discoveryClient.getInstances(s); for(ServiceInstance si : serviceInstances){ uriList.append("<br>services:" + s + ":getHost()=" + si.getHost()); uriList.append("<br>services:" + s + ":getPort()=" + si.getPort()); uriList.append("<br>services:" + s + ":getServiceId()=" + si.getServiceId()); uriList.append("<br>services:" + s + ":getUri()=" + si.getUri()); } } return uriList.toString(); } }

 

在eureka-client模塊再增加兩個配置文件,使用不同的端口,從而在一天電腦可以啟動多個服務提供者,方便測試

增加”application-peer1.properties“文件

spring.application.name=eureka-client
server.port=8091
eureka.client.serviceUrl.defaultZone=http://localhost:8080/eureka/

增加”application-peer1.properties“文件

spring.application.name=eureka-client
server.port=8092
eureka.client.serviceUrl.defaultZone=http://localhost:8080/eureka/

添加完成后eureka-client模塊的目錄結構為:

設置IDEA編輯器的Edit Configurations,增加兩個啟動配置,修改過完后的列表和注意的地方:

配置和環境都設置完成后:就可以分別啟動模塊了:

1.EurekaServerApplication

2.EurekaClientApplication,EurekaClientApplication1,EurekaClientApplication2

啟動后打開http://localhost:8080/顯示如圖:

最后啟動RibbonConsumerApplication模塊在打開http://localhost:8080/顯示如下

消費者RibbonConsumer也注冊成功了。

訪問消費者提供的接口http://localhost:9000/ribbon-consumer,查看是否進行了負載均衡,刷新一次,端口就變化了一次,說明訪問的是不同的服務提供者

 

 

源碼下載地址:https://gitee.com/xuantest/SpringCloud-Ribbon

 


免責聲明!

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



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