多个JVM与并发任务

时间:2011-04-01 16:12:17

标签: java jvm virtualization

我正在将胖客户端代码移植到具有瘦客户端的服务器架构中。

服务器需要为每个客户端运行一个代码实例。代码是多线程的,可以运行很长时间(几周),但只是偶尔与客户端进行交互。客户数量将达到数千。每个客户端需要大约20MB的堆。

我现在有两个选择,

  1. 在服务器上为每个客户端启动一个单独的JVM
  2. 修改我的代码,以便在每个客户端的共享空间中完成所有请求和计算(如在Web应用程序中)
  3. 我可以看到每个人的利弊。对于多个JVM:

    优点:

    • 进程是分开的,如果一个挂起只是杀了它并重新启动。所有其他人都不在乎。
    • 资源可以被限制,因此一个客户端不能吃掉所有CPU /内存
    • 轻松分布在多台机器上

    缺点:

    • 多次加载完整的JRE类库
    • 不是Java EE的做事方式
    • 每个客户都需要通过单独的端口进行通话吗?

    您有推荐的最佳做法吗?

    你知道有关这个问题的任何好的参考书/文章吗?

    是否存在仅使用一个JVM但运行多个代码副本的框架,就好像它是单独的进程空间(资源有限等)?

2 个答案:

答案 0 :(得分:3)

遗憾的是,不可能在单个JVM中基于线程限制资源。但是,我仍然会尝试将您的应用程序移植到单个JVM中,原因如下:

  • 如果你正确编码任务,如果一个线程使用了很多CPU,你仍然可以杀死它(interrupt()是你的朋友)。
  • 如果多个客户端与其他客户端同时工作,我认为他们必须共享CPU。
  • 线程运行了几个星期?无论如何,您应该在子任务中拆分任务,这样您就可以从重新启动中恢复,并在您离开的地方继续工作。
  • 只有在一个应用中,客户端才能共享通信服务器端口。
  • 必须以某种方式以编程方式限制内存消耗。对于数据库而言,这意味着查询必须限于固定数量的结果或类似的结果。
  • 如果每个进程只需要20MB的堆,那么使用单个应用程序就需要更少的资源。我相信每个JVM的开销大约为30MB,而调度1000个线程可能比操作系统调度1000个进程更具性能。
  • 如果您对应用程序进行编码以通过JMX提供信息,您将免费获得一个用于流程的监控控制台。如果为每项任务启动单个流程,则更难监控。

使用单一应用程序方法,除非您真的无法控制用户可以启动哪些任务。

答案 1 :(得分:1)

您可以创建一个Web服务/代理服务,为每个客户端启动JVM,将其关闭。这将使您能够从长时间运行的客户端中删除请求/ JVM。

代理服务器可以为客户端提供一个他们需要与之通信的端口,因为服务器会将请求转发给该客户端正在运行的JVM。

顺便说一句:如果有许多客户端正在运行CPU密集型作业,那么只有很多内核可供使用。您可能会发现JVM需要跨多台计算机运行才能支持所有客户端。