聊聊“技术选型”的那些事
一、前言
我们在展开一个新的产品或者项目开发之前,一般需要进行技术选型,那么什么是技术选型呢?通俗来说就是:我们需要实现某个方面的需求,而市面上已经有很多现成的解决方案,那么我们就需要全面的评估各种解决方案,选择一个最适合我们使用的,这一个过程就是技术选型。
通常来说,技术选型有以下几个阶段:
- 1、技术调研
技术调研是指:可以实现我们需求的解决方案有哪些。我们可以先把这些方案列出来作为备选技术。 - 2、技术对比
技术对比是指:对这些备选技术进行一个全面的横向对比,对比的维度包含以下方面:使用复杂度、文档完善度、社区活跃度、功能完整度、发展趋势,最后肯定还要对比它们的性能了。 - 3、需求配对
需求配对是指:在我们了解了这些备选技术并做了全面的对比后,再根据我们实际的需求来选择一个最适合我们使用的技术。
那么接下来我们就根据以下几个需求来做技术选型:
- 构建分布式&微服务应用的需求
- 使用分布缓存服务的需求
- 使用消息队列的需求
- 使用搜索服务器的需求
这里需要特别说明,技术选型需要对各种技术进行全面的对比,那有可能笔者本身对某个技术的了解就有偏差,主观性比较强,所以以下的言论大家参考即可,不必较真,如有什么描述不对的地方,欢迎一起讨论,一起学习。
分布式&微服务框架选型
1、技术调研
在现在的分布式领域中,比较流行的分布式应用框架有Dubbo、Motan、SpringCloud,他们都可以构建分布式&微服务应用。其中Dubbo和Motan不管是使用上、思想上还是实现上,都是非常相似的技术,它们分别出自互联网大厂阿里和微博,经受了大规模服务调用的实际考验,同时被大量互联网公司应用在他们的生成环境中。而SpringCloud是大名鼎鼎的Spring家族的产品。Spring专注于企业级开源框架的研发,不论是在中国还是在世界上使用都非常广泛,开发出通用、开源、稳健的开源框架就是他们的主业。
2、技术对比
SpringCloud | Dubbo | Motan | |
---|---|---|---|
使用复杂度 | 由于SpringCloud与SpringBoot无缝整合,所以决定了SpringCloud的使用将非常简单,基本上就是加依赖、贴注解就搞定。并且服务提供方和服务消费方通过 Json方式交互,因此只需要定义好相关 Json 字段即可,消费方和提供方无API接口依赖,有效降低了模块的依赖关系。 | 框架使用动态代理的方式,屏蔽了远程调用和参数封装的麻烦,实现了调用远程方法就好像调用本地方法一样。但正因为使用了动态代理,所以服务提供方和服务消费方有API接口依赖,这就导致了项目各个模块之间的依赖关系非常复杂,增加了开发和维护的难度。 | 与Dubbo一致。 |
文档完善度 | Spring官网上有完善的文档,但是中文文档比较少,这对于英文菜鸡来说是一件比较头痛的问题。 | 有非常完善的中文文档。 | 官方文档不是很全,有些功能在文档上找不到。 |
社区活跃度 | 依托Spring开源家族,社区非常活跃,所以开发和维护团队强大,解决问题快,版本升级迭代快。 | 几乎到了停止维护的程度,但是18年一系列的动作,包含恢复维护和捐献给Apache,都一定程度的增加了活跃度,但还远比不上SpringCloud。 | 比Dubbo的活跃度更低。 |
功能完整度 | SpringCloud号称是分布式&微服务一站式解决方案的提供者,在所有的分布式框架中,功能是最齐全的。有几个核心的功能:服务调度、服务治理、服务注册中心、服务网关、熔断器、分布式配置中心、分布式服务跟踪系统、消息总线等。而这些功能的使用是开箱即用的。 | Dubbo在本身框架上,只能提供服务调度、服务治理、服务注册中心的功能,其他的功能需要整合第三方中间件,或者自己二次开发做扩展。增加了项目的复杂度和使用难道。 | 与Dubbo一致。 |
发展趋势 | SpringCloud的市场占有率是程上升的趋势,并且自身在快速发展完善。 | 从目前来看,市场占有率高,但发展平稳,有大量的项目使用Dubbo开发或改造,也有大量的项目从Dubbo改造成SpringCloud。自身发展到了一个成熟的阶段,后续不会有大的改动,除非推翻整个架构重新设计。 | 市场占有率低。 |
性能 | SpringCloud是使用REST接口通讯,而REST其实就是应用层的http协议,吧交互的数据是Json。在数据传输上,效率比较低,并且网络带宽占用比较大。 | Dubbo默认采用TCP协议,数据是二进制文件,传输效率高,带宽占用低。 | 与Dubbo一致。 |
3、需求配对
通过以上的对比,我们发现Motan没有一项对比是占绝对优势的,所以我们可以先排除掉Motan,剩下的就是SpringCloud和Dubbo之间选择了。而SpringCloud和Dubbo各有各的优势与劣势,SpringCloud的优势在于它的社区和发展前景,Dubbo的优势在于它的性能和文档,该选择哪个,就只能看我们具体的需求了。
如果准备开展的产品或项目,服务拆分的粒度是非常细的,那么首先需要考虑的是开发和维护的复杂度,网络性能和带宽其实不是什么太大的问题,如果真的成了问题,通过压缩、二进制、高速缓存、分段降级等方法,也能解决。所以这种情况下,就选择SpringCloud。反之服务拆分粒度不大,不会造成过于复杂和臃肿的模块依赖关系,那么根据Dubbo的网络传输性能来看,我不需要做额外的事情,就有一个性能强的应用,那肯定是选择Dubbo。
分布式缓存选型
1、技术调研
这里说的分布式缓存服务器,其实就是我们常说的Nosql数据库,在不考虑大数据的前提下,java领域里,流行的、优秀的分布式缓存服务器已经过滤剩不多了,我们这里列举3个备选技术:Redis、Memcached、MongoDB。既然我们的需求是使用分布式缓存,那缓存当然主要是操作内存了,这3款备选技术都是主要操作内存,而Redis和Memcached是Key-value型的,MongoDB是文档型的,各自都是自己所属类型Nosql数据库的优秀代表。
2、技术对比
Redis | Memcached | MongoDB | |
---|---|---|---|
使用复杂度 | 简单,就跟操作java的Map一样。 | 简单,就跟操作java的Map一样。 | 对比起来要难很多,需要学习它的查询语言。 |
文档完善度 | 文档齐全。 | 文档齐全。 | 文档齐全,但中文文档稍有欠缺。 |
社区活跃度 | 社区非常活跃,大量的开发者不断为Redis增加新功能。 | 不活跃。 | 虽然MongoDB Inc是一家上市的商业公司,但该公司对社区的回馈力度上却很大,非常注重自己的产品在开源社区中的发展。 |
功能完整度 | 对于key/value型的数据库来说,Redis的功能可以说是十分强大的。从支持的数据库类型来看,它支持String、List、Set、Hash,后续的版本还添加了GEO、Bitmap等数据类型。支持简单事务、消息队列。支持多种数据持久化方式和多种集群方式。 | 同是key/value型数据库,但是支持的数量类型少,只能使用String类型,不支持数据持久化。 | Json格式的文档型数据库,非常接近关系型数据库的使用方式,属于半结构化的数据库(json,xml),有强大的查询语法,健全的事务机制,简单的存储过程定义,也支持数据持久化和集群扩展。 |
发展趋势 | 市场占有率呈现上升趋势,并且版本不断更新,每次更新都新增很多实用的功能。 | 市场占有率低,版本更新慢。 | 在DB-Engines上总得分排名前5,长时间位于第4位,前3为分别是oracle,mysql和SQLServer,由此可以看出MangoDB的流行程度,并且增长率以较大的比率增长。 |
性能 | 在所有以内存操作为主的Nosql数据库中,单实例性能算是中规中矩,因为他是单线程的,没法利用CPU的多核优势,但好在大并发的情况下,减少了数据一致性的问题,和多线程环境上下文切换带来的额外消耗问题。 | 充分的利用了CPU多核优势,单实例性能极高,数据吞吐量也非常大,但由于不能做数据持久化,所以注定了它的应用场景只能作为缓存,不是一个真正意义上的Nosql数据库。 | 也是以操作内存为主,同时支持数据持久化,由于是半结构化的数据库,所以同样有索引功能,结合丰富的查询语句,可以快速的查询数据。 |
3、需求配对
从性能这个维度来看的话,这3款数据库性能都很高,对于我们来说都不会成为瓶颈。那么再通过其他维度对比的话,我们可以排除掉Memcached,因为它和Redis都是key/value数据库,但它各方面都不如Redis,那剩下的就是Redis和MongoDB了。
这两个Nosql数据库分别是key/value型和文档型的代表,各自有自己的应用场景,Redis更适合数据量不大,查询方式简单(即Map的这种通过key查询value),以作为关系型数据库的缓存为主的需求场景下更适合。而如果是以海量数据存储为主,查询复杂度接近关系型数据库,并且想在大多数业务下替换掉关系型数据库的需求场景下,则选择MongoDB。
消息队列技术选型
1、技术调研
分布式消息队列分成Broker类和Brokerless类,Broker类的消息队列,是指有独立部署运行的分布式服务,发送者把消息发送到Broker服务进程,再由Broker服务进程推送给订阅者,或者订阅者主动拉取消息。Brokerless类的消息队列,采用API的方式,编译到应用程序中,在应用程序间进行点对点的通信。而java领域里,分布式消息队列非常多,常见的有:ActiveMQ、RabbitMQ、RocketMQ、ZeroMQ、Kafka。其中RocketMQ是阿里开源的一款消息队列,性能和吞吐量非常高,这点是毋容置疑的,毕竟经受住阿里双11的考验,ZeroMQ则是为数不多的Brokerless类代表。所以我们选择这5款常见的、具有代码性的MQ作为备选技术。
2、技术对比
ActiveMQ | RabbitMQ | RocketMQ | ZeroMQ | Kafka | |
---|---|---|---|---|---|
使用复杂度 | 简单。 | 简单。 | 简单。 | 因为Brokerless的特点,所以需要API的整合,复杂度会稍微高一点。 | 使用方式上,跟其他的MQ有点区别,比如ActiveMQ和RabbitMQ。 |
文档完善度 | 文档全,但是比较乱。 | 文档齐全。官方翻译中文文档正在进行中。 | 是阿里开发的,文档齐全,但却没有中文文档,可能捐给了Apache后就由他们打理了。 | 文档不是很系统。 | 文档齐全。但中文文档稍有欠缺。 |
社区活跃度 | 是Apache下的一个开源项目,已经存在很久了,是非常老牌和成熟的项目,现在社区已经不怎么活跃了。 | 社区非常活跃。 | 社区不太活跃,据说GitHub上提交的问题解决的比较慢。 | 社区活跃度高。 | 社区活跃度高。 |
功能完整度 | 功能比较完善,支持的通讯协议多,消息持久化方式多,支持事务,支持高可用集群。 | 同样支持多种通讯协议和多种持久化方式,不支持事务。并且有插件机制,提供了许多插件,从多方面进行扩展,也可以编写自己的插件,所以功能非常丰富。 | 使用自有的协议通讯,支持持久化,不支持事务,使用分片的方式集群扩容,有容错容灾能力。功能上与Kafka非常相似,在设计上,一定程度的参考Kafka。 | 使用TCP协议作为消息通讯的方式,不支持消息持久化,不支持事务,比较轻巧。 | 使用自有的协议通讯,支持持久化,不支持事务,使用分片的方式集群扩容,有容错容灾能力。 |
发展趋势 | ActiveMQ虽然现在各方面都不太活跃,还有点老旧臃肿,感觉像日落西山的样子。但并不意味着ActiveMQ的寿命将要终止,因为其下一代产品Apollo,真在快速的版本迭代中,以另一种方式继续发展。 | 在分布式消息队列中使用率是最高的,并且使用率还在快速的增加,因为SpringCloud消息总线组件默认就是使用它。 | 当前主要是在中国用的比较多。官网上介绍的使用案例都是中国企业。但RocketMQ是后起之秀,借鉴了很多之前消息队列的优点,比如Kafka。所以后续的发展值得期待 | 知名度和市场占有率都相对较低。 | 大量用在大数据领域。 |
性能 | 性能和吞吐量差强人意,甚至还有用户反映有消息丢失的情况。 | 性能和吞吐量比ActiveMQ高,属于万级。消息也比较可靠。 | 性能和吞吐量非常高,属于十万级。 | 号称是“史上最快的消息队列”,专门为高吞吐,低延迟开发,但是与应用程序共享资源,扩容能力弱,所以这个称号其实有点噱头的意思。 | 性能和吞吐量非常高,属于十万级。 |
3、需求配对
ZeroMQ小而美,RabbitMQ大而稳,RocketMQ和Kakfa快而强。而ActiveMQ似乎没有什么特别可取之处,支持事务功能也比较鸡肋,所以企业新展开的项目一般都不会使用ActiveMQ了,还会使用的,那都是信仰和情怀了。ZeroMQ不是独立运行的中间件服务,除了消耗我们应用的资源外,自身集群扩展能力还很弱。而RocketMQ看似比上不足,比下有余,性能比除了Kafka外的其他MQ都高,但是社区活跃度和产品成熟度却比不上其他MQ。所以在RocketMQ还不是很成熟的现阶段,不会是最好的选择。剩下的RabbitMQ和Kakfa,具体选择哪一个,就按照我们实际需求来选择。
如果仅仅只是希望在自己的项目中添加一个分布式消息队列,并不要求有很高性能和吞吐量的,那RabbitMQ是一个很好的选择,消息既可靠,功能扩展性又高,且有SpringCloud官方支持。但是,如果对性能和吞吐量有很高要求的,或者做数据收集/分发、与大数据领域技术结合等特殊需求的场景下,则使用Kafka。
搜索服务器技术选型
1、技术调研
搜索服务的备选技术上,我们选择的是Solr和Elasticsearch,这两者底层都是使用Lucene搜索引擎,
Solr是Apache的开源项目,Elasticsearch是Elastic公司的开源技术栈之一。都是很流行的搜索服务器。
2、技术对比
Solr | Elasticsearch | |
---|---|---|
使用复杂度 | 简单。 | 对比Solr来说,稍显复杂,特别是安装流程,管理界面上。 |
文档完善度 | 完善,学习资料多。 | 中文文档相对缺乏,学习资料比较少。 |
社区活跃度 | 有更大、更成熟的开发者和贡献者社区。 | 主要靠Elastic公司开发和维护。 |
功能完整度 | 比较成熟。支持的数据格式多,如json、xml、csv,友好的管理界面,官方提供功能多,高可用集群需要依赖zookeeper。 | 不够成熟。只支持json数据格式,更注重于核心功能,高级功能由第三方插件提供,自带高可用集群功能。 |
发展趋势 | 在DB-Engines上总得分排名第15位,每年都有小幅下降。 | 在DB-Engines上总得分排名第7位,每年都以很高的幅度增长。 |
性能 | 当建立索引时, Solr会产生IO阻塞,查询性能下降。对已有的数据搜索时,性能比较高,但是随着数据量增加,Solr的搜索效率会下降。 | 建立索引时,不会产生IO阻塞。这方面Elasticsearch具有明显的优势,这对于实时搜索的要求有很大的帮助。对已有数据搜索没有Solr快,但是随着数据量增加,Elasticsearch的搜索速度没有明显的变化。并且亮点是其分布式的特点,集群扩展非常简单方便,数据分片存储,轻松扩展TB级别,所有节点对外表现对等,自动均衡。 |
3、需求配对
Solr在数据量不大的传统搜索应用表现要好于Elasticsearch,这体现在使用简易度上,功能上完整度上,还有少量数据搜索效率上。但Solr毕竟是很久之前的产品,似乎不太适应当前大数据发展的趋势,而Elasticsearch天生支持大数据,并且很多有大数据需求的互联网公司,实际生产环境测试,将搜索服务器从Solr转到Elasticsearch以后的平均查询速度有了50倍的提升。
所以,总的来说,数据量少的传统搜索应用可以使用Solr,新兴的实时搜索大数据应用选择Elasticsearch。