最近排查一个bug,发现了一系列有意思的东西,对「自定义线程池」、「Jetty线程模型」都有了一些新的认识。
本文预计阅读时间10分钟,包括:
- 问题表现
- 常见原因筛查
- 根因与源码分析
- 最佳实践
- 一些小TIPS
1.问题表现
预发环境偶发请求失败异常,服务端显示错误信息为:
Required String parameter 'seriesbaid' is not present
复制代码
对应controller的api为
@PostMapping
public Object getUserParameter(
HttpServletRequest request,
HttpServletResponse response,
@RequestParam(value = "seriesbaid") String seriesbaid){
}
复制代码
乍一看,是一个非常简单的异常,请求参数里面没有带seriesbaid,导致失败。
但是,经过确认,前端请求参数已经携带了seriesbaid,而且为“偶发失败”,并不是常见的参数传递问题。
2.常见原因筛查
2.1 网关参数丢失??
由于前端请求到达后端服务中会经过网关,所以一开始怀疑是否网关丢失了传递参数。
经过 调用链分析,在偶发的失败的请求中,也确认已经传递了querystring。所以网关没有丢失参数传递。
2.2 特殊字符导致参数转换失败 ??
既然已经传递了querystring到后端服务,那么一种常见的原因,由于queryString中带有特殊字符而导致解析成queryParam失败了。
会是这个问题吗?
我们通过在服务中继承一个spring-web的OncePerRequestFilter,对请求参数进行打印
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
if ("/api/swanparameter".equals(request.getServletPath())) {
LOG.message("shouldLog - swanparameter")
.with("tra