一、什么是多接口依赖场景
在开发中,我们经常会遇到需要调用多个接口来完成一个完整业务功能的情况,这就是多接口依赖场景。比如说,我们要开发一个电商平台的商品详情页面,这个页面需要展示商品的基本信息、评论信息以及库存信息。而这三种信息可能分别来自三个不同的接口。要先调用商品基本信息接口,然后根据这个接口返回的商品 ID 去调用评论信息接口和库存信息接口。
这种场景很常见,像社交平台展示用户信息,需要调用用户基本信息接口、用户动态接口和用户好友接口;新闻资讯类应用展示一篇新闻详情,需要调用新闻内容接口、相关评论接口和推荐新闻接口等等。
二、前置请求失败可能带来的问题
2.1 页面显示异常
还以电商平台商品详情页为例,如果商品基本信息接口请求失败,后面的评论信息接口和库存信息接口就没办法正常获取商品 ID 进行调用。这时候页面可能就会显示异常,比如只显示部分信息,或者干脆一片空白,影响用户体验。
2.2 业务流程中断
在一些复杂的业务流程中,比如在线支付流程。需要先调用订单信息接口获取订单详情,然后根据订单信息调用支付接口。如果订单信息接口请求失败,支付流程就无法继续进行,业务就中断了。
三、常见的容错逻辑处理方法
3.1 重试机制
3.1.1 简介
重试机制就是在接口请求失败后,重新发起请求,尝试几次后再确定是否真的失败。一般来说,请求失败可能是因为网络波动等临时原因,重试几次也许就能成功。
3.1.2 示例(以 JavaScript 为例)
async function requestWithRetry(url, maxRetries = 3) {
let retries = 0;
while (retries < maxRetries) {
try {
const response = await fetch(url); // 发起请求
if (response.ok) { // 判断请求是否成功
return response.json(); // 成功则返回响应数据
}
} catch (error) {
console.log(`请求失败,错误信息:${error.message},正在进行第 ${retries + 1} 次重试`);
}
retries++;
}
console.log('达到最大重试次数,请求失败');
return null;
}
// 使用示例
const apiUrl = 'https://example.com/api/data';
requestWithRetry(apiUrl).then(data => {
if (data) {
console.log('请求成功,数据为:', data);
}
});
3.1.3 优缺点
优点是可以在一定程度上解决由于网络波动等临时问题导致的请求失败,提高请求的成功率。缺点是如果问题是由于接口本身故障或者参数错误导致的,重试也不会成功,还会浪费系统资源。
3.2 降级处理
3.2.1 简介
降级处理就是当某个接口请求失败时,提供一个默认值或者简化的处理方式,保证业务流程能够继续进行。比如说在电商商品详情页,如果商品基本信息接口请求失败,就给页面展示一个默认的商品图片和通用的商品描述。
3.2.2 示例(以 Python 为例)
import requests
def get_product_info():
try:
response = requests.get('https://example.com/api/product_info')
if response.status_code == 200:
return response.json() # 请求成功返回商品信息
except requests.RequestException:
pass
# 请求失败,返回默认商品信息
return {
"name": "默认商品",
"price": "暂无价格",
"description": "这是一个默认商品描述"
}
product_info = get_product_info()
print(product_info)
3.2.3 优缺点
优点是可以保证业务流程的基本可用性,即使接口请求失败,用户也能看到一些基本信息。缺点是提供的默认值可能不够准确,不能满足所有用户的需求。
3.3 熔断机制
3.3.1 简介
熔断机制就像电路中的保险丝,当接口请求失败率达到一定阈值时,就暂时停止对该接口的请求,避免对系统造成更大的压力。过一段时间后,再尝试恢复请求。
3.3.2 示例(以 Java 为例)
import java.util.concurrent.atomic.AtomicInteger;
public class CircuitBreaker {
private static final int FAILURE_THRESHOLD = 5; // 失败阈值
private static final int TIMEOUT = 10000; // 超时时间,单位:毫秒
private AtomicInteger failureCount = new AtomicInteger(0);
private long lastFailureTime = 0;
public boolean allowRequest() {
if (failureCount.get() >= FAILURE_THRESHOLD) {
long currentTime = System.currentTimeMillis();
if (currentTime - lastFailureTime > TIMEOUT) {
// 超时,重置熔断状态
failureCount.set(0);
} else {
return false; // 熔断状态,不允许请求
}
}
return true;
}
public void recordFailure() {
failureCount.incrementAndGet();
lastFailureTime = System.currentTimeMillis();
}
public static void main(String[] args) {
CircuitBreaker breaker = new CircuitBreaker();
if (breaker.allowRequest()) {
try {
// 发起接口请求
// 模拟请求失败
throw new RuntimeException("请求失败");
} catch (Exception e) {
breaker.recordFailure();
System.out.println("请求失败,已记录失败次数");
}
} else {
System.out.println("处于熔断状态,不允许请求");
}
}
}
3.3.3 优缺点
优点是可以保护系统,避免因某个接口故障导致整个系统崩溃。缺点是当接口恢复正常时,可能需要一定时间才能恢复对该接口的请求,影响业务的及时性。
四、在 Insomnia 中实现容错逻辑
4.1 Insomnia 简介
Insomnia 是一款强大的 API 测试工具,它可以帮助我们方便地管理和测试 API 请求。它支持多种请求方法,如 GET、POST、PUT 等,还可以对请求参数、请求头、请求体等进行自定义设置。
4.2 配置重试机制
在 Insomnia 中,我们可以通过编写脚本的方式来实现重试机制。以下是一个简单的示例:
/**
* 使用 Insomnia 的 beforeRequest 钩子实现重试机制
* @param {Object} context - Insomnia 请求上下文
*/
module.exports = async (context) => {
const maxRetries = 3;
let retries = 0;
while (retries < maxRetries) {
try {
const response = await context.http.send(context.request); // 发起请求
if (response.status >= 200 && response.status < 300) { // 判断请求是否成功
return;
}
} catch (error) {
console.log(`请求失败,错误信息:${error.message},正在进行第 ${retries + 1} 次重试`);
}
retries++;
}
console.log('达到最大重试次数,请求失败');
};
将上述脚本保存为一个 .js 文件,然后在 Insomnia 的请求设置中,找到 “Pre-request Scripts” 选项,引入该脚本。这样,当请求失败时,就会自动进行重试。
4.3 配置降级处理
要在 Insomnia 中实现降级处理,我们可以在请求失败后,使用脚本返回一个默认的响应数据。示例如下:
/**
* 使用 Insomnia 的 afterRequest 钩子实现降级处理
* @param {Object} context - Insomnia 请求上下文
* @param {Object} response - 请求的响应信息
*/
module.exports = async (context, response) => {
if (response.status >= 400) { // 判断请求是否失败
const defaultResponse = {
status: 200,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: '这是默认响应数据'
})
};
// 使用默认响应数据替换原响应数据
context.http.respond(defaultResponse);
}
};
同样,将上述脚本保存为 .js 文件,在 Insomnia 的请求设置中,找到 “Post-request Scripts” 选项,引入该脚本。当请求失败时,就会返回预设的默认响应数据。
五、应用场景分析
5.1 实时交易系统
在实时交易系统中,涉及多个接口的调用,如查询用户余额接口、验证交易密码接口、扣除余额接口等。如果查询用户余额接口请求失败,使用重试机制可以在网络波动等情况下保证交易流程的继续进行;如果重试多次仍失败,可以使用降级处理,给用户提示“暂时无法查询余额,请稍后重试”,避免交易流程中断。
5.2 内容展示系统
像网页新闻展示系统,需要调用文章内容接口、图片接口和相关推荐接口。如果图片接口请求失败,使用降级处理展示默认图片,能保证页面的基本展示效果;如果文章内容接口请求失败率过高,使用熔断机制可以避免对系统造成更大压力,同时给用户提示“暂时无法获取文章内容,请稍后重试”。
六、技术优缺点总结
6.1 重试机制
优点:简单易行,能解决部分临时问题导致的请求失败,提高请求成功率。 缺点:对于接口本身故障或参数错误导致的失败无效,可能浪费系统资源。
6.2 降级处理
优点:保证业务基本可用性,即使请求失败用户也能看到部分信息。 缺点:默认值可能不够准确,不能满足所有用户需求。
6.3 熔断机制
优点:保护系统,避免因单个接口故障导致系统崩溃。 缺点:接口恢复正常时,恢复请求需一定时间,影响业务及时性。
七、注意事项
7.1 重试次数和间隔时间
在使用重试机制时,要合理设置重试次数和重试间隔时间。重试次数过多会浪费系统资源,间隔时间过短可能在问题未解决时就再次发起请求。
7.2 默认值的准确性
在进行降级处理时,要确保默认值的准确性和合理性。比如商品价格的默认值不能设置为一个明显不合理的数字。
7.3 熔断阈值和恢复时间
使用熔断机制时,要根据接口的实际使用情况和业务需求,合理设置熔断阈值和恢复时间。阈值设置过低可能导致频繁熔断,影响业务;恢复时间设置过长会影响业务的恢复速度。
八、文章总结
在多接口依赖场景下,前置请求失败的情况很常见,我们需要使用合适的容错逻辑来处理这些问题。重试机制、降级处理和熔断机制是三种常用的容错方法,它们各有优缺点。在实际开发中,我们可以根据具体的业务场景选择合适的容错方法,也可以将多种方法结合使用。Insomnia 作为一款强大的 API 测试工具,为我们实现容错逻辑提供了便利。通过编写脚本,我们可以在 Insomnia 中轻松配置重试机制和降级处理等容错逻辑。同时,在使用这些技术时,要注意一些细节,如重试次数、默认值准确性和熔断阈值等,以确保系统的稳定性和可靠性。
评论
围绕“Insomnia请求链编排:多接口依赖场景下如何处理前置请求失败的容错逻辑”参与讨论