在中间件技术选型前,我们该思考些什么?

Posted 吃草的罗汉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在中间件技术选型前,我们该思考些什么?相关的知识,希望对你有一定的参考价值。

题图: from Instagram

两个月前,我曾写过一篇  的文章,大体对中间件定义、特性、作用,以及发展历程进行了一通理论化梳理。在后台留言区,有不少读者基于自己的经验进行了补充。

在这些补充中,有不少值得进一步思考的话题,比如,有人说 “你说这些理论基本都明白,只是在选型前,思路上多少还会有些懵逼,是否可以结合你的经验来谈一谈?”

我觉得,在构建中间件的过程中,技术选型可以说是最重要且最关键的环节,不仅是中间件,每一个软件系统想要成长壮大都必须做出选择的岔路口。尽管在圈内不乏将某项技术的魔力发挥到了极致的案例,但也有诸多系统由于在技术选型之初缺乏思考,致使后人惊呼:“某某某技术与某某某系统水土不服。”

说到这里,突然想起近些年非常火的Redis,可以说是NoSQL 领域的当红明星,有人说它像“瑞士军刀”,甚至都拿它来解决传统关系数据库解决不了的问题,比如用来做缓存。但 Redis 从诞生那天起就不是用来当缓存的,虽说有很多场景问题它可以解决,但也有很多解决不了,再说了,就算把Redis 当内存数据库来用,假设某个场景对内存的消耗很大,一但崩盘,肯定难以承受。

在我看来,任何一项技术本身都没有错,错在负责人最初对技术选型的理解和后期规划上。就这个问题,我觉得技术选型是一把“双刃剑”,关键在于当你面对复杂场景时,如何进行逻辑式、因果式的思考,以便做出明智的选型决策。

但是,有时候你尽管对某项开源技术深有研究,甚至实战经验丰富,但在面对一些突如其来的挑战时,还是会显得准备不足。为什么会这样?对此,我们又该怎么做?

今天我来讲一下在中间件技术选型前,我们该思考些什么?

导致选型失败的原因有哪些?

几年前,我经历了一次因为ActiveMQ使用不当而出现的故障,当时单单定位就花了整整一个晚上的时间,当时郁闷至极,苦闷的心情至今历历在目。

先来看看当年的故障复盘我都写了些什么:

面对一个没有任何使用经验的开源产物,只是道听途说,或者通过百度搜一下,然后就匆匆忙忙在生产环境开搞,而官方文档却只被当成故障爆发后的救命稻草。

这样的解读似乎有些口无遮拦,又似乎有些偏激,但这种由技术选型导致的问题,在任何一项技术的发展过程中绝非罕见。然而,失败已是无法容忍,还会有人添堵地问你那么一句:“你当初为什么要选这项技术呢?”

我觉得绝大多数选型失败的案例,其原因大致可概括为:缺乏估算、实验不够与轻视经验。这三点该如何理解呢?

| 缺乏估算

简单来说就是对技术模型维度的分析,考虑某个组件是否有可能达到我们想要的目的,确认它是否真的做到了。

就像选择一门开发语言,我们会考虑它的内存模型和性能指标,而数据库选型,我们则会考虑其存储模型、数据量级及成本开销。如果是开源项目,还要考虑它的社区活跃度、分值支持率及文档完整性等。

对于像中间件这种关键技术项,除了考虑它的健壮性、扩展性及灵活性等基本要素,你还应适当阅读核心源码,不能因为耗费精力过多、嫌麻烦,就一笔带过。

| 实验不够

既然是估算,那就有可能存在偏差。比如一个语言虽说具有自动管理内存的功能,但并不代表它在所有场景下都会起作用,因此需要实际场景实验,毕竟用实际数据说话是最靠谱的。

所以,要对核心业务进行场景镜像构建,并使用工具对服务进行特定场景下的分析,或通过提高压力、增加容量或者针对性的测试,来验证是否达到预期,并分析不同场景之间的差异和表现。比如可以尝试在开发环境做一次,在集成测试环境做一次,最后在仿真环境再做一次。

在实际工作中,这几步往往被简化,而我觉得,如果你希望中间件这种关键技术项在生产环境中运行稳定且高效,你就应该严格走好每一步。

| 轻视经验

在技术选型上,我一向忌讳 “在百度搜一下,觉得差不多了就照抄” 的方式,尤其对于中间件这类基础服务来说,忽视经验的举动都是危险行为,在还没弄清楚原理与本质之前,如何才能确定这项技术是否经得起产线的考验?

比如我对分布式数据库进行技术选型,通过百度搜索下,肯定出现许多看上去极其靠谱的信息,但我们的需求是解决并发与读取频率较高,而数据块不大,对于交易系统而言,必须确保数据安全,显然这样的需求无法使用关系型数据库,因为性能是瓶颈,然而看看网上写的,几乎所有的关系型数据库都会说自己能够满足高性能场景。

在实际工作中,我会先列出需求,再细分需求,待明确评判标准之后,或通过基于已有经验进行实验,或走访外部团队进行学习,将经验带回后再进行实验,千万不可盲目的跟风走,哪个热门就选哪个,这些方式不但不正确,而且后患无穷。

中间件技术选型前的三项思考

随着服务化应用的普及,中间件的使用场景得到了广泛衍生,但由于种类越来越多,功能特性越来越丰富,如果准备不足,极有可能被卷进细节之中无法自拔。

对于中间件技术选型这件事本身而言,不能只关注技术,你还需要考虑厂商(或社区)支持力度、服务质量及成本等因素,因此掌握思考方法就非常重要。我先尝试将这种思考方法进行分类:

  • 比如,你想知道这一类技术有哪些功能,或系统有哪些特定行为,那我把它叫做“标准功能”;

  • 再比如,你想了解这一类技术在 “性能、可靠性、可扩展性及安全性”上具备哪些能力,例如在双11中,缓存系统能否扛得住(性能)?当流量瞬间增加时,能否快速平行扩展(可扩展性)?会不会被黑客攻击(安全性)?,那我把这种“能力”称为“非功能特性”;

  • 最后,你还想获悉这一类技术使用什么通讯协议?API标准是什么?实现语言与兼容语言支持哪几种?那我把这几点叫做“技术标准”。

讲到这里,是否有点蒙圈,下面我们逐一进行下解读。

思考一:标准功能

以Kafka举例,它能够解决分步式环境中消息的发送者和接收者之间消息传输、管理和控制问题,提供多种消息交换方式、支持多种消息类型、可靠传输等服务质量控制机制。

虽说Kafka能满足大部分业务场景,但无法严格保证消费顺序,因此无法满足某些业务场景的要求(如实时交易),所以由于标准功能无法达标,从而考虑是否选择RocketMQ,这样不但同时兼顾消费顺序,并可同时满足其他业务场景。

思考二:非功能特性

以ActiveMQ举例,它能够解决分步式环境中消息的基本标准功能,并能支持多系统平台,满足高吞吐量的业务处理。

而“高吞吐量”是个形容词,由于ActiveMQ缓存消息的内存满了之后,默认策略是将消息持久化到磁盘(丢弃策略不谈),如果吞吐量大于千万(或亿级)时,似乎RocketMQ比起ActiveMQ就显得更加符合场景了。

在这多说一句,在我看来,“非功能特征”是中间件技术选型的核心环节,如果非要给他定一个标准,我引用一下《中间件——达成灵便的电子商务的技术基础》中的一段信息:

特性

描述

可伸缩性

产品在性能上必须能容易且有效地伸缩以满足业务需求增长的需求。

灵活性

产品必须易于适应新的需求。

互操作性

产品必须被设计成易于与共享的数据和广泛可得的系统通讯。

可扩展性

产品功能必须在供应商很少介入的情况下能够定制和快速地增强。

可使用性

只需很少的培训就能使让顾客使用产品和他的任何特性,产品应该被设计成其目标使用者的技术水平很匹配。

高效率

产品应能在各种性能水平上工作,能够应付应用对效率的要求。

可靠性

产品必须有被证实可在预定环境中工作的功能与特性。

可管理性

产品必须能被配置、部署、监控和优化以确保其在预定的环境中工作良好

安全

产品必须保护信息和事务的完整性

我觉得,对于中间件技术选型而言,标准功能和非功能特性的界线有时没必要刻意划分,也有人将“非功能特性”比喻成“标准功能”的一种技术属性较高的补充项,听上去反而更加贴切。

思考三:技术标准

还以消息中间件举例,如果由于技术债或外部合作等原因,导致环境中消息的发送者和接收者之间消息传输均使用JMS规范定义,显然选择支持JMS规范的ActiveMQ要比没有实现JMS规范的RocketMQ来的更为合理。

我觉得,所谓标准,可能只是将可行性选项内容统统收入的一种妥协,标准/规范顾然重要,但不能为了标准而标准。

小    结

简单来说,中间件作为企业级应用的重要支撑立柱,在技术选型上所埋下的问题,这背后带来的代价可能是无法承受的,所以我们讲述了在选型之前,该如何去避免导致选型失败的原因,并如何思考选择符合业务场景的标准功能、非功能特性与技术标准,希望对你有所帮助。

相信每位架构设计者,应该都有刻骨铭心的技术选型失败案例,能跟大家分享下吗?欢迎你把答案写到留言区,和我一起讨论。相信经过深度思考的回答,也会让你对知识的理解更加深刻。



 - END - 

欢迎加入知识星球交流、讨论

以上是关于在中间件技术选型前,我们该思考些什么?的主要内容,如果未能解决你的问题,请参考以下文章

消息队列中间件的技术选型分析

消息中间件的技术选型心得-RabbitMQActiveMQ和ZeroMQ

消息中间件的技术选型心得-RabbitMQActiveMQ和ZeroMQ

网关技术选型,为什么选择 Openresty ?事件驱动协程...

消息中间件系列第2讲:如何进行消息队列选型?

消息中间件ActiveMQRabbitMQRocketMQZeroMQKafka如何选型?