Eureka客户端集群环境下获取注册表报GZIP格式异常求助
看起来你遇到的是Eureka集群强制GZIP压缩和Tomcat自带压缩冲突导致的问题,我来帮你拆解一下:
问题根源
Eureka集群模式下,GzipEncodingEnforcingFilter会强制对注册表响应启用GZIP压缩,但你同时在Tomcat的HTTP连接器中设置了compression="force",这就造成了双重压缩的情况:
- Tomcat先把响应内容压缩成GZIP格式
- Eureka的Filter又尝试对已经压缩过的内容再次进行GZIP压缩
- 客户端的Jersey
GZIPContentEncodingFilter接收到的是“压缩了两次”的内容,解压时自然会抛出Not in GZIP format异常
你用curl和自定义HttpClient测试正常,是因为这些工具的压缩处理容错性比Jersey的Filter更好,或者能正确识别异常的响应头并处理。
解决方案
方案1:关闭Tomcat的强制压缩(推荐)
既然Eureka集群已经会强制处理GZIP压缩,就不需要Tomcat再额外做一次了。修改Tomcat server.xml中的HTTP连接器配置,把compression="force"改成compression="off",或者直接去掉这个配置项:
<Connector port="9081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" compression="off"/> <!-- 这里修改为off -->
重启Tomcat后,Eureka的GzipEncodingEnforcingFilter会单独处理压缩,客户端的Jersey Filter就能正常解压了。
方案2:禁用Eureka客户端的GZIP处理
如果不能修改Tomcat配置,可以尝试在客户端移除Jersey的GZIP压缩过滤器,让客户端直接接收Tomcat压缩后的内容(需要确保客户端能正确处理响应头的Content-Encoding)。
你可以通过自定义DiscoveryClient的方式来修改Jersey客户端的过滤器:
// 自定义Eureka客户端配置 DiscoveryClientConfig clientConfig = new DefaultEurekaClientConfig(); // 创建Jersey客户端并移除GZIP过滤器 com.sun.jersey.api.client.Client jerseyClient = Client.create(); List<ClientFilter> filters = jerseyClient.getFilters(); filters.removeIf(filter -> filter instanceof GZIPContentEncodingFilter); // 构造自定义的Eureka HttpClient EurekaHttpClient httpClient = new JerseyEurekaHttpClient(jerseyClient, clientConfig); // 初始化DiscoveryClient时使用这个httpClient DiscoveryClient discoveryClient = new DiscoveryClient(new MyInstanceConfig(), clientConfig, httpClient);
不过这种方式需要你手动管理DiscoveryClient的创建,不如方案1简洁。
方案3:调整Tomcat的压缩规则,排除Eureka的请求路径
如果需要保留Tomcat的压缩功能,可以配置Tomcat只对特定路径启用压缩,排除Eureka的服务发现路径(比如/service-discovery/eureka/**):
<Connector port="9081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" compression="force" compressableMimeType="text/html,text/xml,text/plain,text/css,application/javascript" compressionMinSize="2048"/>
这里通过compressableMimeType只压缩指定类型,而Eureka的注册表响应通常是application/json,不在这个列表里,就不会被Tomcat压缩,交给Eureka的Filter处理。
验证建议
修改配置后,你可以用以下命令验证响应是否正常:
curl -H "Accept-Encoding: gzip" -v http://rdtasap33.testbbh.com:9081/service-discovery/eureka/apps
查看响应头的Content-Encoding是否只有一个gzip,并且能正常解压内容。
内容的提问来源于stack exchange,提问作者ludwik_01

