使用 BizTalk 传输大文件 - 发送端






4.29/5 (6投票s)
如何使用 BizTalk 传输大文件 - 发送端
引言
在BizTalk中处理大文件(200MB+)可能是一个主要的性能瓶颈,因为接收管道会解析文件并将其存储到MessageBox
中。接收文件的BizTalk服务器主机实例和SQL Server的CPU使用率都可能非常高,从而降低系统速度,尤其是在同时接收多个大文件时。
解决此问题的一种方法是创建一个自定义管道组件,该组件接收大文件,将其存储到磁盘,并创建一个包含大文件存储位置信息的小型XML消息。小型XML消息存储到MessageBox
中,而不是大文件本身。它包含与大文件相同上下文信息,并且可以被业务流程编排或发送管道拾取。然后,发送组件获取大文件的路径并执行发送过程。可以安排任务定期删除磁盘上的大文件。
使用BizTalk传输大文件 - 接收端 描述了BizTalk的接收端。在本文中,我将描述如何获取大文件存储位置的信息,并在自定义发送管道组件中发送该信息。我还将简要介绍如何从磁盘删除大文件。
自定义管道组件
创建自定义管道组件的大部分代码在创建自定义管道组件时都比较基础,也可以通过向导生成。但是,我将在下面列出所有代码并进行简短解释。核心代码位于Execute
方法中,该方法是从IComponent
接口实现的。
自定义管道组件在Visual Studio中创建为新的类库,并使用强名称密钥文件进行签名。
添加对Microsoft.BizTalk.Pipeline.dll的引用。
代码首先添加以下命名空间来创建自定义管道组件并从磁盘读取文件。
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using System.IO;
类开头的代码如下所示。一个属性指示这是一个管道组件,另一个属性限制该组件只能在管道的编码阶段使用。编码器管道组件需要实现IBaseComponent
、IComponentUI
和IComponent
接口。
namespace Stm.LargeFileEncoder
{
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
[ComponentCategory(CategoryTypes.CATID_Encoder)]
[System.Runtime.InteropServices.Guid("52dcc4e5-28e1-49a2-81fd-de496ac80fe8")]
public class LargeFileEncoder: IBaseComponent,
IComponentUI, IComponent, IPersistPropertyBag
{
IBaseComponent
接口提供属性,这些属性提供有关组件的基本信息。
#region IBaseComponent
private const string _description =
"Pipeline component used to read large files from disk";
private const string _name = "LargeFileEncoder";
private const string _version = "1.0.0.0";
public string Description
{
get { return _description; }
}
public string Name
{
get { return _name; }
}
public string Version
{
get { return _version; }
}
#endregion
IComponentUI
接口定义了在管道设计器环境中使用的方法和属性。为保持简单,我在此处未提供任何代码。
#region IComponentUI
private IntPtr _icon = new IntPtr();
public IntPtr Icon
{
get { return _icon; }
}
public System.Collections.IEnumerator Validate(object projectSystem)
{
return null;
}
#endregion
核心接口是IComponent
。在这种情况下,它包含一个执行管道组件的方法,该方法从磁盘读取大文件并将其作为消息返回。
#region IComponent
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
// Read filepath from the context properties
string largeFilePath = pInMsg.Context.Read("LargeFilePath",
"http://Stm.CustomPipelineComponents.Schemas.PropertySchema.PropertySchema").ToString();
// Read file from disk
int bufferSize = 1024; // 4096
FileStream fs = new FileStream(largeFilePath, FileMode.Open,
FileAccess.Read, FileShare.Read, bufferSize);
if (fs.CanSeek)
fs.Position = 0;
pInMsg.BodyPart.Data = fs;
return pInMsg;
}
#endregion
如文章使用BizTalk传输大文件 - 接收端中所述,小型XML消息的架构已部署,在这种情况下,包含大文件位置的字段已提升。此方法首先要做的是从消息中读取该位置。接下来,FileStream
使用内部缓冲区从文件读取。消息的BodyPart
的Data
属性设置为FileStream
,并返回消息。这里没有删除大文件的代码。如果发送适配器中发生错误,并且BizTalk设置为在一段时间后重发消息,则无法删除大文件。
发送管道
构建上述组件后,可以将其存储在BizTalk服务器上其他管道组件所在的同一文件夹中。在BTS发送管道项目中,必须将此组件DLL添加到工具栏并在编码阶段使用,并且必须部署管道。
在BizTalk上测试
要测试此项目,需要构建和部署接收端组件(自定义解码器组件、架构和接收管道)、自定义编码器组件和发送管道。大文件将作为.msg文件存储在磁盘上,使用%MessageID%%SourceFileName%
作为发送端口中的宏时,发送端口的输出将是唯一名称加上原始名称。这对于所有类型的文件都适用。
删除大文件
删除大文件可以在计划任务中完成。如果有多个合作伙伴发送和接收大文件,则可能还有更多存储大文件的位置需要删除。
一种方法是创建一个XML文件,该文件为每个位置包含一个节点。这些节点包含存储大文件的目录的路径。可以将.NET程序集设置为计划任务,并从XML文件中读取目录并删除每个目录中的每个文件。如果经常运行计划任务,则首先检查文件是否未被其他进程使用。
删除大文件和存储目录路径的方法有很多种。这只是一个简单的建议。
相关文章
文章使用BizTalk传输大文件 - 接收端 描述了BizTalk的接收端。
文章使用Windows服务和BizTalk服务器传输超大文件 描述了如何使用Windows服务和BizTalk服务器传输超大文件(最多2GB)。