学科分类
目录
Spring Cloud

第一个Ribbon实例

上一章已经实现了Eureka 高可用,理论上使得微服务已经很完美了。但是,考虑到机器自身硬件条件的限制,面对流量高峰,系统同样还会存在宕机等情况。此时,如果使用Ribbon整合Eureka实现负载均衡,将用户请求分摊到多个服务上,能够大幅减轻访问服务压力,使系统达到更好的负载能力。

下面我们在前面搭建的Eureka集群基础上进行改造,具体步骤如下:

1. 改造服务提供者

后续会在服务消费者上集成Ribbon实现客户端负载均衡,为了验证服务消费者调用的是哪个服务提供者的服务,下面我们对服务提供者进行改造,改造后的服务提供者提供了“/port”API接口,用于返回服务提供者的端口号。

在项目eureka-provider和eureka-provider-another中新建controller包,并创建PortController类,该类能够返回当前项目的端口号,具体代码如例1所示。

例1 PortController.java

 1     import org.springframework.beans.factory.annotation.Value;
 2     import org.springframework.web.bind.annotation.RequestMapping;
 3     import org.springframework.web.bind.annotation.RestController;
 4     @RestController
 5     public class PortController{
 6         @Value("${server.port}")
 7         String port;
 8         @RequestMapping("port")
 9         public String getPort(){
 10             return "Hello World, I'm from port:"+port;
 11         }
 12     }

在例1中,第4行代码的@RestController注解标注在PortController类上,其效果等同于@Controller和@ResponseBody注解结合在一起使用的效果。也就是说,@RestController注解将PortController类标注为一个Controller,并且PortController中所有方法的返回对象都会自动序列化为HttpResponse对象;第6行代码的@Value注解用于将配置文件中server.port属性的值注入port;第8行代码的@RequestMapping注解用于指定getPort()方法用于处理路径为/port的请求。

2. 搭建含有Ribbon的服务消费者

(1)使用Spring Initializr方式创建一个名称为eureka-ribbon-client的Spring Boot项目,这里将Group命名为com.itheima,将Artifact命名为eureka-ribbon-client,添加Eureka Client、Ribbon和Web的依赖,项目创建好后的pom.xml文件如例2所示。

例2 eureka-ribbon-client\pom.xml

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

(2)在全局配置文件application.yml进行相关配置,包括指定应用名称、端口号、服务注册地址等信息,具体如例3所示。

例3 eureka-ribbon-client\src\main\resources\application.yml

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

(3)在项目启动类中激活Eureka Client的相关配置。在项目启动类添加@EnableEurekaClient注解开启Eureka Client功能,如例4所示。

例4 eureka-ribbon-client\src\main\java\com\itheima\eurekaribbonclient\EurekaRibbonClientApplication.java

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

(4)创建配置类。在com.itheima.eurekaribbonclient下新建config包,并在该包下创建RibbonConfig类,该类注入restTemplate的Bean,并在这个Bean中加上@LoadBalanced注解,如例5所示。

例5 eureka-ribbon-client\src\main\java\com\itheima\eurekaribbonclient\config\RibbonConfig.java

 1     import org.springframework.boot.web.client.RestTemplateBuilder;
 2     import org.springframework.cloud.client.loadbalancer.LoadBalanced;
 3     import org.springframework.context.annotation.Bean;
 4     import org.springframework.context.annotation.Configuration;
 5     import org.springframework.web.client.RestTemplate;
 6     @Configuration
 7     public class RibbonConfig {
 8         @Bean
 9         @LoadBalanced
 10        public RestTemplate restTemplate(RestTemplateBuilder builder){
 11            return builder.build();
 12        }
 13     }

在例5中,第6行代码使用@Configuration注解将RibbonConfig标注为配置类,第8行代码的@Bean注解注入restTemplate()方法返回的RestTemplate对象;第9行代码使用@LoadBalanced注解使RestTemplate具备了负载均衡的能力。

(5)创建Service类。在com.itheima. eurekaribbonclient下新建service包,并在该包下创建一个RibbonService类,在该类的hi()方法中使用restTemplate调用eureka-client的API接口,如例6所示。

例6 eureka-ribbon-client\src\main\java\com\itheima\eurekaribbonclient\service\RibbonService.java

 1     import org.springframework.beans.factory.annotation.Autowired;
 2     import org.springframework.stereotype.Service;
 3     import org.springframework.web.client.RestTemplate;
 4     @Service
 5     public class RibbonService {
 6         @Autowired
 7         RestTemplate restTemplate;
 8         public String hi(){
 9             return restTemplate.getForObject
 10          ("http://eureka-provider/port",String.class);
 11         }
 12     }

(6)创建Controller类。在com.itheima.eurekaribbonclient下新建controller的包,在该包下新建一个RibbonController的类,在该类上添加@RestController注解,将RibbonController类标注为一个Controller类,写一个hi()方法,调用RibbonService的hi()方法,如例7所示。

例7 eureka-ribbon-client\src\main\java\com\itheima\eurekaribbonclient\controller\RibbonController.java

 1     import com.itheima.eurekaribbonclient.service.RibbonService;
 2      import org.springframework.beans.factory.annotation.Autowired;
 3     import org.springframework.web.bind.annotation.GetMapping;
 4     import org.springframework.web.bind.annotation.RequestParam;
 5     import org.springframework.web.bind.annotation.RestController;
 6     @RestController
 7     public class RibbonController {
 8         @Autowired
 9         RibbonService ribbonService;
 10         @RequestMapping("/hi")
 11         public  String hi(){
 12             return ribbonService.hi();
 13         }
 14     }

3. 测试运行

启动并访问应用。启动服务器eureka-server和eureka-server-another,服务提供者eureka-provider和eureka-provider-another,服务消费者eurek-ribbon-client,在浏览器上访问http://server1:7000http://server2:7009,无论访问哪个Eureka Server,Eureka Server的注册实例都是一样的,界面显示如图1所示和图2所示。

图1 访问server1:7000的页面效果

图2 访问server2:7009的页面效果

从图1和2中可以看出,两个服务提供者和一个服务消费者已经全部成功注册到Eureka实现了高可用,为了演示含有Ribbon的服务消费者负载均衡的效果,使用浏览器多次访问http://localhost:8764/hi,浏览器页面访问效果如图3和图4所示。

图3 浏览器页面效果(1)

图4 浏览器页面效果(2)

从图3和图4可以看出,当访问http://localhost:8764/hi时,浏览器页面会轮流显示两个服务提供者的端口号,说明负载均衡起了效果,负载均衡器会轮流请求服务提供者中的“hi”接口。

点击此处
隐藏目录