如何在Spring Boot应用中配置与使用Brotli压缩?
在Envoy后部署的Spring Boot服务启用Brotli压缩方案
方案一:Envoy侧配置Brotli(推荐)
因为服务部署在Envoy之后,优先在代理层实现压缩更高效,无需修改Spring Boot应用代码,便于统一管理压缩策略。
Envoy配置示例
在HTTP过滤器链中添加compress过滤器并指定Brotli压缩算法:
http_filters: # 其他过滤器(如router等)放在后面 - name: envoy.filters.http.compress typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.compress.v3.Compress compressor_library: name: brotli typed_config: "@type": type.googleapis.com/envoy.extensions.compression.brotli.compressor.v3.Brotli quality: 6 # 压缩质量1-11,默认6,平衡速度与压缩率 window_bits: 22 # 窗口大小范围10-24,越大压缩率越高但内存占用越多 content_type: - application/json - text/html - text/plain - text/css - application/javascript min_content_length: 1024 # 仅压缩大于1KB的响应
- 注意:确保Envoy版本支持Brotli扩展(v1.18+默认包含),旧版本需编译时启用该扩展。
- 协商逻辑:Envoy会自动检查请求的
Accept-Encoding头,仅当包含br时返回Brotli压缩响应,否则 fallback 到gzip或不压缩。
方案二:Spring Boot应用内启用Brotli
如果需要在应用层实现,可通过自定义过滤器或第三方starter完成。
1. 使用第三方starter
引入Spring Boot Brotli starter依赖(Maven):
<dependency> <groupId>io.github.vanroy</groupId> <artifactId>spring-boot-starter-brotli</artifactId> <version>1.0.0</version> <!-- 替换为最新稳定版 --> </dependency>
然后在配置文件中启用压缩:
server: compression: enabled: true mime-types: application/json,text/html,text/plain,text/css,application/javascript min-response-size: 1024
2. 自定义Brotli压缩过滤器
若不想依赖第三方starter,可手动实现过滤器:
import org.brotli.enc.BrotliOutputStream; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class BrotliCompressionFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; String acceptEncoding = req.getHeader("Accept-Encoding"); if (acceptEncoding != null && acceptEncoding.contains("br")) { res.setHeader("Content-Encoding", "br"); res.addHeader("Vary", "Accept-Encoding"); BrotliResponseWrapper wrappedResponse = new BrotliResponseWrapper(res); chain.doFilter(req, wrappedResponse); wrappedResponse.finishCompression(); return; } chain.doFilter(req, res); } static class BrotliResponseWrapper extends HttpServletResponseWrapper { private final BrotliOutputStream brotliOut; public BrotliResponseWrapper(HttpServletResponse response) throws IOException { super(response); this.brotliOut = new BrotliOutputStream(response.getOutputStream()); } @Override public ServletOutputStream getOutputStream() throws IOException { return brotliOut; } public void finishCompression() throws IOException { brotliOut.finish(); } } }
注册过滤器到Spring容器:
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WebConfig { @Bean public FilterRegistrationBean<BrotliCompressionFilter> brotliCompressionFilter() { FilterRegistrationBean<BrotliCompressionFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new BrotliCompressionFilter()); registration.addUrlPatterns("/*"); registration.setOrder(1); // 确保在其他响应处理过滤器前执行 return registration; } }
同时需要引入Brotli核心依赖:
<dependency> <groupId>org.brotli</groupId> <artifactId>brotli</artifactId> <version>0.1.2</version> <!-- 替换为最新稳定版 --> </dependency>
关键注意事项
- 兼容性:Brotli支持现代浏览器(Chrome、Firefox、Edge等),但IE11及以下不支持,需保留gzip作为降级方案。
- 性能调优:Brotli的
quality参数越高,压缩率越高但CPU开销越大,生产环境建议测试后选择合适值(如6或7)。 - 响应头处理:确保返回
Vary: Accept-Encoding头,让缓存服务器正确缓存不同压缩格式的响应。
内容的提问来源于stack exchange,提问作者Anant Pathak
相关产品推荐
相关产品推荐

