Spring Cloud实战系列(二) - 客户端调用Rest + Ribbon

前言

上一篇文章我们介绍了 Eureka 服务注册中心 的搭建,这篇文章介绍一下如何使用 Eureka 服务注册中心,搭建一个简单的 服务端注册服务,由 客户端 通过 Ribbon 负载均衡 地去调用服务案例。

正文

1. 创建服务提供者

创建一个 service-hiModule,创建完成后的 pom.xml 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>io.ostenant.github.springcloud</groupId>
<artifactId>service-hi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service-hi</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR1</spring-cloud.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-cloud-starter-web</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>

通过 注解 @EnableEurekaClient 表明自己是一个 Eureka Client

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableEurekaClient
@RestController
public class ServiceHiApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceHiApplication.class, args);
}
}

创建一个控制器 HelloController,对外提供一个 /hiHTTP 的服务。在响应数据中返回当前 服务实例端口号

1
2
3
4
5
6
7
8
9
10
11
@RestController
public class HelloController {

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

@RequestMapping("/hi")
public String hi(@RequestParam String name) {
return "Hi " + name + ", I am from port: " + port;
}
}

配置文件 中注明的 服务注册中心 的地址,application.yml 配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
spring:
active:
profiles: service-hi1 # service-hi2

---

spring:
profiles: service-hi1
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8763
spring:
application:
name: service-hi

---

spring:
profiles: service-hi2
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8764
spring:
application:
name: service-hi

分别以 spring.profiles.active=hi1spring.profiles.active=hi2 作为 Spring Boot启动命令参数,在 端口号 87638764 启动 2服务提供者 实例。

2. 创建服务消费者

重新新建 service-ribbonModule,在它的 pom.xml 文件分别引入 起步依赖 spring-cloud-starter-eurekaspring-cloud-starter-ribbonspring-boot-starter-web,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>io.ostenant.github.springcloud</groupId>
<artifactId>service-ribbon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service-ribbon</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR1</spring-cloud.version>
</properties>

<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>

<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>

在项目的 配置文件 指定服务的 服务注册中心 的地址,应用名称service-ribbon端口号8762。完整配置文件 application.yml 如下:

1
2
3
4
5
6
7
8
9
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8762
spring:
application:
name: service-ribbon

在应用 启动类 上,通过 @EnableDiscoveryClient服务中心 注册自身信息,向 Spring Boot 容器注册一个 RestTemplate 对象,并通过 @LoadBalanced 注解表明这个 RestRemplate 开启 客户端负载均衡 的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
@SpringBootApplication
@EnableDiscoveryClient
public class ServiceRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceRibbonApplication.class, args);
}

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

写一个 测试接口,注入上面的 RestTemplate 对象来消费 service-hi 服务的 /hi 接口。在 RestTemplateURL 中,我们将具体 服务生产者主机名称端口号 替换为它的 服务名称

1
2
3
4
5
6
7
8
9
10
11
@RestController
public class HelloController {

@Autowired
private RestTemplate restTemplate;

@RequestMapping(value = "/hi")
public String requestForHi(@RequestParam String name){
return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
}
}

在浏览器上多次访问 http://localhost:8762/hi?name=ribbon,浏览器交替显示:

Hi ribbon, I am from port: 8763

Hi ribbon, I am from port: 8764

在具体的调用过程中,Ribbon 提供的 @LoadBalanced 注解会从 Eureka Server 上查询 服务列表,根据 服务名称 找到 SERVICE-HI服务实例。如果有多个 SERVICE-HI 实例,Ribbon 会根据 客户端负载均衡 算法筛选其中一台,并把 URL 中的 SERVICE-HI 替换为具体实例的 主机名称端口号

参考

  • 方志朋《深入理解Spring Cloud与微服务构建》

欢迎关注技术公众号: 零壹技术栈

零壹技术栈

本帐号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。

文章作者: Chen Vainlgory
文章链接: https://geek.vainlgory.top/2019/01/24/Spring Cloud实战系列(二) - 客户端调用Rest + Ribbon/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 零壹技術棧 | VainlgoryのBlog
微信打赏
支付宝打赏