4

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

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

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

4

3 回答 3

5

看起来可以从 SSIS 发出 http 请求,请参阅如何从 SSIS 发出 HTTP 请求?

考虑到这一点,您可以使用通过网关(网关只是一个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
    }
}

希望这可以帮助!

于 2013-08-23T02:17:24.410 回答
2

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

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

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

于 2013-08-22T14:25:08.177 回答
1

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

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

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

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

于 2013-08-22T14:42:39.487 回答