老司机翻车记--记一次中文乱码错误排查

现象

最近在部署dev环境(非本地开发环境)时遇到一个现象:同一套代码,同一个接口,相同的请求参数,通过swagger调用新部署的dev环境返回中文乱码,但是调用本地开发环境,接口可以正常返回。更让人费解的是,另一个接口却没有返回乱码

排查

web环境下的中文乱码,相信大家已经遇到过很多次,对于这类问题的排查应该都比较有经验

对于这类不同环境表现不一致的情况,直觉告诉我们十有八九与新部署的dev环境有关。于是ssh到dev环境机器,查看locale,发现全部都是“POSIX”。再查看本地开发环境locale,全部都是“zh_CN.UTF-8”

至此,初步可以解释上面提到的第一个问题:为什么“同一套代码,同一个接口,相同的请求参数,两个环境一个正常一个中文乱码”

但是为什么另一个接口却没有返回乱码呢?

于是继续查看代码,发现在出问题这个接口内部,使用了spring的@Cacheable注解,而另一个正常的接口内部没有实用该注解。我们的系统依赖该注解实现了基于redis的自定义缓存中间件。难道问题与缓存中间件有关?尝试将@Cacheable注解去除,重新部署服务到dev环境,调用之前乱码的接口,乱码消失

看来基本可以确定问题出现在该缓存中间件上。继续深入缓存中间件源码,发现在String与bytes[]互转的过程中,并没有设置charset(例如UTF-8),这样在转换过程中将使用系统默认charset,于是导致乱码。联系相关老司机修改此处后,故障消失

小结

中文乱码问题是开发中常见的问题之一,特别是在web环境下,由于环节众多,链路较长,任何一个环节的编解码错误都有可能导致此问题。因此排查过程不可人云亦云,随便一百度就认为万事大吉(比如CharacterEncodingFilter并不能解决我这次遇到的这个问题),还是要搞清原理,结合实际情况,根据现象逐步排查。与君共勉

你可能感兴趣的:(老司机翻车记--记一次中文乱码错误排查)