Springcloud实战遇到的问题及解决方式
温馨提示:这篇文章已超过635天没有更新,请注意相关的内容是否还可用!
目录
1.Feign与hystrix使用不会看到错误信息代理检测线程异常,需要先屏蔽。
2.springcloud之Feign、hystrix、ribbon设置超时时间和重试机制(微服务)。
3.feign调用远程服务,并发数量达到一定时会出直接触发hystrix fallbanck方法,原因为hystrix线程池配置问题。
4.ribbom重试MaxAutoRetriesNextServer会带来幂等性问题,尽量慎用。
5.zuul超时配置。
6.zuul中hystrix熔断器配置。
7.高可用配置中心失效
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
#同一台实例最大重试次数,不包括首次调用
MaxAutocRetriesNextServer: 1
#重试负载均衡其他的实例最大重试次数,不包括首次调用
OkToRetryOnAllOperations: false
#是否所有操作都重试
3.feign调用远程服务,并发数量达到一定时会出直接触发hystrix fallbanck方法,原因为hystrix线程池配置问题。
实战测试:
参数详解:
修改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超时配置。
官网:#_zuul_timeouts
8.14 Zuul TimeoutsIf 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地址相互配置进行高可用。
原文链接: