目录
1.Feign与hystrix使用不会看到错误信息,需要先屏蔽。
2.springcloud之Feign、hystrix、ribbon设置超时时间和重试机制(微服务)。
3.feign调用远程服务,并发数量达到一定时会出直接触发hystrix fallbanck方法,原因为hystrix线程池配置问题。
4.ribbom重试MaxAutoRetriesNextServer会带来幂等性问题,尽量慎用。
1.Feign与hystrix使用不会看到错误信息,需要先屏蔽。
2.springcloud之Feign、hystrix、ribbon设置超时时间和重试机制(微服务)。
protected static int getRibbonTimeout(IClientConfig config, String commandKey) {
int ribbonTimeout;
if (config == null) {
ribbonTimeout = RibbonClientConfiguration.DEFAULT_READ_TIMEOUT + RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT;
} else {
int ribbonReadTimeout = getTimeout(config, commandKey, "ReadTimeout",
IClientConfigKey.Keys.ReadTimeout, RibbonClientConfiguration.DEFAULT_READ_TIMEOUT);
int ribbonConnectTimeout = getTimeout(config, commandKey, "ConnectTimeout",
IClientConfigKey.Keys.ConnectTimeout, RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT);
int maxAutoRetries = getTimeout(config, commandKey, "MaxAutoRetries",
IClientConfigKey.Keys.MaxAutoRetries, DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES);
int maxAutoRetriesNextServer = getTimeout(config, commandKey, "MaxAutoRetriesNextServer",
IClientConfigKey.Keys.MaxAutoRetriesNextServer, DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER);
ribbonTimeout = (ribbonReadTimeout + ribbonConnectTimeout) * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1);
}
return ribbonTimeout;
}
公式:ribbonTimeout = (ribbonReadTimeout + ribbonConnectTimeout) * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1);
下面就是:ribbon重试 (3000+3000)*(1+1)*(1+1)=24秒(hystrix的24秒)
#hystrix的超时时间
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 24000 #超时时间24秒
ribbon:
ReadTimeout: 3000 #时间3秒
ConnectTimeout: 3000
MaxAutoRetries: 1 #同一台实例最大重试次数,不包括首次调用
MaxAutoRetriesNextServer: 1 #重试负载均衡其他的实例最大重试次数,不包括首次调用
OkToRetryOnAllOperations: false #是否所有操作都重试
3.feign调用远程服务,并发数量达到一定时会出直接触发hystrix fallbanck方法,原因为hystrix线程池配置问题。
实战测试:https://www.cnblogs.com/seifon/p/9921774.html
参数详解:https://www.cnblogs.com/huangjuncong/p/9043844.html
修改coreSize,maxQueueSize,queueSizeRejectionThreshold(主要)参数
ribbon:
#Ribbon允许最大连接数,即所有后端微服务实例请求并发数之和的最大值。
MaxTotalConnections: 500
#单个后端微服务实例能接收的最大请求并发数
MaxConnectionsPerHost: 500
ReadTimeout: 1000
ConnectTimeout: 1000
# 关闭Ribbon的重试机制
MaxAutoRetriesNextServer: 1
#hystrix 配置
hystrix:
threadpool:
default:
coreSize: 20 #并发执行的最大线程数,默认10
maxQueueSize: 500 #BlockingQueue的最大队列数,默认值-1
queueSizeRejectionThreshold: 500 #即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝,默认值5
command:
default:
execution:
timeout:
#如果enabled设置为false,则请求超时交给ribbon控制
enabled: true
isolation:
thread:
timeoutInMilliseconds: 4000
4.ribbom重试MaxAutoRetriesNextServer会带来幂等性问题,尽量慎用。
5.zuul超时配置。
官网:http://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#_zuul_timeouts
8.14 Zuul Timeouts
If you want to configure the socket timeouts and read timeouts for requests proxied through Zuul, you have two options, based on your configuration:
If Zuul uses service discovery, you need to configure these timeouts with the ribbon.ReadTimeout and ribbon.SocketTimeout Ribbon properties.
If you have configured Zuul routes by specifying URLs, you need to use zuul.host.connect-timeout-millis and zuul.host.socket-timeout-millis.
如果要配置通过zuul代理的请求的连接超时和读取超时,根据您的配置,您有两个选项:
如果zuul使用服务发现,则需要使用Ribbon.ReadTimeout和Ribbon.SocketTimeout功能区属性配置这些超时。
如果通过指定URL配置了zuul路由,则需要使用zuul.host.connect-timeout-millis和zuul.host.socket-timeout-millis。
6.zuul中hystrix熔断器配置。
package com.gateway.fallback;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import com.common.msg.CodeMsg;
import com.common.msg.RrcResponse;
import com.common.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class CommonFallbackProvider implements FallbackProvider{
@Override
public String getRoute() {
return "*";
}
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return 200;
}
@Override
public String getStatusText() throws IOException {
return "OK";
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
//增加zuul找不到服务异常返回信息
log.info("---zuul找不到服务器----");
return new ByteArrayInputStream(JsonUtil.toJson(new RrcResponse(CodeMsg.POC_ERROR_ZUUL.getCode(), CodeMsg.POC_ERROR_ZUUL.getMsg(), null)).getBytes("UTF-8"));
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return headers;
}
};
}
}
7.高可用配置中心失效
如果使用hosts配置,preferIpAddress=true,节约了地址解析的损耗。当preferIpAddress=false,不同ip地址相互配置进行高可用。