前言
上一篇文章介绍了服务注册发现组件Eureka,并搭建了三个工程演示了服务的注册发现,以及消费调用的过程,本章将对服务的消费功能介绍做进一步的延伸,讲解如何用负载均衡组件Ribbon来做服务的消费调用。
Ribbon是一个客户端负载均衡器,它可以很好地控制HTTP和TCP客户端的行为,根据特定的策略来控制请求负载分摊到多个执行单位上,是属于软负载的方式之一,ribbon结合eureka可以在注册中心注册,如果要消费的服务做了集群,那么ribbon就能在调用过程做负载均衡处理。笔者准备了4个工程来展现这个调用过程。
准备好注册的服务工程
上篇文章中我们创建了eureka-server、eureka-client这两个工程作为服务的注册中心客户端,为了实现负载的效果,我们至少需要注册两个服务。
沿用这两个工程,启动server工程,端口为1111;对于同一个工程来说,换一个端口启动,就相当于创建了新的服务实例,将eureka-client的端口改为1113并启动后,这时你会发现:eureka-client在注册中心注册了两个实例,这就相当于一个最简单的集群了。
为了能方便看到负载均衡的效果,我们在eureka-client的应用主类中注入一个变量来获取实例的端口,这样一来,哪个服务被调用就能看到效果了。
值得说明的是,正常情况下,启动两个服务名称相同的springboot工程会报冲突,在idea中,可以这样解决,点开右上角Application右边的下三角 ,弹出选项后,点击Edit Configuration ,在配置页面将默认的Single instance only的钩去掉,这样修改端口之后,启动多个实例就没有问题了。
创建引入ribbon依赖的服务消费者
在主工程中右键新建一个module,工程名称为eureka-ribbon,引入eureka-client和ribbon的依赖,成功后pom文件如下:
<?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.yeya</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eureka</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>
在配置文件application.yml做如下的配置:
spring:
application:
#工程名称
name: eureka-ribbon
eureka:
client:
service-url:
#注册中心的url
defaultZone: http://localhost:1111/eureka
server:
#端口
port: 1114
在启动类上加入@EnableDiscoveryClient 注解,并初始化restTemplate,在restTemplate加上@LoadBalanced注解表明这个restRemplate开启负载均衡的功能。
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaApplication {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
新建一个controller类来访问eureka-client中的 “/hello” 接口,通过restTemplate对传入的服务地址做负载均衡并返回访问地址,代码如下:
@RestController
public class ConsumeController {
@Autowired
private LoadBalancerClient client;
@Autowired
RestTemplate restTemplate;
@GetMapping("/consumer")
public String consumer() {
String dc = restTemplate.getForObject("http://eureka-client/hello",String.class);
return dc;
}
}
在main主类中启动eureka-ribbon工程,打开浏览器,访问http://localhost:1111/,可以看到有三个工程已经注册成功,分别是client的两个工程和eureka-ribbon工程,
开启新网页标签,访问http://localhost:1114/consumer,多次刷新后,浏览器会交替显示:
hi forezp,i am from port:8762
hi forezp,i am from port:8763
这表明,ribbon在调用同一个服务实例时做了负载均衡,也实现了我们预想中的效果。
总结
到这里,ribbon结合restTemplate的实现负载均衡的效果已经给大家展示完毕了,本文一共用到了四个工程,这是项目的架构图:
从架构图上看,工程之间的调用并不复杂,建议读者们自己尝试写个实例验证一下。
本文源码地址:https://github.com/Taoxj/SpringCloudDemo/tree/master/ribbon