2012-02-01 73 views
6

我是一个真正的Erlang新手(1周前开始),我试图通过创建一个小而高效的聊天服务器来学习这种语言。 (当我说有效率的时候,我的意思是我有5台服务器用来对数十万连接的客户端进行压力测试 - 一百万会很棒!)什么是最好的,最有效的客户端池技术与Erlang

我发现一些教程这样做,唯一的是,每个教程我发现,是IRC喜欢的。如果一个用户发送消息,除发件人以外的所有用户都将收到该消息。 我想稍微改变一下,并使用一对一的讨论。

什么是搜索连接用户的最有效的客户端池? 我想过注册过程,因为它似乎尽我所需,但我真的不认为这是更好的方式来做到这一点。 (或者最好的办法就是这样做)。

有没有人会有这样的建议吗?

编辑:

每个连接的客户端都会影响到一个ID。

当用户连接时,它首先发送一个登录命令给它的id。 当一个用户要发送消息到另一个消息看起来像这样

[ID-NUMBER][Message] %% ID-NUMBER IS A FIXED LENGTH

当我问“最有效的客户池”,我实际上是寻找检索最快的方式/添加/连接的客户端列表,它可能是大(几千 - 百年甚至几百万)在删除一个客户端

编辑2:

为了回答一些问题:

  • 我使用原始套接字(使用telnet,现在与服务器通信) - 可能会移动后到SSL ...
  • 这是我自己的协议
  • 每一个客户是一个催生的Pid
  • 每个客户端的Pid都链接到它自己的监视器上(主要是为了调试的原因 - 客户端如果断开连接,它应该通过自己从头开始的认证来重新连接)
  • 我在开始编码之前已经阅读了几本书,所以我还没有掌握Erlang的每一个方面,但我不是没有意识到这一点,我会在需要的时候阅读更多关于它的内容。
  • 我真正想要的是存储和搜索PID的最佳方式,以便将PID直接从进程发送到进程。

我应该使用列表编写自己的搜索客户端函数吗?

还是应该使用ets?

甚至使用register/2取消注册/ 1和whereis/1来维护我的客户端列表,使用它的唯一ID作为原子,这似乎是最简单的方法,我真的不知道它是否是高效,但我很确定这是一个丑陋的解决方案;-)?

+0

我认为这是一个很棒的问题,虽然有点波浪。 – 2012-02-01 15:31:16

+0

您可以针对'搜索连接用户最有效的客户端池是什么?'这个更具体一点吗?我没有得到你的问题。 – Isac 2012-02-01 16:17:50

+0

@Isac:我编辑了我的帖子,希望你能找到更具体的 – TheSquad 2012-02-01 16:57:21

回答

1

我在做类似使用gproc作为发布订阅(类似于页面上的演示)你的聊天程序的东西。每个客户都注册为ID。要查找特定的客户端,请查看该客户端ID。要订阅客户端,请将属性添加到正在订阅的客户端ID的进程中。要发布,请调用gproc:send(ClientId,Message)。这涵盖了你的用例,更一般的基于聊天的聊天室,并且可以处理分布式的无主进程注册表。

我没有测试,看看它是否扩展到数以百万计,但它使用ETS做存储和GPROC是乌尔夫Wiger坚如磐石的代码。我不会指望能够写出更好的实现。

+0

谢谢我会研究它。是的,如果它是由Ulf Wiger写的,那么我会很难做到! +1给我迄今最尖锐的方式做到这一点! – TheSquad 2012-02-02 15:45:54

+0

它会比注册流程更有效率(在这种情况下,了解注册限制对我来说不是问题)? – TheSquad 2012-02-02 15:50:34

+0

这似乎正是我需要的!谢谢。我们只希望它能够很好地扩展。 – TheSquad 2012-02-03 14:57:58

2

我也是一种新的二郎神(几个月),所以我希望这可以让你在正确的道路:)

首先,因为你是个“新手”,你应该知道这些网站:

嘛,想着非持久性数据库,我建议setsgb_sets模块(文档here)。

如果你想持久化,你应该尝试dets(参见上面的文档),但是我不能说明任何关于效率的事情,所以你应该进一步研究这个话题。

在本书Learn You Erlang中,有一章节data structures表示sets对于读密集型系统更好,而gb_sets更适合平衡使用。

+0

谢谢我已阅读你发布的大部分内容,将查看Lear You Some Erlang。是的,是我的领导之一,只是看看是否有更多的选择。 – TheSquad 2012-02-02 15:36:02

1

现在,Messaging系统是每个人在来Erlang时都想做的事情,因为两者自然融合在一起。然而,在继续之前还有很多事情需要研究。消息传递基本上涉及以下事情:User Registration,User Authentication,Sessions Management,Logging,Message Switching/routinge.t.c.

现在,要做所有这些或大部分这些,需要有一个数据库,当然是IN-MEMORY,这就是我要么Mnesia要么是ETS Tables。既然你是Erlang的新手,我想你还没有真正掌握了这些。在某一时刻,你需要保持Who is communicating with whoWho is available for Chat e.t.c.因此,你可能需要查找一些东西并在某处写东西。

另一件事是你没有告诉我们客户。它会是一个Web客户端(HTTP),它是一个全新的协议,你正在通过原始套接字实现吗?哪种方式,你将需要掌握一些名为:Concurrency in Erlang。如果用户连接并被分配了ID,如果您的设计是A process Per User,那么您将不得不保存这些进程的Pid,或者根据一些标准注册它们,并再次监视它们是否死于e.t.c.这将我带到OTPSupervision trees。然而,有很多关于客户端和服务器交互的信息,即需要e.t.c的网络通信。或者它只是一个简单的Erlang RPC项目,您正在为自己的修订做些什么?



编辑

使用ETS Tables,或使用Mnesia RAM tables。不要想到注册这些Pid或将它们存储在列表,数组或集合中。看看this solution这是给this question

+1

其实我已经用boost-asio编写了一个使用C++的整个服务器端通信协议。但是我有一些限制,我主要想要超越线程。我认为Erlang是这样做的语言!我已经编辑了我的帖子回答你的问题,当你有时间时对他们采取很多措施,谢谢。 +1 – TheSquad 2012-02-02 15:38:53

+1

我也编辑了答案 – 2012-02-03 07:00:20

相关问题