前面介绍了 Netflix Ribbon 与 Spring Cloud 集成,并且从 Eureka 注册中心获取服务列表,手动指定不同的负载均衡策略(如:默认的轮询策略,随机策略)。本章节将介绍怎样禁用 Eureka,自动手动维护服务列表。
参考“Netflix Ribbon 与 Spring Cloud 集成(一)”章节提供的 User 服务,这里将不再赘述。
本文将使用 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>
该文件用来配置客户端,配置如下:
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
该 @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();
}
}实现一个简单的控制器,该控制器将分别使用 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;
}
}客户端代码使用 @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);
}
}运行效果如下图:

仔细观察上面的结果,采用的是轮询负载均衡算法。下一章将介绍在禁用 Eureka 后,在配置文件中指定负载均衡算法为随机算法。