【问题标题】:Stateless Blocking Server Design无状态阻塞服务器设计
【发布时间】:2010-12-05 12:31:12
【问题描述】:

请帮忙。

我正在设计一个具有以下功能的无状态服务器:

  1. 客户端向服务器提交作业。
  2. 在服务器尝试执行作业时客户端被阻止。
  3. 服务器将生成一个或多个线程来执行作业。
  4. 作业完成、超时或失败。
  5. 创建适当的响应(基于结果),解除对客户端的阻塞,并将响应移交给客户端。

这是我目前想到的。

  1. 客户端向服务器提交作业。
  2. 服务器为作业分配一个 ID,将作业放置在一个队列中,然后将客户端放置在另一个队列中(它将被阻止)。
  3. 拥有一个线程池来执行作业、获取结果并适当地创建响应。
  4. 根据 ID,从队列中挑选出客户端(从而解除阻塞),给它响应并发送出去。

步骤 1、3、4 看起来很简单,但是关于如何将客户端放入队列然后阻止它的任何想法。此外,任何可以帮助我设计这只小狗的指针都将不胜感激。

干杯

【问题讨论】:

    标签: java stateless


    【解决方案1】:

    为什么需要屏蔽客户端?似乎更容易(几乎)立即返回(在执行初始验证后,如果有的话)并为给定工作的客户提供唯一 ID。然后,客户端将能够使用所述 ID 进行轮询,或者提供回调。

    阻塞意味​​着您持有一个套接字,这显然限制了您可以同时服务的客户端数量上限。如果这不是您的方案所关心的问题并且您绝对需要阻止(也许您无法控制客户端代码并且无法让它们轮询?),那么生成线程来执行这项工作几乎没有意义,除非您实际上可以将它分成并行任务。在这种情况下,唯一的“队列”将是公共线程池持有的队列。工作流程基本上是:

    1. 创建线程池(如ThreadPoolExecutor
    2. 对于每个客户端请求:
      1. 如果您有可以并行执行的作业的任何部分,请将它们委托给池。
      2. 并且/或者在当前线程中执行它们。
      3. 等到合并的作业部分完成(如果适用)。
      4. 将结果返回给客户端。
    3. 关闭线程池。

    本身不需要 ID;虽然您可能需要使用某种latch 来处理上面的 2.1 / 2.3。

    超时可能有点棘手。如果您需要它们或多或少地精确,您必须让您的主线程(接收客户端请求的线程)不工作,并在达到超时时发出已提交的作业部分(通过翻转标志)的信号并立即返回.您必须定期检查所述标志并在翻转后终止执行;然后池将回收线程。

    【讨论】:

    • 感谢 ChssPly76。到目前为止,我只知道服务器的功能是什么。客户端如何连接到服务器仍在争论中(由我之上的权力在工作中)。如果他们选择网络服务,我不会感到惊讶。
    【解决方案2】:

    你是如何与客户沟通的?

    我建议您创建一个对象来表示每个作业,其中包含作业参数和连接到客户端的套接字(或其他通信机制)。然后线程池将在作业处理结束时发送响应以解除对客户端的阻塞。

    【讨论】:

      【解决方案3】:

      超时会有些棘手,并且会隐藏陷阱,但基本设计似乎很简单,在构造函数中编写一个接受 Socket 的类。在 socket.accept 上,我们只是做一个新的套接字处理实例化,具有远见和规划可扩展性,或者如果这是一个基准测试实验,那么套接字处理类只是去数据处理的东西,当它返回时你有一些状态或其他东西的布尔值或数字类型,null btw 的方便位置,ether 将成功从套接字写入输出流或通知客户端超时或您的业务需要的任何内容

      如果您必须为长期运行的重型运输车提供可扩展且有效的设计,请直接访问 nio ...我描述的手动编码一次性解决方案可能无法很好地扩展,但可以为以下问题提供基本的概念化基础代码正确工作的 nio 设计。

      (抱歉,我认为是直接在代码中 - 设计模式在代码工作后应用到代码中。不支持的部分会被重新设计,而不是之前)

      【讨论】:

      • @ChssPly76 - 是的,很棘手,而且也不只是一点点。听起来 op 有一个自定义的“for nio”问题。
      猜你喜欢
      • 2016-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-25
      • 1970-01-01
      • 2012-06-16
      • 2015-04-25
      • 2012-02-11
      相关资源
      最近更新 更多