为什么我要选择erlang+go进行服务器架构

服务器非业余研究http://blog.csdn.net/erlib 作者Sunface

估计很多同学看到这里都会觉得迷惑,go的大名已经如雷贯耳了,但是erlang?这个东东是神马?难道是编程语言?怎么从来没听说过。

这里请允许我先介绍一下使用Erlang开发的比较有名的应用:

一:whatsapp

只凭32个技术人员,如何应付4.5亿的用户?对于刚刚被Facebook用190亿美元收购的WhatsApp来说,答案是Erlang——一种诞生于上世纪80年代的编程语言,终于在此时走到了聚光灯下。

这个应用把erlang的特性发挥到了极致,利用到了它最好的vm、 集群基础设施、数据库mnesia, 消除了非常多的数据Scale、内存池和锁的问题, 提到的技术和修正点非常值得我们参考。

虽然大部分的解决方法我们在日常都差不多用过。但是他很系统的整理出来,用在商业系统了,这是个非常大的飞跃。

可以服务4.5亿用户的高可靠架构:

需要注意的是, WhatsApp的整体架构并未公开,这里仅仅是从不同信息源中获取不同的片段。Rick Reed的讲座主要分享了使用Erlang实现单服务器200万连接数,虽然很有价值,但是并不是整个应用架构

这些统计是当下系统的一些数据,更多针对数据存储、消息、meta-clustering以及新加入的BEAM/OTP补丁。

·4.5亿的活跃用户,并且是史上最快达到这个数字的公司

·32个工程师,平均每人支撑1400万活跃用户

·每天收发跨7个平台的500亿消息

·平均每天注册用户过百万

·0广告开销

·800万投资

·数百个节点

·8000+核心

·数百TB内存

·每秒Erlang消息超过7000万

·在2011年,WhatsApp单服务器取得 100万个tcp会话,同时还有内存和CPU剩余。在2012年,tcp会话发展到了200万

2013年WhatsAppf发表twriter声明70亿消息入站,110亿消息出战,即每天处理180亿消息,伟大的2013!

二百多万的长连接push服务器:

whatsapp数据集mnesia的规模:

生产系统的数据:

每秒的消息数:

发展历程:

1. WhatsApp服务器基本上完全使用Erlang实现

·做后端消息路由的服务器系统使用Erlang实现

·值得炫耀的是,如此庞大数量的活跃用户只使用非常少的服务器来管理,团队一致认为这很大程度上归功于Erlang。

·值得注意的是,Facebook Chat就是在2009年使用Erlang开发,他们弃用Erlang的原因是难以招聘到优秀的程序员。

2. WhatsApp服务器最早从Ejabberd开始

·Ejabberd是个非常出名的开源Jabber服务器,使用Erlang实现。

·最初选用它的原因是开放、广受开发者关注、易于开始以及Erlang在大型通信系统上的长期口碑。

·接下来的许多年一直从事Ejabberd的重写和修改,包括从XMPP转换到内部开发协议、调整代码库以及重设计一些核心组件,对Erlang VM做了大量的修改以获得高性能。

3. 为了应对每天500亿消息,工作重心被放到可靠系统的打造上,货币化对于我们来说还是件遥远的事情。

4. 系统的健康状况主要看队列的长度,每个节点上消息队列的长度都会被一直监控,超过预先设置的临界值则会发出提醒,多个警报发生则标志着系统进入了下一个瓶颈。

5. 通过上传图片、音频、视频到一个HTTP服务器上来发送多媒体消息,然后将链接与Base64编码的缩略图一起添加到内容(如果可用)。

6. 有些代码基本上每天都在变化,通常情况下是一天几次;当然,峰值期间必须避开的。Erlang非常适用于将修改或者是新功能添加到产品,热加载意味着无需重新启动就可以实现修改,错误可以很快的得到解决,同样通过热加载,系统变得更加松耦合,这可以让更新快速的发布。

7. WhatsApp使用了什么样的协议?WhatsApp服务器池使用了SSL Socket,在客户端重新连接对消息进行检索之前,所有消息都会在服务器上排队。消息的成功检索会发回给WhatsApp服务器,它将会被重新转发给原始发送者;一旦客户端成功接收这条消息,它就会在服务器存储中擦除。

8. WhatsApp注册程序的内部工作机制是什么样的?WhasApp依赖电话IMEI号码来建立用户名/密码,这点在最近已经修改。WhatsApp现在会让应用发送一个包含5位数Pin的一般请求,然后给这个电话号码发送一个SMS,这意味着WhatsApp客户端不再受限于某台手机。基于Pin的号码,应用会从WhatsApp请求一个唯一的键,这个键将作为未来的使用密码,这同样意味着在新的设备上注册后会无效原有设备上的键。

结果

开始时每个服务器有20万个并发连接。

第一个瓶颈出现每台服务器42.5万个连接的时候。系统遇到了很多冲突,工作停止了。安装调度器检测有多少有用的任务被停止、睡眠,或回转了。在加载时,它开始遇到睡眠锁,整个系统只用35-45%的CPU利用率,但调度程序的CPU利用率却达到了95%。

第一轮修复使连接数超过100万个。

VM利用率为76%,CPU利用率为73%,BEAM模拟器利用率为45%,与用户百分比很吻合,这是件好事,因为模拟器得和用户一样。

通常CPU利用率并不是好的评估方法,因为可能由于调度程序使用CPU导致系统看起来很忙。

一个月以后解决了瓶颈,每个服务器连接数达到200万个。

BEAM利用率为80%,与FreeBSD开始分页的情况接近。CPU利用率大致相同,有两倍的连接数。调度程序遇到了冲突,但运行得很好。

看来测试可以暂停了,这时开始分析Erlang代码。

最初每个连接有两个Erlang进程,消减为一个。

用计时器完成一些工作。

在每个服务器有280万连接时达到顶峰

571k pkts/sec, >200k dist msgs/sec

做一些内存优化,VM加载下降到70%。

尝试过将连接数增加到300万,但没有成功。

·当系统遇到故障时,查看长消息队列(单个消息队列或消息队列总和)。

·将每个进程的消息队列统计添加到BEAM设备上。包括发送/接收了多少条消息以及发送/接收的速度。

二:RabbitMq

这个相信大家都听说过,世界上最好的企业消息队列系统之一。

三:Web框架

Mochiweb,CowBoy等

四:电信级别的应用

爱立信等电信公司

五:游戏服务器领域的大范围应用

特别是在页游和手游领域,erlang简直如鱼得水,用erlang开发出的千万级流水游戏也是数不胜数

六:数据库

CouchDB,Riak等

七:其他领域的应用

目前据我所知,在银行业务,医疗业务,云业务领域都可以看到erlang活跃的身影.

为什么我要选择Erlang呢?

一、erlang特别适合中小团队创业:

erlang有异常成熟、经过电信级别大规模验证的OTP应用库,只需要很简单的代码就能建立起异常稳定、容错性强、扩展性强、高并发的服务器框架,这也是erlang最宝贵的核心价值所在。

二、erlang是天生的并发语言:

erlang的并发特性是语言级别的,从开发伊始就采用了CSP并发模式, 以进程为单位,进程间没有共享内存,变量不可变的实现方式保证了无锁的并发模型,因此也是异常高效的,换句话说:你只要像平常一样写代码就能并发,完全不用操心任何底层实现,你的代码能完美的并行运行在多核服务器上,如果你能写出漂亮的并发级别的算法和代码(尽量少的顺序代码),那在32核机器上就能跑出32倍性能!!!! Go 语言的并发模型也是取经于Erlang,但是我认为Erlang的并发模型更优秀,因为进程间完全没有共享内存,完全无锁。

三、再介绍下我当初的业务需求:

一款多人在线游戏,一个玩家走一步都要把消息广播给同屏的玩家,玩家聊天,战斗更涉及到大量的消息广播;如何应对?再有一个及其普通却不太容易搞定的的需求:在线玩家列表怎么实现?是啊,你是不是在想用哪种锁合适?提到的两个场景的关键词是:高并发,大量广播;可能你还会想到"锁".

我尝试过在.net下使用完成端口+TPL库+protocol buffer来完成上面的功能,但是并没有通过测试的检验,测试模型是聊天.在收发消息方面,客户端和服务器一对一的收发压力不大,但是一旦开启广播,压力一下就上去了.对象的频繁创建会导致垃圾回收,而垃圾回收会导致CPU和内存都飘忽不定,中间加入对象池会得到一定缓解,但是不能彻底解决问题,然后想到的就是人为干预垃圾回收,判断标准是什么呢?那就是用PerformanceCounter吧,结果发现PerformanceCounter一次调用分配的内存相当大!最后一版的结果是:聊天室模型,一人说话广播给所有人,300人在线能够稳定,人数一多就开始不淡定了.这些都是经过量化分析得出的结果,使用的工具是Visual Studio2010中的Performace Profile工具.

需要解决的第二个问题就是并发加锁,最简单的测试模型就是在线玩家列表.这个问题同样困扰了我很久,尝试各种锁,还是在抛异常,要么就是性能的下降,问题此起彼伏.后续还要解决TCP通信的数据格式,以及粘包等问题......

项目时间紧张,存在的风险很多,要尽快把技术方案确定下来然后去推进别的事情;但是可供选择的方案有C++和Erlang.坦白讲我和团队的基础如果使用C++方案,一定能搞出来,但是排错和性能优化将是一个巨大的挑战.那么Erlang呢?从开篇引用的那段文字看,好像这就是我需要的,简单了解了一下语法,还是很惊喜,由于之前对F#有过接触,一下感觉很亲切.而且我特别关注到:

优点:

1.面向并发,有成熟而且久经考验的框架可供使用,网络部分已经经过了良好封装

2.内存缓存解决方案进程字典,前者的读写速度是50NS-100Ns级别的

3.对二进制数据解析的语法是直观,简单,强大(游戏中有大量的二进制数据要处理

4.没有共享内存! 没有锁!(我们在代码中没有过显示使用锁)

缺点

1.从一种语言过渡到另一种语言,会有各种不爽:

2.控制逻辑简单只有if 和 case ,而且有if没有else,没有continue break goto

3.包括kernel库和standlib库在内,很多函数和变量的命名和传统语言不一样

因此我们就决定了采用erlang来重新写一套全新的架构,事实证明当初的决定是无比正确的,一个极少需要重启、能热更、稳定的游戏服务器实在是太重要了,而且开发过程和维护是如此的快速和轻松,我们的团队一致认为:从来没有想过开发会是这么一件愉快的事情!

既然Erlang已经被我“吹”的快飞起来了,为什么还要使用Go?

   鉴于Go语言已经妇孺皆知了,我也就不介绍了,大概说说我自己的情况,我这人没啥其他兴趣爱好,业余时间绝大部分都花费在所谓的“程序员要不停的学习才不会落伍”上,因此在11年的时候,知道了go,断断续续学习了一年后,Go1.1版本出来后,发现改进很大,就开始认真研究并常年混迹在google-group及国外大牛的博客世界中,自我感觉还可以。当然我绝对不是Go的“朝圣者”,也发现Go确实不是非常完美,具体可以参见“为什么我要放弃Go“,此文作者的观点我虽然不敢完全苟同,但是有些观点还是赞同的,比如说很多Go爱好者是非常护短的,如果你敢说什么“坏话”,就等着被查水表吧 ;)。

由于Erlang和Go都是非常棒的语言,这里就出现一个问题:二选其一还是物尽其用?经过深思熟虑后,我和团队选择了后者。首先,erlang的OTP写服务器并发框架非常之简单、稳定且高性能,erlang的Mnesia数据库也是很轻量:速度很快,分布式简单,使用起来也很原生态(是Erlang标准库支持的),所有的这些都能把程序员从繁琐的工作中解放出来,但是,erlang也有个挺重要的问题(在不同业务场景中此问题也许很突出,也可能完全无关紧要,至少85%的情况下不算一个问题):它是虚拟机语言,对于顺序代码的执行速度只有C的七分之一,虽然可以利用多核的优势,但是在大型mmorpg中,消息密集时,CPU的瓶颈还是挺明显的,会影响玩家顺畅的体验感觉(ARPG)。

因此我就想如果逻辑这部分用Go来写,是不是可以很好的利用这两个语言的优点进行互补?心动不如行动,由于我们的erlang游戏架构的藕合度还是挺低的,因此分离出来地图服务器,用Go重新实现了下,通过socket跟erlang架构部分进行通信,发现效果异常之好,Go的性能、并发的原生支持再配合上erlang写游戏框架,在性能上已经绝不亚于C++框架,但是后者大家都懂,中关村程序员据说平均寿命50多岁,很大的一部分原因是因为这个。

以后的路怎么走?

    混合型编程会是以后的主流,因为没有哪个语言是完美的,包括被众多“朝圣者”所推崇的Go,如果我们能根据自己的业务场景,选对合适的语言,那不敢说事半功10倍,至少事半功倍应该是有的,所以不要被主流语言(Java,C++)禁锢了我们的世界,局限了我们的创新,如果能做到轻松愉快的开发,那这个世界该多美好!!

时间: 2024-10-26 06:47:47

为什么我要选择erlang+go进行服务器架构的相关文章

为什么我要选择erlang+go进行服务器架构(2)

为什么我要选择Erlang呢? 一.erlang特别适合中小团队创业: erlang有异常成熟.经过电信级别大规模验证的OTP应用库,只需要很简单的代码就能建立起异常稳定.容错性强.扩展性强.高并发的服务器框架,这也是erlang最宝贵的核心价值所在. 二.erlang是天生的并发语言: erlang的并发特性是语言级别的,从开发伊始就采用了CSP并发模式, 以进程为单位,进程间没有共享内存,变量不可变的实现方式保证了无锁的并发模型,因此也是异常高效的,换句话说:你只要像平常一样写代码就能并发,

为什么我要选择erlang+go进行server架构(2)

原创文章,转载请注明出处:server非业余研究http://blog.csdn.net/erlib 作者Sunface 为什么我要选择Erlang呢? 一.erlang特别适合中小团队创业: erlang有异常成熟.经过电信级别大规模验证的OTP应用库,仅仅须要非常easy的代码就能建立起异常稳定.容错性强.扩展性强.高并发的server框架,这也是erlang最宝贵的核心价值所在. 二.erlang是天生的并发语言: erlang的并发特性是语言级别的,从开发伊始就採用了CSP并发模式, 以

Erlang cowboy websocket 服务器

Erlang cowboy websocket 服务器 原文见于: http://marcelog.github.io/articles/erlang_websocket_server_cowboy_tutorial.html 本文不是原文的简单翻译,是参考原文,根据我的理解和实践写出来的.本文的源码见于: https://github.com/marcelog/erws 1 引言 Erlang可以用来实现一个websocket服务器.cowboy这样框架可以完成这个任务,是我们不必关注webs

同一世界服务器架构--Erlang游戏服务器

Erlang最大的优点是方便,很多基础功能都已经集成到Erlang语言中.之前用C++写服务器的时候,管理TCP连接很繁琐,需要写一大堆代码来实现.底层的框架需要写很多代码实现,这样既浪费时间,又会有很多BUG.但是用Erlang就方便多了,底层的一切你都不需要考虑,你只需要考虑,服务器的架构以及业务逻辑.从此让你彻底从底层的泥潭中解脱.我从去年年底开始了解学习Erlang,到现在我已经彻底爱上了Erlang.好了,废话不多说,开始详细介绍下我设计的这个服务器架构吧. 首先看下整个架构的布局,如

怎样选择优秀的云服务器供应商

云计算的概念内涵丰富而模糊,大多数人缺乏清晰准确的认知,直到云服务器的出现,使人们从基础设施服务层面入手,对云计算获得较为直观具体的认识.云服务器的产品优势,主要集中在稳定性.扩展性.性能.灵活性.安全性等方面,且日益表现出标准化的趋同发展形势.此时,一个高品质的云服务器供应商,不但可以帮助企业改进IT架构,获得业务增长,更能通过优质服务减轻企业运维压力.那么,怎样选择优秀的云服务器供应商呢? 一.判断供应商的云平台基础架构表现. 新型的云平台,是为解决传统IT架构不够稳定和安全.单点故障等问题

如何选择适合的国内服务器? 服务器比的是什么?国内服务器的优势在哪里?

在这个互联网发展越来越快的时代,用户在选择服务器时,速度,稳定性和防御成了重中之重.网络是否流畅,是否常常出现卡顿,这些都是很关键的因素.(服务器租用咨询QQ:1373852350)而且现在网络安全越来越得到人们的重视,网络攻击不断,同行之间的恶意竞争越来越频繁.这就需要带防御攻击能力的服务器来抵挡各种各样的攻击.服务器根据地域可以分为国内与国外的.因为服务器的速度直接决定了用户的体验,所以租用服务器首先需要考虑的就是速度,国内服务器相比国外服务器来讲,优势就是速度,一般国内的服务器国内访问的速

如何正确选择境外免备案服务器

众所周知,国内的服务器是需要进行备案的,否则搭建的网站是不允许被打开的,但境外的服务器则是免备案的,所以许多站长都会选择境外服务器 .那么,境外免备案服务器租用该如何正确选择呢? 首先,我们要知道目前免备案服务器有两大类,一种是香港服务器,香港使用的是国际带宽,所以说备案方面也是跟国际准则接轨的,所以香港服务器不需要备案,站长可以直接租用后使用进行网站建设.另一种就是国外服务器,国外服务器是指在其他国家服务器租用或是托管服务器,由于每个国家对互联网的政策不一样,所以说国外服务器也是不需要备案的.

怎么选择适合自己的服务器??

怎么选择适合自己的服务器??一,价格,这是我们最关心的问题,性价比一定要高.最好全方位了解这个机房,包括和你谈业务的工作人员,如果这个工作人员不是很负责人不是很负责人的话,那么恐怕即使你用了该机房机房资源,那以后的售后未必好啊.详情企鹅:428140675 二,数据湾香港服务器带宽,这个不用多说了,每个人都有每个人的考虑.带宽,一般过于便宜的机房都是带宽给不够就是线路不稳定,总之相信一句话:天上不掉馅饼. 三,看机房的总带宽,硬防之类的具体细节,这是很关键的,必须要引起足够的重视.这个东西只听业

怎么选择好的香港服务器?

壹基比Yang-3005303285 好的香港服务器,是企业互联网业务正常开展的有力保障,可以避免用户耗费过多的精力和成本去维护服务器的正常运行.面对型号繁多且层出不穷的香港服务器产品,怎样选择好的香港服务器呢?众所周知,好的香港服务器,意味着足够高的稳定性,足够快的访问速度,以及契合企业需求.那么,怎样选择好的香港服务器呢? 一.明晰需求,确定初步服务器购置计划 怎样的香港服务器才最适合自己?企业评估自身需求时,不妨从技术现状.业务发展和成本控制这三个角度入手.首先,你需要回答几个问题:服务器