1.1 Feign调用WebApi
1.1.1 配置pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1.1.2 客户端--启动设置:@EnableFeignClients
@EnableFeignClients
@SpringBootApplication
public class SpringBootConsulApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootConsulApplication.class, args);
}
}
1.1.3 Feign服务类
@FeignClient(name= "service-provider")
public interface HelloRemoteService {
@RequestMapping(value = "/hello")
public User hello(@RequestParam(value = "id") int id);
}
1.1.4 测试调用类
@Autowired
private HelloRemoteService userService;
/**
* 使用Feign,调用远程接口
* @return
*/
@RequestMapping("/FeignCall")
public User FeignCall(@RequestParam(value = "id") int id) {
User callServiceResult = userService.hello(id);
System.out.println(callServiceResult);
return callServiceResult;
}
1.2 Feign添加OAuth2 AuthorizatinHeader
1.2.1 实现feign.RequestInterceptor接口
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignOauth2RequestInterceptor implements RequestInterceptor {
private final String AUTHORIZATION_HEADER = "Authorization";
private final String BEARER_TOKEN_TYPE = "Bearer";
@Override
public void apply(RequestTemplate requestTemplate) {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
if (authentication != null && authentication.getDetails() instanceof OAuth2AuthenticationDetails) {
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();
requestTemplate.header(AUTHORIZATION_HEADER, String.format("%s %s", BEARER_TOKEN_TYPE, details.getTokenValue()));
}
}
}
1.2.2 调用接口时,Feign自动添加Token
1.3 Feign调用时添加熔断器Hystrix
1.3.1 服务端--添加超时及异常API
@RestController
public class HelloController {
private static Logger LOGGER = LoggerFactory.getLogger(HelloController.class);
@RequestMapping("/hello")
public @ResponseBody User hello(@RequestParam(value = "id") int id) {
LOGGER.info("invoking hello endpoint");
return new User(id, "hello consul from provider 1");
}
@RequestMapping("/timeout")
public String timeout() throws InterruptedException {
LOGGER.info("invoking timeout endpoint");
Thread.sleep(10000L);
return "timeout from provider 1";
}
@RequestMapping("/exception")
public String exception() {
LOGGER.info("invoking exception endpoint");
if (System.currentTimeMillis() % 2 == 0) {
throw new RuntimeException("random exception from provider 1");
}
return "exception from provider 1";
}
}
1.3.2 客户端--启动设置
@EnableFeignClients
@EnableHystrixDashboard
@EnableCircuitBreaker
@SpringBootApplication
public class SpringBootConsulApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootConsulApplication.class, args);
}
}
1.3.3 客户端--Yaml配置
server:
port: 8504
spring:
application:
name: service-consumer
cloud:
consul:
discovery:
register: false
host: 192.168.56.10
port: 8500
feign:
httpclient:
connection-timeout: 5000
connection-timer-repeat: 5000
enabled: true
max-connections: 200
max-connections-per-route: 50
hystrix:
enabled: true
ribbon:
# 暂不开启熔断机制
hystrix:
enabled: false
# 配置ribbon默认的超时时间
ConnectTimeout: 5000
ReadTimeout: 5000
# 是否开启重试
OkToRetryOnAllOperations: true
# 每个实例重试次数
MaxAutoRetries: 2
# 重试的时候实例切换次数
MaxAutoRetriesNextServer: 3
## hystrix相关配置
## hystrix默认会读取classpath下的config.properties文件,application会覆盖config.properties中的属性
hystrix:
threadpool:
# 指定服务的配置
user-service:
coreSize: 20
maxQueueSize: 200
queueSizeRejectionThreshold: 3
# userThreadPool是UserTimeOutCommand中配置的threadPoolKey
userThreadPool:
coreSize: 20
maxQueueSize: 20
queueSizeRejectionThreshold: 3
# 这是默认的配置
default:
coreSize: 10
maxQueueSize: 200
queueSizeRejectionThreshold: 2
command:
# 指定feign客户端中具体的方法
HelloRemoteService#timeout():
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
userCommandKey:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000
# 这是默认的配置
default:
execution:
timeout:
enabled: true
isolation:
strategy: THREAD
thread:
timeoutInMilliseconds: 15000
interruptOnTimeout: true
interruptOnFutureCancel: false
semaphore:
maxConcurrentRequests: 2
fallback:
enabled: true
isolation:
semaphore:
maxConcurrentRequests: 10
circuitBreaker:
enabled: true
forceOpen: false
forceClosed: false
requestVolumeThreshold: 4
errorThresholdPercentage: 50
sleepWindowInMilliseconds: 10000
metrics:
rollingStats:
timeInMilliseconds: 5000
numBuckets: 10
rollingPercentile:
enabled: true
timeInMilliseconds: 60000
numBuckets: 6
bucketSize: 100
healthSnapshot:
intervalInMilliseconds: 500
1.3.4 客户--消费接口设置
@Component
@FeignClient(name= "service-provider", fallback = HelloRemoteFallbackService.class)
public interface HelloRemoteService {
@RequestMapping(value = "/hello")
public User hello(@RequestParam(value = "id") int id);
@RequestMapping(value = "/timeout", method = RequestMethod.GET)
public String timeout();
@RequestMapping(value = "/exception", method = RequestMethod.GET)
public String exception();
}
1.3.5 客户端--Fallback设置
@Component
public class HelloRemoteFallbackService implements HelloRemoteService {
@Override
public User hello(int id)
{
System.out.println("调用服务失败--hello");
return null;
}
@Override
public String timeout() {
System.out.println("调用服务失败--timeout");
return "timeout 降级";
}
@Override
public String exception() {
System.out.println("调用服务失败--exception");
return "exception 降级";
}
}
1.3.6 客户端--相关配置
# 线程池大小
hystrix.threadpool.default.coreSize=1
# 缓冲区大小, 如果为-1,则不缓冲,直接进行降级 fallback
hystrix.threadpool.default.maxQueueSize=200
# 缓冲区大小超限的阈值,超限就直接降级
hystrix.threadpool.default.queueSizeRejectionThreshold=2
# 执行策略
# 资源隔离模式,默认thread。 还有一种叫信号量
hystrix.command.default.execution.isolation.strategy=THREAD
# 是否打开超时
hystrix.command.default.execution.timeout.enabled=true
# 超时时间,默认1000毫秒
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=15000
# 超时时中断线程
hystrix.command.default.execution.isolation.thread.interruptOnTimeout=true
# 取消时候中断线程
hystrix.command.default.execution.isolation.thread.interruptOnFutureCancel=false
# 信号量模式下,最大并发量
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests=2
# 降级策略
# 是否开启服务降级
hystrix.command.default.fallback.enabled=true
# fallback执行并发量
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests=100
# 熔断策略
# 启用/禁用熔断机制
hystrix.command.default.circuitBreaker.enabled=true
# 强制开启熔断
hystrix.command.default.circuitBreaker.forceOpen=false
# 强制关闭熔断
hystrix.command.default.circuitBreaker.forceClosed=false
# 前提条件,一定时间内发起一定数量的请求。 也就是5秒钟内(这个5秒对应下面的滚动窗口长度)至少请求4次,熔断器才发挥起作用。 默认20
hystrix.command.default.circuitBreaker.requestVolumeThreshold=4
# 错误百分比。达到或超过这个百分比,熔断器打开。 比如:5秒内有4个请求,2个请求超时或者失败,就会自动开启熔断
hystrix.command.default.circuitBreaker.errorThresholdPercentage=50
# 10秒后,进入半打开状态(熔断开启,间隔一段时间后,会让一部分的命令去请求服务提供者,如果结果依旧是失败,则又会进入熔断状态,如果成功,就关闭熔断)。 默认5秒
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=10000
# 度量策略
# 5秒为一次统计周期,术语描述:滚动窗口的长度为5秒
hystrix.command.default.metrics.rollingStats.timeInMilliseconds=5000
# 统计周期内 度量桶的数量,必须被timeInMilliseconds整除。作用:
hystrix.command.default.metrics.rollingStats.numBuckets=10
# 是否收集执行时间,并计算各个时间段的百分比
hystrix.command.default.metrics.rollingPercentile.enabled=true
# 设置执行时间统计周期为多久,用来计算百分比
hystrix.command.default.metrics.rollingPercentile.timeInMilliseconds=60000
# 执行时间统计周期内,度量桶的数量
hystrix.command.default.metrics.rollingPercentile.numBuckets=6
# 执行时间统计周期内,每个度量桶最多统计多少条记录。设置为50,有100次请求,则只会统计最近的10次
hystrix.command.default.metrics.rollingPercentile.bucketSize=100
# 数据取样时间间隔
hystrix.command.default.metrics.healthSnapshot.intervalInMilliseconds=500
# 设置是否缓存请求,request-scope内缓存
hystrix.command.default.requestCache.enabled=false
# 设置HystrixCommand执行和事件是否打印到HystrixRequestLog中
hystrix.command.default.requestLog.enabled=false
# 限流策略
#如果没有定义HystrixThreadPoolKey,HystrixThreadPoolKey会默认定义为HystrixCommandGroupKey的值
hystrix.threadpool.userGroup.coreSize=1
hystrix.threadpool.userGroup.maxQueueSize=-1
hystrix.threadpool.userGroup.queueSizeRejectionThreshold=800
hystrix.threadpool.userThreadPool.coreSize=1
hystrix.threadpool.userThreadPool.maxQueueSize=-1
hystrix.threadpool.userThreadPool.queueSizeRejectionThreshold=800
hystrix.command.userCommandKey.execution.isolation.thread.timeoutInMilliseconds=5000
1.3.7 资料
Hystrix属性配置详情:https://github.com/Netflix/Hystrix/wiki/Configuration
SpringCloud的限流、熔断和降级:https://blog.csdn.net/chenxyz707/article/details/80913725
Feign、Hystrix使用时的超时时间(timeout)设置问题:https://blog.csdn.net/mxmxz/article/details/84633098
本文暂时没有评论,来添加一个吧(●'◡'●)