Erlang 最好、最高效的客户端池技术是什么

发布于 2025-01-01 00:50:33 字数 1110 浏览 2 评论 0原文

我是一个真正的 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作为原子,这似乎是最简单的方法,我真的不知道它是否有效,但我我很确定这是一个丑陋的解决方案;-)?

I'm a real Erlang newbie (started 1 week ago), and I'm trying to learn this language by creating a small but efficient chat server. (When I say efficient I mean I have 5 servers used to stress test this with hundreds of thousands connected client - A million would be great !)

I have find some tutorials doing so, the only thing is, that every tutorial i found, are IRC like. If one user send a message, all user except sender will receive it.
I would like to change that a bit, and use one-to-one discussion.

What would be the most effective client pool for searching a connected user ?
I thought about registering the process, because it seems to do everything I need, but I really don't think this is the better way to do it. (Or most pretty way to do it anyway).

Does anyone would have any suggestions doing this ?

EDIT :

Every connected client is affected to an ID.

When the user is connected, it first send a login command to give it's id.
When an user wants to send a message to another one the message looks like this

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

When I ask for "the most effective client pool", I'm actually looking for the fastest way to retrieve/add/delete one client on the connected client list which could potentially be large (hundred of thousands -- maybe millions)

EDIT 2 :

For answering some questions :

  • I'm using Raw Socket (Using telnet right now to communicate with server) - will probably move to ssl later...
  • It is my own protocol
  • Every Client is a spawned Pid
  • Every Client's Pid is linked to it's own monitor (mostly for debugging reason - The client if disconnected should reconnect by it's own starting auth from scratch)
  • I have read a couple a book before starting coding, So I do not master yet every aspect of Erlang but I'm not unaware of it, I will read more about it when needed I guess.
  • What I'm really looking for is the best way to store and search thoses PIDs to send message directly from process to process.

Should I write my own search Client function using lists ?

or should I use ets ?

Or even use register/2 unregister/1 and whereis/1 to maintain my client list, using it's unique id as atom, it seems to be the simplest way to do so, I really don't know if it is efficient, but I'm pretty sure this is the ugly solution ;-) ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

两个我 2025-01-08 00:50:33

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

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

I'm doing something similar to your chat program using gproc as a pubsub (similar to the demo on that page). Each client registers as it's id. To find a particular client, you do a lookup on that client id. To subscribe to a client, you add a property to that process of the client id being subscribed to. To publish, you call gproc:send(ClientId,Message). This covers your use case, the more general room based chat as well, and can handle distributed masterless registry of processes.

I haven't tested to see if it scales to millions, but it uses ets to do the storage and gproc is rock solid code by Ulf Wiger. I wouldn't count on being able to write a better implementation.

柠檬心 2025-01-08 00:50:33

我对 Erlang 还很陌生(几个月了),所以我希望这能让你走上正确的道路:)

首先,由于你是一个“新手”,你应该了解这些网站:

  • < a href="http://www.erlang.org/doc/index.html" rel="nofollow">Erlang 官方文档:
    最常见的模块位于 stdlib 应用程序中,因此从那里开始。
  • 替代文档
    有实时搜索引擎,搜索的时候真的很好用
    对于特定模块。
  • Erlang 编程规则
    让你进入erlang编程的思维模式。
  • 学习一些 Erlang 书籍
    每个从 Erlang 开始的人都必须阅读的一本书。真的很全面
    阅读起来很有趣!
  • Trapexit.org
    论坛和食谱,用于搜索程序员面临的常见问题。

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

如果您想要持久性,您应该尝试 dets (请参阅上面的文档),但我无法说明有关效率的任何内容,因此您应该进一步研究这个主题。

《Learn You Some Erlang》一书中有一章介绍数据结构 这表明 sets 更适合读取密集型系统,而 gb_sets 更适合平衡使用。

I'm also kind of new to Erlang (a couple of months), so I hope this can put you in the correct path :)

First of all, since you're a "newbie", you should know about these sites:

Well, thinking about a non persistent database, I would suggest the sets or gb_sets modules (documentation here).

If you want persistence, you should try dets (see documentation above), but I can't state anything about efficiency, so you should research this topic a bit further.

In the book Learn You Some Erlang there is a chapter on data structures that says that sets are better for read intensive systems, while gb_sets is more appropriate for a balanced usage.

苏佲洛 2025-01-08 00:50:33

现在,消息系统是每个人来到 Erlang 时都想做的,因为两者自然地融合在一起。然而,在继续之前有很多事情需要研究。消息传递基本上涉及以下内容:用户注册用户身份验证会话管理日志记录消息交换/路由

现在,要做所有或大部分这些,需要有一个数据库,当然是内存中的,这导致我要么Mnesia美国教育考试服务中心表格。由于您是 Erlang 新手,我想您还没有真正掌握如何使用这些。某一时刻,您需要维护谁正在与谁通信谁可以聊天等,因此您可能需要查找内容并在某个地方编写内容。< br>
另一件事是你还没有告诉我们客户。它将是一个 Web 客户端 (HTTP),它是您通过原始套接字实现的全新协议吗?无论哪种方式,您都需要掌握一些叫做:Erlang 中的并发的知识。如果用户连接并分配了一个ID,如果您的设计是每个用户一个进程,那么您将必须保存这些进程的 Pids 或根据某些条件注册它们,再次监视它们是否死亡等等,这让我想到了 OTP 和监督树。不过,还有很多,请告诉我们更多有关客户端和服务器交互、您需要的网络通信等的信息,或者这只是您正在为自己的修订所做的一个简单的 Erlang RPC 项目?

编辑

使用ETS表,或使用Mnesia RAM表。不要考虑注册这些 Pids 或将它们存储在列表、数组或集合中。看看这个解决方案,它被提供给

Now, Messaging systems are what everyone wants to do when they come to Erlang because the two naturally blend. However, there are a number of things to look into before one continues. Messaging basically involves the following things: User Registration, User Authentication, Sessions Management,Logging, Message Switching/routing e.t.c.

Now, to do all or most of these, one needs to have a Database, certainly IN-MEMORY, thats leads me to either Mnesia or ETS Tables. Since you are new to Erlang, i suppose you have not yet really mastered working with these. At one moment, you will need to maintain Who is communicating with who, Who is available for Chat e.t.c. Hence you might need to look up things and write things some where.

Another thing is you have not told us the Client. Is it going to be a Web Client (HTTP), is it an entirely new protocol you are implementing over raw Sockets ? Which ever way, you will need to master something called: Concurrency in Erlang. If a user connects and is assigned an ID, if your design is A process Per User, then you will have to save the Pids of these Processes or register them against some criteria, yet again monitor them if they die e.t.c. Which brings me to OTP and Supervision trees. There is quite alot, however, tell us more about the Client and Server interaction, the Network Communication you need e.t.c. Or is it just a simple Erlang RPC project you are doing for your own revision ?

EDIT

Use ETS Tables, or use Mnesia RAM tables. Do not think of registering these Pids or Storing them in a list, Array or set. Look at this solution which was given to this question

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文