Python可扩展聊天服务器

10 投票
2 回答
2402 浏览
提问于 2025-04-17 04:44

我刚开始学习用Python做网络编程,所以写了一些聊天服务器和客户端的例子。在网上看到的很多资料都提到用线程模块来处理客户端与服务器的连接。我知道如果想要一个可扩展的服务器,需要用一些额外的技巧,因为如果线程数量太多可能会让服务器崩溃(如果我说错了请纠正我,是不是因为全局解释器锁GIL的问题?),但这不是我现在关注的重点。

奇怪的是,我在Python的文档中看到过,创建子进程是处理套接字的正确方法(可惜我找不到那个参考了,抱歉 :()。

所以问题是:我应该使用线程还是进程?或者有没有更好的解决方案?

请告诉我答案,并解释一下它们之间的区别。

顺便说一下:我知道有像Twisted这样的库写得很好。我并不是在寻找一个现成的可扩展服务器,而是想理解如何写一个可以扩展的,或者至少能处理1万客户端的服务器。

编辑:操作系统是Linux。

2 个回答

0

成千上万的线程可能会让服务器瘫痪(如果我说错了请纠正我,但这是不是因为GIL的原因?)

首先,GIL和线程的数量没有关系。如果你在这些线程中进行的是输入输出操作(IO),那么你可以有成千上万的线程,而不会因为GIL或者其他原因出现问题。

GIL主要是在你进行需要大量CPU计算的任务时才会影响性能。

可以看看David Beazly的这场非常有用的讲座,了解更多关于GIL的信息。

11

Facebook 需要一个可以扩展的服务器,所以他们写了 Tornado(这个用的是异步处理)。Twisted 也是一个很有名的可扩展工具(它同样使用异步处理)。Gunicorn 也是一个表现很好的工具(它使用多个进程)。我知道的这些快速、可扩展的工具都没有使用线程。

想要尝试不同的方法,可以从标准库中的 SocketServer 模块开始:http://docs.python.org/library/socketserver.html。这个模块让你可以很方便地通过继承 ThreadingMixin 或 ForkingMixin 来切换不同的方法。

另外,如果你想了解异步处理的方法,最简单的方式就是阅读一篇关于 Tornado 实现的博客文章:http://golubenco.org/2009/09/19/understanding-the-code-inside-tornado-the-asynchronous-web-server-powering-friendfeed/

祝你好运,开心编程 :-)

撰写回答