file

图中是程序员日常解决产线问题的图。

为了增加趣味性。 我编了一个故事。

日常踩坑故事

故事背景

在一家互联网公司,产品经理小李和架构师老李正在紧急处理一个用户反馈的问题:工单导出数据时出现了500错误,用户的需求是能够顺利导出数据。小李心中焦急,因为这个问题直接影响到用户的使用体验。

故事开始

小李:老李,我刚收到反馈,用户在导出工单数据时遇到500错误。是不是上次我们限制导出最大1000条数据的设置出了问题?

老李:这很有可能。我们先从日志入手查一下,找出具体的错误信息。

(老李打开日志,查看相关的traceId:fdqdukxbuesv

老李:看这里,前端的报错信息显示了FeignException.clientErrorStatus,这表明在调用接口时遇到了问题。

小李:具体是什么问题?

老李:根据调用的代码,有几个关键点。首先,我们使用GET方法来传递参数,但是当参数过长时,会超出URL的限制,导致请求失败。

问题分析

(老李翻看代码,定位到具体的接口)

老李:这个接口是/dict/item/open/getTreeByLabel,我们发现传递的itemIds参数没有去重,可能导致请求的URL过长。此外,底层实现也没有有效去重,效率低下。

小李:那我们该如何解决这个问题?

老李:我们可以快速修复一下:在导出工单时,先对工单类型进行去重,确保传递的参数不会超过限制。同时,长远来看,我们应该将接口协议改为POST方法,将参数放到请求体中,避免URL长度限制。

解决方案

(老李开始修复代码)

老李:我会先在代码中添加去重逻辑,并将协议改为POST。这样就可以避免参数过长的问题,我们再进行一次测试。

(老李完成代码,并进行测试)

小李:测试结果如何?

老李:测试通过了,工单数据成功导出了。不过,为了进一步提升性能,我还建议在整个链路中,尽早进行去重处理,这样从源头开始就能减少传递的参数量。

小结与反思

小李:感谢老李,看来日志系统真的能帮助我们快速定位问题。以后在设计接口时,我们也要注意参数的传递方式,尤其是集合类型的参数。

老李:对,尤其是使用Feign时,集合参数一定要使用@RequestBody来传递,以避免超出URL长度限制。我们还要考虑到高效的代码实现和用户体验,去重也是一个重要的优化方向。

(两人相视一笑,心中都有了新的思路,为接下来的工作打下了基础。)

故事结尾

在这个解决问题的过程中,小李和老李不仅解决了用户的痛点,还建立了更为紧密的合作关系。他们明白了在技术实现上,如何兼顾用户需求与系统性能的重要性,提升了整个团队的响应能力和效率。

下面是实际的工作日常。

问题反馈

工单导出数据报500,有印象是上次限制导出Max1000条数据是不?

![file](http://lifcpu
lic.oss-cn-shenzhen.aliyuncs.com/15243_769A51FBFB654C82991819635F2DA357)

目标

解决问题,让导出可以正常进行;

解决过程

找日志。

traceId:"fdqdukxbuesv" and level:ERROR

前端报错日志:

file

at feign.FeignException.clientErrorStatus(FeignException.java:213)
    at feign.FeignException.errorStatus(FeignException.java:194)
    at feign.FeignException.errorStatus(FeignException.java:185)
    at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:92)
    at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:98)
    at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:141)
    at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:91)
    at com.vvvd.xxx.common.sentinel.feign.PigxSentinelInvocationHandler.invoke(PigxSentinelInvocationHandler.java:99)
    at org.springframework.cloud.openfeign.FeignCachingInvocationHandlerFactory$1.proceed(FeignCachingInvocationHandlerFactory.java:66)
    at org.springframework.cache.interceptor.CacheInterceptor.lambda$invoke$0(CacheInterceptor.java:54)
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:351)
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:64)
    at org.springframework.cloud.openfeign.FeignCachingInvocationHandlerFactory.lambda$create$1(FeignCachingInvocationHandlerFactory.java:53)
    at com.sun.proxy.$Proxy226.getTreeByLabel(Unknown Source)
    at com.pig4cloud..crm.controller.TicketInfoV2Controller.export(TicketInfoV2Controller.java:111)

定位到代码:

file

**
     * 根据子节点查找父级内容,返回label  xx/xx/xx
     * @param itemIds
     * @param language
     * @param from
     * @return
     */
    @GetMapping("/dict/item/open/getTreeByLabel")
    R<Map<Long,String>> getTreeByLabel(@RequestParam(value = "itemIds") List<Long> itemIds, @RequestParam(value = "language") String language, @RequestHeader(SecurityConstants.FROM) String from);

可以看出两个问题,

1 个是参数太长了,没有去重;

2 接口协议使用的是GET , RequestParam ,这个协议是有参数长度限制的;

3 底层实现接口也需要去重增加效率,大概率是递归的处理方式。

最快的解决客户问题,让他可用的方法是结合业务逻辑, 甲方导出工单数据,它的工单类型去重之后不会太多。

修复代码:

file

彻底修复的方法还需做到第2步,协议也要修改,改为post方法,集合类型的参数放到body中;

file

file

改完之后,走一遍测试。

file

file

实现方法过滤。

file

小结

  1. 要善于使用日志系统定位问题,可以找到是对应的哪个类哪一行代码报错了;
  2. Feign协议定义,如果参数是集合类型,一定要使用@RequestBody,否则会报错, url中的参数长度是有最大长度的;
  3. 要提高处理效率,一定要注意去重,从整个链路分析来看,从源头开始去重效果最显著;
原创不易,关注诚可贵,转发价更高!转载请注明出处,让我们互通有无,共同进步,欢迎沟通交流。

李福春
119 声望11 粉丝

code for life .