# spring-cloud-trip-ribbon-feign **Repository Path**: iherr/spring-cloud-trip-ribbon-feign ## Basic Information - **Project Name**: spring-cloud-trip-ribbon-feign - **Description**: No description available - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-10-12 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 一、服务提供者和服务消费者 | 名词 | 概念 | | -------- | :-----: | | 服务提供者 | 服务的被调用方| | 服务消费者 | 服务的调用方| > 服务提供者 提供接口服务后,并注册到注册中心。 > 服务消费者 我们创建了注册中心,以及服务的提供者,并成功地将服务提供者注册到了注册中心上。 要想消费服务是很简单的,我们只需要使用RestTemplate即可,或者例如HttpClient之类的http工具也是可以的。 在集群环境下,我们必然是每个服务部署多个实例,那么“服务消费者”消费“服务提供者”时的负载均衡就是关键。 ### 二、负载均衡器 > Ribbon Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。简单地说,Ribbon是一个客户端负载均衡器。 Ribbon工作时分为两步:第一步先选择 Eureka Server, 它优先选择在同一个Zone且负载较少的Server;第二步再根据用户指定的策略,在从Server取到的服务注册列表中选择一个地址。其中Ribbon提供了多种策略,例如轮询、随机、根据响应时间加权等。 > Feign Feign是一个声明式的web service客户端,它使得编写web service客户端更为容易。创建接口,为接口添加注解,即可使用Feign。Feign可以使用Feign注解或者JAX-RS注解,还支持热插拔的编码器和解码器。Spring Cloud为Feign添加了Spring MVC的注解支持,并整合了Ribbon和Eureka来为使用Feign时提供负载均衡。 ### 三、 项目基础配置 为实现ribbon负载均衡,需要几个基础的module * eureka-server,作为eureka的server服务注册中心 * service-provider-1,eureka-client端,连接到eureka-server成为服务提供者1。 * service-provider-2,eureka-client端,连接到eureka-server成为服务提供者2。和service-provider-1提供相同的接口。 > eureka-server eureka的服务端基本配置,参考实战(2)的内容,端口为8761。 > service-provider 有2个,内容一样,提供的端口分别为8001和8002。 1、pom.xml依赖 ``` org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client ``` 2、增加注解@EnableDiscoveryClient,即可将service-provider服务注册到Eureka上面去。 3、yml配置中,两个项目的spring.application.name需要保持一致,均为service-provider。 ```xml server: port: 8001 spring: application: name: service-provider eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: prefer-ip-address: true ``` 4、UserController接口,返回的文本可做区分service1和service2,以便ribbon负载时区别开来。 ```java @RestController public class UserController { @GetMapping("/{id}") public String findById(@PathVariable Long id) { return "service1"; } } ``` 5、访问测试 * 访问http://localhost:8001/1 返回service1 * 访问http://localhost:8002/1 返回service2 ### 四、Ribbon项目配置 > 1、pom.xml依赖 ``` org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client ``` 2、启动类中,增加注解@EnableDiscoveryClient,即可将service-provider服务注册到Eureka上面去。并使用@LoadBalanced注解,为RestTemplate开启负载均衡的能力。 ```java @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } ``` 3、yml配置中,项目的spring.application.name为service-consumer-ribbon,端口8010。 ```xml server: port: 8010 spring: application: name: service-consumer-ribbon eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: prefer-ip-address: true ``` 4、RibbonController.java ```java @RestController @RequestMapping("ribbon") public class RibbonController { private static final Logger LOGGER = LoggerFactory.getLogger(RibbonController.class); @Autowired private RestTemplate restTemplate; @Autowired private LoadBalancerClient loadBalancerClient; @GetMapping("/{id}") public String findById(@PathVariable Long id) { return this.restTemplate.getForObject("http://service-provider/" + id, String.class); } @GetMapping("/log-instance") public void logUserInstance() { ServiceInstance serviceInstance = this.loadBalancerClient.choose("service-provider"); RibbonController.LOGGER.info("{}:{}:{}", serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort()); } } ``` 5、测试 需要先依次启动项目基础配置中的3个module。才能启动ribbon项目。 * 访问http://localhost:8010/ribbon/1 会间隔返回service1和service2。 * 访问http://localhost:8010/ribbon/log-instance 会在项目日志中打印调用的ip和端口,8001和8002间隔出现。 * 访问http://localhost:8761 可以看到2个SERVICE-PROVIDER和一个SERVICE-CONSUMER-RIBBON。 ### 五、Feign项目配置 > 1、pom.xml依赖 ``` org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-openfeign ``` 2、启动类中,增加注解@EnableDiscoveryClient 即可将service-provider服务注册到Eureka上面去。 增加@EnableFeignClients,启用Feign。 3、yml配置中,项目的spring.application.name为service-consumer-feign,端口8011。 ```xml server: port: 8011 spring: application: name: service-consumer-feign eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: prefer-ip-address: true ``` 4、FeignController.java,使用@FeignClient("service-provider")注解绑定service-provider服务,还可以使用url参数指定一个URL ```java @FeignClient(name = "service-provider") public interface UserFeignClient { @RequestMapping(value = "/{id}", method = RequestMethod.GET) public String findById(@PathVariable("id") Long id); } ``` 5、UserFeignClient.java ```java @RestController public class FeignController { @Autowired private UserFeignClient userFeignClient; @GetMapping("/feign/{id}") public String findById(@PathVariable Long id) { return this.userFeignClient.findById(id); } } ``` 6、测试 需要先依次启动项目基础配置中的3个module。才能启动feign项目。 * 访问http://localhost:8011/feign/1 会间隔返回service1和service2。 * 访问http://localhost:8761 可以看到2个SERVICE-PROVIDER和一个SERVICE-CONSUMER-FEIGN。