移动互联网时代,推送服务是很重要的基础服务之一。很多公司都推出了自己的推送服务。推送服务对稳定性、高并发等有很高的要求,之前我们报道过小米的推送服务,今天我们又采访了云巴的创始人兼 CEO 张虎,探讨了推送服务的技术选型、编程语言的选择和程序员的成长等话题。
张虎,曾就职于华为、Oracle 等公司,有十几年的软件研发经验。Oracle VM 的创始团队成员,早在 2007 年就开始基于 Xen 做开发。极光推送的创始人,原 CTO,创意并主导开发的系统为过万开发者、过亿终端用户提供了推送服务。现为云巴的创始人,CEO。
InfoQ:作为国内最早做推送服务的人之一,可以介绍下您在做推送服务时的技术选型吗?比如考虑了哪些因素,在协议、架构、编程语言等方面有哪些考量?
张虎:最早开始做推送服务时,我就把当时的产品定位为一个开放的云服务,面向所有的 Android/iOS 系统,定位在亿级用户量。协议的选择、系统的架构设计、使用的技术平台都基于这个考虑。
协议的选择:
a. 推送系统的业务逻辑相对简单,在选取协议时,不需要使用太复杂的协议。
b. 由于目标用户量巨大,考虑到带宽、编解码等因素,优先选择二进制协议。
当时最早的系统原型是用 XMPP 搭建的,但后来在产品化阶段改用了自定义的二进制协议。(目前的产品云巴采用了开放的二进制协议 MQTT。)
架构设计:
a. 架构设计首先要考虑弹性扩容的问题。容量可以通过添加服务器扩大,并且能在不中断业务的前提下在线扩容。
b. 考虑到系统要长期不间断运行,支持在线替换业务逻辑也非常重要。这样之后修复 bug、升级业务逻辑,都不会中断业务。
c. 同时,架构还要方便自动化部署、运维和业务监控等。
编程语言:
选取什么样的编程语言主要看业务的类型。
实时的消息系统有如下几个特点:
a. 维持大量长连接;
b. 请求并发量大;
c. 业务逻辑相对简单。
这种场景目前看我个人感觉最匹配的语言/平台应该是 Erlang/OTP。早期因为种种原因主要采用C语言。但在现在的产品(云巴)里,主要采用 Erlang/OTP。
InfoQ:您在微博上提到,"1 年前,团队 Erlang 经验接近零;1 年后,系统多个主要模块用 Erlang 开发",可以具体介绍一下其间的经历吗?现在国内的大学计算机教育还是以以C语言为代笔的命令式语言为主,函数式编程风格很多人并不习惯。您的团队是如何引导大家学习和应用 Erlang 的?
张虎:我们一直觉得,大并发的实时通讯场景,用 Erlang 是最佳选择,所以在开始做云巴这个产品时,我们就刻意在团队里学习、培养 Erlang 方面的开发人员。
最早从我自己开始,调研现有的哪些产品使用了 Erlang,特别是实时高并发的产品,阅读他们的博客和发表的文章,了解他们的心得。后来我开始写一些产品的原型,团队部分成员开始尝试解决一些小的 bug,慢慢开始写一些小的模块。这段时间我会 review 所有代码,引导团队学习正确的方法。经过一段时间的积累,部分成员就慢慢能独立编码,再发展就有人能参与 review 代码了。
任何编程语言的学习和使用,语言本身的门槛其实都是有限的,只要静下心来花一点时间,很快就能掌握。重要的是要很好的掌握语言的最佳实践,需要多看别人的代码,多动手验证。
另外,计算机的基础知识可能更重要。理解现有知识栈里各个环节的原理,对学习一门新的语言、平台有很大的帮助。比如任务调度、内存管理、编译 (compile)、链接(link)、代码装载(load) 等等。
以 Erlang 为例,除了 Erlang 本身的语法外,Erlang 的任务调度、垃圾回收、消息机制、动态代码替换等等,如果有良好的操作系统原理基础,对理解这些概念非常有帮助。
InfoQ:最近几年,Scala 和 Go 等语言也比较热门。如果现在再做技术选型的话,你会选择此类语言吗?
张虎:因为 Scala 和 Go 也为了适用于高并发的场景做了很多工作,我们也在持续关注。我们也会不定期用这些语言写一些业务模块,帮助我们深入了解这个语言的特征。
InfoQ:看过您的几篇博客,比如“请不要说自己是 Java 程序员”。您强调的是用正确的语言做正确的事。当然,其前提是对不同的编程语言有较深入的理解。您是如何快速掌握一门新的编程语言的呢?依靠文档、手册或书籍?还是对语法有了基本的了解之后,快速实现一些小型项目?
张虎:一门高级语言被发明,一般都有一些它试图去解决的问题。在深入地学习前,了解这些目的会很有帮助。
然后我会快速地了解它的开发、编译和运行环境,跑通一个 “Hello, World.”。
下一步就是根据这门语言试图解决的问题场景,写一个小的项目原型,了解典型的业务框架。再就是做一些基准测试,了解 CPU 和内存的使用特点。
简单地说,设定一个典型应用场景,快速 “玩” 起来,是学习一门语言的好的开始。其他深入的了解,可以在使用过程中,根据需要一个一个具体研究。
InfoQ:您有一篇博客——“我理解的优秀软件工程师”,看得出您对工程师的综合素质要求是比较高的。您的团队在招聘的时候是如何把控全栈工程师的选拔的呢?
张虎:简单地说,我期待的优秀软件工程师不是只知道事情是怎么样,更应该了解它为什么是这样。
比如所有软件工程师都知道编译代码、部署运行,这个不能说明太多问题。但是对代码的编译过程、装载过程、部署到框架或者操作系统上的过程、然后怎么启动、通过什么机制与其他模块通讯等,这些基本原理了解程度,往往决定一个工程师能力的关键。
InfoQ:您是否可以结合个人的经历,对工程师的成长提供一些建议?
张虎:我们开始学习编程的时候,还没有那么多高级的语言、平台,电脑的配置也很低,一开始主要是在像 DOS 这样的环境下学习C语言和汇编语言编程,接触了很多基础的知识。
后来,为了深入了解操作系统原理,在嵌入式系统上学习 uCOS、vxWorks,到后来学习 Linux Kernel。阅读它们的代码,在机器上用调试器观察它们的运行过程。同时还研究过链接器和加载器(linkers and loaders)这些相关的东西。
虽然现在几乎都不会直接用这些东西,但这个过程中打下的基础对我帮助非常巨大。
比较而言,现在的计算机教育会有很大不一样,很多人在大学就开始学习用一些很高级、大型的语言/平台来解决具体的业务问题,而对基础知识的学习非常少,我个人感觉这是本末倒置。
有好的基础,应用性质的东西,在需要使用的时候,自然就学会了。如果基础不好,很难有提高。
在 InfoQ 举办的 ArchSummit 深圳 2014 大会上,张虎曾做过题为“实时系统架构与实践”的演讲,感兴趣的读者可以观看。
亲爱的读者,您对程序员的个人成长有何看法呢?欢迎和我们交流。