如何处理变慢的API?

在开始时表现良好的API会随着时间的推移而导致性能降低。学习如何管理和解决这些性能问题是开发者必须具备的技能之一。

作为一名工程师,你花了很多时间在API上——你要么是为别人构建API,要么是在使用别人的API。使用API既是一门艺术,也是一门科学。工程师们犯的最常见的错误之一就是对性能的思考不够充分。我们希望让事情先做起来,然后再处理性能问题。这很好,但是如果在构建v1的时候能够意识到这一点,你以后就可以避免。如果你使用API的时间够长,我相信你知道刚开始一切都很顺利,但随着时间的推移,API就会变得缓慢。

当我们在使用别人API时,这些API是我们几乎无法控制的,那就会变得很棘手。通常,许多API在最初的几毫秒内就会响应,但随着时间的推移,复杂性的增加,它们开始变得缓慢。一些用户操作可能会在我们正在使用的API中触发一个代价高昂的查询,然后就会出现问题。API不能保证预期性能,所以在使用API时,意识到这点会督促您关注什么样的东西会减慢它们的速度,尤其是在项目的关键路径上。

我们来看一个或两个用户操作共享一个视图区域以显示其响应的用例。如果其中一个连接到这些操作的API需要花很长时间,那么我们可能会遇到,如果处理不当视图就会混乱的情况。

例如Google’amzn股票’,您会看到如下所示:由用户选择的时间范围控制的一个单一的股票趋势图,如1天、5天、1个月等。

当我们切换时间段时,视图区域会反映变化。让我们假设您的API调用获取1年趋势图会出现问题,用户点击它,它一直在加载,那么用户失去耐心,切换到一个较短的时间段,比如3个月,则立刻加载出图表。当用户正在查看3个月的图表时,刚开始获取1年数据的API调用返回其响应并重新绘制具有1年数据的图表。

这不是一个复杂的问题。你可以查看当前活跃的时间段,忽略晚到的响应。但是,当您构建v1时,您可能不认为在开发UI时需要这种处理,因为当您开发它时,所有的API都会立即返回。您可能没有预料到API会在某些场景中或随着时间的推移而减慢。

现在,如果这种情况影响到应用程序中提供多个组件的公共共享服务的状态,情况可能会变得更糟,并且在这种情况下寻找根本原因会变得非常复杂。

我们来看看如何解决这个问题。一个简单的方法是在该公共共享服务中维护一个标记,以跟踪我们当前期待响应的后台API。但是如果我们多次调用同一个API会怎么样呢?标志是行不通的。我们可以延长标志来存储每个后台API调用的“状态”,但这会变得混乱和复杂,每当我们去存储状态,我们都要承担很大的风险,因为“记住”API的变化,我们需要保持状态更新,但这几乎总会导致不良的缺陷。

所以你维护的“全局”状态越少越好。它不仅有助于保持代码简单和模块化,而且还为您提供更多自由去提高并发性。

在这种情况下,一种更好的方法是,不要处理来自慢速API的响应,而是简单地停止接收来自它的响应。只需终止那些您不再关心响应和继续运行的API。您可以通过跟踪所有正在进行的API调用来轻松地执行此操作,并且当您需要启动新的API调用时,只需终止不再需要的先前的调用即可。

如果您使用的是jQuery ajax方法,那么请保留对jQuery ajax方法返回的XMLHttpRequest的引用,并在适当的时候调用您的流中的中止方法。

如果您使用的是ES6 promises,那么对不起,这是行不通的——您不能终止与promises相关的一个正在进行的API调用。更多关于promises使用在这里。

欢迎来到RxJS世界!RxJS试图通过完全异步的事件驱动模型来为API性能的混乱带来秩序。如果某件事需要时间,那就花点时间吧。让我们用我们所拥有的一切来运行。我不是在这里讨论它是好是坏,或者它是否是最好的方法,但是我发现用RxJS处理这些类型的情况是很方便的。

在这种情况下,您可以简单地在您的可观察对象上使用一个switch 结构,并获得您感兴趣的最新异步事件,而不必担心任何状态维护或终止先前正在进行的API。当您使用正确的构造时,这个库内部为您做了所有这些操作,所以您不必担心它们!

以plunker为例。在这个例子中,一个缓慢的API使用Observable.timer。 作为共享服务构造函数的一部分创建的RxJS主体实例asyncActionSubject,使用switch结构来简单地切换到返回的最新observable。 其余的都由RxJS框架负责。在这里查看RxJSGitHub页面了解更多详细信息。

关键小贴士

  • 在使用API时,请始终考虑什么情况可能导致其减慢。您可以根据API正在做什么,返回多少和什么类型的数据,以及如果您正在测试的简单例子变得复杂时将会发生什么。如果你的代码路径结合许多过滤器和选择器为用户操作服务,那么这一点尤为重要。
  • 始终考虑大局–用户如何与您的代码交互,进而影响你正在使用的API?退一步,思考会出什么错,从源头处理这些情况。
  • 总是尽可能分散和无状态。集中和有状态是调试和并发性的敌人。这可以节省很多麻烦。
  • 小心使用异步调用——它们是好的,但它们也会很棘手。了解它们在您的情况下如何工作,以及当调用按时间顺序返回时会发生什么。
  • 最后,越少越好。即使一个API返回很多数据量,最低数据量和实际上消耗的最少数据量。

原文:How to Deal With Slow APIs (https://dzone.com/articles/how-to-deal-with-slow-apis) 作者:Tom Smith 翻译:lloog

原文发布于微信公众号 - CSDN技术头条(CSDN_Tech)

原文发表时间:2017-08-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java一日一条

Java开发的几个注意点

比如,没有把一些需要并发执行时使用的线程数设置成可在属性文件中配置。那么你的程序无论在DEV环境中,还是TEST环境中,都可以顺畅无阻地运行,但是一旦部署在PR...

10410
来自专栏Golang语言社区

为什么决定要重新造一个轮子?

目前网上优秀的开源游戏服务器框架也不少(当然与web框架比起来就少太多了),但总结起来都各有各的优缺点,下面列出我在选型过程中的一些考量,希望大家能开放的讨论,...

77870
来自专栏aoho求索

几种分布式调用链监控组件的实践与比较(二)比较

引言:最近在调研与选型分布式调用链监控组件。选了主要的三种APM组件进行了实践与比较。本来打算一篇文章写完的,篇幅太长,打算分两篇。距离《几种分布式调用链监控组...

55880
来自专栏后端技术探索

携程异步消息系统实践

今天会跟大家分享一下我们在携程,现在应该是正在推广的一个新的消息系统,主要会偏重于讲一些架构和实现方面的内容。目前我在携程大概一年多都在做新的消息系统Herme...

16530
来自专栏MongoDB中文社区

来自MongoDB的新年大礼: MongoDB 4.0将正式支持ACID事务!

MongoDB CTO Eliot Horowitz 刚刚于2月16日凌晨在MongoDB西雅图大会上宣布(当地时间2月15日上午),MongoDB将在4.0版...

21910
来自专栏Linyb极客之路

12大要点让你的Java开发所向披靡~

比如,没有把一些需要并发执行时使用的线程数设置成可在属性文件中配置。那么你的程序无论在DEV环境中,还是TEST环境中,都可以顺畅无阻地运行,但是一旦部署在PR...

9320
来自专栏美团技术团队

【沙龙干货】RDS平台介绍

今天我就给大家讲一下我们这边做的数据库运维的自动化平台,他是怎么样子的。首先我会给大家简单介绍一下我们做平台的背景,以及平台的一些技术架构,以及针对我们DBA和...

55640
来自专栏开源项目

码云推荐 | tabris.js + restify + 码云打造个人 APP

前言: 从9月初开始到现在,我一直在寻找一个适合自己的,可以跨平台的开发APP的js框架。 虽然之前自己也有陆续接触过Weex,React Native,F...

59180
来自专栏北京马哥教育

实战:基于Python构建运维自动化平台

导语: 今天与大家一起探讨如何基于Python构建一个可扩展的运维自动化平台,也希望能与大家一起交流,共同成长。 此次分享将通过介绍OMServer、OMana...

1K50
来自专栏Debian社区

Irssi: 命令行下的 IRC 客户端

IRSSI 是一款优秀的命令行下的 IRC 客户端,支持常见的操作系统,包括Windows、Mac OSX,Debian、RHEL等系统。本文介绍如何在Debi...

18120

扫码关注云+社区

领取腾讯云代金券