抽取rabbitmq网络层做的echo server
传说rabbitmq网络层实现的优雅高效,于是我就尝试着将其中的网络层抽取出来,模拟着做了一个echo服务器,代码放在这里.
这里面绝大部分都是可以重用的,或者说稍微改一下配置比如端口地址就可以了.业务相关的部分可以通过回调函数start_client来做到,见echo_server.erl代码中,启动tcp_server_sup的时候,传入的Acceptcallback参数是echo_server:start_client函数,这个函数将在接收到一个新的链接之后调用,在echo_server中这个函数的作用是通过tcp_connection_sup动态创建一个echo_connection子进程来管理接收到的这个socket,在echo_connection中真正做业务处理.这里的tcp_connection_sup,也是可以根据传入的MFA参数来创建子进程的,为以后的扩展提供了方便.
再来看echo_connection中如何处理业务逻辑.在之前看过的erlang服务器代码比如onecached中,处理客户端连接请求的做法是,创建两个子进程,其中一个负责接收数据,另一个是一个gen_fsm负责控制处理逻辑的业务状态机,两者之间通过消息传递.这样的做法有两个问题,第一是子进程之间传递消息多了一次消息copy的过程,第二是gen_fsm内部实际上是根据tag来判断状态机的走向(具体可以阅读stdlib中gen_fsm的实现代码),两个因素加起来对性能的影响还是不小的.
rabbitmq的做法是内置状态机,通过切换callback的形式处理不同的业务,这样只有一个子进程处理一个链接,性能提高不少.
测试这个echo服务器的客户端我使用的是telnet,telnet输入的数据会自动在后面加上”\r\n”发送到对端,于是代码中以这个来判断是否接收了一条消息,抽取出来回复给对端.
整个代码中,就是echo_server/echo_connection部分需要根据业务重写,其他的部分都可以重用,另外也可以按照前面提示的自己嵌入状态机来处理请求.
参考资料: Rabbitmq的网络层要点浅析