Erlang——hotwheels源码剖析

整体构架:

janus_app(supervisor,  Pid_root)监工了以下四个:

janus_transport_sup(实质为transport, supervisor, Client Instance Supervisor):每个TCP会话创建一个transport进程来处理对应客户端的请求。

janus_topman_sup(实质为topman, worker, Topic Manager):通过topman(gen_server)模块创建多个pubsup模块(gen_server)进程来管理主题。

janus_proxy_mapper_sup(实质为mapper,worker, Client Proxy Mapper):客户端代理模块的记录。

janus_sup(实质为janus_acceptor,worker,TCP Server):接收TCP请求并处理。


以上的架构仅是初步的模块划分,接下来我会讲到对于TCP网络请求更为详细和精华的部分。如有错误或不足,请一定要拍我,谢谢!

启动流程:

janus.app ——》 janus_app.erl(supervisor),创建上述四个进程,在这里仅对janus_acceptor.erl进行跟踪。——》在janus_acceptor.erl中,acceptor_init()通过gen_tcp:listen()产生ListenSocket,此时{active, false}为阻塞,然后进入acceptor_loop开始循环监听客户端TCP请求。这个循环主要进行3个处理:

1.gen_accept()产生Socket;

2.gen_tcp:controlling_process()将上述Socket的通信分配到新生成的transport进程去处理;

3.设置transport的{active, once}开始消息接收 ——》得到消息后handle_info({tcp, Socket, Bin}, State)转交给新创建的janus_flash:process()进行处理,将服务器的业务逻辑提取到一个新的模块,这一点是很有必要的,因为在笔者目前的一个项目中由于当时Erlang的设计理念不成熟导致单个模块极端膨胀化,没有足够时间重构。——》janus_flash创建client_proxy(gen_server)客户代理来处理如心跳等会话管理操作,这里的心跳在下面会有背景介绍,facebook也采用这样的思想来维持会话的哦,亲。——》最后在mapper(gen_server)进行客户端会话代理的记录。


值得说的是:在janus_acceptor的gen_tcp:listen()的前后使用了proc_lib:start_link()和proc_lib:init_ack()配对处理来确保进程创建的原子性。

proc_lib:start_link()和proc_lib:init_ack()之间通过消息传递机制实现了一个小型的进程创建或相关处理的原子操作,在大家最为熟悉的gen_server, gen_fsm, gen_event中都应用了这种处理方式。说到erlang的标准库,我个人有一些在标准库函数的改进和扩充,接下来有时间的话我会写一个系列博客,讲述如何自学erlang以及使用一些好的erlang代码风格去编写更好的产品级代码。


接下来在hotwheels中其它的一些模块:

flashbot.erl & barrier.erl & bot.erl & histo.erl & launcher.erl:数据统计,计算latence等。

bin.erl:利用了re模块对二进制进行正则表达式计算(类似与perl的正则匹配规则)。

common.erl:提供了一个产生随机token的函数。

t.erl :调试相关处理,利用了dbg模块。

util.erl:对进程进行管理。



手机上的消息推送的解决方案目前有以下几种常用的方式:

1.定期查询:按照指定的时间间隔连接服务器查询获取最新的消息。实现起来简单,非实时,查询时间过短则流量耗费多,耗电量大。

2.长轮询(android适用):基本上与目前很多网站使用的方式一样(WEB阿里旺旺、微博、人人等等)。客户端发起一个很长超时时间的请求,然后服务器端在没有消息的时候阻塞这个请求(一直不给返回值)直到快要超时为止,有消息到来再返回响应。客户端收到响应或超时后立即再发起请求。

这种算是比较好的方式了,消息能够及时地到达客户端。但考虑到移动互联网的特点(网络不稳定、设备内存小)这种方式不能保证重要的消息一定能推送到客户端,另外anroid在手机内存小的情况下可能会杀这个在等待PUSH消息不怎么活动的进程。

3.push(iphone适用):由于iphone app在后台没有网络连接,则只能通过apple 官网的push去推送消息,但是有个比较郁闷的地方,即切到后台以后采用强制关闭的手段就不能获取通知来关闭push了,所以经常有些程序你没有开启但他照样推push,这可不一定是app的“强盗推销”,而有可能是这点所导致的。因此我阅读了apple官网,找到了一个权宜之计,就是apple push的destroy方法来获取该app应用的不积极用户并解除push关系。

4.XMPP:开源im通讯协议,貌似除了qq其它im都支持该协议。缺点就是先要有注册、登陆等过程,无线网络环境下连接的效果不怎么样。而且新浪的xmpp服务器不太稳定。。。

5.MQTT:基于代理发布/订阅 模式的消息传输协议,据说很适合无线手机应用,有时间就去看看,也有erlang的开源项目,可惜只到了0.1.0版本。。。https://github.com/erylee/eMQTT


刚学erlang,最近才找到学习的状态,明天会写一个cowboy的源码剖析。也欢迎大家就别的erlang问题和我讨论。没图没表的挺不好意思的,没办法,机子上就只有我不熟的linux系统。。。。。。


好想回去做c++。。。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值