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