通过zuul网关请求服务有时候个别请求时候"timestamp":“2018-09-07 11:45:38”,“status”:500,“error”:“Internal Server Error” “message”:”GENERAL”
之前这个一开始问题分析是网关超时配置时间太短的原因,随后开始调大网关时间:
网关的三种时间配置 由于zuul集成了hystrix和ribbon, 所以也就包含了这几中的响应时间,ribbon当使用serviceId的方式配置使用这个,当服务使用url 的方式的话使用下面的zuul.host的配置方式,另外hystrix的时间必须大于ribbon所需要的时间和因为下面还包含重连时间(一次连接zuul失败的二次重连可以是同一个实例也可以是下一个实例)
ribbon:
ReadTimeout: 5000
ConnectTimeout: 5000
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 1
hystrix:
command:
default:
execution:
timeout:
enabled: false #Edgware.RELEASE中,timeoutInMilliseconds不起作用,暂时关掉
isolation:
thread:
timeoutInMilliseconds: 10000
zuul:
host:
socket-timeout-millis: 10000
connect-timeout-millis: 10000
上面的配置不成又换了 下面的配置
zuul重连机制好需要如下jar
org.springframework.retry
spring-retry
#retry
#该参数用来开启重试机制
spring.cloud.loadbalancer.retry.enabled=true
#断路器的超时时间,断路器的超时时间需要大于ribbon的超时时间,不然不会触发重试。
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
#ribbon请求连接的超时时间
ribbon.ConnectTimeout=250
#请求处理的超时时间
ribbon.ReadTimeout=1000
#对所有操作请求都进行重试
ribbon.OkToRetryOnAllOperations=true
#对当前实例的重试次数
ribbon.MaxAutoRetries=1
#对下个实例的重试次数
ribbon.MaxAutoRetriesNextServer=1
我更新zuul配置后发现还是会出现同样的问题,随后找到资料说是因为集成了hystrix但是找不到可回退的方法fallback所以又查看了配置可回退的fallback功能功能通过继承zuulFallbackProvider或者FallbackProvider 这里还得注意SpringCloud版本的区别 并且下面注册的bean能够被扫描到
Dalston及更低版本
/**
* 自定义Zuul回退机制处理器。
*
* Provides fallback when a failure occurs on a route 英文意思就是说提供一个回退机制当路由后面的服务发生故障时。*/
@Component
public class SrpingCLoudFallBack implements FallbackProvider {
@Override
public String getRoute() {
// 表明是为哪个微服务提供回退,*表示为所有微服务提供回退
return "*";
}
@Override
public ClientHttpResponse fallbackResponse(Throwable cause) {
if (cause instanceof HystrixTimeoutException) {
return response(HttpStatus.GATEWAY_TIMEOUT);
} else {
return this.fallbackResponse();
}
}
@Override
public ClientHttpResponse fallbackResponse() {
return this.response(HttpStatus.INTERNAL_SERVER_ERROR);
}
private ClientHttpResponse response(final HttpStatus status) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return status;
}
@Override
public int getRawStatusCode() throws IOException {
return status.value();
}
@Override
public String getStatusText() throws IOException {
return status.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
/*返回json格式数据*/
com.alibaba.fastjson.JSONObject r=new com.alibaba.fastjson.JSONObject();
r.put("state", "501");
r.put("msg", "service is unavailable,请求失败");
return new ByteArrayInputStream(r.toJSONString().getBytes("UTF-8"));
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Edgware及更高版本
@Component
public class MyFallbackProvider implements FallbackProvider {
@Override
public String getRoute() {
// 表明是为哪个微服务提供回退,*表示为所有微服务提供回退
return "*";
}
@Override
public ClientHttpResponse fallbackResponse(Throwable cause) {
if (cause instanceof HystrixTimeoutException) {
return response(HttpStatus.GATEWAY_TIMEOUT);
} else {
return this.fallbackResponse();
}
}
@Override
public ClientHttpResponse fallbackResponse() {
return this.response(HttpStatus.INTERNAL_SERVER_ERROR);
}
private ClientHttpResponse response(final HttpStatus status) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return status;
}
@Override
public int getRawStatusCode() throws IOException {
return status.value();
}
@Override
public String getStatusText() throws IOException {
return status.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream("服务不可用,请稍后再试。".getBytes());
}
@Override
public HttpHeaders getHeaders() {
// headers设定
HttpHeaders headers = new HttpHeaders();
MediaType mt = new MediaType("application", "json", Charset.forName("UTF-8"));
headers.setContentType(mt);
return headers;
}
};
}
}
• Dalston及更低版本通过实现ZuulFallbackProvider 接口,从而实现回退;
• Edgware及更高版本通过实现FallbackProvider 接口,从而实现回退。
• 在Edgware中:• FallbackProvider是ZuulFallbackProvider的子接口。
• ZuulFallbackProvider已经被标注Deprecated ,很可能在未来的版本中被删除。
• FallbackProvider接口比ZuulFallbackProvider多了一个ClientHttpResponse fallbackResponse(Throwable cause); 方法,使用该方法,可获得造成回退的原因。
通过上面的实现以为现在可以解决问题了,但是悲哀的是还是报同样错误,后来想关闭hystrix设置结果还是不成
hystrix.command.default.execution.timeout.enabled=true
看来是思路不对,后来查找hystrix有两种策略方式一种是THREAD 以及SEMAPHORE ,默认是 SEMAPHORE 我更改成了后者并且设置了信号量大小,问题解决
http://www.itmuch.com/spring-cloud-sum/spring-cloud-concurrent/
最后配置
#开启重连机制
spring.cloud.loadbalancer.retry.enabled=true
zuul.retryable=true
#zuul超时配置
#zuul.host.socket-timeout-millis=800000
#zuul.host.connect-timeout-millis=300000
#hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000000
##hystrix.command.default.execution.timeout.enabled=true
##hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000000
##ribbon.ReadTimeout=8000
##ribbon.ConnectTimeout=2000
##ribbon.OkToRetryOnAllOperations=true
##ribbon.MaxAutoRetries=3
##ribbon.MaxAutoRetriesNextServer=3
##ribbon.eureka.enabled=true
#hystrix.command.default.execution.timeout.enabled=true 这个报错 404和正常请求交替
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=200000000000
feign.hystrix.enabled=true
ribbon.ReadTimeout=80000
ribbon.ConnectTimeout=50000
zuul.semaphore.max-semaphores=2000
ribbon.OkToRetryOnAllOperations=true
ribbon.MaxAutoRetries=3
ribbon.MaxAutoRetriesNextServer=3
ribbon.eureka.enabled=true
zuul.ribbon-isolation-strategy=semaphore