Netflix Ribbon 与 Spring Cloud 集成(四)

前面介绍了 Netflix Ribbon 与 Spring Cloud 集成,并且禁用从 Eureka 注册中心获取服务列表,而是手动维护服务列表。本章节将介绍分别通过配置文件和 @Configuration 类来指定负载均衡算法。

提供 User 服务

参考“Netflix Ribbon 与 Spring Cloud 集成”章节提供的 User 服务,这里将不再赘述。

实现客户端

maven 依赖

本文将使用 Spring Boot 1.5.2.RELEASE版本,如下:

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

maven 依赖如下:

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

application.yml

该文件用来配置客户端,配置如下:

server:
  port: 8080

spring:
  application:
    name: demo

eureka:
  client:
    serviceUrl:
      # 指定注册中心
      defaultZone: http://localhost:8077/eureka/

ribbon:
  eureka:
    # 关闭 Eureka,不使用 Eureka 管理服务列表
    enabled: false

# 提供给 LoadBalancerClient 的 choose() 方法进行使用
# 测试 LoadBalancerClient 负载均衡的策略
user:
  ribbon:
    # 指定服务列表
    listOfServers: 127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003
    # 配置负载均衡算法为随机算法
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

上面配置文件中,通过 NFLoadBalancerRuleClassName 项配置负载均衡算法,这里配置为随机负载均衡策略(com.netflix.loadbalancer.RandomRule)。如果你更喜欢使用 @Configuration 配置类配置 Ribbon,只需在 @Configuration 配置类中注入 IRue Bean 即可。代码如下:

@Bean
public IRule getIRule() {
    System.out.println(RibbonConfig.class.getName() + " :: getRule()");
    // 指定随机负载均衡策略
    return new RandomRule();
}

RibbonConfig.java

该 @Configuration 配置类用来配置 RestTemplate,且使用 @LoadBalanced 注解使得 RestTemplate 拥有负载均衡能力。代码如下:

package com.huangx.springcloud.ribbon;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RibbonConfig {

    @Bean
    @LoadBalanced
    /** 启动负载均衡 */
    public RestTemplate restTemplate() {
        System.out.println(RibbonConfig.class.getName() + " :: restTemplate()");
        return new RestTemplate();
    }

}

HelloControler.java

实现一个简单的控制器,该控制器将分别使用 RestTemplate 和 LoadBalancerClient 实现负载均衡调用服务接口,代码如下:

package com.huangx.springcloud.ribbon;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;

@RestController
public class HelloControler {

   @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private LoadBalancerClient loadBalancer;

    /**
     * 使用注入的 RestTemplate 实现服务调用,开启了负载均衡
     * @return
     */
    @RequestMapping(value = "/testTemplate")
    public String testTemplate(){
        // user 是服务名,下面将根据服务名进行调用,不能使用IP地址进行调用
        String str = restTemplate.getForObject("http://user/info", String.class);
        System.out.println(str);
        return str;
    }

    /**
     * 使用 LoadBalancerClient 去实现手动调用服务
     * @return
     */
    @RequestMapping(value = "/testLoadBalancerClient")
    public String testLoadBalancerClient(HttpServletResponse response) {
        response.setHeader("Content-Type", "text/html; charset=UTF-8");

        ServiceInstance instance = loadBalancer.choose("user");
        if(null == instance) {
            return "ServiceInstance is null";
        }
        // 服务地址
        String str = instance.getServiceId() + " " + instance.getHost()
                + ":" + instance.getPort();
        // 调用服务
        String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/info";
        RestTemplate template = new RestTemplate();
        str += "<br/>调用结果:" + template.getForObject(url, String.class);

        System.out.println(str);
        return str;
    }

}

DemoApplication.java

客户端代码使用 @EnableDiscoveryClient 注解启用 Eureka 客户端,代码如下:

package com.huangx.springcloud.ribbon;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

@Controller
@SpringBootApplication
/** 标记这是Eureka客户端 */
@EnableDiscoveryClient
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(RibbonDemo3Application.class, args);
    }
}

运行效果如下图:

细心的读者会发现,前面几个实例均在配置 RestTemplate 对象时均使用了 @LoadBalanced 注解。在后续章节我们将详细介绍 @LoadBalanced 注解的含义和用法,以及内部实现原理。

说说我的看法
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号