2

请帮忙。

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

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

这是我到目前为止所想到的。

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

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

干杯

4

3 回答 3

2

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

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

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

本身不需要 ID;尽管您可能需要为上面的 2.1 / 2.3使用某种闩锁。

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

于 2009-10-10T01:06:32.870 回答
0

你是如何与客户沟通的?

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

于 2009-10-10T00:19:01.400 回答
0

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

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

(对不起,我认为直接在代码中 - 然后在代码工作后将设计模式应用于代码。不支持的内容会被重新设计,而不是之前)

于 2009-10-10T01:43:12.860 回答