spring-cloud-microservice
org.example
1.0-SNAPSHOT
4.0.0
microservice-cloud-consumer-dept-openFeign
org.example
microservice-cloud-api
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-tomcat
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-jetty
org.springframework
springloaded
1.2.8.RELEASE
org.apache.logging.log4j
log4j-core
ch.qos.logback
logback-core
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
2.2.10.RELEASE
org.springframework.cloud
spring-cloud-starter-openfeign
3.1.3
org.springframework.cloud
spring-cloud-starter-loadbalancer
3.1.3
com.netflix.ribbon
ribbon-loadbalancer
2.7.18
compile
org.springframework.cloud
spring-cloud-netflix-ribbon
2.2.10.RELEASE
compile
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
2.2.10.RELEASE
org.springframework.boot
spring-boot-maven-plugin
org.projectlombok
lombok
feign:
circuitbreaker:
enabled: true
package com.example.service;
import com.example.config.FeignConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Service
@FeignClient(value = "MICROSERVICECLOUDPROVIDERDEPTHYSTRIX",configuration = FeignConfiguration.class)
public interface DeptHystrixService {
@GetMapping("/dept/getInfo/Hystrix/200/{id}")
String dept_200(@PathVariable("id") Integer id);
@GetMapping("/dept/testTimeOut/Hystrix/{id}")
String testTimeOut(@PathVariable("id") Integer id);
}
package com.example.controller;
import com.example.service.DeptHystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class DeptHystrixController {
@Autowired
private DeptHystrixService deptHystrixService;
@GetMapping("/consumer/dept/getInfo/Hystrix/200/{id}")
public String dept_200(@PathVariable("id") Integer id) {
String info = deptHystrixService.dept_200(id);
log.info(info);
return "客户端请求"+info;
}
//在客户端进行降级
//超时测试,该服务的响应时间为 3 秒
@GetMapping("/consumer/dept/testTimeOut/Hystrix/{id}")
@HystrixCommand(fallbackMethod = "deptTimeoutHandler")
public String testTimeOut(@PathVariable("id") Integer id){
String info = deptHystrixService.testTimeOut(id);
//当Application.yml中没有配置当前端口号,只能使用此方式获取端口
log.info(info);
return info;
}
// testTimeOut方法的 专用 fallback 方法
public String deptTimeoutHandler(Integer id){
log.info("testTimeOut 出错,服务被降级!");
return "因当前请求testTimeOut超时,客户端服务降级,返回提示信息!当前线程:"+Thread.currentThread().getName()+"请求超时500。ID+"+id;
}
}
spring:
application:
name: feignServer
server:
port: 80
servlet:
context-path: /
#Jetty specific properties
jetty:
threads:
acceptors: -1 #Number of acceptor threads to use. When the value is -1, the default, the number of acceptors is derived from the operating environment.
selectors: -1 #Number of selector threads to use. When the value is -1, the default, thenumber of selectors is derived from the operating environment.
max-http-form-post-size: 200000 #Maximum size of the form content in any HTTP post request.
eureka:
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: true #指示此客户端是否应从 eureka 服务器获取 eureka 注册表信息
service-url: #监控页面地址
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #发布的服务注册中心地址,单机
defaultZone: http://eurekaserver7001.com:7001/eureka/,http://eurekaserver7002.com:7002/eureka/,http://eurekaserver7003.com:7003/eureka/ #集群版 将当前的 Eureka Server 注册到 7003 和 7003 上,形成一组互相注册的 Eureka Server 集群
feign:
client:
config:
## default 设置的全局超时时间,指定服务名称可以设置单个服务的超时时间
feignServer: #feignServer这个服务单独配置超时时间
connectTimeout: 6000
readTimeout: 6000
circuitbreaker:
enabled: true
ribbon:
eager-load:
enabled: true #关闭懒加载
# 指的是建立连接后从服务器读取到可用资源所用的时间
ReadTimeout: 6000
# 指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间
ConnectTimeout: 6000
eureka:
enabled: false #禁用Eureka
logging:
level:
com:
example:
service: debug
MICROSERVICECLOUDPROVIDERDEPT:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 7000 #配置请求超时时间
DeptHystrixService#testTimeOut(Integer):
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 #配置具体方法超时时间 为 3 秒
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=mmm
hystrix.command.xxx#yyy(zzz).execution.isolation.thread.timeoutInMilliseconds=mmm
格式说明如下:
- xxx:为包含该服务方法的类的名称(通常为服务绑定接口的名称),例如 DeptHystrixService 接口。
- yyy:服务方法名,例如 testTimeOut 方法。
- zzz:方法内的参数类型,例如 Integer、String 等等
- mmm:要设置的超时时间,单位为毫秒(1 秒 =1000 毫秒)
package com.example;
import com.example.config.FeignConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.cloud.openfeign.EnableFeignClients;
//OpenFeign和Eureka整合以后,容户端可以直接调用用,不用关心服务的IP地址和端口号
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients //开启 OpenFeign 功能
// 如果只有一个服务就可以直接使用@RibbonClient注解,而不需要@RibbonClients。
// name是写服务提供方的服务名 configuration是指定我们上面创建的配置类
@RibbonClients(value = {
@RibbonClient(name = "MICROSERVICECLOUDPROVIDERDEPT",configuration = FeignConfiguration.class)
})
//@RibbonClient(name = "MICROSERVICECLOUDPROVIDERDEPT",configuration = FeignConfiguration.class)
@EnableHystrix //启用 Hystrix
public class MicroserviceCloudConsumerDeptOpenFeignApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserviceCloudConsumerDeptOpenFeignApplication.class, args);
}
}
//一旦该方法失败并抛出了异常信息后,会自动调用 @HystrixCommand 注解标注的 fallbackMethod 指定的方法
@HystrixCommand(fallbackMethod = "dept_timeout_handler",
规定 5 秒钟以内就不报错,正常运行,超过 5 秒就报错,调用指定的方法
commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")})
@Override
public String dept_timeout_500(Integer id) {
try {
//Thread.sleep(6000);
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "服务端当前线程:"+Thread.currentThread().getName()+"请求超时500。ID+"+id;
}
// 当服务出现故障后,调用该方法给出友好提示
public String dept_timeout_handler(Integer id){
return "服务端因当前请求超时,服务降级,返回提示信息!当前线程:"+Thread.currentThread().getName()+"请求超时500。ID+"+id;
}
DeptHystrixService#testTimeOut(Integer):
execution:
isolation:
thread:
timeoutInMilliseconds: 5000 #配置具体方法超时时间 为 5 秒
重启 microservice-cloud-consumer-dept-openFeign,使用浏览器访问,访问http://localhost/consumer/dept/testTimeOut/Hystrix/1
由此可见可以正常访问dept_timeout_500方法内的数据,请求并未超时。