Load Balancing
Introduction
The Izenda application can be load balanced to offer better performance and scalability. The most common scenario would be to load balance the API among two or more servers. The diagram below assumes that SSL is terminated by the load balancer. To clarify, traffic to the load balancer is encrypted and the load balancer sends unencrypted traffic to the API server(s) in a trusted network.
Configuration
- Update the WebApiUrl value in the izenda_config.js file with the IP or host name of the load balancer.
- Update the WebApiUrl in the [IzendaSystemSetting] table with the hostname or IP of the load balancer.
Scheduling
The Izenda Scheduler will store scheduling information in RAM of the server by default. If you are using any type of a distributed enviroment where there is more than one instance of the Izenda API (webfarms, etc.) you will need to use a database (ADO.NET job store) for storage of the scheduling information. Please follow the instructions below for setting up the scheduler to run in a distributed environment:
1. Download the creation script for your database type:
Download quartz database script ~databasetablestables_sqlServer.sql inside Quartz.NET-3.0.7.zip. Use that script to create the database on your DB server. https://github.com/quartznet/quartznet/releases/tag/v3.0.7
- Create the database (by default the table prefix “QRTZ_” but this can be set in the config)
Note:
- If using the .NET Core API resources, the Quartz configuration in steps 3 and 4 will instead be in a separate quartz.config file which can be downloaded here.
- The quartz.config file should be placed in the root of the Izenda API directory.
3. Add quartz config section into Web.config
<section name=”quartz” type=”System.Configuration.NameValueSectionHandler” />
- Add quartz section content into Web.config (under the </system.webServer> tag) and replace the value of config quartz.dataSource.QuartzNET_DS.connectionString by your server name (Server), user (User Id) and password (Password) to access quartzNET307 database.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <quartz><addkey="quartz.scheduler.instanceName"value="Izenda_Quartz"/><addkey="quartz.scheduler.instanceId"value="Izenda_API"/><addkey="quartz.threadPool.threadCount"value="10"/><addkey="quartz.jobStore.type"value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"/><addkey="quartz.jobStore.driverDelegateType"value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"/><addkey="quartz.jobStore.tablePrefix"value="QRTZ_"/><addkey="quartz.jobStore.lockHandler.type"value="Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz"/><addkey="quartz.jobStore.dataSource"value="QuartzNET_DS"/><addkey="quartz.dataSource.QuartzNET_DS.connectionString"value="[YOUR CONNECTION STRING HERE]"/><!-- If you are using a database other than SQL Server, be sure to use the appropriate provider for your database SqlServer - SQL Server driver for .NET Framework 2.0 OracleODP - Oracle’s Oracle Driver OracleODPManaged - Oracle’s managed driver for Oracle 11 MySql - MySQL Connector/.NET Npgsql - PostgreSQL Npgsql For more information, please consult the Quartz documentation: https://www.quartz-scheduler.net/documentation/quartz-3.x/tutorial/job-stores.html --><addkey="quartz.dataSource.QuartzNET_DS.provider"value="SqlServer"/><addkey="quartz.jobStore.useProperties"value="true"/><addkey="quartz.jobStore.misfireThreshold"value="60000"/><addkey="quartz.jobStore.clustered"value="true"/><addkey="quartz.serializer.type"value="json"/></quartz> |
- Each instance in the cluster node should use the same copy of the quartz properties above except each node in the cluster MUST have a unique instanceId (quartz.scheduler.instanceId)
- The datasource name is QuartzNET_DS, you can define whatever name you want, just note that it always come with config quartz.dataSource.QuartzNET_DS.xyz
- Above are setting for MS SQL Server, if you want to use other DBMS you have to use correct database script for that DB type and must set correct quartz properties which are related to DB connection, that are quartz.jobStore.driverDelegateType, quartz.dataSource.QuartzNET_DS.connectionString, and quartz.dataSource.QuartzNET_DS.provider. Prefer JobStores tutorial chapter here https://www.quartz-scheduler.net/documentation/quartz-3.x/tutorial/job-stores.html).
- To verify the config is correct or not on Izenda API, check the log file of all cluster nodes and make sure that there is only one node logs out the line contains “[Izenda_Quartz_Worker-###][INFO ][SubscriptionJob ] Start scheduling {#number} subscription jobs”
- After setting this configuration you will need to alter a setting in IzendaSystemSetting table as below:
1 2 3 | UpdateIzendaSystemSettingSetValue=1WhereName='UseADOJobStore' |
- Then you will need to clear any schedules already running in memory to add them to the database using the Update statement below:
1 | UPDATEIzendaSubscriptionSETIsScheduled='0' |
Warning: As general best practice, we recommend backing up your database before making any manual updates.
- After making these changes, all API instances should be restarted.