失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 作为程序员 你有过一个简单bug查询了很久才解决的经历吗? – 网络

作为程序员 你有过一个简单bug查询了很久才解决的经历吗? – 网络

时间:2018-10-03 00:17:25

相关推荐

作为程序员 你有过一个简单bug查询了很久才解决的经历吗? – 网络

第一个要分享的bug,是Java语言通过HTTP客户端RestTemplate调用弱语言PHP封装的HTTP接口引起的,对方将配置数据,处理成JSON提供给偶,其数据结构如下:

[{

“operateWord”:”测试1″,

“title”:”测试1″,

“url”:””

},{

“operateWord”:”测试2″,

“title”:”测试2″,

“url”:””

}]

Java这边通过对象的列表来接收java.util.List<Banner>

@Setter

@Getter

publicclassBanner{

privateStringoperateWord;

privateStringtitle;

privateStringurl;

}

自测验证,测试通过后上线,偶尔会出现可用率降低的情况,其异常日志的主要信息如下

java.lang.ClassCastException:com.alibaba.fastjson.JSONObjectcannotbecasttocom.alibaba.fastjson.JSONArray

后来此问题延续了一段时间,通过偶这边的出入参日志,和对方的接口日志,来配合复现,当该JSON中只有一个元素时,数据结构会由对象数组退化为对象,即当该返回值只有一个元素时,其返回结果如下:

{

“operateWord”:”测试2″,

“title”:”测试2″,

“url”:””

}

而Java这边是强一致语言,仍通过对象的数组去接收,如何能成功接收呢?随后,PHP侧的接口同事将其提供的返回值数据结构进行格式化,确保任何时候都返回对象的数组的JSON数据结构,Java这边就可以正常解析了。大家需要关注的是:弱语言的返回值,可能因元素个数的不同而转化其数据结构,从而在与Java的交互中出问题。

第二个要分享的bug是,RestTemplate使用过程中的不规范编码问题,对其通过Bean机制创建共享服务理解不透导致。通过RestTemplate获取配置信息,测试上线,7天时间内,无任何问题,时间一长,可用率陆陆续续下降,重启docker服务,该接口的可用率恢复,出现的异常信息如下

org.springframework.web.client.RestTemplate-GETrequestfor”http://xxx”resultedin400(BadRequest);invokingerrorhandler

Exceptioninthread”main”org.springframework.web.client.HttpClientErrorException:400BadRequest

atorg.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:88)

atorg.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:532)

由于400这个状态码,第一感觉就是对方接口有变更,从而引起偶的业务可用率下降。经对方同事排期,其7天内无任何变更,和偶这边的应用部署时间一致。近一个月的时间内,只能通过重启保障线上业务的正常可用。而偶这边在预发环境对该接口进行了多次压测,发现该400的状态可以复现。复现后,发现RestTemplate的请求头信息过大,已超过4k。再和代码对照起来看,将RestTemplate初始化Bean之后,在service代码中,不断的设置头信息,即

publicclassWxMappingJackson2HttpMessageConverterextendsMappingJackson2HttpMessageConverter{

privateObjectMapperobjectMapper=newObjectMapper();

publicWxMappingJackson2HttpMessageConverter(){

List<MediaType>mediaTypes=newArrayList<MediaType>();

mediaTypes.add(newMediaType(“text”,”html”,Charset.forName(“UTF-8”)));

mediaTypes.add(newMediaType(“text”,”plain”,Charset.forName(“UTF-8”)));//加入text/html类型的支持

setSupportedMediaTypes(mediaTypes);//tag6

objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY,true);

setObjectMapper(objectMapper);

}

}

privatefinalstaticWxMappingJackson2HttpMessageConverterhttpMessageConverter=newWxMappingJackson2HttpMessageConverter();

restTemplate.getMessageConverters().add(httpMessageConverter);

该请求头过大,而ngix默认的请求头信息限制4k,当超时4k时,拒绝提供服务,从而导致400的状态码。

这两个bug,都是线上正常运行一段时间后,才出现的,这种往往更恼火,在测试阶段很隐蔽,线上出现之后,也不是很容易排查。编写代码时,还是需要用心去写,尽量避免这些bug呢。

作者:夕阳雨晴,偶的:偶尔美文,主流Java,为你讲述不一样的码农生活。

如果觉得《作为程序员 你有过一个简单bug查询了很久才解决的经历吗? – 网络》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。