C# 扩展Windows服务

C# 扩展Windows服务,c#,windows-services,scalability,horizontal-scaling,C#,Windows Services,Scalability,Horizontal Scaling,我正在寻找一些关于如何扩展我公司目前运行的Windows服务的信息。我们正在使用.NET 4.0(将来可能会升级到4.5),并在Windows Server 2012上运行它 关于该服务 该服务的工作是查询日志表中的新行(我们正在使用Oracle数据库),处理信息,创建和/或更新其他5个表中的一组行(我们称之为跟踪表),更新日志表,然后重复 日志记录表包含大量XML(每行最多可达20 MB),需要选择这些XML并保存在其他5个跟踪表中。始终以每小时500000行的最大速率添加新行。 跟踪表的流量

我正在寻找一些关于如何扩展我公司目前运行的Windows服务的信息。我们正在使用.NET 4.0(将来可能会升级到4.5),并在Windows Server 2012上运行它

关于该服务
该服务的工作是查询日志表中的新行(我们正在使用Oracle数据库),处理信息,创建和/或更新其他5个表中的一组行(我们称之为跟踪表),更新日志表,然后重复

日志记录表包含大量XML(每行最多可达20 MB),需要选择这些XML并保存在其他5个跟踪表中。始终以每小时500000行的最大速率添加新行。
跟踪表的流量要高得多,从最小表中的90000行到最大表中的数百万行,每小时不等。更不用说这些表上也有更新操作

关于正在处理的数据
我觉得这一点对于根据这些对象的分组和处理方式找到解决方案非常重要。数据结构如下所示:

public class Report
{
    public long Id { get; set; }
    public DateTime CreateTime { get; set; }
    public Guid MessageId { get; set; }
    public string XmlData { get; set; }
}

public class Message
{
    public Guid Id { get; set; }
}
RecordId        Number
InstanceId      Number    Nullable
SELECT * FROM ReportAssignment 
WHERE (InstanceId IS NULL OR InstanceId NOT IN (1, 2, 3))   // 1,2,3 are the active instances
AND RecordId % 3 == 0    // 0 is the index of the current instance in the list of active instances
  • 报告是我需要选择和处理的日志数据
  • 每封邮件平均有5份报告。在某些情况下,这可能在1到数百之间变化
  • 消息有一堆其他集合和其他关系,但它们与问题无关

今天,我们的Windows服务几乎无法管理16核服务器上的负载(我不记得完整的规格,但可以肯定地说,这台机器是一头野兽)。我的任务是找到一种扩展和添加更多机器的方法,这些机器将处理所有这些数据,并且不会干扰其他实例

目前,每条消息都有自己的线程并处理相关报告。我们分批处理报告,按它们的MessageId分组,以便在处理数据时将DB查询的数量减少到最小

限制

  • 在这个阶段,我可以使用任何我认为合适的架构从头开始重新编写这个服务
  • 如果一个实例崩溃,其他实例需要能够找到崩溃实例的位置。任何数据都不会丢失
  • 此处理需要尽可能接近实时,从插入数据库的报告开始

我正在寻找任何关于如何建立这样一个项目的意见或建议。我假设这些服务需要是无状态的,或者是否有一种方法可以以某种方式同步所有实例的缓存?我应该如何协调所有实例并确保它们不处理相同的数据?如何在它们之间平均分配负载?当然,如何处理实例崩溃而无法完成其工作

编辑

删除了与工作项无关的信息,Windows Workflow可能是重构服务的最快方法

从WF中可以得到的最有用的东西是工作流持久性,如果从保存工作流的最后一个点开始工作流发生任何情况,那么经过适当设计的工作流可以从持久性点恢复

这包括在处理工作流时,如果任何其他进程崩溃,可以从另一进程恢复工作流。如果使用共享工作流存储,则恢复过程不需要在同一台计算机上。请注意,所有可恢复的工作流都需要使用工作流存储

对于工作分配,您有两个选项

  • 通过工作流调用,通过
    WorkflowService
    类使用WCF端点,生成与基于主机的负载平衡相结合的消息的服务。请注意,您可能希望在此处使用设计模式编辑器来构造输入方法,而不是手动设置
    Receive
    和相应的
    SendReply
    处理程序(这些处理程序映射到WCF方法)。您可能会为每条消息调用服务,也可能为每条报告调用服务。请注意,
    CanCreateInstance
    属性在这里很重要。与之关联的每个调用都将创建一个独立运行的运行实例。
    ~



  • 使用具有队列支持的服务总线。至少,您需要能够接受来自任意数量的客户机的输入,并且其输出可以被唯一地标识和处理一次。想到的几个是NServiceBus、MSMQ、RabbitMQ和ZeroMQ。在这里提到的项目中,NServiceBus是专门为.NET准备的开箱即用的。在云环境中,您的选项还包括特定于平台的产品,如Azure Service Bus和Amazon SQS。
    ~






    ~
    请注意,服务总线只是发起消息的生产者和可以存在于任意数量机器上从队列读取消息的消费者之间的粘合剂。类似地,您可以使用此间接方式生成报告。用户将创建工作流实例,然后使用工作流持久性

  • Windows AppFabric可用于承载工作流,允许您使用许多适用于IIS负载平衡的技术来分发您的工作。我个人对它没有任何经验,因此除了它有现成的良好监控支持之外,我对它没什么可说的。
    ~

  • 我通过自己编写所有这些可伸缩性和冗余的东西来解决这个问题。如果有人需要,我会解释我做了什么以及我是如何做到的

    我在每个实例中创建了几个进程,以跟踪其他进程,并知道特定实例可以处理哪些记录。启动时,实例将在名为
    Instances
    的表中的数据库(如果尚未注册)中注册。此表包含以下列:

    Id                 Number
    MachineName        Varchar2
    LastActive         Timestamp
    IsMaster           Number(1)