当前位置: 首页 > news >正文

记一次远程API调用失败

记一次远程API调用失败

最近开发忙,项目紧,系统出现一些忽隐忽现的问题,本地也不能复现,当时也无法理解,就先搁置了,现在回想起来,这里还是明智的。

这个bug很神奇

  • 今天,原本好好的API,突然抽风爆出数据转换异常,看看异常信息,指向一个远程调用API response json转换异常

  • 2020-04-09 15:12:57.236 DEBUG 22236 --- [http-nio-9010-exec-2] c.l.framework.remote.crm.CrmRemoteApi    : [CrmRemoteApi#getProviderType] ---> POST http://micro-service-crm/remote/provider/type/list HTTP/1.1
    2020-04-09 15:13:02.336 DEBUG 22236 --- [http-nio-9010-exec-5] c.l.framework.remote.crm.CrmRemoteApi    : [CrmRemoteApi#getProviderType] <--- HTTP/1.1 200 (5133ms)
    2020-04-09 15:13:02.339 ERROR 22236 --- [http-nio-9010-exec-5] c.l.f.exception.GlobleExceptionHandler   : Exception:Error while extracting response for type [java.util.List<com.lansen.framework.dto.provider.CrmMaterialInfoPartnerEntity>] and content type [application/json;charset=utf-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT tokenat [Source: (PushbackInputStream); line: 1, column: 1]feign.codec.DecodeException: Error while extracting response for type [java.util.List<com.lansen.framework.dto.provider.CrmMaterialInfoPartnerEntity>] and content type [application/json;charset=utf-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT tokenat [Source: (PushbackInputStream); line: 1, column: 1]at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:180)at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:140)at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)at com.sun.proxy.$Proxy213.getProviderType(Unknown Source)
    
  • 这个问题应该不难,看了一下异常远程API

  •     @Overridepublic List<Map<String, String>> getProviderType(List<String> materialNos) {return crmMaterialInfoPartnerService.getProviderType(materialNos);}
    
  • 看代码返回值不符合开发规范**(开发规范返回值不能使用Map,必须是具体实体类)**,找了一下负责这个模块功能的开发者“乐宝”(乐宝是我们项目组的一位呆萌男孩,是个态度和工作都很努力的大眼小伙儿,遇到问题总是眼睛瞳孔放大,眼神一片迷茫还伴随着不断点头,总之非常可爱),简单讲解了一下异常信息,把这个问题交给“乐宝”解决。下午的时候找到乐宝,问了一下修复情况,乐宝还是一头雾水,看我过来了,试探问是不是我这个返回实体有包含自己的情况

  • public class CrmMaterialInfoPartnerEntity extends BaseEntity {@TableField(exist = false)List<CrmMaterialInfoPartnerEntity> materialList;
    }
    
  • 想到这点,他赶紧删掉测了一圈,问题还是一样,由于时间紧,这块儿自引用先按下不表,叮嘱乐宝先尝试解决,不行就换一种写法试试,经过了几轮儿排查,不知不觉已经是下午6点了,乐宝说改好了,代码提交开始发测试版本,版本发完测试验证问题依然存在,乐宝本地验证没问题,不过他发现第一次是正常的,清理了redis,问题就出现了,这问题奇怪了,怎么会跟redis有关系呢,顿时陷入了沉思中…

这个bug很调皮

  • 乐宝说返回List集合的接口都有问题,他已经修复了2个模块了,测试后仍然报错,找不到问题的原因,先让乐宝保留本地修改的代码,暂不提交。我开始盯着代码思考这个问题,一般这种转换异常的问题,要么是返回值映射有问题,要么是传参映射有问题,顺着这两个思路我打开了debug模式,A服务远程调用B服务,先检查B服务有没有接收到请求,排查B服务收到了请求,但是B服务还未响应请求,A服务突然报错了what???…

  • 沉思中时,老大哥也过来帮忙排查,我俩简单同步问题信息后,定位到gateway的feign调用超时问题,开始修改配置,把超时时间设置大些,把redis超时时间也调大,正在尝试测试时,另一个项目组也模拟出一种偶现问题,调用远程API时提示强制退出登录,这是什么情况?猜测两个问题应该来源一个出处,为什么远程API会跟redis有关系呢?于是过去看了一下强制退出登录的问题,也没摸到头绪,回来时老大哥模拟出来一种新思路,服务刚启动时清空redis问题会出现,这时候把远程服务重启,再次清理redis发现问题没有了,重新整理思路,代码开始在脑子里浮现,每一个服务都有一个权限认证拦截器,只有这里使用到了redis,难道是这里出现的问题?废话不多说,开始在这里debug,一番排查后,发现远程服务验证token时候出错了,根据报错信息还是很难分辨出为什么异常,老大哥提出我们在这里打一下token看一下调用时候token有什么问题,

  • 2020-04-09 18:53:33.913 DEBUG 15880 --- [http-nio-9002-exec-2] c.l.f.web.filter.BaseInterceptor         : 当前访问URL:/remote/provider/type/list,
    redis  token: eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJkMWMyNzExNC1mZmU2LTQ0MTktODMzNC1hNjQwNjQ5YTYwODQiLCJpc3MiOiJKV1QiLCJzdWIiOiJ7XCJ1c2VySWRcIjpcImQ3YzNlNmY0NGMwMmUxMmM2NTVjOGRmM2NhZDM3MDFkXCIsXCJ1c2VyTmFtZVwiOlwiYW5kZXJzXCIsXCJ0eXBlXCI6XCJhY2NvdW50XCIsXCJhcHBsaWNhdGlvbklkXCI6XCJiMmFlZmNhMmI4YjA0YzJiYTEyZGYwY2JlZTkwdDJjZVwiLFwidGltZVwiOjE1ODY0Mjk1NjgzMzB9IiwiaWF0IjoxNTg2NDI5NTY4LCJleHAiOjE1ODcwMzQzNjh9.uvWNCUZR9JucS5aBdKdNui8bPxXVlXW_-wD1-pbt4rI 
    remote token: eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJjMjQ0MmZjYy1mM2QxLTRjMzEtOTc5Yi00NDlhNTg4ZTRmMjMiLCJpc3MiOiJKV1QiLCJzdWIiOiJ7XCJ1c2VySWRcIjpcImQ3YzNlNmY0NGMwMmUxMmM2NTVjOGRmM2NhZDM3MDFkXCIsXCJ1c2VyTmFtZVwiOlwiYW5kZXJzXCIsXCJ0eXBlXCI6XCJhY2NvdW50XCIsXCJhcHBsaWNhdGlvbklkXCI6XCJiMmFlZmNhMmI4YjA0YzJiYTEyZGYwY2JlZTkwdDJjZVwiLFwidGltZVwiOjE1ODY0MzA1NTI2MTh9IiwiaWF0IjoxNTg2NDMwNTUyLCJleHAiOjE1ODcwMzUzNTJ9.SdqEVuVfUn7oPOoYZmVTwugONbfg8Vy12W2ffpNqdnM
    

两次token不一致,why???

  • 只有远程API调用的时候token不一致,检查了一遍认证拦截器,没有发现异常问题,突然想到了远程API的feign拦截器,打开代码一看,恍然大悟,就是这里了

  •     @Overridepublic void apply(RequestTemplate requestTemplate) {FeignRequestContext feignRequestContext = FeignRequestContextLocal.getInstance().get();if (Objects.nonNull(feignRequestContext)) {requestTemplate.headers(feignRequestContext.buildHeaders());}else if(Objects.nonNull(CommonUtils.getRequest())) {requestTemplate.headers(getHeads(CommonUtils.getRequest()));}}private Map<String, Collection<String>> getHeads(HttpServletRequest request) {FeignRequestContext feignRequestContext = new FeignRequestContext(request);FeignRequestContextLocal.getInstance().set(feignRequestContext);return feignRequestContext.buildHeaders();}
    
  • 由于有异步处理的业务场景,这里使用了线程变量存储远程上下文参数,这里没有考虑到清理,去掉这里的线程变量,程序运行舒畅了,到此问题圆满解决了,真是一场深刻的bug排查。

相关文章:

记一次远程API调用失败

记一次远程API调用失败 最近开发忙&#xff0c;项目紧&#xff0c;系统出现一些忽隐忽现的问题&#xff0c;本地也不能复现&#xff0c;当时也无法理解&#xff0c;就先搁置了&#xff0c;现在回想起来&#xff0c;这里还是明智的。 这个bug很神奇 今天&#xff0c;原本好好的…...

【力扣】746.使用最小花费爬楼梯

题目描述 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费。 示例…...

06:【stm32】中断一:NVIC的配置

中断 1、中断的简介1.1、什么是中断1.2、为什么需要中断 2、中断的优先级2.1、中断优先级的表示方法 3、NVIC3.1、什么的NVIC3.2、NVIC的内部结构3.3、中断向量表3.4、程序实现①开启中断源②配置NVIC③中断响应函数 1、中断的简介 1.1、什么是中断 正在进行的事务被突发事件打…...

Flutter简介

Flutter是一个由Google开发的开源移动UI框架&#xff0c;它允许开发者使用Dart语言来构建高性能、高保真的iOS和Android应用。Flutter的设计理念是"编写一次&#xff0c;到处运行"&#xff08;write once, run everywhere&#xff09;&#xff0c;这意味着开发者可以…...

WT2605C蓝牙语音芯片赋能对讲机新体验:无屏操控、音频解码与蓝牙音箱三合一

一、产品概况 对讲机市场是一个技术成熟且具有广泛应用前景的市场。对讲机作为无线通信设备的一种&#xff0c;在许多不同的领域和业务中发挥着重要作用。从技术发展角度来看&#xff0c;对讲机经历了从模拟到数字的转型&#xff0c;以及从简单通信工具向多功能设备的演进。当…...

ctfshow-web入门-sql注入(web191-web195)

目录 1、web191 2、web192 3、web193 4、web194 5、web195 1、web191 过滤了 ascii 使用 ord 代替&#xff1a; import requests import string url "http://a585c278-320a-40e7-841f-109b1e394caa.challenge.ctf.show/api/index.php" out for j in range(1…...

【ARM】v8架构programmer guide(3)_ARMv8的寄存器

目录 4.ARMv8 registers 4.1 AArch64 特殊寄存器 4.1.1 Zero register 4.1.2 Stack pointer &#xff08;SP) 4.1.3 Program Counter &#xff08;PC) 4.1.4 Exception Link Register(ELR) 4.1.5 Saved Process Status Register &#xff08;SPSR&#xff09; 4.2 Proc…...

SpringIOC整合dbUtil做的增删改查以及转账业务的实现

目录 一、xml方式实现 1.介绍lombok插件 2.功能 3.步骤 3.1 idea安装插件(只做一次) 3.2 添加坐标 3.3 编写注解 4.核心类 4.1 QueryRunner 4.2 query() 查询 4.3 update() 增删改 5.配置文件applicationContext.xml 6.junit测试 6.1使用步骤 6.1.1 坐标 6.1.2…...

【Nacos无压力源码领读】(二) 集成 LoadBanlancer 与 OpenFeign

上一篇文章中, 详细介绍了 Nacos 注册中心的原理, 相信看完后, 大家应该完全掌握了 Nacos 客户端是如何自动进行服务注册的, 以及 Nacos 客户端是如何订阅服务实例信息的, 以及 Nacos 服务器是如何处理客户端的注册和订阅请求的; 本文承上启下, 在订阅服务实例的基础上, 介绍如…...

CP AUTOSAR标准之DefaultErrorTracer(AUTOSAR_SWS_DefaultErrorTracer)(更新中……)

1 简介和功能概述 本规范描述了默认错误跟踪器的API。基础软件中检测到的所有开发和运行时错误都会报告给此模块。API参数允许跟踪错误来源和类型: 检测到错误的模块检测到错误的函数错误类型此模块API背后的功能不在本规范的范围内。软件开发人员和软件集成商应根据其特定应用…...

SpringMVC (发送请求——>参数传递—— >响应数据)

设置请求访问路径 RequestMapper&#xff1a;将请求访问路径和我们业务层的方法联系起来 ResponseBody&#xff1a;将我们业务层方法的返回值转化为json&#xff0c;xml或其他格式的数据返回给页面 两种请求 get请求 post请求 测试案例 RequestMapping("/getNameAndAge&…...

认识Modbus RTU与Modbus TCP

&#xff08;选自成都纵横智控-Modbus RTU与Modbus TCP协议区别详解 &#xff09; Modbus RTU 和 Modbus TCP 是两种常用的工业通信协议&#xff0c;用于连接电子设备&#xff0c;但它们在多方面有所不同。以下是它们的详细比较&#xff1a; Modbus RTU 协议类型&#xff1a; …...

如何在 Kubernetes 中使用 ClickHouse 和 JuiceFS

ClickHouse 结合 JuiceFS 一直是一个热门的组合&#xff0c;社区中有多篇实践案例。今天的文章来自美国公司 Altinity&#xff0c;一家提供 ClickHouse 商业服务的企业&#xff0c;作者是 Vitaliy Zakaznikov&#xff0c;他尝试了这个组合并公开了过程中使用的代码。原文有两篇…...

云计算任务调度优化matlab仿真,对比蚁群优化和蛙跳优化

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 ACO蚁群优化 4.2 蛙跳优化 5.完整程序 1.程序功能描述 云计算任务调度优化,优化目标位任务消耗时间&#xff0c;调度后的经济效益以及设备功耗&#xff0c;对比蚁群优化算法和蛙跳优化…...

基于双PI+EKF扩展卡尔曼滤波的PMSM速度控制simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 PMSM数学模型 4.2 双PI控制器设计 4.3 扩展卡尔曼滤波器(EKF) 4.4 控制系统实现 5.完整工程文件 1.课题概述 基于双PIEKF扩展卡尔曼滤波的PMSM速度控制simulink建模与仿真。对比基于双PI的扩展卡…...

医疗器械注册资源宝库数屿医械官方平台!

医学影像设备市场作为医疗器械领域的佼佼者&#xff0c;技术门槛高且规模庞大&#xff0c;2021年全球规模达458亿美元&#xff0c;预计2022年逼近500亿美元&#xff0c;增长动力源自技术革新与临床需求攀升。中国市场亦不甘落后&#xff0c;受政策驱动与市场需求双重提振&#…...

Django如何移除数据库字段?

关键步骤&#xff1a; 第一步&#xff1a;python manage.py makemigrations 你的项目名称第二步&#xff1a; python manage.py migrate (.venv) PS D:\python_workpace\django_xitong_shezhi\pythonProject\myproject> python manage.py makemigrations myproject Migra…...

阶段项目——拼图小游戏

Java学习笔记&#xff08;新手纯小白向&#xff09; 第一章 JAVA基础概念 第二章 JAVA安装和环境配置 第三章 IntelliJ IDEA安装 第四章 运算符 第五章 运算符联系 第六章 判断与循环 第七章 判断与循环练习 第八章 循环高级综合 第九章 数组介绍及其内存图 第十章 数…...

基于本地消息表实现分布式事务(最终一致性)

前言 传统单体架构下&#xff0c;所有的功能模块都在一个应用下&#xff0c;所有的代码和业务逻辑都在同一个应用下实现&#xff0c;所以保证数据的一致性就很简单&#xff0c;保证相关操作都在同一个本地事务下就可以了。 但是在微服务架构下&#xff0c;将一个应用拆分成了…...

大数据mapper书写范式hdfs

文章目录 1. 大数据mapper书写范式hdfs 1. 大数据mapper书写范式hdfs import json import sysdef read_input(input_stream):for line in input_stream:yield line.rstrip(\n)def load_json_data(json_line):try:data json.loads(json_line)unique_id data.get(id)combined_…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

二维FDTD算法仿真

二维FDTD算法仿真&#xff0c;并带完全匹配层&#xff0c;输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...