0

我有几个代理和一个数据库表 ( BackgroundJobWork),记录每个代理的工作量。该表将包含每个工作项的条目。

当我想分配一个新的工作项时,我首先检查这个表并选择一个已经分配给它的工作项最少的代理。

当代理完成工作项时,它会将其状态更改为分配以外的状态。

有一个转折。代理在另一个表中报告其心跳 ( BackgroundJobService)。如果代理未能及时报告,则其在该表中的状态设置为“无响应”。用于确定加载最少的代理的 SQL 查询必须仅检查“活动”代理。

这是我的 SQL 查询,用于选择负载最少的实时代理:

SELECT bjw.AllocatedAgentHostName HostName, bjw.AllocatedAgentServiceName ServiceName,
  SUM(CASE WHEN bjw.WorkStatusTypeId IN (2,3,4) THEN 1 ELSE 0 END) AS InProgress
  FROM BackgroundJobWork bjw, BackgroundJobService bjs
  WHERE bjw.AllocatedAgentHostName = bjs.HostName
        AND bjw.AllocatedAgentServiceName = bjs.ServiceName
        AND bjs.AgentStatusTypeId = 2
  GROUP BY bjw.AllocatedAgentHostName, bjw.AllocatedAgentServiceName
  ORDER BY InProgress

在哪里:

  • BackgroundJobWork.WorkStatusTypeId2、3 或 4 对应于分配给特定代理(由HostName+ServiceName字段对表示)
  • BackgroundJobService.AgentStatusTypeId2 对应一个在线代理

不幸的是,我的查询有一个错误。如果代理在BackgroundJobWork表中根本没有条目会发生什么?在这种情况下,我的查询生成的结果中省略了该代理,即使它是实时代理。这是一个丑陋的错误。

我可能应该把我的 SQL 换一种方式——而不是查看工作负载表 ( BackgroundJobWork),然后将其与实时状态表 ( BackgroundJobService) 进行匹配,我应该首先查看后者并与前者匹配,这是因为实时状态表保证每个代理都只有一行。

但我不确定,直到现在还没有产生令人满意的查询。

4

2 回答 2

0

我可能应该把我的 SQL 换一种方式...

就是这样。尝试左加入 BJW 对抗 BJS,而不是像现在这样内加入 BJS 对抗 BJW。

SELECT bjs.HostName HostName, bjs.ServiceName ServiceName,
  SUM(CASE WHEN bjw.WorkStatusTypeId IN (2,3,4) THEN 1 ELSE 0 END) AS InProgress
  FROM BackgroundJobService bjs
  LEFT JOIN BackgroundJobWork bjw 
        ON bjw.AllocatedAgentHostName = bjs.HostName
        AND bjw.AllocatedAgentServiceName = bjs.ServiceName
  WHERE bjs.AgentStatusTypeId = 2
  GROUP BY bjs.HostName, bjs.ServiceName
  ORDER BY InProgress

顺便说一句,出于可维护性的原因,请考虑显式使用 INNER JOIN 而不是过时的逗号语法。

于 2013-08-06T15:10:23.253 回答
0

请尝试下面提到的查询。在此查询中,“Union”之后的部分是在 BackgroundJobWork 但在 BackGroundJobService 中不存在的代理列表,并且由于它们没有运行任何服务,因此您可以在其中提及任何其他值:

SELECT bjw.AllocatedAgentHostName HostName, bjw.AllocatedAgentServiceName ServiceName,
SUM(CASE WHEN bjw.WorkStatusTypeId IN (2,3,4) THEN 1 ELSE 0 END) AS InProgress
FROM BackgroundJobService bjs
JOIN BackgroundJobWork bjw 
ON bjw.AllocatedAgentHostName = bjs.HostName
AND bjw.AllocatedAgentServiceName = bjs.ServiceName
WHERE bjs.AgentStatusTypeId = 2
GROUP BY bjs.HostName, bjs.ServiceName
ORDER BY InProgress
UNION
select hostname,'No Service Currently',0 from BackgroundJobService where AgentStatusTypeId = 2
and hostname not in(Select distinct AllocatedAgentHostName from BackgroundJobWork)
于 2013-08-06T15:18:45.627 回答