Spring Cloud学习笔记【二】Eureka 服务提供者/服务消费者(ribbon)

Ribbon 是 Netflix 发布的开源项目,主要功能是为 REST 客户端实现负载均衡。它主要包括六个组件:

  • ServerList,负载均衡使用的服务器列表。这个列表会缓存在负载均衡器中,并定期更新。当 Ribbon 与 Eureka 结合使用时,ServerList 的实现类就是 DiscoveryEnabledNIWSServerList,它会保存 Eureka Server 中注册的服务实例表。
  • ServerListFilter,服务器列表过滤器。这是一个接口,主要用于对 Service Consumer 获取到的服务器列表进行预过滤,过滤的结果也是 ServerList。Ribbon 提供了多种过滤器的实现。
  • IPing,探测服务实例是否存活的策略。
  • IRule,负载均衡策略,其实现类表述的策略包括:轮询、随机、根据响应时间加权等,我们也可以自己定义负载均衡策略,比如我们就利用自己实现的策略,实现了服务的版本控制和直连配置。实现好之后,将实现类重新注入到 Ribbon 中即可。
  • ILoadBalancer,负载均衡器。这也是一个接口,Ribbon 为其提供了多个实现,比如 ZoneAwareLoadBalancer。而上层代码通过调用其 API 进行服务调用的负载均衡选择。一般 ILoadBalancer 的实现类中会引用一个 IRule。
  • RestClient,服务调用器。顾名思义,这就是负载均衡后,Ribbon 向 Service Provider 发起 REST 请求的工具。

Ribbon 工作时会做四件事情:

  1. 优先选择在同一个 Zone 且负载较少的 Eureka Server;
  2. 定期从 Eureka 更新并过滤服务实例列表;
  3. 根据用户指定的策略,在从 Server 取到的服务注册列表中选择一个实例的地址;
  4. 通过 RestClient 进行服务调用。

一、服务提供者

1、创建一个Spring Starter Project,命名service-producer,添加依赖

 1 <dependencies>
 2   <dependency>
 3     <groupId>org.springframework.boot</groupId>
 4     <artifactId>spring-boot-starter-web</artifactId>
 5   </dependency>
 6   <dependency>
 7     <groupId>org.springframework.cloud</groupId>
 8     <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 9   </dependency>
10 </dependencies>

2、配置属性(application.yml)

server:
  port: 8080  #启动其他实例时需要修改端口号
spring:
  application:
    name: SERVICE-PRODUCER
eureka:
  client:
    serviceUrl:
      defaultZone: http://admin:123456@localhost:8761/eureka/

3、控制层创建一个controller,对外提供一个接口(这里比较简单就只返回服务的端口号)

 1 package com.carry.springcloud.controller;
 2 
 3 import javax.servlet.http.HttpServletRequest;
 4 
 5 import org.springframework.web.bind.annotation.GetMapping;
 6 import org.springframework.web.bind.annotation.RestController;
 7 
 8 @RestController
 9 public class ProducerController {
10 
11     @GetMapping("/getPortInfo")
12     public String produce(HttpServletRequest request) {
13         int localPort = request.getLocalPort();
14         return "调用服务的端口号为:" + localPort;
15     }
16 }

4、启动类加上@EnableEurekaClient注解即可

5、测试

打开浏览器访问localhost:8080/getPortInfo,出现以下结果说明是OK的

二、服务消费者(Ribbon)

1、创建一个Spring Starter Project,命名service-consumer-ribbon,添加依赖

 1 <dependencies>
 2    <dependency>
 3       <groupId>org.springframework.boot</groupId>
 4       <artifactId>spring-boot-starter-web</artifactId>
 5    </dependency>
 6    <dependency>
 7       <groupId>org.springframework.cloud</groupId>
 8       <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 9    </dependency>
10    <dependency>
11       <groupId>org.springframework.cloud</groupId>
12       <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
13    </dependency>
14 </dependencies>

2、配置属性(application.yml)

server:
  port: 8082
spring:
  application:
    name: SERVICE-CONSUMER-RIBBON
eureka:
  client:
    serviceUrl:
      defaultZone: http://admin:123456@localhost:8761/eureka/

3、在启动类中@Bean 将 restTemplate注入到ioc容器, 并使用@LoadBalanced 注解声明开启 负载均衡

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

4、编写一个controller,注入RestTemplate用其调用服务提供者接口

 1 package com.carry.springcloud.controller;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.web.bind.annotation.GetMapping;
 5 import org.springframework.web.bind.annotation.RestController;
 6 import org.springframework.web.client.RestTemplate;
 7 
 8 @RestController
 9 public class RibbonController {
10 
11     @Autowired
12     RestTemplate restTemplate;
13 
14     @GetMapping("/getPoducerInfo")
15     public String getPoducerInfo() {
16         String result = this.restTemplate.getForObject("http://SERVICE-PRODUCER/getPortInfo", String.class);
17         return result;
18     }
19 }

注:上面代码中restTemplate.getForObject第一个参数url规则为:协议http+服务名(即application.yml配置spring.application.name的值)+接口值

5、测试

1、启动Eureka服务

2、启动两个服务提供者SERVICE-PRODUCER实例,端口分别为8080和8081

3、启动服务消费者SERVICE-CONSUMER-RIBBON

4、浏览器中访问 localhost:8761,注册成功

5、访问服务消费者localhost:8082/getPoducerInfo

再次访问

结果显示是轮询调用两个服务提供者实例,这是因为默认的负载均衡算法是轮询,也可自行修改负载均衡算法,例如:随机算法,权重,只需要在application.yml里配置即可。

猜你喜欢

转载自www.cnblogs.com/carrychan/p/9473161.html