落跃之城

书读万卷,路行万里;惜时如金,内外兼修。

微服务架构简单搭建——Spring Cloud Eureka、Ribbon实现服务治理与服务消费

首先讲一下本文使用的版本:

Spring Boot:2.3.4.RELEASE

Spring Cloud:Hoxton.SR7

Spring Cloud Netflix:2.2.4.RELEASE

注意:Spring Cloud各种组件的版本搭配非常重要!!!官方提供的版本特别乱,之前以伦敦市地铁站名为版本名,现在又推出2020.0版本,开始以数字为版本号。如果版本用错了,会导致各种莫名其妙的问题!

可参考官方网站:https://spring.io/projects/spring-cloud

目前的版本搭配如图所示:

本文要搭建三个组件:服务注册中心、服务提供者和服务消费者,其中通过Spring Cloud Eureka实现服务注册与发现,通过Spring Cloud Ribbon实现客户端负载均衡,也就是服务消费,接下来介绍搭建过程:

一、服务注册中心(Eureka Server)

https://start.spring.io/中新建Spring Boot工程,记为Eureka Server。

设置pom.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5     <parent>
 6         <groupId>org.springframework.boot</groupId>
 7         <artifactId>spring-boot-starter-parent</artifactId>
 8         <version>2.3.4.RELEASE</version>
 9         <relativePath/> <!-- lookup parent from repository -->
10     </parent>
11     <groupId>cn.edu.whu</groupId>
12     <artifactId>eureka</artifactId>
13     <version>0.0.1-SNAPSHOT</version>
14     <name>eureka</name>
15     <description>Eureka Server for MicroServices</description>
16 
17     <properties>
18         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
19         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
20         <java.version>1.8</java.version>
21         <spring-cloud.version>Hoxton.SR7</spring-cloud.version>
22         <netflix.version>2.2.4.RELEASE</netflix.version>
23     </properties>
24 
25     <dependencies>
26         <dependency>
27             <groupId>org.springframework.boot</groupId>
28             <artifactId>spring-boot-starter-web</artifactId>
29         </dependency>
30 
31         <dependency>
32             <groupId>org.springframework.boot</groupId>
33             <artifactId>spring-boot-starter-test</artifactId>
34             <scope>test</scope>
35         </dependency>
36 
37         <!-- SpringCloud Eureka 注册中心依赖 -->
38         <dependency>
39             <groupId>org.springframework.cloud</groupId>
40             <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
41             <version>${netflix.version}</version>
42         </dependency>
43     </dependencies>
44     <dependencyManagement>
45         <dependencies>
46             <dependency>
47                 <groupId>org.springframework.cloud</groupId>
48                 <artifactId>spring-cloud-dependencies</artifactId>
49                 <version>${spring-cloud.version}</version>
50                 <type>pom</type>
51                 <scope>import</scope>
52             </dependency>
53         </dependencies>
54     </dependencyManagement>
55     <build>
56         <plugins>
57             <plugin>
58                 <groupId>org.springframework.boot</groupId>
59                 <artifactId>spring-boot-maven-plugin</artifactId>
60             </plugin>
61         </plugins>
62     </build>
63 
64 </project>
View Code

在启动程序前添加@EnableEurekaServer注解,代码如下:

 1 import org.springframework.boot.SpringApplication;
 2 import org.springframework.boot.autoconfigure.SpringBootApplication;
 3 import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
 4 
 5 @SpringBootApplication
 6 @EnableEurekaServer
 7 public class EurekaApplication {
 8 
 9     public static void main(String[] args) {
10         SpringApplication.run(EurekaApplication.class, args);
11     }
12 
13 }

然后配置application.properties如下:

1 server.port=1111
2 
3 eureka.instance.hostname=localhost
4 eureka.client.register-with-eureka=false
5 eureka.client.fetch-registry=false
6 eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
7 eureka.instance.prefer-ip-address=true

其中eureka.client.register-with-eureka=false表示不向注册中心注册自己;

eureka.client.fetch-registry=false表示不检索其他服务注册中心

本文仅提供一个服务注册中心,构建高可用注册中心时采用其他设置。

启动工程并在浏览器访问URL:http://localhost:1111/,可看到如下页面:

表明服务注册中心已经搭建成功,但是服务实例列表中还为空,说明没有服务注册进来。

二、服务提供者(Eureka Client)

https://start.spring.io/中新建Spring Boot工程,记为Demo,作为服务提供者提供Hello Service。

设置pom.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5     <parent>
 6         <groupId>org.springframework.boot</groupId>
 7         <artifactId>spring-boot-starter-parent</artifactId>
 8         <version>2.3.4.RELEASE</version>
 9         <relativePath/> <!-- lookup parent from repository -->
10     </parent>
11     <groupId>com.example</groupId>
12     <artifactId>demo</artifactId>
13     <version>0.0.1-SNAPSHOT</version>
14     <name>demo</name>
15     <description>Demo project for Spring Boot</description>
16     <properties>
17         <java.version>1.8</java.version>
18         <spring-cloud.version>Hoxton.SR7</spring-cloud.version>
19         <netflix.version>2.2.4.RELEASE</netflix.version>
20     </properties>
21     <dependencies>
22         <dependency>
23             <groupId>org.springframework.boot</groupId>
24             <artifactId>spring-boot-starter</artifactId>
25         </dependency>
26 
27         <dependency>
28             <groupId>org.springframework.boot</groupId>
29             <artifactId>spring-boot-starter-test</artifactId>
30             <scope>test</scope>
31         </dependency>
32 
33         <dependency>
34             <groupId>org.springframework.boot</groupId>
35             <artifactId>spring-boot-starter-web</artifactId>
36         </dependency>
37 
38         <dependency>
39             <groupId>org.springframework.cloud</groupId>
40             <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
41             <version>${netflix.version}</version>
42         </dependency>
43     </dependencies>
44     <dependencyManagement>
45         <dependencies>
46             <dependency>
47                 <groupId>org.springframework.cloud</groupId>
48                 <artifactId>spring-cloud-dependencies</artifactId>
49                 <version>${spring-cloud.version}</version>
50                 <type>pom</type>
51                 <scope>import</scope>
52             </dependency>
53         </dependencies>
54     </dependencyManagement>
55 
56     <build>
57         <plugins>
58             <plugin>
59                 <groupId>org.springframework.boot</groupId>
60                 <artifactId>spring-boot-maven-plugin</artifactId>
61             </plugin>
62         </plugins>
63     </build>
64 
65 </project>
View Code

Eureka Client不需要在启动程序前添加注解,只要在pom.xml添加设置就会自动注册。

新建HelloController.java,用于提供访问服务,代码如下:

 1 import org.slf4j.Logger;
 2 import org.slf4j.LoggerFactory;
 3 import org.springframework.web.bind.annotation.RequestMapping;
 4 import org.springframework.web.bind.annotation.RestController;
 5 
 6 @RestController
 7 public class HelloController {
 8 
 9     public static final Logger logger = LoggerFactory.getLogger(HelloController.class);
10 
11     @RequestMapping("/hello")
12     public String index() {
13         String basePath = "Hello Service";
14         logger.info("Hello Service!" );
15         return basePath;
16     }
17 }

再配置application.properties如下:

1 spring.application.name=Hello-Service
2 eureka.client.service-url.defaultZone=http://localhost:1111/eureka/

启动工程,再查看注册中心的管理页面,可看到该服务已经注册成功:

三、服务消费者(Ribbon)

将上文中提供Hello Service的工程生成Jar包,并放到两个路径下,通过java -jar命令行在不同的端口启动:

java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8081

java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8083

以此制造两个提供相同服务的提供者:

从而用Ribbon来通过客户端负载均衡的策略,消费这两个服务。

https://start.spring.io/中新建Spring Boot工程,记为Ribbon,作为服务消费者。

设置pom.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5     <parent>
 6         <groupId>org.springframework.boot</groupId>
 7         <artifactId>spring-boot-starter-parent</artifactId>
 8         <version>2.3.4.RELEASE</version>
 9         <relativePath/> <!-- lookup parent from repository -->
10     </parent>
11     <groupId>com.example</groupId>
12     <artifactId>ribbon</artifactId>
13     <version>0.0.1-SNAPSHOT</version>
14     <name>ribbon</name>
15     <description>Demo project for Spring Boot</description>
16     <properties>
17         <java.version>1.8</java.version>
18         <spring-cloud.version>Hoxton.SR7</spring-cloud.version>
19         <netflix.version>2.2.4.RELEASE</netflix.version>
20     </properties>
21     <dependencies>
22         <dependency>
23             <groupId>org.springframework.boot</groupId>
24             <artifactId>spring-boot-starter-web</artifactId>
25         </dependency>
26 
27         <dependency>
28             <groupId>org.springframework.boot</groupId>
29             <artifactId>spring-boot-starter-test</artifactId>
30             <scope>test</scope>
31         </dependency>
32 
33         <dependency>
34             <groupId>org.springframework.cloud</groupId>
35             <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
36             <version>${netflix.version}</version>
37         </dependency>
38 
39         <dependency>
40             <groupId>org.springframework.cloud</groupId>
41             <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
42             <version>${netflix.version}</version>
43         </dependency>
44     </dependencies>
45     <dependencyManagement>
46         <dependencies>
47             <dependency>
48                 <groupId>org.springframework.cloud</groupId>
49                 <artifactId>spring-cloud-dependencies</artifactId>
50                 <version>${spring-cloud.version}</version>
51                 <type>pom</type>
52                 <scope>import</scope>
53             </dependency>
54         </dependencies>
55     </dependencyManagement>
56 
57     <build>
58         <plugins>
59             <plugin>
60                 <groupId>org.springframework.boot</groupId>
61                 <artifactId>spring-boot-maven-plugin</artifactId>
62             </plugin>
63         </plugins>
64     </build>
65 
66 </project>
View Code

在启动程序前添加@LoadBalanced注解,完整代码如下:

 1 import org.springframework.boot.SpringApplication;
 2 import org.springframework.boot.autoconfigure.SpringBootApplication;
 3 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
 4 import org.springframework.context.annotation.Bean;
 5 import org.springframework.web.client.RestTemplate;
 6 
 7 @SpringBootApplication
 8 public class RibbonApplication {
 9 
10     @Bean
11     @LoadBalanced
12     RestTemplate restTemplate() {
13         return new RestTemplate();
14     }
15 
16     public static void main(String[] args) {
17         SpringApplication.run(RibbonApplication.class, args);
18     }
19 
20 }

新建ConsumerController,用于消费Hello Service服务,代码如下:

 1 import org.springframework.beans.factory.annotation.Autowired;
 2 import org.springframework.web.bind.annotation.RequestMapping;
 3 import org.springframework.web.bind.annotation.RequestMethod;
 4 import org.springframework.web.bind.annotation.RestController;
 5 import org.springframework.web.client.RestTemplate;
 6 
 7 @RestController
 8 public class ConsumerController {
 9 
10     @Autowired
11     RestTemplate restTemplate;
12 
13     @RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET)
14     public String helloConsumer(){
15         return restTemplate.getForObject("http://HELLO-SERVICE/hello",String.class);
16     }
17 
18     @RequestMapping("/hello")
19     public String hello(){
20         return "Ribbon Hello";
21     }
22 }

注意其中http://HELLO-SERVICE/hello一定要使用在注册中心注册的服务名,而不用IP地址,这才是服务消费的意义所在。

然后配置application.properties如下:

1 server.port=9000
2 spring.application.name=Ribbon-Consumer
3 eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
4 eureka.client.fetchRegistry=true

将自身也注册到注册中心,这时可以看到注册中心管理界面中又多了一个服务:

表示两个服务提供者和一个服务消费者,都已经注册成功。

接下来在浏览器中访问URL:http://localhost:9000/ribbon-consumer,可看到返回如下:

表明已经通过Ribbon访问Hello Service成功。

多访问几次,可发现两个服务提供者交替打印日志,说明在交替调用它们的服务。

至此,已经完成微服务架构中服务注册与发现、客户端负载均衡的功能。

posted on 2021-04-16 12:03  落跃之城  阅读(120)  评论(0编辑  收藏  举报

导航