最近项目中遇到这样的需求,biztalk需要通过FTP adapter到合作伙伴的FTP服务器上取文件,并且在同一个FTP服务器上有多个路径取不同类型的数据,这样biztalk接收端就要建立多个receive location,每个location对应到一个FTP服务器上的一个路径。FTP服务器还有个限制,对同一个IP同时允许的连接数有限制为10个,而实际上biztalk需要对这个FTP建立的receive location有几十个,如果不加控制的话,很可能超过十个请求同时连接到FTP服务器,超过的连接将会收到超连接数的错误,导致接收失败。
这种情况就要控制到FTP服务器的连接请求在同一时间内限制在十个以内,如何做到这点?
在讨论这个问题前,先要介绍一下host和host instance。
在biztalk中,每个orchestration、receive location和send port都需要指定运行他们的Host,实际上对于receive location和send port是指定handler,而每个handler是跟Host一一对应的。
Host分两类,进程内和独立进程,如果是在biztalk进程内运行的Host叫进程内Host,大多数 biztalk服务都运行在进程内Host。在biztalk进程外进程运行的Host叫独立Host,基本上HTTP和SOAP这类需要外部IIS这类进程接收消息的Request-Response双向接收端口需要使用独立主机。这里只讨论进程内主机。
Biztalk Host是个逻辑上的概念,不能直接使用,与Host相对应的Host instance才是真正运行biztalk orchestration、receive location和send port的实际承载者(有点像类的概念,实例化为对象后才能使用)。在一个biztalk group中可以建立多个Host,在group里的每个biztalk server可以对group里的每个Host在本地建立一个instance,最多只能建一个,也可以不建。
在biztalk运行时,orchestration、receive location和send port都会由指定的Host相应的Host instance进程进行处理。实际上每个biztalk进程内主机就是一个BTSNTSvc.exe服务进程,安装biztalk后,默认有两个主机:进程内host是BizTalkServerApplication,独立主机是BizTalkServerIsolatedHost,在services中可以看到默认进程内主机实例的服务BTSSvc$BizTalkServerApplication,是一个BTSNTSvc.exe进程。如果在biztalk再建一个进程内host和相应的host instance,在services中就会多一个BTSNTSvc.exe服务进程与之相对应。
到此,介绍了host和host instance后,回过头来看一开始的需要控制到同一个FTP的连接数的需求。可以设想,能不能把连接到这个FTP的所有receive location都由同一个host instance服务进程处理,然后在这个服务进程内控制receive location并发数,如果能做到这点就能控制到FTP的同时连接数了。
十分幸运的是,biztalk的运行机制能帮我们实现这个设想。Biztalk 运行时,每个host instance就是一个进程,大家知道,每个进程都可以维护一个(也只有一个)进程池,biztalk就是使用这个进程池将orchestration、receive location或send por的实例作为一个线程放入进程池内运行。Dotnet 2.0的进程池默认最大工作线程数是25,也就是说默认状况下,一个host instance同时并发只能运行25个orchestration、receive location或send port的实例。
基于这个机制,应该可以在运行FTP receive location的那个host instance进程,修改它的最大工作线程为10个,这样,就能控制FTP receive location并发连接数在10个以内,多出来的并发连接请求在线程池外排队,等线程池内有空闲的线程继续运行。
下面是修改host instance的最大线程数的方法。
打开注册表,导航至[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTSSvc$hostinstancename],其中红色部分是要修改的主机实例名。在这个key下新建一个CLR Hosting 的key,然后在这个CLR Hosting key下,建一个MaxWorkerThreads的REG_DWORD的值,值的数据设置为10,这就设置了这个host instance的最大工作线程为10个。如下图:
最后,有一点需要注意:MaxWorkerThreads的值的最小值跟服务器的CPU核心数有关系,即这个值不能小于CPU的核心数,如果这个值小于CPU的核心数,这个host instance的服务进程在下次启动时将出错无法启动。在biztalk中表现为启动这个host instance提示:
在services中,启动相应的服务,提示: