高容量Java服务器的线程模型

时间:2016-08-08 18:39:15

标签: java multithreading sockets server client-server

我正在为一个非常大的模拟创建一个Java服务器,我有几个高级设计问题。

一些背景:

  • 服务器将运行模拟。
  • 客户端将通过移动设备的TCP连接连接到服务器,并与模拟中的数据结构进行交互。最初,我将尝试在客户端中使用简单的轮询方案。我发现很难在移动设备和服务器之间维持长期的TCP连接,我还不确定客户端是否会尝试保持开放的TCP连接,或者他们是否会设置它并将其拆除传输。
  • 当客户端在移动设备上处于活动状态时,我希望客户端每分钟至少轮询几次服务器。
  • 无论客户端是否连接,模拟都将继续运行。
  • 现有客户的总数可能会非常庞大​​,数千人。
  • 客户端主要轮询服务器以获取模拟状态,但有时也会向模拟发出控制命令。
  • 所有邮件都很小。
  • 我希望服务器能够在Linux下在多核CPU服务器硬件上运行。

目前我对服务器中的线程模型有以下想法:

  • 模拟逻辑由几个线程执行。模拟逻辑线程对模拟数据结构进行读写操作。
  • 对于每个客户端,都有一个Java线程对该客户端的套接字执行阻塞读取调用。当从客户端收到轮询命令时,相应的客户端线程从模拟数据结构中读取信息(一个客户端轮询通常会对总数据结构的一小部分感兴趣)并在客户端上向客户端发送回复&# 39; s socket。因此,需要在客户端线程和模拟线程之间同步对数据结构的访问(我会尝试在数据的较小子集上进行锁定)。如果从客户端收到控制命令,则客户端线程将写入数据结构。

对于少数客户,我认为这样可以正常工作。

问题1:此线程模型是否适用于大量(数千)连接的客户端?我不熟悉这种Java实现中的内存/ CPU开销。

问题2:我想避免让服务器异步向客户端发送消息,但在某些情况下我可能需要让服务器发送"现在自己更新"消息与某些或许多客户端异步,我不太清楚如何做到这一点。让模拟逻辑线程发送这些消息似乎没有...可能是某些"客户端通知线程池"概念

1 个答案:

答案 0 :(得分:0)

你问两个问题;我会回答第一个问题。

我之前编写的应用程序涉及一个应用程序中的数千个线程。我们曾经遇到过Linux服务器上最大线程数问题;对我们来说,我认为限制大约是1000个线程。这影响了我们的Java应用程序,因为Java线程使用本机线程我们将限制设置得更高,应用程序扩展到大约2000个线程,这是我们所需要的,没有问题;如果我们需要将它扩大得更高,我不知道会发生什么。

默认的最大线程数为1000表明在单个Linux服务器上运行数千个线程可能并不明智。我认为主要问题是需要为每个线程分配足够的堆栈内存。

我们预期的长期修复方法是更改​​为一个体系结构,其中来自线程池的线程每个服务多个套接字。这真的不是一个问题;对于每个套接字,线程只需处理任何挂起的消息,然后再转到下一个套接字。您必须小心同步内存访问,但您的应用程序已经需要这样做,因为您的模拟已经与多个线程进行交互,因此该部分不会发生巨大变化。