我想知道支持大规模客户端(至少10K)实现修复服务器的服务器(基于TCP)架构。我的观点是我们如何设计它。如何监听开放端口?使用选择或轮询或任何其他功能。如何处理客户端的响应?在大规模情况下,我们无法为每个客户端创建一个线程。响应的处理应该在不同的可执行文件中并通过IPC将请求和响应共享给服务器可执行文件。还有更多。如果有人解释它或提供任何链接,我将不胜感激。谢谢
3 回答
C10K 问题是有关该主题的一个极好的信息资源。虽然那里的尺寸看起来有点旧,但这些技术今天仍然适用。
架构取决于您要对客户端传入数据执行的操作。我的猜测是,对于每条传入的消息,您都会执行一些计算,并且可能还会返回响应。
在这种情况下,我将创建 1 个接收所有传入消息的主侦听器线程(实际上,如果您的硬件有超过 1 个物理网络设备,我会为每个设备使用一个侦听器线程并确保每个设备都在侦听特定设备) . 获取您机器上的 CPU 数量,并为每个 CPU 创建工作线程,并将每个线程绑定到一个 cpu(也许工作线程的数量应该是 num_of_cpu-1,以便为侦听器和调度程序留下可用的 cpu)。
每个线程都有一个队列和信号量,主侦听器线程只是将传入的数据推送到这些队列中。负载均衡有很多种方式(后面会讲)。
每个工作线程只处理给它的请求,并将响应放在另一个由调度程序读取的队列中。
调度程序 - 这里有 2 个选项,使用一个线程作为调度程序(或每个网络设备的线程作为侦听器),或者让调度程序实际上与侦听器是同一个线程。将它们放在同一个线程上会有一些好处,因为它可以更容易地检测丢失的套接字连接并在没有线程同步的情况下使用相同的 fds 进行读写。但是,可能是使用 2 个不同的线程会提供更好的性能,需要对其进行测试。
关于负载平衡的注意事项:这是一个独立的话题。最简单的事情是为所有工作线程使用 1 个队列,但问题是它们必须锁定才能弹出项目,并且锁定会损害性能。(但你得到最平衡的负载)。
另一种非常简单的方法是为每个工作人员设置一个私有队列,并在插入时执行循环。每 X 个周期后检查所有队列的大小。如果某些队列比其他队列大得多,则将它们留在接下来的 X 个周期中,然后再次重新检查它们。这不是最好的方法,而是一种简单的实现方法,并且在不需要锁定的情况下提供了一些负载平衡。
顺便说一句 - 有一种方法可以在 2 个线程之间实现队列而不阻塞 - 但这也是另一个主题。
我希望它有帮助,盖伊
如果客户端和服务器在一个安全的网络上,那么安全方面是最小的——在传输被加密的范围内。如果客户端和服务器不在安全网络上 - 您首先希望服务器和客户端相互验证,然后启动加密数据传输。对于数据传输,服务器端身份验证就足够了。在此身份验证结束时,使用会话密钥生成加密数据流(对称)。考虑使用 TFTP,它很容易实现并且可以很好地扩展。