spring-cloud - 使用zuul出现大量CLOSE_WAIT
问题描述
使用springcloud zuul的时候,出现大量的TCP CLOSE_WAIT状态,有大神知道是什么原因吗?
这是我的zuul配置
家长会
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath />
</parent>
pom.xml
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.SR2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies>
应用程序属性
server.port=8081 spring.application.name=zuul-server-test eureka.instance.preferIpAddress=true eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port} eureka.instance.leaseRenewalIntervalInSeconds=5 eureka.instance.leaseExpirationDurationInSeconds=10 eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8080/eureka/ zuul.add-host-header=true zuul.sensitive-headers= hystrix.command.default.execution.timeout.enable=true hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000 zuul.host.connect-timeout-millis=60000 zuul.host.socket-timeout-milllis=60000 ribbon.eureka.enabled=true ribbon.ReadTimeout=60000 ribbon.ConnectTimeout=30000 ribbon.MaxAutoRetries=0 ribbon.MaxAutoRetriesNextServer=1 ribbon.OkToRetryOnAllOperations=false ribbon.httpclient.enabled=false ribbon.okhttp.enabled=true zuul.routes.hello.path=/hello/** zuul.routes.hello.sensitiveHeaders= zuul.routes.hello.service-id=hello-server
爪哇
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class DevcloudZuulApplication {
public static void main(String[] args) {
SpringApplication.run(DevcloudZuulApplication.class, args);
}
}
当我访问http://localhost:8081/hello/index.html时,创建了 tcp 链接,端口 8082 是 hello-server
tcp 0 0 ::ffff:192.168.120.20:8082 ::ffff:192.168.120.20:21505 ESTABLISHED 47968/java
tcp 0 0 ::ffff:192.168.120.20:21505 ::ffff:192.168.120.20:8082 ESTABLISHED 132689/java
tcp 0 0 ::ffff:192.168.120.20:8082 ::ffff:192.168.120.20:21510 ESTABLISHED 47968/java
tcp 0 0 ::ffff:192.168.120.20:21510 ::ffff:192.168.120.20:8082 ESTABLISHED 132689/java
tcp 0 0 ::ffff:192.168.120.20:8082 ::ffff:192.168.120.20:21504 ESTABLISHED 47968/java
tcp 0 0 ::ffff:192.168.120.20:21504 ::ffff:192.168.120.20:8082 ESTABLISHED 132689/java
然后它改变了
tcp 0 0 ::ffff:192.168.120.20:8082 ::ffff:192.168.120.20:21505 FIN_WAIT2 -
tcp 1 0 ::ffff:192.168.120.20:21505 ::ffff:192.168.120.20:8082 CLOSE_WAIT 132689/java
tcp 0 0 ::ffff:192.168.120.20:8082 ::ffff:192.168.120.20:21510 FIN_WAIT2 -
tcp 0 0 ::ffff:192.168.120.20:21510 ::ffff:192.168.120.20:8082 CLOSE_WAIT 132689/java
tcp 0 0 ::ffff:192.168.120.20:8082 ::ffff:192.168.120.20:21504 FIN_WAIT2 -
tcp 1 0 ::ffff:192.168.120.20:21504 ::ffff:192.168.120.20:8082 CLOSE_WAIT 132689/java
最后,
tcp 1 0 ::ffff:192.168.120.20:21505 ::ffff:192.168.120.20:8082 CLOSE_WAIT 132689/java
tcp 1 0 ::ffff:192.168.120.20:21504 ::ffff:192.168.120.20:8082 CLOSE_WAIT 132689/java
tcp 1 0 ::ffff:192.168.120.20:21510 ::ffff:192.168.120.20:8082 CLOSE_WAIT 132689/java
这种状态将持续数小时。
解决方案
CLOSE_WAIT
此处描述:TCP 连接状态
此端点已收到来自远程端点的关闭请求,此 TCP 现在正在等待来自本地应用程序的连接终止请求。
Ribbon 使用连接池向上游发送请求。每次,它都会释放连接而不是关闭它,以避免建立新连接的开销。
通过配置ribbon.PoolKeepAliveTime
默认值为 15 * 60 秒,池中的连接具有存活时间。
public class DefaultClientConfigImpl implements IClientConfig {
public static final long DEFAULT_POOL_KEEP_ALIVE_TIME = 15 * 60L;
public static final TimeUnit DEFAULT_POOL_KEEP_ALIVE_TIME_UNITS = TimeUnit.SECONDS;
}
public class OkHttpRibbonConfiguration {
@Value("${ribbon.client.name}")
private String name = "client";
@Configuration
protected static class OkHttpClientConfiguration {
private OkHttpClient httpClient;
@Bean
@ConditionalOnMissingBean(ConnectionPool.class)
public ConnectionPool httpClientConnectionPool(IClientConfig config, OkHttpClientConnectionPoolFactory connectionPoolFactory) {
Integer maxTotalConnections = config.getPropertyAsInteger(
CommonClientConfigKey.MaxTotalConnections,
DefaultClientConfigImpl.DEFAULT_MAX_TOTAL_CONNECTIONS);
Object timeToLiveObj = config
.getProperty(CommonClientConfigKey.PoolKeepAliveTime);
Long timeToLive = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME;
Object ttlUnitObj = config
.getProperty(CommonClientConfigKey.PoolKeepAliveTimeUnits);
TimeUnit ttlUnit = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME_UNITS;
if (timeToLiveObj instanceof Long) {
timeToLive = (Long) timeToLiveObj;
}
if (ttlUnitObj instanceof TimeUnit) {
ttlUnit = (TimeUnit) ttlUnitObj;
}
return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
}
}
推荐阅读
- firebase - 如何在bigquery中计算每个screen_class(firebase)的平均访问时间?
- javascript - 滑动、刷新、布局可以替换为 lambda 错误
- 3dsmax - 如何在 3dsmax 中使用 maxscript 创建工具栏
- vue.js - 更好的 nuxt vuex 工作流程?
- php - 侧边栏中未显示 WordPress 类别 (post-new.php)
- postgresql - Postgres / K8S:PANIC 找不到有效的检查点记录 / CrashLoopBackOff
- sql - Prolog to SQL:有什么方法可以改进单元测试的 SQL 代码并优雅地修复边缘情况?
- google-apps-script - 如何在 Google Apps 脚本中创建搜索栏?
- tensorflow - 无法使用 GradientTape 重现 model.fit
- android - com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:应为 BEGIN_ARRAY,但在第 1 行第 1 列为 STRING