知道这10个让你的API接口突然超时的原因吗?

这篇具有很好参考价值的文章主要介绍了知道这10个让你的API接口突然超时的原因吗?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

不知道你有没有遇到过这样的场景:我们提供的某个API接口响应时间原本一直都很快,但在某个不经意的时间点,突然出现了接口超时

也许你会有点懵,到底是为什么呢?

今天跟大家一起聊聊接口突然超时的10个原因,希望对你会有所帮助。

1.网络异常

接口原本好好的,突然出现超时,最常见的原因,可能是网络出现异常了。比如:偶然的网络抖动,或者是带宽被占满了。

1.1 网络抖动

经常上网的我们,肯定遇到过这样的场景:大多数情况下我们访问某个网站很快,但偶尔会出现网页一直转圈,加载不出来的情况。

有可能是你的网络出现了抖动,丢包了。

网页请求API接口,或者接口返回数据给网页,都有可能会出现网络丢包的情况。

网络丢包可能会导致接口超时。

2.1 带宽被占满

有时候,由于页面或者接口设计不合理,用户请求量突增的时候,可能会导致服务器的网络带宽被占满的情况。

服务器带宽指的是在一定时间内传输数据的大小,比如:1秒传输了10M的数据。

如果用户请求量突然增多,超出了1秒10M的上限,比如:1秒100M,而服务器带宽本身1秒就只能传输10M,这样会导致在这1秒内,90M数据就会延迟传输的情况,从而导致接口超时的发生。

所以对于有些高并发请求场景,需要评估一下是否需要增加服务器带宽。

2.线程池满了

我们调用的API接口,有时候为了性能考虑,可能会使用线程池异步查询数据,最后把查询结果进行汇总,然后返回。

如下图所示:

接口超时,java,数据库,程序人生,后端,开发语言

调用远程接口总耗时 200ms = 200ms(即耗时最长的那次远程接口调用)

在java8之前可以通过实现Callable接口,获取线程返回结果。

java8以后通过CompleteFuture类实现该功能。我们这里以CompleteFuture为例:

public UserInfo getUserInfo(Long id) throws InterruptedException, ExecutionException {
    final UserInfo userInfo = new UserInfo();
    CompletableFuture userFuture = CompletableFuture.supplyAsync(() -> {
        getRemoteUserAndFill(id, userInfo);
        return Boolean.TRUE;
    }, executor);

    CompletableFuture bonusFuture = CompletableFuture.supplyAsync(() -> {
        getRemoteBonusAndFill(id, userInfo);
        return Boolean.TRUE;
    }, executor);

    CompletableFuture growthFuture = CompletableFuture.supplyAsync(() -> {
        getRemoteGrowthAndFill(id, userInfo);
        return Boolean.TRUE;
    }, executor);
    CompletableFuture.allOf(userFuture, bonusFuture, growthFuture).join();

    userFuture.get();
    bonusFuture.get();
    growthFuture.get();

    return userInfo;
}

这里我用到了executor,表示自定义的线程池,为了防止高并发场景下,出现线程过多的问题。

但如果用户请求太多,线程池中已有的线程处理不过来,线程池会把多余的请求,放到队列排队,等待空闲线程的去处理。

如果队列中排队的任务非常多,某次API请求一直在等待,没办法得到及时处理,就会出现接口超时问题。

这时候,我们可以考虑是否核心线程数设置太小了,或者有多种业务场景共用了同一个线程池。

如果是因为核心线程池设置太小,可以将其调大一些。

如果是因为多种业务场景共用了同一个线程池,可以拆分成多个线程池

3.数据库死锁

有时候接口超时得有点莫名其妙,特别是遇到数据库出现死锁的时候。

你提供的API接口中通过某个id更新某条数据,此时,正好线上在手动执行一个批量更新数据的sql语句。

该sql语句在一个事务当中,并且刚好也在更新那条数据,可能会出现死锁的情况。

由于该sql语句执行时间很长,会导致API接口的那次更新数据操作,长时间被数据库锁住,没法即使返回数据,而出现接口超时问题。

你说坑不坑?

所以建议在执行数据库批量操作前,一定要评估数据的影响范围,不要一次性更新太多的数据,不然可能会导致很多意想不到的问题。

此外,批量更新操作建议在用户访问少的时段执行,比如:凌晨。

4.传入参数太多

有时候,偶尔的一次接口超时,是由于参数传入太多导致的。

例如:根据id集合批量查询分类接口,如果传入的id集合数据量不多,传入几十个或上百个id,不会出现性能问题。毕竟id是分类表的主键,可以走主键索引,数据库的查找速度是非常快的。

但如果接口调用方,一次性传入几千个,甚至几万个id,批量查询分类,也可能会出现接口超时问题。

因为数据库在执行sql语句之前,会评估一下耗时情况,查询条件太多,有可能走全表扫描更快。

所以这种情况下sql语句可能会丢失索引,让执行时间变慢,出现接口超时问题。

因此我们在设计批量接口的时候,建议要限制传入的集合的大小,比如:500。

如果超过我们设置最大的集合大小,则接口直接返回失败,并提示给用户:一次性传入参数过多

该限制一定要写到接口文档中,避免接口调用方,在生产环境调用接口失败而踩坑。要在接口开发阶段通知到位。

此外,如果接口调用方要传入的参数就是很多怎么办?

答:可能是需求不合理,或者系统设计有问题,我们要尽量在系统设计阶段就规避这个问题。

如果我们重新进行系统设计改动比较大的话,有个临时的解决方案:在接口调用方中多线程分批调用该接口,最后将结果进行汇总。

5.超时时间设置过短

通常情况下,建议我们在调用远程API接口时,要设置连接超时时间读超时时间这两个参数,并且可以动态配置。

这样做的好处是,可以防止调用远程API接口万一出现了性能问题,响应时间很长,把我们自己的服务拖挂的情况发生。

比如:你调用的远程API接口,要100秒才返回数据,而你设置的超时时间是100秒。这时1000个请求过来,去请求该API接口,这样会导致tomcat线程池很快被占满,导致整个服务暂时不可用,至少新的请求过来,是没法即使响应的。

所以我们需要设置超时时间,并且超时时间还不能设置太长。

并发量不大的业务场景,可以将这两个超时时间设置稍微长一点,比如:连接超时时间为10秒,读超时时间为20秒。

并发量大的业务场景,可以设置成秒级或者毫秒级

有些小伙伴为了开发方便,在多种业务场景共用这两个超时时间。

某一天,在并发量大的业务场景中,你将该超时时间改短了。

但直接导致并发量不大的业务场景中,出现调用API接口超时的问题。

因此,不建议多种业务场景共用同一个超时时间,最好根据并发量的不同,单独设置不同的超时时间。

6.一次性返回数据太多

不知道你有没有遇到过这样的需求:我们有个job,每天定时调用第三方API查询接口,获取昨天更新的数据,然后更新到我们自己的数据库表中。

由于第三方每天更新的数据不多,所以该API接口响应时间还是比较快的。

但突然有一天,该API接口却出现了接口超时问题。

查看日志发现,该API接口一次性返回的数据太多,而且该数据的更新时间相同。

这就可以断定,该API接口提供方进行了批量更新操作,修改了大量的数据,导致该问题的发生。

即使我们在job中加了失败重试机制,但由于该API一次性返回数据实在太多太多,重试也很有可能会接口超时,这样会导致一直获取不到第三方前一天最新的数据。

所以第三方这种根据日期查询增量数据的接口,建议做成分页查询的,不然后面没准哪一天,遇到批量更新的操作,就可能出现接口超时的问题。

7. 死循环

死循环也会导致接口超时?

死循环不应该在接口测试阶段就发现了,为什么要到生产环境才发现?

确实,绝大部分死循环问题,在测试阶段可以发现。

但有些无限递归隐藏的比较深,比如下面的情况。

死循环其实有两种:

  1. 普通死循环

  2. 无限递归

7.1 普通死循环

有时候死循环是我们自己写的,例如下面这段代码:

while(true) {
    if(condition) {
        break;
    }
    System.out.println("do samething");
}

这里使用了while(true)的循环调用,这种写法在CAS自旋锁中使用比较多。

当满足condition等于true的时候,则自动退出该循环。

如果condition条件非常复杂,一旦出现判断不正确,或者少写了一些逻辑判断,就可能在某些场景下出现死循环的问题。

出现死循环,大概率是开发人员人为的bug导致的,不过这种情况很容易被测出来。

还有一种隐藏的比较深的死循环,是由于代码写的不太严谨导致的。如果用正常数据,可能测不出问题,但一旦出现异常数据,就会立即出现死循环。

7.2 无限递归

如果想要打印某个分类的所有父分类,可以用类似这样的递归方法实现:

public void printCategory(Category category) {
  if(category == null 
      || category.getParentId() == null) {
     return;
  } 
  System.out.println("父分类名称:"+ category.getName());
  Category parent = categoryMapper.getCategoryById(category.getParentId());
  printCategory(parent);
}

正常情况下,这段代码是没有问题的。

但如果某次有人误操作,把某个分类的parentId指向了它自己,这样就会出现无限递归的情况。导致接口一直不能返回数据,最终会发生堆栈溢出

建议写递归方法时,设定一个递归的深度,比如:分类最大等级有4级,则深度可以设置为4。然后在递归方法中做判断,如果深度大于4时,则自动返回,这样就能避免无限递归的情况。

8.sql语句没走索引

你有没有遇到过这样一种情况:明明是同一条sql,只有入参不同而已。有的时候走的索引a,有的时候却走的索引b?

没错,有时候mysql会选错索引,甚至有时会不走索引。

mysql在执行某条sql语句之前,会通过抽样统计来估算扫描行数,根据影响行数、区分度、基数、数据页等信息,最后综合评估走哪个索引。

有时候传入参数1,sql语句走了索引a,执行时间很快。但有时候传入参数2,sql语句走了索引b,执行时间明显慢了很多。

这样有可能会导致API接口出现超时问题。

必要时可以使用force index来强制查询sql走某个索引。

9.服务OOM

我之前遇到过这样一种场景:一个根据id查询分类的接口,该id是主键,sql语句可以走主键索引,竟然也出现了接口超时问题。

我当时觉得有点不可思议,因为这个接口平均耗时只有十几毫秒,怎么可能会出现超时呢?

但从当时的日志看,接口响应时间有5秒,的确出现了接口超时问题。

最后从Prometheus的服务内存监控中,查到了OOM问题。

其实该API接口部署的服务当时由于OOM内存溢出,其实挂了一段时间。

当时所有的接口都出现了请求超时问题。

但由于K8S集群有监控,它自动会将挂掉的服务节点kill掉,并且在容器中重新部署了一个新的服务节点,幸好对用户没造成太大的影响。

10.在debug

我们有时候需要在本地开发工具,比如:idea中,直接连接测试环境的数据库,调试某个API接口的业务逻辑。

因为在开发环境,某些问题不太好复现。

为了排查某个bug,你在请求某个本地接口时,开启了debug模式,一行行的跟踪代码,排查问题。

走到某一行代码的时候,停留了很长一段时间,该行代码主要是更新某条数据。

此时,测试同学在相关的业务页面中,操作更新了相同的数据。

这种也可能会出现数据库死锁的问题。

由于你在idea的debug模式中,一直都没有提交事务,会导致死锁的时间变得很长,从而导致业务页面请求的API接口出现超时问题。

当然如果你对常规的接口超时问题比较感兴趣,可以看看我的另一篇文章,里面有非常详细的介绍。

 文章来源地址https://www.toymoban.com/news/detail-522441.html

到了这里,关于知道这10个让你的API接口突然超时的原因吗?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何让你的 WebSocket 接口测试更高效?拯救你的接口测试工作

    目录 引言 WebSocket介绍 HTTP与WebSocket的区别 WebSocket测试方法 使用在线工具 使用Postman 使用Jmeter 使用Python 结语 你是否曾经为 WebSocket 接口测试中复杂的协议和难以捕获的数据而感到束手无策?WebSocket 协议与传统的 HTTP 协议不同,测试方法也需要针对其特殊性进行优化。 本文将

    2024年02月07日
    浏览(38)
  • 常见的HTTP接口超时问题出现原因及解决办法

    HTTP 接口超时问题是指在 HTTP 请求发送到服务器后,由于等待服务器响应的时间超过了预设的超时时间,导致请求被中断。以下是可能导致 HTTP 接口超时问题的原因和解决方法: 网络延迟或不稳定:网络延迟或不稳定可能导致请求在传输过程中耗费的时间超过了预设的超时时

    2024年02月02日
    浏览(42)
  • 快速搭建API随心搭,让你的web开发更加高效

    随着互联网的发展,越来越多的应用和服务需要通过API接口来实现。API(Application Programming Interface,应用程序编程接口)可以理解为两个软件之间的桥梁,通过API接口,两个软件可以相互交流并进行数据交换。如今,API已经成为许多公司和应用程序的核心,因此快速搭建并管

    2024年02月08日
    浏览(50)
  • 使用magic-api ,让你的开发效率蹭蹭提升

    一个基于Java的接口快速开发框架,通过magic-api提供的UI界面完成编写接口,无需定义Controller、Service、Dao、Mapper、XML、VO等Java对象即可完成常见的HTTP API接口开发 官网:https://ssssssss.org 示例:ssssssss-team/magic-api-example demo:https://magic-api.ssssssss.org 源码:magic-api: magic-api 是一个基于

    2024年02月10日
    浏览(50)
  • Windows 10计算机性能优化:让你的电脑更流畅

    Windows 10是目前最流行的操作系统之一,但在长期使用过程中,可能会出现一些性能方面的问题。本文将为你介绍如何选择合适的Windows 10版本,并提供一些优化技巧,使你的电脑性能更加流畅。此外,还将特别关注游戏用户和工科工作流,提供相应的优化方向。让我们开始吧

    2024年02月10日
    浏览(53)
  • 10几个国内AI大模型,让你的工作学习效率翻倍!

    ✍创作者:全栈弄潮儿 🏡 个人主页: 全栈弄潮儿的个人主页 🏙️ 个人社区,欢迎你的加入:全栈弄潮儿的个人社区 📙 专栏地址:AI大模型 随着ChatGPT迅速走红,国内各大企业纷纷发力认知大模型领域。经过一段时间的酝酿,国内AI大模型也相继发布,快速点燃国内科技圈

    2024年02月08日
    浏览(40)
  • 超级实用!Android Studio的10大神器插件,让你的开发效率翻倍!

    Android Studio是一款功能强大的集成开发环境(IDE),专为Android应用程序开发而设计。它提供了丰富的工具和功能,使开发者能够轻松创建高质量的Android应用。除了内置的功能外,Android Studio还支持插件系统,允许开发者根据自己的需求进行定制和扩展。在这篇文章中,我们将

    2024年03月14日
    浏览(45)
  • 爆炸性!接口鉴权方式及实战案例,这篇文章让你的接口安全像坦克防护!

    接口鉴权是指在访问API接口时对用户进行身份验证和权限检查,以确保API接口的安全性和可靠性。常见的接口鉴权方式包括API Key、Basic Authentication、OAuth、Token 等。本文将详细解析这些常见的接口鉴权方式,并使用Python代码进行演示。 一、API Key API Key 是一种基于密钥的验证方

    2024年02月16日
    浏览(45)
  • 利用css var函数让你的组件样式输出规范样式API,可定制性更高;

    我们平时在使用Elementui Antdesing这些UI库时,难免会碰到使用deep强行侵入式去修改组件内部样式的情况;   比如下列代码,我们需要把ant的分页样式进行高度自定义,就得使用deep去修改;   这种实现方式确实能够达到我们的目的,但在开发时确总觉得不太合适: 1、他属于强

    2024年02月03日
    浏览(39)
  • 【API接口工具】postman设置超时时间、请求等默认配置

    Postman 会自动为某些设置选择默认值,以便您可以开始工作。根据您的用例随时更改设置或自定义您的 Postman 体验。 要更改 Postman 中的设置,请选择 设置图标 标题中的设置图标,然后选择设置。在 Postman 桌面应用程序中,您还可以选择⌘+逗号 (,)或Ctrl+逗号 (,) 使用“General”

    2024年02月08日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包