作者 | 章烨明
杏仁医生CTO。中老年程序员,关注各种技术和团队管理。
技术选型对于广大程序员,特别是互联网公司的技术负责人或者架构师来说,一定不陌生。小到日常开发中的一个工具库的选择,大到整个系统语言、架构层面的选择,都是技术选型的范围。今天我们就简单聊聊技术选型。
一般而已,我们会碰到的技术选型,可以分为以下几类:
基础设施选型:云平台或IDC、编程语言、数据库等。
框架和库的选型:前后端的开发框架、核心类库等。
中间件选型:负载平衡、消息中间件、缓存中间件等。
第三方服务选择:第三方的推送、短信等。
实际上,我们常常面临的不是单个技术的选型,而是对于一个项目所涉及的一整套的技术、方案、规范或者产品的选型。这就需要我们更仔细的去权衡各种技术、各种组合的利弊,作出取舍。
技术选型,其实本质上就是一种架构决策。《系统架构》这本书里将架构决策总结成了六种模式,包括选项、筛选、指派、分区、排列和连接。而技术选型明显属于其中的选项(Decision-Option)模式,也即每个决策都是一套离散选项,从中选择一个合适的。
首先考虑的是项目。
我们要明确项目本身的性质,包括项目的规模、重要程度、时间要求等等。如果是一个小规模的实验性项目,那么尝试一些新技术也未尝不可。如果时间要求非常紧,那可以考虑基于开源或商用的程序修改。淘宝当年上线时候,就是购买了一个商用程序后修改的。另外,项目的成本和预算也是必须要考虑的。如果预算足够,我们也可以考虑购买商用程序或者第三方服务。
项目的需求也会影响甚至限制技术的选型。特别要注意的是那些非功能性的需求,例如对并发性、实时性、可用性、数据一致性、安全性等方面的需求,往往对技术方案和选型有很大影响。例如支付相关的应用,对数据的一致性有非常高的要求,那核心的支付数据的存储,就会倾向选择 Oracle、PostgreSQL 这种强一致性的数据库,而不会去选 MongoDB(虽然据说马上也要支持事务了)。
其次要考虑的是团队,也就是说人的因素。
技术选型一定要考虑当前团队人员的技术组成。对于一些比较基础的技术的选型,比如语言和框架、数据库等等,往往最合适的选择就是团队最熟悉的技术。如果打算选择不同的技术的话,那就要考虑下团队是否有人能够 Hold 住了。另一个必须要考虑的是招聘,如果使用的是比较小众的技术,那么当需要扩充团队的时候,招聘人员会比较困难。我们杏仁在这方面就取了一个巧,最开始我们用的是基于 JVM 的 Scala 语言,但是我们招聘的时候,都是打的 Java 工程师的幌子。
团队的发展时期对于技术选型也会有一定影响。对于早期团队,大多数员工都是喜欢创新、愿意承担风险,那么可以选择一些相对较新、有挑战的技术;团队发展到一定阶段,那就要开始考虑团队效率、开发规范等因素,此时往往会选择一些比较大众的、经过验证的技术。
我加入现在的公司时,我们正好开始转型。原有的产品是基于 Web 的网站,我们打算开发一个移动 APP。我们原先后端应用使用的是 Scala 语言和 Play 框架,当时面临的一个问题是,新的产品后端应该选择什么技术?虽然也考虑过 Java,但因为时间很紧,我们还是选择了团队最熟悉的 Scala。但后面我们开始服务化的时候,就选择了 Java。
还有一点就是,虽然技术选型需要考虑团队人员的喜好,但千万不要因为某几个人的个人喜好,来决定技术的选型。还是通过细致的分析和实验来进行选型。而决策者也需要看的更长远一些,推动团队技术向前发展。
技术选型当然也必须考虑技术因素,例如技术特性(易用性、可维护性、可扩展性、性能等)、技术成熟度、社区活跃度、架构匹配和演化等等。
技术特性往往是大家都会去关注的,相信不必多说。但是注意不要只是浏览网上看到的各种分析,对于重要的特性,还是需要去亲自实验一下或者做一些测试,有第一手的感觉。另外,这些特性往往不可兼得,所以我们需要对照项目因素和团队因素来进行取舍。
技术的发展有其内在趋势,Gartner 每年都会发布一个 Hyper Cycle,标记各种技术的发展阶段;另外一个很好的参考是 ThoughtWorks 的技术雷达。我们可以根据项目、团队等因素去选择不同成熟度的技术和产品。但是对于核心项目,最好还是选择足够成熟的技术,切忌盲目追求新技术。
对于比较重要的应用,我们一般会选择比较大众的技术,因为使用的人多了,也从某种程度上说明这个产品是比较优秀的,并且招聘也会更容易些。这方面可以参考的有 Github 的 star 数、Google Trends、百度指数等等。社区活跃度也是必须要考虑的因素,你一定不会想用一个没有人维护,提了问题也没人回复的技术产品吧。
最后还需要考虑技术产品和当前架构的匹配程度。一个团队的技术栈太过散乱,对开发和运维会是很大的压力,甚至影响系统的稳定性。例如我们当前的数据库使用的是 MySQL,而一个技术产品如果要求必须引入 MongoDB,那我一定会多想一下,我们多维护一个 MongDB 是不是值得。另外,如果大家对自己架构的演化有一定规划,那也要考虑引入的新的技术产品和未来的架构是否能够匹配。
最后,可能还会有一些额外的因素要考虑。比如许可协议的问题,前段时间闹得沸沸扬扬的 React Native 许可协议事件,相信大家记忆犹新。还有一些公司,可能对于使用第三方的程序或者服务,有一些原则甚至规范,那也一定要注意参考。另外,在稍大一些的公司里可能还会涉及一些派系之争,这里就不多说了。
我们上面已经列出了很多技术选型需要考虑的因素,那么到底如何进行技术选型呢?大致上可以分为以下几个步骤:
首先要明确选型的需求和目的,最好能列出必须要考虑的各种因素以及评判标准。
然后就可以开始寻找候选技术或产品了。这时范围可以尽量广一些,搜集尽可能多的候选技术和产品。
其次就可以进行初步筛选。把一些由于各种限制无法选择的、或者明显不可能的技术或产品排除,筛选出 3 个左右备选方案。
再然后就要做一些详细的调查和分析了。可以列一个表格,把备选方案、以及需要考虑的因素放到表格的横向和纵向中去,一个个进行评估的分析。此时可能会需要做一些小 Demo 验证可行性,或者做一些性能测试、压力测试等等。必要的话可以在表格里给每一个因素打分。
最后,对分析结果进行评审,作出最后决定。
技术选型分析表,每一格里可以有具体的打分,也可以有优势劣势的评价。
候选A | 候选B | 候选C |
---|---|---|
技术成熟度 | ||
架构一致性 |
当然,小的不太重要的技术选型也不一定要这么麻烦,而重要的技术选型则可能要反复各个步骤多次。
一定要进行可行性分析,如果不太确定,做个 Demo 验证一下。如果项目进行到一半,发现原来设想的某个方案不可行,那会是非常痛苦和浪费时间的事情。
不要有思维定势,习惯性的使用某些技术,比如服务化就用 Dubbo、缓存就用 Redis,具体问题要具体分析。也不要赶时髦,在重要的项目上使用太新的不够成熟的技术。
随着业务发展,很多架构需要不断升级,所以一定要考虑未来如果要替换某项技术,是否会很麻烦。可以选择符合一些标准的技术或产品,或者在应用中部署一个适配层,方便未来适配其他技术。
架构应该尽可能统一,一个领域避免引入太多相同功能的技术产品。
最后,大家其实会发现,技术选型既是一种科学、又是一种艺术,有时候并没有对错之分。最后面临两难选择的时候,还是需要决策人拿出勇气,拍板决定,坚定的去推进。
全文完
以下文章您可能也会感兴趣:
微服务环境下的集成测试探索(一) —— 服务 Stub & Mock
微服务环境下的集成测试探索(二)—— 契约式测试
乐高式微服务化改造(上)
乐高式微服务化改造(下)
一个创业公司的容器化之路(一) - 容器化之前
一个创业公司的容器化之路(二) - 容器化
一个创业公司的容器化之路(三) - 容器即未来
响应式编程(上):总览
响应式编程(下):Spring 5
复杂业务状态的处理:从状态模式到 FSM
后端的缓存系统浅谈
谈谈到底什么是抽象,以及软件设计的抽象原则
所谓 Serverless,你理解对了吗?
Linux 的 IO 通信 以及 Reactor 线程模型浅析
函数扩展
Apache Common Pool2 对象池应用浅析
服务网格:微服务进入2.0时代
我们正在招聘 Java 工程师,欢迎有兴趣的同学投递简历到 rd-hr@xingren.com 。
长按左侧二维码关注我们,这里有一群热血青年期待着与您相会。