【问题标题】:What is the best, most efficient, Client pool technique with Erlang什么是 Erlang 最好、最有效的客户端池技术
【发布时间】:2012-02-24 05:50:47
【问题描述】:

我是一个真正的 Erlang 新手(1 周前开始),我正在尝试通过创建一个小型但高效的聊天服务器来学习这门语言。 (当我说高效时,我的意思是我有 5 台服务器用于对数十万连接的客户端进行压力测试 - 一百万会很棒!)

我找到了一些这样做的教程,唯一的是,我找到的每个教程都类似于 IRC。如果一个用户发送一条消息,除了发件人之外的所有用户都会收到它。 我想稍微改变一下,并使用一对一的讨论。

搜索连接用户最有效的客户端池是什么? 我考虑过注册该进程,因为它似乎可以完成我需要的一切,但我真的认为这不是更好的方法。 (或者无论如何都是最漂亮的方式)。

有人对此有什么建议吗?

编辑:

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

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

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

当我询问“最有效的客户端池”时,我实际上是在寻找最快的方法来检索/添加/删除已连接客户端列表中的一个可能很大(数十万 - 可能是数百万)的客户端)

编辑 2:

回答一些问题:

  • 我正在使用原始套接字(现在使用 telnet 与服务器通信)- 稍后可能会迁移到 ssl...
  • 这是我自己的协议
  • 每个客户端都是一个派生的 Pid
  • 每个客户端的 Pid 都链接到它自己的监视器(主要是出于调试原因 - 如果断开连接,客户端应该通过它自己的从头开始的身份验证重新连接)
  • 在开始编码之前我已经阅读了几本书,所以我还没有掌握 Erlang 的各个方面,但我并不是不了解它,我想我会在需要时阅读更多关于它的内容。
  • 我真正在寻找的是存储和搜索这些 PID 以直接在进程之间发送消息的最佳方式。

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

或者我应该使用 ets 吗?

甚至使用 register/2 unregister/1 和 whereis/1 来维护我的客户列表,使用它的唯一 id 作为 atom,这似乎是最简单的方法,我真的不知道它是否有效,但我很确定这是丑陋的解决方案 ;-) ?

【问题讨论】:

  • 我认为这是一个很棒的问题,虽然有点曲折。
  • 您能否更具体地说明“搜索连接用户最有效的客户端池是什么?”?我没明白你的问题。
  • @Isac : 我已经编辑了我的帖子,希望你会发现它更具体
  • @TheSquad 好多了,谢谢!
  • 也检查答案编辑

标签: sockets erlang client-server server-side


【解决方案1】:

我也是 Erlang 的新手(几个月),所以我希望这能让你走上正确的道路 :)

首先,既然你是“新手”,你应该了解这些网站:

好吧,考虑到非持久性数据库,我建议使用setsgb_sets 模块(文档here)。

如果你想要持久性,你应该尝试dets(参见上面的文档),但我无法说明效率,所以你应该进一步研究这个话题。

在《Learn You Some Erlang》一书中,有一章关于data structuressets 更适合阅读密集型系统,而gb_sets 更适合平衡使用。

【讨论】:

  • 谢谢 我已经阅读了您发布的大部分内容,将研究 Lear You Some Erlang。是的,是我的领导之一,只是看看是否有更多的选择。
【解决方案2】:

我正在使用gproc 作为发布订阅(类似于该页面上的演示)来执行与您的聊天程序类似的操作。每个客户端都注册为它的 ID。要查找特定客户,您可以查找该客户 ID。要订阅客户端,您需要将属性添加到所订阅的客户端 ID 的进程中。要发布,您调用 gproc:send(ClientId,Message)。这涵盖了您的用例,也包括更一般的基于房间的聊天,并且可以处理分布式无主注册进程。

我还没有测试它是否可以扩展到数百万,但它使用 ets 进行存储,而 gproc 是 Ulf Wiger 的坚如磐石的代码。我不会指望能够编写更好的实现。

【讨论】:

  • 谢谢,我会调查的。是的,如果它是由 Ulf Wiger 写的,我将很难超越它! +1 为我提供了迄今为止最有针对性的方法!
  • 会比注册进程更有效吗(知道在这种情况下注册的限制对我来说不是问题)?
  • 这似乎正是我所需要的!谢谢。让我们希望它能很好地扩大规模。
【解决方案3】:

现在,消息系统是每个人在使用 Erlang 时都想做的事情,因为这两者自然融合。但是,在继续之前,有许多事情需要研究。消息传递基本上涉及以下内容:User RegistrationUser AuthenticationSessions ManagementLoggingMessage Switching/routing 等。

现在,要完成所有或大部分这些,需要有一个数据库,当然是在内存中,这使我可以选择 MnesiaETS Tables。由于您是 Erlang 的新手,我想您还没有真正掌握使用这些。在某一时刻,您需要维护Who is communicating with whoWho is available for Chat 等。因此,您可能需要在某些地方查找内容并写下内容。

另一件事是您没有告诉我们客户。它将成为 Web 客户端 (HTTP),它是您正在通过原始套接字实现的全新协议吗?无论哪种方式,您都需要掌握一种叫做:Concurrency in Erlang 的东西。如果用户连接并分配了ID,如果您的设计是A process Per User,那么您将必须保存这些进程的 Pid 或根据某些标准注册它们,如果它们死亡等,则再次监视它们。这让我想到了OTPSupervision trees。有很多,但是,告诉我们更多关于客户端和服务器交互,你需要的网络通信等等。或者它只是一个简单的 Erlang RPC 项目,您正在为自己的修订而做?



编辑

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

【讨论】:

  • 实际上我已经使用 C++ 和 boost-asio 编写了一个完整的服务器端通信协议。但是有一些限制是我想超越的,主要是关于线程。我认为 Erlang 是这样做的语言!我已经编辑了我的帖子,回答了您的问题,请在您有时间的时候多做一些,谢谢。 +1
猜你喜欢
  • 1970-01-01
  • 2010-11-18
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
  • 2023-03-20
  • 2015-12-05
  • 1970-01-01
相关资源
最近更新 更多