如何轻松和安全地构建的满足合规要求的智能产品,实现业务需求?4月26日,告诉你答案! 了解详情
写点什么

关于设计低延迟应用的一些经验

  • 2016 年 4 月 17 日
  • 本文字数:2087 字

    阅读完需:约 7 分钟

在开发和架构设计过程中,我们往往会被要求构建低延迟的应用,快速的响应各类请求对于优化用户体验来说非常重要。而设计低延迟应用时需要考虑很多因素,也正是这些因素将其与其它应用区分开来,它们包括:要产生更少的垃圾,转换更少次数的数据,让应用需要的数据随时可获取等。本文从这几个方面,介绍低延迟应用与普通应用之间的差别。

简单性是关键

如果我们想让一样东西执行得更快,最好的方式是让它做更少的工作。也就是说,要产生更少的垃圾,转换更少次数的数据,让应用需要的数据随时可获取。

如果你想获得稳定的性能,简单性尤其重要。如果你期待 99% 或者 99.9%的准确率,那么如果你看到系统出错,此时肯定是绝大多数事情都在变糟。系统越复杂,事情就会变得越糟糕。如果吞吐量也对你很重要,你会发现一个缓慢的输出会对结果产生很不好的影响,你有必要开始担心 99.99% 或更高的准确率,因为在系统再次处于正常运行状态之前,即使一个非常不常见的延迟也会影响许多请求或事件,何况很多时候,数百或数千个延迟也并不少见。

不要考虑容易添加,而要考虑容易移除

你不需要考虑太多如何方便地添加代码的事情,而是要考虑怎么轻松地剔除那些不需要做的事情。许多框架在设计的时候就会考虑让其能够轻松上手,也很容易添加功能,这样如果你需要框架少做一些事情,那么它就可以少做一些事情。

解决这一点的最好方法是使用非常轻薄的库和框架(在调用堆栈和数据变换的方面),如果不需要甚至可以做得更少。

你想要一个清晰简单的解决方案,但你也想有选项可以替换或删除你不需要的任何功能。

转换更少次数的数据

我常常对代码的错综复杂感到惊讶。它经常像揉面或揉数据一样被执行。相同的数据被转换一次又一次,然后还会再返回来转换为另一种形式,最后与某些自定义数据放入一种数据结构中,被用来构建另一种数据结构。所有这些复杂过程都减慢了应用程序的运行速率,并掩盖了应用程序实际做的事情。

你需要设计自己的应用程序,这样你可以看到数据从一端到另一端发生了什么,以致你可以删除你实际上不需要的一些步骤(并且可能是错误的来源)。

我见过一个日期的例子,要将一个 64 位长整数转换成一个日期对象,然后再转换为一个 MM / DD / YYYY 的字符串,再转换为一个 yyyy / MM / DD 的字符串,再转换为日期类型,并最终转换回 64 位长整形。

我也见过另一个例子,要将 64 位 double 型转换为一个 double 型对象,转换为字符串类型后又解析为 double 型,进行一些不正确的或复杂的四舍五入,最后转化为了最初的 64 位 double 型。

这听起来很傻,但是有些框架经常会这样做。每个库中每种层次的部分由不同的人写入,数据在每个库所使用的模型之间转换。

计算机科学中的所有问题都可以从抽象层面来解决。

代码的可读性

很多代码是以一种自然语言的风格,在高层次上对应用程序进行描述。即使我不懂编程,我也知道代码要做的事情。这工作就像魔术。但问题是,代码虽然在高层次上编写,但是执行的时候并不是像你想象的那样。虽然功能性问题可以通过好的测试被发现。当你的设计掩盖了计算机实际执行的有关细节的时候,虽然代码正确执行,但是该如何判断它执行的很差呢?有些代码在大部分情况下执行得很好,只在很少的时候表现不好,此时更难检测。即使性能分析工具也帮不了太多。

低延迟代码的优越性是它能够轻易地读出你让计算机需要实现的事情。这个操作是 O(1),O(log N) 或者 O(N)?这个操作是线程安全的吗?如果我不需要让它是线程安全的,是不是不会这么容易?

这种低层次的代码是有用的,但你仍然需要从高层次上理解代码要做的工作。总存在一部分代码告诉你组件是用来干什么的。这种高层次的组件调用往下,以致你可以看到它是怎么工作的。反过来又可以看到代码在低层次上工作的细节。

业务和基础架构代码的分离

如果应用程序没有做自己应该做的事情,你应该改变你的业务逻辑来解决它。如果应用程序不以这种方式执行,你应该改变你的基础架构,使得你的应用程序仍然做它需要做的事情。

几个不错的案例

Aeron( https://github.com/real-logic/Aeron
Chronicle( http://chronicle.software/hft-products/

到底有多少差异?

使用低延迟技术能够显著提高一个应用的典型性能,也能增加它的吞吐量。在一致性条件下,能够减少 99%的延迟。

设计已经尽可能快了吗?

对于我们正在开发的项目,这并不是最关键的优点。它不仅仅是生产力。主要的优点是开发最简单的解决方案,来解决为提高性能所需要解决的问题,通过更少的努力让其变得更快,只有当它已被确定是必须的才执行。

简单性也能提高可维护性

我们使用的拇指规则是,一个成功的系统在维护上的开销是构建上的开销的三倍。系统的简单性和透明性有助于最大限度地减少你的长期成本,因为其能够帮助以更小的风险,更短的时间运行一个应用。

既然简单性是如此重要,为什么不是每个人都这样做呢?

构建一个大的、复杂的系统很容易,你只要不断地增加功能。使系统尽量简单是非常困难又需要经验的。为了在开发的时候尽量避免添加不需要的东西,你经常需要多年开发相同类型解决方案的经验。

查看英文原文: How Do Low Latency Applications Differ From Regular Applications?

2016 年 4 月 17 日 19:003247
用户头像

发布了 268 篇内容, 共 107.7 次阅读, 收获喜欢 23 次。

关注

评论

发布
暂无评论
发现更多内容

2.1.2 类加载器的工作原理与自定义加载器 -《SSM深入解析与项目实战》

谙忆

《effective-go》 学习笔记

半亩房顶

Go 语言

“啰嗦”是成事唯一正确的方法

霍太稳@极客邦科技

团队管理 个人成长 团队协作 沟通

数据采集能力受限?企业数字化运营如何迈出第1步

易观大数据

真正的勇士,会跨过六道裂谷,奔向云与AI的彼端

脑极体

List 和 Map 的排序

一盐难进

Java

# spring boot自定义线程池进行异步调用

一盐难进

Java

learn go with tests 学习笔记(七)反射

半亩房顶

反射 Go 语言

Executor看不懂?教你如何盘它

Edison

后端 线程池

500行代码写一个俄罗斯方块游戏

程序员生活志

消息疯狂堆积!RocketMQ出Bug了?

Edison

RocketMQ 中间件

踩坑记 | Flutter升级影响了NestedScrollView?

哈利迪

android

关于微服务架构思考

Arthur

用户体验(UX)设计≠用户界面(UI)设计

刘华Kenneth

敏捷 设计 UX 用户体验

话题讨论 | 特朗普正式封禁微信,iPhone 和微信二选一?

InfoQ写作社区官方

写作平台 话题讨论

以区块链为基础 通证经济是下一代互联网的数字经济

CECBC

区块链 落地应用

ARTS Week8

丽子

DevOps 技术栈

柴锋

Linux DevOps 运维 敏捷 Shell

零代码/无代码 vs 低代码 如何分类?如何区别?到底有什么不同?分析超过20款零代码低代码产品

代码制造者

编程 低代码 行业资讯 零代码

RocketMQ源码解析-开篇

Edison

RocketMQ 中间件

我是如何参与硅谷顶级开源项目并赚得2500美金

阿水

硅谷 Minio

Python爬取微信公众号文章保存到数据库

wjchenge

MySQL事物-学习笔记

Edison

MySQL 数据库 数据库事务

nested exception is java.lang.IllegalStateException: refreshAfterWrite requires a LoadingCache异常解决

谙忆

LeetCode题解:24. 两两交换链表中的节点,递归,JavaScript,详细注释

Lee Chen

大前端 LeetCode

原来你是这样的B+树

Java技术宝典

B+树

从数据中台到AI中台,企业到底要建什么中台?

脑极体

政策加持迎来区块链技术应用“红利期”

CECBC

疫情之年 下半年区块链应用落地会加速么?

CECBC

区块链 场景应用落地

你为什么还在用存储过程?

架构师修行之路

数据库设计 架构设计

learn go with tests 学习笔记(六)进程同步

半亩房顶

Go 语言

关于设计低延迟应用的一些经验_Java_Peter Lawrey_InfoQ精选文章