使用@sap-cloud-sdk/http-client调用接口时出现重复请求问题排查
我们使用SAP Cloud SDK的@sap-cloud-sdk/http-client库的executeHttpRequest函数,通过Cloud Connector向本地收敛mediation系统发送请求,连接依赖BTP子账户中维护的Destination。但出现异常:调用特定端点的微服务时,明明只发起一次请求,Cloud Connector日志却显示同时触发了三次请求。
代码示例:
const { executeHttpRequest } = require('@sap-cloud-sdk/http-client'); const express = require('express'); const app = express(); app.use(express.json()); app.post('/xyz', async (req, res) => { try { async function callPostApi(req, destination) { const response = await executeHttpRequest( { destinationName: destination, }, { method: 'POST', url: req.url, data: req.body, maxContentLength: Infinity, maxBodyLength: Infinity, headers: { "Content-Type": "application/json" }, } ); return response.data; } const responseData = await callPostApi(req, "Destination Name"); res.status(200).send(responseData); } catch (error) { console.error('Error:', error); res.status(500).send({ message: "An error occurred", error }); } });
原因1:SAP Cloud SDK默认重试机制触发
executeHttpRequest默认自带重试逻辑,当遇到5xx状态码、部分4xx状态码或连接超时等情况时,会自动重试请求。如果本地mediation系统响应慢,或者返回了触发重试的状态码,就会导致Cloud Connector收到多次请求。解决方案:在请求配置里显式关闭重试,添加
disableRetry: true参数:const response = await executeHttpRequest( { destinationName: destination, }, { method: 'POST', url: req.url, data: req.body, maxContentLength: Infinity, maxBodyLength: Infinity, headers: { "Content-Type": "application/json" }, disableRetry: true // 关闭默认重试逻辑 } );原因2:Destination健康检查产生额外请求
BTP的Destination如果开启了自动健康检查,会定期向目标端点发送请求验证连通性。如果健康检查的端点和你调用的业务端点一致,就会在业务请求的同时出现额外日志。解决方案:登录BTP子账户查看对应Destination的配置,若不需要健康检查直接关闭;或者调整健康检查的端点路径,避免和业务请求路径重叠。
原因3:Cloud Connector连接探测请求
Cloud Connector在建立或恢复连接时,会发送探测请求验证通道可用性,这类请求会被记录在日志中,看起来像是额外的业务请求。通常这类请求会是OPTIONS方法,或者路径有明显探测特征。解决方案:如果是正常的连接探测,属于Cloud Connector的机制,无需特殊处理;若探测请求过于频繁影响业务,可调整Cloud Connector的连接空闲超时设置,减少重新连接的频率。
原因4:代码中存在隐式重复调用
检查Express路由是否被多次注册,或者是否有中间件意外触发了请求转发。比如是否在其他地方重复定义了app.post('/xyz', ...),或者全局中间件导致请求被重复处理。解决方案:排查代码逻辑,确保路由只注册一次,且没有中间件会重复触发请求调用。
内容的提问来源于stack exchange,提问作者user27061034

