Feign提供聲明式的遠程調用,借用動態代理實現遠程調用,使編寫Web服務客戶端變得更容易。 Spring Cloud增加了對Spring MVC註釋的支持,並使用了Spring Web中默認使用的相同HttpMessageConverters。 Spring Cloud集成了Ribbon和Eureka,在使用Feign時提供負載均衡的http客戶端。
快速入門
- Eureka-server配置
server.port=8088
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
spring.security.user.name=mask
spring.security.user.password=111111
- Eureka-Server
@SpringBootApplication
@EnableEurekaServer
public class EurekaApp{
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class,args);
}
}
- 服務提供者A
spring.application.name=USER-SERVICE
eureka.instance.instance-id=001
eureka.instance.prefer-ip-address=true
eureka.instance.lease-expiration-duration-in-seconds=20
eureka.instance.lease-renewal-interval-in-seconds=10
eureka.client.register-with-eureka=true
eureka.client.healthcheck.enabled=true
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://mask:111111@localhost:8088/eureka/
@SpringBootApplication
@EnableEurekaClient
@RestController
@RequestMapping("main")
public class EurekaApp {
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class,args);
}
@RequestMapping(value = "index", method = {RequestMethod.GET})
public String index() {
return "服務A";
}
}
- 服務提供者B
server.port=8081
spring.application.name=USER-SERVICE
eureka.instance.instance-id=002
eureka.instance.prefer-ip-address=true
eureka.instance.lease-expiration-duration-in-seconds=20
eureka.instance.lease-renewal-interval-in-seconds=10
eureka.client.register-with-eureka=true
eureka.client.healthcheck.enabled=true
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://mask:111111@localhost:8088/eureka/
@SpringBootApplication
@EnableEurekaClient
@RestController
@RequestMapping("main")
public class EurekaApp {
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class,args);
}
@RequestMapping(value = "index", method = {RequestMethod.GET})
public String index() {
return "服務B";
}
}
- Eureka-Consumer
新增依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
創建接口 UserServiceController
@FeignClient(name = "USER-SERVICE") //name爲服務名
public interface UserServiceController {
@GetMapping("main/index") //該方法映射的路徑
String index();
}
server.port=8089
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=false
eureka.client.service-url.defaultZone=http://mask:111111@localhost:8088/eureka/
@SpringBootApplication
@RestController
@EnableFeignClients
public class EurekaSpringBootConsumer {
public static void main(String[] args) {
SpringApplication.run(EurekaSpringBootConsumer.class,args);
}
@Autowired
private UserServiceController userServiceController;
@GetMapping("/rpc/test")
public String index() {
String index = userServiceController.index();
System.out.println(index);
return "OK";
}
}
訪問http://localhost:8089/rpc/test
底層會根據接口方法的配置信息參數發送請求給遠程的服務器這種實現比單純的使用Ribbon更加的優雅。實際上Feign底層就是對Ribbon組件的封裝。
注:在Fegin裏不能傳遞自定義類型至GET查詢參數
Feigen 熔斷
默認Feign沒有開啓熔斷策略,需要用戶在配置文件中指定
- EurekaConsumer中新增配置
feign.hystrix.enabled=true
- 修改UserServiceController
@FeignClient(name = "USER-SERVICE", fallback = UserServiceFailBack.class) //name爲服務名
public interface UserServiceController {
@GetMapping("main/index") //該方法映射的路徑
String index();
}
- 新增UserServiceFailBack類
@Component
public class UserServiceFailBack implements UserServiceController{
@Override
public String index() {
return "熔斷";
}
}
- 修改服務B使其拋出異常
@RestController
@RequestMapping("main")
public class TestController {
@RequestMapping(value = "index", method = {RequestMethod.GET})
public String index() {
int i = 1/0;
return "服務B";
}
}
啓動服務多次訪問http://localhost:8089/rpc/test如下圖可看出服務B拋出異常後執行熔斷後代碼
Feign超時設置
feign.client.config.USER-SERVICE.connect-timeout=500
feign.client.config.USER-SERVICE.read-timeout=500
Hystrix Dashboard
- pom引入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- application.properties新增
management.endpoints.web.exposure.include=*
- 啓動類新增註解
@EnableHystrixDashboard
@EnableCircuitBreaker
配置HyStrix屬性
在和Feign整合後,用戶無法配置Feign的ComandProperties,但是可以通過配置Bean的形式配置
- Bean
@Bean
public SetterFactory setterFactory(){
SetterFactory setterFactory =new SetterFactory() {
@Override
public HystrixCommand.Setter create(Target<?> target, Method method) {
String groupKey = target.name();
String commandKey = Feign.configKey(target.type(), method);
HystrixCommandProperties.Setter setter = HystrixCommandProperties.Setter()
//設置統計指標5秒爲一個時間窗口
.withMetricsRollingStatisticalWindowInMilliseconds(5000)
//操過80%失敗率
.withCircuitBreakerErrorThresholdPercentage(50)
//操作5個開啓短路器
.withCircuitBreakerRequestVolumeThreshold(5)
//設置線程隔離
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
//設置斷路器的開啓時間爲5秒
.withCircuitBreakerSleepWindowInMilliseconds(5000);
return HystrixCommand.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
.andCommandPropertiesDefaults(setter);
}
};
return setterFactory;
}