Configuring a Forms Routing Service Cluster

Laserfiche Forms 11 supports having the routing service in a cluster, which can greatly enhance the routing engine's ability to process user submissions, user tasks, service tasks, etc.

Basic Architecture

To setup Routing Service cluster, you will need following:

  1. Multiple machines with Laserfiche Forms installed
  2. A tcp/ip layer load balancer (such as Nginx, NLB, or F5)

Features

A Routing Service Cluster will be able to process the actions below over a distributed environment:

  1. Process user submissions.
  2. Process workflow callbacks.
  3. Process user tasks and service tasks.
  4. Stop instances, retry steps, and delete instances when deleting business process.

Other features and services will only be available on the primary Routing Service node.

Performance Benefits

Based on extensive testing, the best cost/performance benefits can be obtained when the following routing service deployment recommendations are followed:

Below is a brief example of performance gains using Routing Service Clusters when processing form submissions with 100 fields:

Configure a Forms Routing Service Cluster with NLB

The Routing Service can work as a cluster in a NLB (Windows Network Load Balancing) environment. In this scenario, we do not need an extra load balancing server, but there are limitations when compared to an external load balancer like Nginx:

  1. Forms IIS Server can not be hosted by the machines inside the cluster, as load balancing will not be performed.
  2. In an NLB based environment, the submission recovery service can only distribute submissions to the primary Routing Service node.

If you need to setup a cluster for the Forms IIS Server as well, you will need to setup a separate NLB cluster that hosts the Forms IIS Server nodes.

General Configuration

If you want to use NLB as load balancer, you need at least three machines (at least one NLB cluster with two Windows Servers hosting the Routing Service, and one separate machine for the Forms IIS Server). Before starting the configuration ensure the following requirements are completed:

  1. The Forms IIS Server is hosted in a separate machine apart from the Routing Service nodes.
  2. All Forms servers must have the same date/time settings. Sync all server clocks before proceeding.
  3. The Forms IIS Server node can access ports on all NLB cluster servers (ports 8168, 8170, *8172/8176, 8268, 8732, and 8736, you may need to allow firewall exceptions manually.)

    Important: Whether port 8172 or 8176 is used depends on the originally installed version of Laserfiche Forms. Use port 8172 for all Forms 11 versions installed prior to 11 Update 3 and upgraded to 11 Update 3 or newer; otherwise port 8176 for initial installations of Forms 11 Update 3 or newer. You can verify the port number required by checking the routing engine service configuration file ("C:\Program Files\Laserfiche\Laserfiche Forms\Forms\bin\RoutingEngineServiceHost.exe.config" by default) to determine the actual port used by the current Forms installation.

  4. All Routing Service nodes have access to the Forms IIS Server port 8268.

Configuring the NLB Cluster

  1. Install NLB on all machines that will host the Routing Service, see the Microsoft NLB documentation for additional information.
  2. Open the Network Load Balancing Manager in one of the NLB nodes.
  3. Create a new cluster in the Network Load Balancing Manager UI, with cluster operation mode set to Multicast.
  4. Add all nodes to the cluster, with the primary node Host priority set to 1, and all other nodes set to 2.
  5. Configure the cluster port rules in Cluster Properties:
    1. For port *8172/8176, follow the image below:
    2. For all other ports (8168, 8170, 8732, 8736, and 8738) follow the image below:
  6. After the configuration is complete, right-click the cluster name and select Control Hosts -> Start.

Configuring the Forms IIS Server

For the Forms IIS Server, follow the steps below:

  1. Install Forms.
  2. Open the Forms Configuration site, and on the Database tab, configure a valid database.
  3. On the Forms Server tab, verify that the primary Forms Server URL is //{IIS-machine-address}/Forms where {IIS-machine-address} is the address of the of this IIS server.
  4. On the Notification Service tab, verify that the Laserfiche Notification Hub URL is //{IIS-machine-address}:8181
  5. Browse to the Forms installation folder and open the Forms\Web.config file. The default installation path is C:\Program Files\Laserfiche\Laserfiche Forms\Forms\Web.config.
  6. Locate the <client> configuration block. For each wcf endpoint, change the address to the NLB cluster address. The Laserfiche.PushNotificationService.SharedContracts.IPushNotificationService, LicenseManagerService, LicenseManagerService2 and LicenseManagerSTS service will continue to use localhost. Refer to the following sample configuration. (See the note above regarding port 8172/8176.)
    <client>
    	<endpoint address="net.tcp://{nlb-cluster-address}:8176/lfinstance" 
    		binding="netTcpBinding" bindingConfiguration="timeoutBinding" 
    		contract="Laserfiche.Forms.Routing.IInstanceProcessing" name="" />
    	<endpoint address="net.tcp://{nlb-cluster-address}:8172/lfinstance" binding="netTcpBinding"
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IInstanceProcessing" 
    		name="" />
    	<endpoint address="net.tcp://{nlb-cluster-address}:8168/lfrouting" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IRoutingEngineService" 
    		name="" />
    	<endpoint address="net.tcp://localhost:8268/lfpushnotification" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" 
    		contract="Laserfiche.PushNotificationService.SharedContracts.IPushNotificationService" 
    		name="" />
    	<endpoint address="net.tcp://{nlb-cluster-address}:8732/lfautotrigger" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IAutoTrigger" 
    		name="" />
    	<endpoint address="net.tcp://{nlb-cluster-address}:8736/lfformexport" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IFormExportService" 
    		name="" />
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" contract="LicenseManagerService.ILicenseManager" 
    		name="LicenseManagerService">
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" contract="LicenseManagerService.ILicenseManager2" 
    		name="LicenseManagerService2">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/sts" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILFSecurityTokenService" 
    		contract="LicenseManagerSTS.ILFSecurityTokenService" name="LicenseManagerSTS">
    		<identity />
    	</endpoint>
    	<endpoint address="net.tcp://{nlb-cluster-address}:8738/lflicensing" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.ILicensingService" 
    		name="" />
    	<endpoint address="net.tcp://{nlb-cluster-address}:8170/attachmentTransfer" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBindingStreamed" 
    		contract="FormsModel.SharedContracts.IAttachmentTransferService" name="" />
    	<endpoint address="net.tcp://{nlb-cluster-address}:8174/lookup" 
    		binding="netTcpBinding" bindingConfiguration="timeoutBinding" 
    		contract="FormsModel.SharedContracts.IRoutingLookupService" name="" />
    	</client> 

    Note: The lflicensing endpoint is only required for Laserfiche Forms prior to version 11 Update 3.

    Note: The lookup service endpoint address only needs to be updated to {nlb-cluster-address} if the Forms server is configured to use the routing service as a proxy to execute lookup rules; otherwise use localhost.

  7. Browse to the Forms installation folder and open the Config\Web.config The default installation path is C:\Program Files\Laserfiche\Laserfiche Forms\Config\Web.config.
  8. Locate the <client> configuration block. For each wcf endpoint, change the address to the NLB cluster address. Refer to the following sample configuration.
    <client>
    	<endpoint address="net.tcp://{nlb-cluster-address}:8738/lflicensing" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.ILicensingService" 
    		name="" />
    	<endpoint address="net.tcp://{nlb-cluster-address}:8168/lfrouting" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IRoutingEngineService" 
    		name="" />
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" contract="LicenseManagerService.ILicenseManager" 
    		name="LicenseManagerService">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" contract="LicenseManagerService.ILicenseManager2" 
    		name="LicenseManagerService2">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/sts" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILFSecurityTokenService" 
    		contract="LicenseManagerSTS.ILFSecurityTokenService" name="LicenseManagerSTS">
    		<identity />
    	</endpoint>
    </client>

    Note: The lflicensing endpoint is only required for Laserfiche Forms prior to version 11 Update 3.

  9. Disable the Laserfiche Forms Routing Service Windows service to prevent routing from taking place outside the cluster.
  10. Restart the Laserfiche Notification Master Service Windows service.

Configuring the Routing Service on the Primary Node

  1. Install Forms.
  2. Open the Forms Configuration site, and on the Database tab, configure Forms to use the same database as the Forms IIS Server.
  3. Browse to the Forms installation folder and open the Forms\bin\RoutingEngineServiceHost.exe.config file. The default installation path is C:\Program Files\Laserfiche\Laserfiche Forms\Forms\bin\RoutingEngineServiceHost.exe.config.
  4. Locate the <appSettings> configuration block. Add following setting:
    <add key="RoutingEngineExecutionMode" value="ClusterPrimary" />
  5. Locate the <runtime> configuration block. Add following setting:
    <gcServer enabled="true"/>
    With this option enabled, the routing service will use the server garbage collection instead of workstation garbage collection. This will utilize more memory and CPU resources and achieve greater throughput.
  6. Locate the <client> configuration block. Change the address of Laserfiche.PushNotificationService.SharedContracts.IPushNotificationService to use the Forms IIS Server address. Refer to the following sample configuration. (See the note above regarding port 8172/8176.)
    <client>
    	<endpoint address="net.tcp://localhost:8172/lfinstance" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IInstanceProcessing" 
    		name="" />
    	<endpoint address="net.tcp://localhost:8168/lfrouting" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IRoutingEngineService" 
    		name="" />
    	<endpoint address="net.tcp://{forms-IIS-server-address}:8268/lfpushnotification" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" 
    		contract="Laserfiche.PushNotificationService.SharedContracts.IPushNotificationService" 
    		name="" />
    	<endpoint address="net.tcp://localhost:8732/lfautotrigger" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IAutoTrigger" 
    		name="" />
    	<endpoint address="net.tcp://localhost:8736/lfformexport" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IFormExportService" 
    		name="" />
    	<endpoint address="net.tcp://localhost:8738/lflicensing" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.ILicensingService" 
    		name="" />
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager" name="LicenseManagerService">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager2" name="LicenseManagerService2">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/sts" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILFSecurityTokenService" 
    		contract="LicenseManagerSTS.ILFSecurityTokenService" name="LicenseManagerSTS">
    		<identity />
    	</endpoint>
    </client>

    Note: The lflicensing endpoint is only required for Laserfiche Forms prior to version 11 Update 3.

  7. Restart the Laserfiche Forms Routing Service Windows service.

Configuring the Routing Service on Other Nodes in the NLB Cluster

On each remaining server in the cluster, perform the following:

  1. Install Forms
  2. Open the Forms Configuration site, and on the Database tab configure it to use the same database as the Forms IIS Server.
  3. Browse to the Forms installation folder and open the Forms\bin\RoutingEngineServiceHost.exe.config file. The default installation path is C:\Program Files\Laserfiche\Laserfiche Forms\Forms\bin\RoutingEngineServiceHost.exe.config.
  4. Locate the <appSettings> configuration block. Add following setting:
    <add key="RoutingEngineExecutionMode" value="ClusterSecondary" />
  5. Locate the <runtime> configuration block. Add following setting:
    <gcServer enabled="true"/>
    With this option enabled, the routing service will use the server garbage collection instead of workstation garbage collection. This will utilize more memory and CPU resources and achieve greater throughput.
  6. Locate the <client> configuration block. Change the address of the Laserfiche.PushNotificationService.SharedContracts.IPushNotificationService to use the Forms IIS Server address. Refer to the sample configuration below. (See the note above regarding port 8172/8176.)
    <client>
    	<endpoint address="net.tcp://localhost:8172/lfinstance" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IInstanceProcessing" 
    		name="" />
    	<endpoint address="net.tcp://localhost:8168/lfrouting" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IRoutingEngineService" 
    		name="" />
    	<endpoint address="net.tcp://{forms-IIS-server-address}:8268/lfpushnotification" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" 
    		contract="Laserfiche.PushNotificationService.SharedContracts.IPushNotificationService" 
    		name="" />
    	<endpoint address="net.tcp://localhost:8732/lfautotrigger" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IAutoTrigger" 
    		name="" />
    	<endpoint address="net.tcp://localhost:8736/lfformexport" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IFormExportService" 
    		name="" />
    	<endpoint address="net.tcp://localhost:8738/lflicensing" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.ILicensingService" 
    		name="" />
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager" name="LicenseManagerService">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager2" name="LicenseManagerService2">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/sts" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILFSecurityTokenService" 
    		contract="LicenseManagerSTS.ILFSecurityTokenService" name="LicenseManagerSTS">
    		<identity />
    	</endpoint>
    				</client>

    Note: The lflicensing endpoint is only required for Laserfiche Forms prior to version 11 Update 3.

  7. Restart the Laserfiche Forms Routing Service Windows service.

Configure a Forms Routing Service Cluster with Nginx

Using Nginx, you can make multiple Laserfiche Forms instances (including Forms IIS Server and Routing Service) perform in a clustered environment.

General configuration

For a Forms cluster to work, you need at least 3 machines (two machines hosting Forms instances and one machine hosting Nginx). Before starting the configuration ensure the following requirements are completed:

  1. All Forms servers must have the same date/time settings. Sync all server clocks before proceeding.
  2. Nginx is hosted in a separate machine, and it is recommended that the latest official, stable version of Nginx is used. Download the latest version here.
  3. Ensure that the Nginx machine can access ports in all Forms machines (ports 8168, 8170, *8172/8176, 8268, 8732, and 8736, you may need to allow firewall exceptions manually. See the note above regarding port 8172/8176.)
  4. The Laserfiche Notification Master Service and Laserfiche Notification Hub Service may only be hosted in one cluster node. In this documentation, it is assumed that these two services are hosted in the primary Forms node.

Configuring Nginx

When acting as a load balancer for Forms, Nginx has two primary functions:

  1. Redirect http/https requests to the Forms Cluster.
  2. Redirect wcf requests to Forms Cluster.

The configuration file (nginx.conf) will be similar to the following sample. The http section performs load balancing configuration for http requests, and the stream section performs load balancing configuration for wcf requests. Replace primary-address with the address of the primary node, secondary-address-1 with the address of the secondary node, nginx-host-name with the Nginx machine name, path-to-crt-file and path-to-crt-key-file with the appropriate paths (See the note above regarding port 8172/8176 and set instance processing ports accordingly):

worker_processes	1;

events {
	worker_connections	1024;
}

http {
	include		mime.types;
	default_type	application/octet-stream;
	
	# uncomment below lines if you want to have logs for all http requests
	#log_format	main	escape=json	'{$remote_addr - $remote_user [$time_local] "$request" '
			'$status $body_bytes_sent "$http_referer" '
			'"$http_user_agent" "$http_x_forwarded_for $upstream_addr"}';
	
	#access_log	access_http.log  main;
	#error_log	access_http_error.log;
	
	#send_file	on;
	tcp_nopush	on;
	
	keepalive_timeout	65;
	
	#gzip	on;
	
	upstream formsIISHttps {
		# make sure ip_hash is used because Forms IIS Server instances do not share sessions
		ip_hash;
		server {primary-address}:443;
		server {secondary-address-1}:443;
	}

	upstream formsIISHttp {
		# make sure ip_hash is used because Forms IIS Server instances do not share sessions
		ip_hash;
		server {primary-address}:80;
		server {secondary-address-1}:80;
	}
	
	upstream notificationhub {
		server	{primary-address}:8181;
	}
	
	server {
		listen 80;
		server_name {nginx-host-name};
		
		location / {
			charset UTF-8;
			
			proxy_set_header   X-Real-IP            $remote_addr;
			proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
			proxy_set_header   Host                   $http_host;
			proxy_set_header   X-NginX-Proxy    true;
			proxy_set_header   Connection "";
			
			proxy_pass  https://formsIISHttp;
		}
	}
	
	server {
		listen 443 ssl;
		server_name {nginx-host-name};
		# required if you would like to use a https connection
		ssl_certificate "{path-to-crt-file}";
		ssl_certificate_key "{path-to-crt-key-file}";
		
		location / {
			charset UTF-8;
			
			proxy_set_header   X-Real-IP            $remote_addr;
			proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
			proxy_set_header   Host                   $http_host;
			proxy_set_header   X-NginX-Proxy    true;
			proxy_set_header   Connection "";
			
			proxy_pass  https://formsIISHttps;
		}
	}

	# uncomment this if your notification hub is using http	
	# server {
	#	listen 8181;
	#	server_name {nginx-host-name};
	
	#	location / {
	#		charset UTF-8;
	
	#		proxy_set_header   X-Real-IP            $remote_addr;
	#		proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
	#		proxy_set_header   Host                   $http_host;
	#		proxy_set_header   X-NginX-Proxy    true;
	#		proxy_set_header   Connection "";
	
	#		proxy_pass  http://notificationhub;
	#	}
	#}
	
	# uncomment this if your notification hub is using http	
	server {
		listen 8181 ssl;
		server_name {nginx-host-name}
		# required if you would like to use a https connection
		ssl_certificate "{path-to-crt-file}";
		ssl_certificate_key "{path-to-crt-key-file}";
		
		location / {
			charset UTF-8;
			
			proxy_set_header   X-Real-IP            $remote_addr;
			proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
			proxy_set_header   Host                   $http_host;
			proxy_set_header   X-NginX-Proxy    true;
			proxy_set_header   Connection "";
			
			proxy_pass  https://notificationhub;
		}
	}
}

# configuration for wcf nettcpbinding
stream {

# enable these two lines if you would like logging for requests
# log_format	basic	'$time_iso8601 $remote_addr '
'$protocol $status $bytes_sent $bytes_received '
'$session_time $upstream_addr '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';

# access_log  access_tcp.log basic;

	#lfinstance
	upstream instanceprocessing {
		server  {primary-address}:8172;
		server  {secondary-address-1}:8172;
	}
	
	#lfrouting
	upstream routingprimary {
		server {primary-address}:8168;
	}
	
	#lfautotrigger
	upstream autotrigger {
		server {primary-address}:8732;
	}
	
	#lfformexport
	upstream formsexport {
		server {primary-address}:8736;
	}
	
	#attachmentTransfer
	upstream attachmenttransfer {
		server {primary-address}:8170;
	
	}
	
	#licenseservice
	upstream licenseservice {
		server {primary-address}:8738;
	}
	
	#notificationservice 
	upstream notificationservice {
		server {primary-address}:8268;
	}
	
	server {
		listen       {nginx-address}:8168;
		proxy_pass   routingprimary;
			# uncomment following 2 lines if you want wcf call return 
			# immediately when Routing Service node is down for some 
			# reason instead of waiting for a 1-min timeout.
		#proxy_timeout 3s;
		#proxy_connect_timeout 1s;
	}
	
	server {
		listen	{nginx-address}:8172;
		proxy_pass	instanceprocessing;
	}
	
	server {
		listen	{nginx-address}:8732;
		proxy_pass	autotrigger;
	}
	
	server {
		listen	{nginx-address}:8736;
		proxy_pass	formsexport;
	}
	
	server {
		listen	{nginx-address}:8170;
		proxy_pass	attachmenttransfer;
	}
	
	server {
		listen	{nginx-address}:8738;
		proxy_pass	licenseservice;
	}
	
	server {
		listen	{nginx-address}:8268;
		proxy_pass	notificationservice;
	}
}

Note: The licenseservice proxy is only required for Laserfiche Forms prior to version 11 Update 3.

After configuration is completed, start the Nginx service. Please refer to the Nginx official documentation if you are not familiar with Nginx.

Configuring the Primary Forms Node

  1. Install Forms.
  2. Open the Forms configuration site, and in the Database tab configure a valid database.
  3. In the Forms Server tab, the primary Forms Server URL should be set to //{nginx-address}/Forms
  4. In the Notification Service tab, the Laserfiche Notification Hub URL should be //{nginx-address}:8181
  5. Browse to the Forms installation folder and open the Forms\Web.config file. The default installation path is C:\Program Files\Laserfiche\Laserfiche Forms\Forms\Web.config.
  6. Locate the <netTcpBinding> configuration block. Change the security mode of timeoutBinding and timeoutBindingStreamed from Transport to None. Refer to the following sample.
    <netTcpBinding>
    	<binding name="timeoutBinding" receiveTimeout="00:59:00" sendTimeout="00:59:00" 
    		openTimeout="00:59:00" closeTimeout="00:59:00" maxReceivedMessageSize="200000000">
    		<security mode="None" />
    	</binding>
    	<binding name="timeoutBindingStreamed" transferMode="Streamed" receiveTimeout="00:59:00" 
    		sendTimeout="00:59:00" openTimeout="00:59:00" closeTimeout="00:59:00" 
    		maxReceivedMessageSize="200000000">
    		<security mode="None" />
    	</binding>
    </netTcpBinding>

    This is to ensure that the WCF client can connect to the WCF server after Ngnix processes the request.

  7. Locate the <client> configuration block. For each wcf endpoint, change the address to the machine address that hosts Nginx for the wcf services. The LicenseManagerService, LicenseManagerService2 and LicenseManagerSTS service will continue to use localhost. Refer to the following sample configuration. (See the note above regarding port 8172/8176.)
    <client>
    	<endpoint address="net.tcp://{nginx-address}:8172/lfinstance" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IInstanceProcessing" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8168/lfrouting" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IRoutingEngineService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8268/lfpushnotification" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" 
    		contract="Laserfiche.PushNotificationService.SharedContracts.IPushNotificationService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8732/lfautotrigger" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IAutoTrigger" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8736/lfformexport" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IFormExportService" 
    		name="" />
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager" name="LicenseManagerService">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager2" name="LicenseManagerService2">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/sts" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILFSecurityTokenService" 
    		contract="LicenseManagerSTS.ILFSecurityTokenService" name="LicenseManagerSTS">
    		<identity />
    	</endpoint>
    	<endpoint address="net.tcp://{nginx-address}:8738/lflicensing" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.ILicensingService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8170/attachmentTransfer" 
    		binding="netTcpBinding" bindingConfiguration="timeoutBindingStreamed" 
    		contract="FormsModel.SharedContracts.IAttachmentTransferService" name="" />
    </client>
    
  8. Browse to the Forms installation folder and open the Config\Web.config The default installation path is C:\Program Files\Laserfiche\Laserfiche Forms\Config\Web.config.
  9. Locate the <netTcpBinding> configuration block. Change the security mode for timeoutBinding from Transport to None. See the following sample.
    <netTcpBinding>
    	<binding name="timeoutBinding" receiveTimeout="00:20:00" sendTimeout="00:20:00" 
    		openTimeout="00:20:00" closeTimeout="00:20:00">
    		<security mode="None" />
    	</binding>
    </netTcpBinding>	
  10. Locate the <client> configuration block. For each wcf endpoint, change the address to the machine address that hosts Nginx for the wcf services.. LicenseManagerService, LicenseManagerService2 and LicenseManagerSTS service will continue to use localhost.
    <client>
    	<endpoint address="net.tcp://{nginx-address}:8738/lflicensing" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.ILicensingService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8168/lfrouting" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IRoutingEngineService" 
    		name="" />
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager" name="LicenseManagerService">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager2" name="LicenseManagerService2">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/sts" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILFSecurityTokenService" 
    		contract="LicenseManagerSTS.ILFSecurityTokenService" name="LicenseManagerSTS">
    		<identity />
    	</endpoint>
    </client>

    Note: The lflicensing endpoint is only required for Laserfiche Forms prior to version 11 Update 3.

  11. Browse to the Notification Service installation folder and open the Service\Laserfiche.PushNotificationService.Master.Host.exe.config. The default installation path is C:\Program Files (x86)\Laserfiche\Laserfiche Notification\Service\Laserfiche.PushNotificationService.Master.Host.exe.config.
  12. Locate the <netTcpBinding> configuration block. Change the security mode for timeoutBinding from Transport to None. See the following sample.
    <netTcpBinding>
    	<binding name="timeoutBinding" receiveTimeout="00:20:00" sendTimeout="00:59:00" 
    		openTimeout="00:59:00" closeTimeout="00:59:00" maxReceivedMessageSize="200000000">
    		<security mode="None">
    		</security>
    	</binding>
    </netTcpBinding>
  13. Restart the Laserfiche Notification Master Service Windows service.
  14. Browse to the Forms installation folder and open the Forms\bin\RoutingEngineServiceHost.exe.config file.
  15. Locate the <appSettings> configuration block and add following setting:
    <add key="RoutingEngineExecutionMode" value="ClusterPrimary" />
  16. Locate the <runtime> configuration block. Add following setting:
    <gcServer enabled="true"/>
    With this option enabled, the routing service will use the server garbage collection instead of workstation garbage collection. This will utilize more memory and CPU resources and achieve greater throughput.
  17. Locate the <netTcpBinding> configuration block. Change the security mode for timeoutBinding from Transport to None. See the following sample.
    <netTcpBinding>
    	<binding name="timeoutBinding" receiveTimeout="00:59:00" sendTimeout="00:59:00" 
    		openTimeout="00:59:00" closeTimeout="00:59:00" maxReceivedMessageSize="200000000">
    		<security mode="None" />
    	</binding>
    	<binding name="timeoutBindingStreamed" transferMode="Streamed" receiveTimeout="00:59:00" 
    		sendTimeout="00:59:00" openTimeout="00:59:00" closeTimeout="00:59:00" 
    		maxReceivedMessageSize="200000000">
    		<security mode="None" />
    	</binding>
    </netTcpBinding>
  18. Locate the <client> configuration block. For each wcf endpoint, change the address to the machine address that hosts Nginx for the wcf services.. LicenseManagerService, LicenseManagerService2 and LicenseManagerSTS service will continue to use localhost. (See the note above regarding port 8172/8176.)
    <client>
    	<endpoint address="net.tcp://{nginx-address}:8172/lfinstance" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IInstanceProcessing" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8168/lfrouting" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IRoutingEngineService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8268/lfpushnotification" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" 
    		contract="Laserfiche.PushNotificationService.SharedContracts.IPushNotificationService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8732/lfautotrigger" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IAutoTrigger" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8736/lfformexport" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IFormExportService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8738/lflicensing" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.ILicensingService" 
    		name="" />
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" contract="LicenseManagerService.ILicenseManager" 
    		name="LicenseManagerService">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" contract="LicenseManagerService.ILicenseManager2" 
    		name="LicenseManagerService2">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/sts" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILFSecurityTokenService" 
    		contract="LicenseManagerSTS.ILFSecurityTokenService" name="LicenseManagerSTS">
    		<identity />
    	</endpoint>
    </client>

    Note: The lflicensing endpoint is only required for Laserfiche Forms prior to version 11 Update 3.

  19. Restart the Laserfiche Forms Routing Service Windows service.

Configuring the Secondary Forms Node

  1. Install Forms.
  2. Open the Forms configuration site, and in the Database tab configure a valid database.
  3. Browse to the Forms installation folder and open the Forms\Web.config file. The default installation path is C:\Program Files\Laserfiche\Laserfiche Forms\Forms\Web.config.
  4. Locate the <netTcpBinding> configuration block. Change the security mode of timeoutBinding and timeoutBindingStreamed from Transport to None. Refer to the following sample.
    <netTcpBinding>
    	<binding name="timeoutBinding" receiveTimeout="00:59:00" sendTimeout="00:59:00" 
    		openTimeout="00:59:00" closeTimeout="00:59:00" maxReceivedMessageSize="200000000">
    		<security mode="None" />
    	</binding>
    	<binding name="timeoutBindingStreamed" transferMode="Streamed" 
    		receiveTimeout="00:59:00" sendTimeout="00:59:00" openTimeout="00:59:00" 
    		closeTimeout="00:59:00" maxReceivedMessageSize="200000000">
    		<security mode="None" />
    	</binding>
    </netTcpBinding>
  5. Locate the <client> configuration block. For each wcf endpoint, change the address to the machine address that hosts Nginx for the wcf services. The LicenseManagerService, LicenseManagerService2 and LicenseManagerSTS service will continue to use localhost. Refer to the following sample configuration. (See the note above regarding port 8172/8176.)
    <client>
    	<endpoint address="net.tcp://{nginx-address}:8172/lfinstance" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IInstanceProcessing" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8168/lfrouting" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IRoutingEngineService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8268/lfpushnotification" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" 
    		contract="Laserfiche.PushNotificationService.SharedContracts.IPushNotificationService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8732/lfautotrigger" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IAutoTrigger" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8736/lfformexport" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IFormExportService" 
    		name="" />
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager" name="LicenseManagerService">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager2" name="LicenseManagerService2">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/sts" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILFSecurityTokenService" 
    		contract="LicenseManagerSTS.ILFSecurityTokenService" name="LicenseManagerSTS">
    		<identity />
    	</endpoint>
    	<endpoint address="net.tcp://{nginx-address}:8738/lflicensing" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.ILicensingService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8170/attachmentTransfer" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBindingStreamed" 
    		contract="FormsModel.SharedContracts.IAttachmentTransferService" name="" />
    </client>
    

    Note: The lflicensing endpoint is only required for Laserfiche Forms prior to version 11 Update 3.

  6. Browse to the Forms installation folder and open the Config\Web.config The default installation path is C:\Program Files\Laserfiche\Laserfiche Forms\Config\Web.config.
  7. Locate the <netTcpBinding> configuration block. Change the security mode for timeoutBinding from Transport to None. See the following sample.
    <netTcpBinding>
    	<binding name="timeoutBinding" receiveTimeout="00:20:00" sendTimeout="00:20:00" 
    		openTimeout="00:20:00" closeTimeout="00:20:00">
    		<security mode="None" />
    	</binding>
    </netTcpBinding>	
  8. Locate the <client> configuration block. For each wcf endpoint, change the address to the machine address that hosts Nginx for the wcf services.. LicenseManagerService, LicenseManagerService2 and LicenseManagerSTS service will continue to use localhost.
    <client>
    	<endpoint address="net.tcp://{nginx-address}:8738/lflicensing" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.ILicensingService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8168/lfrouting" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IRoutingEngineService" 
    		name="" />
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager" name="LicenseManagerService">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager2" name="LicenseManagerService2">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/sts" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILFSecurityTokenService" 
    		contract="LicenseManagerSTS.ILFSecurityTokenService" name="LicenseManagerSTS">
    		<identity />
    	</endpoint>
    </client>

    Note: The lflicensing endpoint is only required for Laserfiche Forms prior to version 11 Update 3.

  9. Browse to the Forms installation folder and open the Forms\bin\RoutingEngineServiceHost.exe.config file.
  10. Locate the <appSettings> configuration block and add following setting:
    <add key="RoutingEngineExecutionMode" value="ClusterSecondary" />
  11. Locate the <runtime> configuration block. Add following setting:
    <gcServer enabled="true"/>
    With this option enabled, the routing service will use the server garbage collection instead of workstation garbage collection. This will utilize more memory and CPU resources and achieve greater throughput.
  12. Locate the <netTcpBinding> configuration block. Change the security mode for timeoutBinding from Transport to None. See the following sample.
    <netTcpBinding>
    	<binding name="timeoutBinding" receiveTimeout="00:59:00" sendTimeout="00:59:00" 
    		openTimeout="00:59:00" closeTimeout="00:59:00" maxReceivedMessageSize="200000000">
    		<security mode="None" />
    	</binding>
    	<binding name="timeoutBindingStreamed" transferMode="Streamed" receiveTimeout="00:59:00" 
    		sendTimeout="00:59:00" openTimeout="00:59:00" closeTimeout="00:59:00" 
    		maxReceivedMessageSize="200000000">
    		<security mode="None" />
    	</binding>
    </netTcpBinding>
  13. Locate the <client> configuration block. For each wcf endpoint, change the address to the machine address that hosts Nginx for the wcf services.. LicenseManagerService, LicenseManagerService2 and LicenseManagerSTS service will continue to use localhost. (See the note above regarding port 8172/8176.)
    <client>
    	<endpoint address="net.tcp://{nginx-address}:8172/lfinstance" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IInstanceProcessing" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8168/lfrouting" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IRoutingEngineService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8268/lfpushnotification" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" 
    		contract="Laserfiche.PushNotificationService.SharedContracts.IPushNotificationService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8732/lfautotrigger" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IAutoTrigger" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8736/lfformexport" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IFormExportService" 
    		name="" />
    	<endpoint address="net.tcp://{nginx-address}:8738/lflicensing" binding="netTcpBinding" 
    		bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.ILicensingService" 
    		name="" />
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager" name="LicenseManagerService">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/service" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILicenseManager" 
    		contract="LicenseManagerService.ILicenseManager2" name="LicenseManagerService2">
    		<identity />
    	</endpoint>
    	<endpoint address="http://localhost:5048/LicenseManager/sts" binding="ws2007HttpBinding" 
    		bindingConfiguration="WS2007HttpBinding_ILFSecurityTokenService" 
    		contract="LicenseManagerSTS.ILFSecurityTokenService" name="LicenseManagerSTS">
    		<identity />
    	</endpoint>
    </client>

    Note: The lflicensing endpoint is only required for Laserfiche Forms prior to version 11 Update 3.

  14. Restart the Laserfiche Forms Routing Service Windows service.
  15. Disable Laserfiche Notification Master Service Windows service and Laserfiche Notification Hub Service Windows service

Submission Recovery

Before Laserfiche Forms 11, the submission recovery action will be automatically triggered when you start the Laserfiche Forms Routing Service to process the submission XML files under %programdata%\Laserfiche Forms\RoutingError. With Forms 11, the Forms IIS Server will continuously move the submission XML files under %programdata%\Laserfiche\Forms\RoutingError to the Forms database, and the primary Routing Service node will perform the submission recovery actions. If any submission XML files remain under %programdata%\Laserfiche Forms\RoutingError before upgrading to Laserfiche Forms 11, and you install the Forms IIS Server on a new machine, perform the following steps after the upgrade:

  1. Locate the previous Forms server, and browse to the folder %programdata%\Laserfiche Forms\RoutingError.
  2. If any xml files exist in that folder, copy all files to the new Forms IIS Server, the destination folder will be: %programdata%\Laserfiche\Forms\RoutingError.
  3. Make sure the identity used for running the FormsAppPool has full control on the RoutingError folder.
  4. After a short period of time, Forms will start processing these submissions.

To Add Forms Auditing to a Cluster

  1. On the primary Forms node, configure Forms auditing with Laserfiche Audit Trail.
  2. Restart the Laserfiche Forms Routing Service Windows service.