【发布时间】:2016-12-14 15:30:31
【问题描述】:
我正在为一个相当大的模拟创建一个 Java 服务器,我有几个高级设计问题。
一些背景:
- 服务器将运行模拟。
- 客户端将通过来自移动设备的 TCP 连接连接到服务器,并与模拟中的数据结构进行交互。最初,我将尝试在客户端中使用简单的轮询方案。我发现很难在移动设备和服务器之间维持长期的 TCP 连接,我还不确定客户端是否会尝试保持打开的 TCP 连接,或者他们是否会为每次传输设置并拆除它。
- 当客户端在移动设备上处于活动状态时,我希望客户端每分钟至少轮询服务器几次。
- 无论客户端是否连接,模拟都会继续运行。
- 现有客户的总数可能会非常庞大,达到数千。
- 客户端主要轮询服务器以获取模拟状态,但有时也会向模拟发出控制命令。
- 所有消息都很小。
- 我希望服务器能够在多核 CPU 服务器硬件上的 Linux 下运行。
目前我对服务器中的线程模型有以下想法:
- 模拟逻辑由几个线程执行。模拟逻辑线程同时读取和写入模拟数据结构。
- 对于每个客户端,都有一个 Java 线程对该客户端的套接字执行阻塞读取调用。当从客户端接收到轮询命令时,相应的客户端线程从模拟数据结构中读取信息(一个客户端轮询通常会对总数据结构的一小部分感兴趣)并在客户端的套接字上向客户端发送回复.因此,对数据结构的访问需要在客户端线程和模拟线程之间同步(我会尝试对较小的数据子集进行锁定)。如果从客户端接收到控制命令,客户端线程将写入数据结构。
对于少数客户,我认为这会很好。
问题 1:这种线程模型是否适用于大量(数千)连接的客户端?我不熟悉在这样的 Java 实现中会有什么内存/CPU 开销。
问题 2:我想避免让服务器异步向客户端发送消息,但在某些情况下,我可能需要让服务器向某些或多个客户端异步发送“立即更新”消息,但我不太愿意确定如何做到这一点。让模拟逻辑线程发送这些消息似乎不正确......也许是一些“客户端通知线程池”概念?
【问题讨论】:
-
我怀疑任何人都可以回答:“数千个线程”。推送到客户端向我建议 Web 套接字。这个设计对我来说听起来很复杂。多线程代码很难编写,即使对于聪明人来说也是如此。如果您没有使用新的并发包或 map/reduce 或类似 MPI 的东西,那感觉就像您做错了。没有更多细节无法判断。
-
架构是一个非常广泛的主题,通常不适合在这里 - 这个问题在Programmers SE 会更好。 StackOverflow 适用于特定编码问题(例如,实施或排除所述架构的给定部分)。
-
谢谢 duffymo 我会研究 MPI。是的,这种设计意味着数以千计的并发 Java 线程(尽管每个线程在其生命周期的绝大部分时间里都是空闲的)
-
啊哈,谢谢 brichins
-
@brichins 在引用其他网站时,指出cross-posting is frowned upon 通常会有所帮助
标签: java multithreading sockets server client-server