You are viewing limited content. For full access, please sign in.

Question

Question

Load Balancing Forms When Routing Service is Not In NLB

asked on April 14, 2022

We have a Forms environment where there is a Primary Forms server that runs the Routing Service that is not in the NLB and then 3 Forms servers that are in an NLB. Reading the Network Load Balancing for Laserfiche Web Products paper, it is assuming that the Routing Service is part of the NLB. My question is, is there anything different from what is listed in the paper to setup our environment correctly with the setup we have? We are using Forms 10.4.4.444 and will not be upgrading to Forms 11 yet.

0 0

Answer

SELECTED ANSWER
replied on April 18, 2022 Show version history

The identity is only required when the Routing Service is running with a domain user, the white paper doesn't make it clear. The online help has been updated to make it more accurate. We have an updated version for the white paper but it was not uploaded to the support site yet, it will be updated soon.

The lfpushnotification need to be changed as well since we only need to have one notification service running for one system.  I updated my original reply. 

Since you have the Primary Forms Server with Routing Service and Notification Service running on a seperate machine, you need to configure the Forms servers in the cluster to connect to the Routing Service and Notification Service on the Primary Forms Server machine. 

You can either disable the Routing Service, Notification Service on other machines or leave them running, the status of them will not affect the system since they are not in use.

0 0

Replies

replied on April 17, 2022 Show version history

If the Primary Forms Server that runs the Routing Service is not in the NLB cluster, you just need following change in the web.config for the Forms servers in the NLB cluster to connect to the Routing Service: 

<client>
<endpoint address="net.tcp://{routing-service-machine-address}:8168/lfrouting" binding="netTcpBinding" bindingConfiguration="timeoutBinding" contract="Laserfiche.Forms.Routing.IRoutingEngineService" name="" />
<endpoint address="net.tcp://{routing-service-machine-address}:8268/lfpushnotification" binding="netTcpBinding" bindingConfiguration="timeoutBinding" contract="Laserfiche.PushNotificationService.SharedContracts.IPushNotificationService" name="" />
<endpoint address="net.tcp://{routing-service-machine-address}:8732/lfautotrigger" binding="netTcpBinding" bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.IAutoTrigger" name="" />
<endpoint address="net.tcp://{routing-service-machine-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://{routing-service-machine-address}:8738/lflicensing" binding="netTcpBinding" bindingConfiguration="timeoutBinding" contract="FormsModel.SharedContracts.ILicensingService" name="" />
<endpoint address="net.tcp://{routing-service-machine-address}:8170/attachmentTransfer" binding="netTcpBinding" bindingConfiguration="timeoutBindingStreamed" contract="FormsModel.SharedContracts.IAttachmentTransferService" name="" />
</client>

replace {routing-service-machine-address} with the actual machine name.

0 0
replied on April 18, 2022

For clarification, the /lfpushnotification does not need to be changed? Also, in the whitepaper it says to insert the

<identity><userPrincipalName value ="{someone@example.com}" /></identity>

Is that needed?

0 0
replied on April 18, 2022

I am also guessing that the "Laserfiche Notification Hub Service" and "Laserfiche Notification Master Service" services need to be disabled on each NLB server? The whitepaper does not specify that, only the Forms Routing Service.

0 0
SELECTED ANSWER
replied on April 18, 2022 Show version history

The identity is only required when the Routing Service is running with a domain user, the white paper doesn't make it clear. The online help has been updated to make it more accurate. We have an updated version for the white paper but it was not uploaded to the support site yet, it will be updated soon.

The lfpushnotification need to be changed as well since we only need to have one notification service running for one system.  I updated my original reply. 

Since you have the Primary Forms Server with Routing Service and Notification Service running on a seperate machine, you need to configure the Forms servers in the cluster to connect to the Routing Service and Notification Service on the Primary Forms Server machine. 

You can either disable the Routing Service, Notification Service on other machines or leave them running, the status of them will not affect the system since they are not in use.

0 0
replied on April 19, 2022

On step 4 of the online help instructions, does it have to be the cluster IP address or can it be the cluster full internet name? If so, can that be updated accordingly?

0 0
replied on April 20, 2022

It can be either cluster IP address or cluster full internet name, we will update the document accordingly. 

0 0
replied on January 8, 2023

The online help has been updated.

1 0
replied on February 8, 2023 Show version history

I have been working on this configuration today and have been unable to get the real-time notifications to work. I have turned off both the Notification Hub Service and Master Service on the LB servers and edited the \forms\web.config files as referenced in the online help.

When I look at F12 Developer Tools it shows 'Failed to load resource: the server responded with a status of 500 ()'.

If I hit the Primary Forms server that is running the Notification service directly the real-time notifications work, so I'm sure it has something to do with traffic flowing through the LB.

The Forms\App\Operational logs for the LB servers give the following warning message:

Log Name:      Laserfiche-Forms-App/Operational
Source:        Laserfiche-Forms-App
Date:          2/8/2023 3:19:30 PM
Event ID:      28100
Task Category: NotificationServerConnectionDownWarning
Level:         Warning
Keywords:      Session0,Session1,Session2,Session3
User:          XXXXXX
Computer:      XXXXXX
Description:
A connection to the notification server could not be made. Notifications and real-time updates have been disabled. [LFF8100-NotificationServerConnectionDown]

Details:
URL: /Forms/webapi/v1/notification/GetPushNotificationToken?forceNew=false&skipErrMsg=true
Error: NotificationServerConnectionDown
Date: 2/8/2023 3:19:30 PM (US Mountain Standard Time)
HTTP Status Code: 500
Business Process ID: 0
User: XXXXXX
IP: 10.96.8.10
Browser: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.78

Stack Trace:
Caught exception: Laserfiche.Forms.CommonUtils.Exceptions.LFFormsException
Message: A connection to the notification server could not be made. Notifications and real-time updates have been disabled. [LFF8100-NotificationServerConnectionDown]
   at E_Forms.WebApi.Version1.Controllers.NotificationController.GetPushNotificationTokenGeneral(PushServiceRegisterRequest registerReq, Boolean forceNew)
   at lambda_method(Closure , Object , Object[] )
   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_2.<GetExecutor>b__2(Object instance, Object[] methodParameters)
   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()


Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="Laserfiche-Forms-App" Guid="{98141CA4-660B-51C6-66B4-EC37F5B2FD87}" />
    <EventID>28100</EventID>
    <Version>0</Version>
    <Level>3</Level>
    <Task>37434</Task>
    <Opcode>0</Opcode>
    <Keywords>0x8000f00000000000</Keywords>
    <TimeCreated SystemTime="2023-02-08T22:19:30.688450700Z" />
    <EventRecordID>541</EventRecordID>
    <Correlation />
    <Execution ProcessID="8560" ThreadID="10628" />
    <Channel>Laserfiche-Forms-App/Operational</Channel>
    <Computer>XXXXXX</Computer>
    <Security UserID="XXXXXX" />
  </System>
  <EventData>
    <Data Name="message">A connection to the notification server could not be made. Notifications and real-time updates have been disabled. [LFF8100-NotificationServerConnectionDown]

Details:
URL: /Forms/webapi/v1/notification/GetPushNotificationToken?forceNew=false&amp;skipErrMsg=true
Error: NotificationServerConnectionDown
Date: 2/8/2023 3:19:30 PM (US Mountain Standard Time)
HTTP Status Code: 500
Business Process ID: 0
User: XXXXXX
IP: XXXXXX
Browser: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.78

Stack Trace:
Caught exception: Laserfiche.Forms.CommonUtils.Exceptions.LFFormsException
Message: A connection to the notification server could not be made. Notifications and real-time updates have been disabled. [LFF8100-NotificationServerConnectionDown]
   at E_Forms.WebApi.Version1.Controllers.NotificationController.GetPushNotificationTokenGeneral(PushServiceRegisterRequest registerReq, Boolean forceNew)
   at lambda_method(Closure , Object , Object[] )
   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.&lt;&gt;c__DisplayClass6_2.&lt;GetExecutor&gt;b__2(Object instance, Object[] methodParameters)
   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.ApiControllerActionInvoker.&lt;InvokeActionAsyncCore&gt;d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.&lt;CallOnActionExecutedAsync&gt;d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Web.Http.Filters.ActionFilterAttribute.&lt;CallOnActionExecutedAsync&gt;d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.&lt;ExecuteActionFilterAsyncCore&gt;d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.&lt;CallOnActionExecutedAsync&gt;d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Web.Http.Filters.ActionFilterAttribute.&lt;CallOnActionExecutedAsync&gt;d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.&lt;ExecuteActionFilterAsyncCore&gt;d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.&lt;CallOnActionExecutedAsync&gt;d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Web.Http.Filters.ActionFilterAttribute.&lt;CallOnActionExecutedAsync&gt;d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.&lt;ExecuteActionFilterAsyncCore&gt;d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.ActionFilterResult.&lt;ExecuteAsync&gt;d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.ExceptionFilterResult.&lt;ExecuteAsync&gt;d__6.MoveNext()

</Data>
  </EventData>
</Event>

 

0 0
replied on February 9, 2023 Show version history

Your setup is still "Primary Forms server that runs the Routing Service that is not in the NLB and then 3 Forms servers that are in an NLB"? And the real-time notification doesn't work when access the NLB web server from a machine that is not in the NLB?  For the Forms servers in the NLB, you have configured to use notification service on the primary Forms Server right? 

You need to make sure the ports (8268 for lfpushnotification 8181 for the Notification Hub Service) are opened between the primary Forms server and the NLB cluster. 

For "When I look at F12 Developer Tools it shows 'Failed to load resource: the server responded with a status of 500 ()'.", what does the request URL looks like? Does it containt "8181//signalr/"? which is the request to the notification hub server from the web browser? 

Follow two diagrams show how the real-time notification work:

  • The web browser(Client) need to be able to access the Hub Service(LF Push Hub) using port 8181.
  • The Forms server(Forms) need to be able to access the Master Service(LF Push Master) using port 8268.
  • The Master Server(LF Push Master) need to be able to access Forms server (using port 8268) and Hub Service(using port 8181). 

 

0 0
replied on February 9, 2023

I'm still looking into everything that you sent, but thought I would at least send you the Request URL for the 500 error: https://xxxx.xxxx.com/Forms/webapi/v1/notification/GetPushNotificationToken?forceNew=false&skipErrMsg=true

0 0
replied on February 10, 2023

Just for easier reading, would you mind adding ports to each of the numbers in both diagrams?

0 0
replied on February 10, 2023 Show version history

After checking with a couple of teams at our organization I have decided to move the Primary Forms Server into the LB. We will end up increasing its CPU and RAM accordingly. I am still running into the same issue on the secondary server, but I will start a new post for the issue since the configuration of our servers has changed.

0 0
replied on January 10, 2023

@████████ how does this type of scenario where the Primary Forms server is not in the cluster change the instructions for 'Configuring a Forms Routing Service Cluster'?

0 0
You are not allowed to follow up in this post.

Sign in to reply to this post.