通过Erlang构建TCP服务应用案例(最原始方式)
文章来源:公众号-智能化it系统。
案例介绍
本文介绍的案例是tcp网络服务器的构建,用最原始的方式(非otp)。其功能很简单,通过网络tcp接口接收数据,按照指定的格式解析,并把数据存储至mongodb。接口消息的格式有明确规定,每条消息之间用“|”分割,用“#”标识一群消息的结束,消息中的每个字段格式为“字段名:字段值”,每个字段之间以空格分割。
该案例原先是用c#开发,后期随着数据的增长,一天到了数十亿,一连串的问题接连而来。频繁崩溃,性能跟不上等等。当时单机处理的上限是一天6亿。
后来在休闲时间用erlang语言实现了同样的功能,最后测试的性能和稳定性有了不错的体现,因为当时时间有限,没有把他优化的很好,但是是一个很有意思的应用。
考虑erlang的原因
当前早就进入了多核时代,一台服务器的cpu不可能只有一个,系统会否合理的利用是一个问题,大部分系统无法完全的利用,甚至只用了一个cpu,无疑这是对资源的浪费。而erlang可以让程序员轻松的解决。
erlang在国内尚未大范围的普及,大型的公司和系统能见到的非常少。但是价值不容小看。目前很流行的rabbitmq ,就是用erlang开发的。erlang的特点可以用两个字形容之:土,快。
土:erlang语言非常难以上手,甚至被评价为对程序员的眼睛最有杀伤力的语言,一开始编写会非常头疼。而且,其数据抽象能力实在不敢恭维,复杂的逻辑使用之会非常难受。
快:即其性能的优异表现了,使用erlang可以充分的利用上多核资源,效率非常的快。那么为什么其有这种功力呢,有以下几点特征,供参考:
-
如果您是一个java或c++等常用语言的开发者,您可以认为erlang没有变量,所有的变量只能赋值一次。
-
erlang没有线程的概念,erlang由轻量级的进程组成。以充分利用多核cpu。
-
erlang没有共享内存的概念,所有的进程通过消息来传递信息。这一点就是和文章开端的描述是对应的。
-
erlang进程之间传递数据非常快
综合以上的特征,需要高并发,高稳定性,并且中间逻辑简单的系统,erlang是非常不错的选择。
案例实现
该案例实现的关键点将在这里分享,包括关键的源码。
1. 建立tcp socket,并监听
{ok, listen} = gen_tcp:listen(28801, [list, {packet, 0}, {reuseaddr, true}, {active, once}]),
这里注意消息接收模式是active once,即半阻塞模式。接收模式的不同对系统影响很大,具体使用需要谨慎。
2. 建立mongodb的连接,并保存
mongodb需要下载公共包,mongodb-erlang-refactor,然后编译,小编阅读了其中的代码,部分的mongodb需要略做修改。
--建立连接
mongo_id_server:init([])
--存储数据
savemongo(list,con,cat) ->
try
[mongo:do(unsafe, master, con, 'soc_tobebuffered', fun() ->
mongo:insert(list_to_atom(cat), val)
end) || val <- list]
catch
_:_ -> io:format("error~p~n",[calendar:local_time()]),
exit("stop")
end.
3.在接收到数据后,开启进程处理
erlang创建进程使用spawn,pset = spawn(fun tcpreceivermulblopool:dataprocess1/0),具体处理逻辑见下。
该案例中没有用erlang otp来开发,所以算是最原始的代码,现在把主要的逻辑实现的代码分享如下,因为时间急迫,注释没有加,感兴趣的可以通过扫描文章下方的二维码关注公众号:智能化it系统,进一步的沟通了解。最终,在笔记本电脑上测试,每天处理的数据量可以达到10亿,笔记本的配置是4核,主频2.5,内存4g,大家可以按照案例的业务场景自己来测试。
公众号-智能化it系统。每周都有技术文章推送,包括原创技术干货,以及技术工作的心得分享。扫描下方关注。
上一篇: ViewPager之上传报名信息图片
下一篇: 一个分页效果ruby版可作为面试题吧