前言
我们已经集成ribbon与hystrix,实现服务的负载均衡与熔断,在Spring Cloud中,使用feign已经集成这两种功能。新建一个module实现feign-service服务,pom依赖如下
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1. feign实现ribbon
application.yml可以保持不变,这里修改application-name的值
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8082/eureka/
server:
port: 8205
spring:
application:
name: feign-service
在main方法上注上@EnableFeignClients注解
package com.spring.cloud.feign.servce;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignServiceMain {
public static void main(String[] args) {
SpringApplication.run(FeignServiceMain.class, args);
}
}
restTemplate已经不需要我们注入bean了,feign已经实现,并且通过配置文件可配置负载均衡的模式。
我们要改造的是service服务bean,使用@FeignClient(value = "服务名称,注册中心注册的application name")来实现,此时仅需要接口就可以了,feign会动态生成代理类。
package com.spring.cloud.feign.servce.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.Map;
@FeignClient(value = "RIBBON-SERVICE")
public interface ConsumerService {
@RequestMapping(value = "/mark",method = RequestMethod.GET)
Map consumerMark();
}
接口方法有参数,可使用@RequestParam绑定,同controller的RequestMapping写法一样。
启动main方法,测试负载均衡,访问http://localhost:8205/consumer/
交替打印,说明负载均衡成功。
2. feign熔断
熔断需要我们写熔断处理逻辑,并绑定处理方法,在feign中,是通过熔断处理类实现的,只需要绑定熔断处理类就可以了,feign熔断后会自动去熔断处理类,通过相应的方法处理。
建立熔断处理类
package com.spring.cloud.feign.servce.service;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class ConsumerServiceHystrix implements ConsumerService{
@Override
public Map consumerMark() {
Map<String, String> map = new HashMap<>();
map.put("error", "service is not used");
return map;
}
}
绑定熔断处理逻辑,在FeignClient注解加上参数 fallback = ConsumerServiceHystrix.class
package com.spring.cloud.feign.servce.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.Map;
@FeignClient(value = "RIBBON-SERVICE", fallback = ConsumerServiceHystrix.class)
public interface ConsumerService {
@RequestMapping(value = "/mark",method = RequestMethod.GET)
Map consumerMark();
}
当发生熔断,feign会自动去找本地实现处理逻辑。
改造后启动main服务
遗憾没有熔断功能,原因是Spring Cloud在某个版本后feign自动是默认关闭熔断能力的,需要配置打开
feign:
hystrix:
enabled: true
访问:http://localhost:8205/consumer/
服务熔断了
总结
feign继承了ribbon与hystrix的功能,其中hystrix默认是关闭的,需要配置打开,负载均衡可以均匀的负载服务器的流量,熔断可以防止流量击穿当前服务,进入调用链的下游。