【问题标题】:How can SQL Server 2012 (or SSIS) notify NServiceBus upon completion of a task?SQL Server 2012(或 SSIS)如何在任务完成后通知 NServiceBus?
【发布时间】:2013-08-22 13:37:33
【问题描述】:

我们有一些运行时间很长的 ETL 包(有些运行了几个小时)需要由 NServiceBus 端点启动。我们不需要在整个过程中保持单个事务处于活动状态,并且可以将其分解为更小的事务。由于 NServiceBus 处理程序会将其自身包装在一个事务中,因此我们不希望在单个事务中处理它,因为它会超时——更不用说在 DBMS 中产生锁定问题了。

我目前的想法是我们可以异步生成另一个进程,立即从处理程序返回,并在完成时发布事件(成功或失败)。我还没有找到很多关于如何将新的 NServiceBus 4.0 SQL Server Broker 支持与传统的 MSMQ 传输集成的文档。这可能吗?

在 SQL Server 2012(或 SSIS 包)中让长时间运行的进程以异步方式完成时通知 NServiceBus 订阅者的首选方法是什么?

【问题讨论】:

  • 对nservicebus一无所知,是否有什么东西会阻止您的SSIS包在完成时调用方法/将消息放入队列?
  • 我不知道,我只是在问最简单的方法是什么。最坏的情况是,您可以在 SSIS 中手动编写代码(或 SQL Server 上的 CLR 中的一些托管代码)以将消息放入 MSMQ 队列中——但是,您随后会丢失 NServiceBus 中内置的一些功能,这些功能可以帮助您管理这些排队。

标签: ssis sql-server-2012 nservicebus


【解决方案1】:

看起来可以从 SSIS 发出 http 请求,请参阅 How to make an HTTP request from SSIS?

考虑到这一点,您可以使用通过网关(网关只是一个HttpListener)向 NServiceBus 发送消息到您的发布者,告诉它发布一条消息,通知所有订阅者长期运行的 ETL 包已完成.

要向网关发送消息,您需要执行以下操作:

var webRequest = (HttpWebRequest)WebRequest.Create("http://localhost:25898/Headquarters/");
webRequest.Method = "POST";
webRequest.ContentType = "text/xml; charset=utf-8";
webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)";

webRequest.Headers.Add("Content-Encoding", "utf-8");
webRequest.Headers.Add("NServiceBus.CallType", "Submit");
webRequest.Headers.Add("NServiceBus.AutoAck", "true");
webRequest.Headers.Add("NServiceBus.Id", Guid.NewGuid().ToString("N"));

const string message = "<?xml version=\"1.0\" ?><Messages xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://tempuri.net/NServiceBus.AcceptanceTests.Gateway\"><MyRequest></MyRequest></Messages>";

using (var messagePayload = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(message)))
{
    webRequest.Headers.Add(HttpRequestHeader.ContentMd5, HttpUtility.UrlEncode(Hasher.Hash(messagePayload))); //Need to specify MD5 hash of the payload
    webRequest.ContentLength = messagePayload.Length;

    using (var requestStream = webRequest.GetRequestStream())
    {
        messagePayload.CopyTo(requestStream);
    }
}

using (var myWebResponse = (HttpWebResponse) webRequest.GetResponse())
{
    if (myWebResponse.StatusCode == HttpStatusCode.OK)
    {
        //success
    }
}

希望这会有所帮助!

【讨论】:

  • 我最终在概念验证中使用了这个解决方案,而且效果很好。我将发布一些我需要对此代码进行的更改,以便它可以作为 C# CLR 过程正常工作并接受这个答案。
【解决方案2】:

在 SSIS 2012 中实际上有一个任务是在 MSMQ 中放置消息,Message Queue Task。您只需将其指向您的 MSMQ 连接,就可以使用表达式自定义您的消息,包括包名称、成功/失败、行数等。

根据我们讨论的包数量以及您希望消息的定制程度,最好的办法是编写一个独立的实用程序来创建您想要的任何格式的消息,然后使用执行流程任务来调用该实用程序带有您要传入的包中的任何参数以格式化为消息。

您也可以使用相同的代码库并创建自定义 SSIS 任务(比听起来容易得多。)

【讨论】:

    【解决方案3】:

    我必须帮助遵守 DRY 原则的一个想法是使用 Master SSIS 包。

    在我看来,它看起来像是一个带有X 的执行包任务。将包配置为将包名称作为参数。配置执行包任务以使用参数来确定要调用的包。

    X 可能是一个脚本任务,但正如@Kyle Hale 指出的那样,它可能是Message Queue Task。我把这个决定留给那些更精通 NServiceBus 的人。

    在我看来,重要的是不要将此逻辑添加到每个包中,因为那将是维护的噩梦。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-19
      • 1970-01-01
      相关资源
      最近更新 更多