This site contains the documentation that is relevant to older WSO2 product versions and offerings.
For the latest WSO2 documentation, visit https://wso2.com/documentation/.

Setting Up Deployment Pattern 1

This page guides you through setting up deployment pattern 1, which is a HA clustered deployment of WSO2 Identity Server. For more information about deployment pattern 1 and its high level architecture, see Deployment Patterns - Pattern 1. 

You can install multiple instances of WSO2 products in a cluster to ensure that if one instance becomes unavailable or is experiencing high traffic, another instance will seamlessly handle the requests. For complete information on clustering concepts, see Clustering Overview in the Common Product Administration Guide.

Creating a cluster of WSO2 Identity Server instances involves a standard two node cluster for high availability. To ensure that the instances share governance registry artifacts, you must create a JDBC mount.

At a high level, use the following options to cluster Identity Server with a minimum of two nodes. The first section includes instructions on setting up databases. The second section involves setting up a standard two node cluster, the third section involves setting up the Identity Server dashboard in a clustered environment and the third section includes additional configurations if you need to set up a load balancer to front your cluster.




Setting up the databases

Before you begin

Before you begin, note that creating separate databases as shown below is not actually required and can be skipped. Instead, you can point all the datasources given below to a single database. This will NOT make a difference in performance. To do this, you can skip this section and proceed to the Configuring the datasources section.

However, if you do want to separate the data logically into separate databases, you can follow the steps given below.

Each Carbon-based product uses a database to store information such as user management details and registry data. All nodes in the cluster must use one central database for config and governance registry mounts. By default, each WSO2 product is shipped with an embedded H2 database that works for all types of data. 

Embedded H2 is not recommended in production

The embedded H2 database is NOT recommended in enterprise testing and production environments. It has lower performance, clustering limitations, and can cause file corruption failures. Please use an industry-standard RDBMS such as Oracle, PostgreSQL, MySQL, or MS SQL instead.

You can use the embedded H2 database in development environments and as the local registry in a registry mount. However, in a production environment it is recommended to change this. For more information on how to do this, set up the database and see the Changing the Carbon Database topic in the product administration guide.

You can create the following databases and associated datasources. This is NOT mandatory and you can choose to not create these databases if you wish and simply have a single database to handle all these concerns.

Database NameDescriptionScript locationDatasource file to be modified
WSO2_USER_DB
JDBC user store.
<PRODUCT_HOME>/dbscripts/
<PRODUCT_HOME>/dbscripts/identity/
<PRODUCT_HOME>/repository/conf/datasources/master-datasources.xml
USERSTORE_DBAuthorization manager configurations, internal permissions and roles.
<PRODUCT_HOME>/dbscripts/
<PRODUCT_HOME>/repository/conf/datasources/master-datasources.xml
IDENTITY_DBContains identity related data, for example, OAuth 2.0, SAML 2.0, etc.
<PRODUCT_HOME>/dbscripts/identity/
<PRODUCT_HOME>/repository/conf/datasources/master-datasources.xml
METRICS_DBMetrics Database is used to store the runtime metrics data reported by the Metrics JDBC Reporter periodically. There are 5 tables to store metrics data for each metric type. The metric types are Counter, Meter, Gauge, Histogram, and Timer.
<PRODUCT_HOME>/dbscripts/
<PRODUCT_HOME>/repository/conf/datasources/metrics-datasources.xml
BPS_DBThis is used for data pertaining to the workflow feature.
<PRODUCT_HOME>/dbscripts/
<PRODUCT_HOME>/repository/conf/datasources/bps-datasources.xml
REGISTRY_DBShared database for config and governance registry mounts in the product's nodes. This includes data on tenants and keystores.
<PRODUCT_HOME>/dbscripts/
<PRODUCT_HOME>/repository/conf/datasources/master-datasources.xml
REGISTRY_LOCAL1Local registry space in node1. Startup data for node 1.
<PRODUCT_HOME>/dbscripts/
<PRODUCT_HOME>/repository/conf/datasources/master-datasources.xml
REGISTRY_LOCAL2Local registry space in node 2. Startup data for node 2.
<PRODUCT_HOME>/dbscripts/
<PRODUCT_HOME>/repository/conf/datasources/master-datasources.xml

To understand this concept further, see the following diagram.

For more information on the concept of sharing governance and config registry databases across the cluster, see the topic on Sharing Databases in a Cluster in the WSO2 Product Administration Guide.

Do the following configurations to implement the database setup.

Creating the databases

Create the databases that you require using the RDBMS of your choice and run the relevant script for the RDBMS of your choice according to the table above. For instructions on how to do this, see Setting up the Physical Database in the WSO2 Product Administration Guide.

Configuring the datasources

Configure the datasources for the databases that you created above in both the WSO2 Identity Server nodes of your cluster. For instructions on how to configure the datasources for the databases you created, see Changing the Carbon Database in the WSO2 Product Administration Guide.

Note: For the BPS_DB and METRICS_DB, you need to configure the datasources in the <PRODUCT_HOME>/repository/conf/datasources/bps-datasources.xml file and <PRODUCT_HOME>/repository/conf/datasources/metrics-datasources.xml file respectively as indicated in the table above.

 Click here to see a sample configuration for node 1 for a MySQL database.

This sample is for datasources that point to the REGISTRY_LOCAL1REGISTRY_DBIDENTITY_DB, and WSO2_USER_DB databases. This is a MySQL sample so these configurations will vary for a different RDBMS.

<datasources-configuration xmlns:svns="http://org.wso2.securevault/configuration">     <providers>
        <provider>org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader</provider>
    </providers>
    <datasources>
        <datasource>
            <name>REGISTRY_LOCAL1</name>
            <description>The datasource used for registry- local</description>
            <jndiConfig>
                <name>jdbc/WSO2CarbonDB</name>
            </jndiConfig>
            <definition type="RDBMS">
                <configuration>
                    <url>jdbc:mysql://carbondb.mysql-wso2.com:3306/REGISTRY_LOCAL1?autoReconnect=true</url>
                    <username>regadmin</username>
                    <password>regadmin</password>
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                    <maxActive>50</maxActive>
                    <maxWait>60000</maxWait>
                    <testOnBorrow>true</testOnBorrow>
                    <validationQuery>SELECT 1</validationQuery>
                    <validationInterval>30000</validationInterval>
                </configuration>
            </definition>
        </datasource>
        <datasource>
            <name>REGISTRY_DB</name>
            <description>The datasource used for registry- config/governance</description>
            <jndiConfig>
                <name>jdbc/WSO2RegistryDB</name>
            </jndiConfig>
            <definition type="RDBMS">
                <configuration>
                    <url>jdbc:mysql://carbondb.mysql-wso2.com:3306/REGISTRY_DB?autoReconnect=true</url>
                    <username>regadmin</username>
                    <password>regadmin</password>
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                    <maxActive>50</maxActive>
                    <maxWait>60000</maxWait>
                    <testOnBorrow>true</testOnBorrow>
                    <validationQuery>SELECT 1</validationQuery>
                    <validationInterval>30000</validationInterval>
                </configuration>
            </definition>
        </datasource>
         <datasource>
            <name>WSO2_USER_DB</name>
            <description>The datasource used for registry and user manager</description>
            <jndiConfig>
                <name>jdbc/WSO2UMDB</name>
            </jndiConfig>
            <definition type="RDBMS">
                <configuration>
                    <url>jdbc:mysql://carbondb.mysql-wso2.com:3306/WSO2_USER_DB</url>
                    <username>regadmin</username>
                    <password>regadmin</password>
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                    <maxActive>50</maxActive>
                    <maxWait>60000</maxWait>
                    <testOnBorrow>true</testOnBorrow>
                    <validationQuery>SELECT 1</validationQuery>
                    <validationInterval>30000</validationInterval>
                </configuration>
            </definition>
        </datasource>
         <datasource>
            <name>IDENTITY_DB</name>
            <description>The datasource used for identity data</description>
            <jndiConfig>
                <name>jdbc/WSO2IDENTITYDB</name>
            </jndiConfig>
            <definition type="RDBMS">
                <configuration>
                    <url>jdbc:mysql://carbondb.mysql-wso2.com:3306/IDENTITY_DB</url>
                    <username>regadmin</username>
                    <password>regadmin</password>
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                    <maxActive>50</maxActive>
                    <maxWait>60000</maxWait>
                    <testOnBorrow>true</testOnBorrow>
                    <validationQuery>SELECT 1</validationQuery>
                    <validationInterval>30000</validationInterval>
                </configuration>
            </definition>
        </datasource>
   </datasources>
</datasources-configuration>

When configuring the second node

Tip: In the second WSO2 Identity Server instance (node 2), you must configure REGISTRY_LOCAL2 as the local database instead of REGISTRY_LOCAL1. These configurations must change accordingly.

 Click here to see a sample configuration for node 2 for a MySQL database
<datasources-configuration xmlns:svns="http://org.wso2.securevault/configuration"> 
     <providers> 
        <provider>org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader</provider> 
    </providers> 
    <datasources> 
        <datasource> 
            <name>REGISTRY_LOCAL2</name> 
            <description>The datasource used for registry- local</description> 
            <jndiConfig> 
                <name>jdbc/WSO2CarbonDB</name> 
            </jndiConfig> 
            <definition type="RDBMS"> 
                <configuration> 
                    <url>jdbc:mysql://carbondb.mysql-wso2.com:3306/REGISTRY_LOCAL2?autoReconnect=true</url> 
                    <username>regadmin</username> 
                    <password>regadmin</password> 
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName> 
                    <maxActive>50</maxActive> 
                    <maxWait>60000</maxWait> 
                    <testOnBorrow>true</testOnBorrow> 
                    <validationQuery>SELECT 1</validationQuery> 
                    <validationInterval>30000</validationInterval> 
                </configuration> 
            </definition> 
        </datasource> 
        <datasource> 
            <name>REGISTRY_DB</name> 
            <description>The datasource used for registry- config/governance</description> 
            <jndiConfig> 
                <name>jdbc/WSO2RegistryDB</name> 
            </jndiConfig> 
            <definition type="RDBMS"> 
                <configuration> 
                    <url>jdbc:mysql://carbondb.mysql-wso2.com:3306/REGISTRY_DB?autoReconnect=true</url> 
                    <username>regadmin</username> 
                    <password>regadmin</password> 
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName> 
                    <maxActive>50</maxActive> 
                    <maxWait>60000</maxWait> 
                    <testOnBorrow>true</testOnBorrow> 
                    <validationQuery>SELECT 1</validationQuery> 
                    <validationInterval>30000</validationInterval> 
                </configuration> 
            </definition> 
        </datasource> 
         <datasource> 
            <name>WSO2_USER_DB</name> 
            <description>The datasource used for registry and user manager</description> 
            <jndiConfig> 
                <name>jdbc/WSO2UMDB</name> 
            </jndiConfig> 
            <definition type="RDBMS"> 
                <configuration> 
                    <url>jdbc:mysql://carbondb.mysql-wso2.com:3306/WSO2_USER_DB</url> 
                    <username>regadmin</username> 
                    <password>regadmin</password> 
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName> 
                    <maxActive>50</maxActive> 
                    <maxWait>60000</maxWait> 
                    <testOnBorrow>true</testOnBorrow> 
                    <validationQuery>SELECT 1</validationQuery> 
                    <validationInterval>30000</validationInterval> 
                </configuration> 
            </definition> 
        </datasource> 
         <datasource> 
            <name>IDENTITY_DB</name> 
            <description>The datasource used for identity data</description> 
            <jndiConfig> 
                <name>jdbc/WSO2IDENTITYDB</name> 
            </jndiConfig> 
            <definition type="RDBMS"> 
                <configuration> 
                    <url>jdbc:mysql://carbondb.mysql-wso2.com:3306/IDENTITY_DB</url> 
                    <username>regadmin</username> 
                    <password>regadmin</password> 
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName> 
                    <maxActive>50</maxActive> 
                    <maxWait>60000</maxWait> 
                    <testOnBorrow>true</testOnBorrow> 
                    <validationQuery>SELECT 1</validationQuery> 
                    <validationInterval>30000</validationInterval> 
                </configuration> 
            </definition> 
        </datasource> 
   </datasources> 
</datasources-configuration>



Clustering Identity Server for high availability

The following diagram represents the typical two node WSO2 Identity Server cluster in active-active mode. Note that this representation does not include the load balancer.

Figure: Identity Server cluster for high availability

Do the following configurations to set this up.

  1. Install Identity Server on each node.
  2. Do the following changes to the <IS_HOME>/repository/conf/axis2/axis2.xml file for both nodes.

    1. Enable clustering on node 1 and node 2 by setting the clustering element to true:  
      <clustering class="org.wso2.carbon.core.clustering.hazelcast.HazelcastClusteringAgent" enable="true">

    2. Specify the name of the cluster this node will join.
      <parameter name="domain">wso2.is.domain</parameter>

    3. Use the well known address (WKA) based clustering method. In WKA-based clustering, we need to have a subset of cluster members configured in all the members of the cluster. At least one well known member has to be operational at all times.
      <parametername="membershipScheme">wka</parameter>

    4. Configure the localMemberHost and localMemberPort entries. These must be different port values for the two nodes if they are on the same server to prevent any conflicts.

      <parametername="localMemberHost">127.0.0.1</parameter>
      <parametername="localMemberPort">4000</parameter>
    5. Under the members section, add the hostName and port for each WKA member. As we have only two nodes in our sample cluster configuration, we will configure both nodes as WKA nodes.

      <members>
          <member>
            <hostName>127.0.0.1</hostName>
            <port>4000</port>
          </member>
          <member>
            <hostName>127.0.0.2</hostName>
            <port>4010</port>
          </member>
      </members>

      Note: You can also use IP address ranges for the hostName. For example,  192.168.1.2-10. This should ensure that the cluster eventually recovers after failures. One shortcoming of doing this is that you can define a range only for the last portion of the IP address. You should also keep in mind that the smaller the range, the faster the time it takes to discover members since each node has to scan a lesser number of potential members.

  3. Configure caching.

    From WSO2 Identity Server 5.2.0 onwards, distributed caching is disabled and it is not recommended to use this due to many practical issues that are related to configuring and running distributed caching properly. WSO2 Identity Server employs Hazelcast as the primary method of implementing cluster messages while using distributed caching in a simple setup.

    About Clustering

    For information on clustering, see Clustering WSO2 Products.

    About Caching

    • Why caching

      Caching is an additional layer on top of databases. It enables to keep the recently used data that are fetched from the database in local memory, so that for subsequent data requests instead of fetching from the database the data can be served from the local memory. Caching has certain advantages and disadvantages that you need to evaluate when deciding on your caching strategy.

    • Advantages
      • The load on the underlying database or LDAP is reduced as data is served from already fetched data in memory.

      • Improved performance due to the reduced number of database calls for repetitive data fetching.

    • Disadvantages
      • Coherency problems may occur when the data change is not immediately reflected on cached data if one node or an external system updates the database.

      • Data in memory can become stale yet be served, e.g., serving data from memory while its corresponding record in the database is deleted.

    Caching in WSO2 Identity Server

    Historically WSO2 Identity Server used distributed caching to utilize the above-mentioned advantages as well as to minimize the coherence problem. However, in newer deployment patterns where the network is not tightly controlled, distributed caching fail in unexpected ways. Hence, we no longer recommend using distributed caching. Instead, it is recommended to have local caches (if required) and cache invalidation messages (if required) by considering the information given below.

    • The ForceLocalCache property

      When Hazelcast clustering is enabled certain caches act as distributed caches. The ForceLocalCache property within the <cache> section in the carbon.xml file in the <IS_HOME>/repository/conf directory is there to mark that all the caches should act like local caches even in a clustered setup. (This is by default set to true)

      <ForceLocalCache>true</ForceLocalCache>

      Cache invalidation uses Hazelcast messaging to distribute the invalidation message over the cluster and invalidate the caches properly.  This is used to minimize the coherence problem in a multi-node setup.

    • Typical clustered deployment cache scenarios

      ScenarioLocal CachingDistributed CachingHazelcast ClusteringDistributed InvalidationDescription
      1. All caches are local with distributed cache invalidationEnabledNot ApplicableEnabledEnabled
      • This is the recommended approach.

      • Hazelcast messaging invalidates the caches.

      2. All caches are local without distributed cache invalidationEnabledNot ApplicableDisabledDisabled
      • Invalidation clears only the caches in specific nodes. Other caches are cleared at cache expiration. 

      • Hazelcast communication is not used.

      • As the decisions take time to propagate over nodes (default cache timeout is 15 minutes), there is a security risk in this method. To reduce the risk, reduce the default cache timeout period. To learn how to reduce the default cache timeout period, see Configuring Cache Layers - timeout.

      3. No cachingDisabledDisabledDisabledDisabled
      • The data are directly acquired from the database. 

      • Eliminates the security risks caused due to not having cache invalidation.

      • This method will create a performance degradation due to the lack of caching.

      4. Certain caches are disabled while the remaining are localEnabled for the available local cachesNot ApplicableEnabledEnabled
      • To reduce the security risk created in the second scenario and to improve performance in comparison with the third scenario, disable the security-related caches and sustain the performance-related caches as local caches. 

      • This requires identification of these caches depending on the use case.

      5. Distributed caching enabledDisabled—the ForceLocalCache property is set to false.EnabledEnabledNot Applicable
      • This scenario is only recommended if the network has tight tolerance where the network infrastructure is capable of handling high bandwidth with very low latency. 

      • Typically this applies only when you deploy all the nodes in a single server rack having fiber-optic cables. In any other environments, this implementation will cause cache losses. Thus, this implementation is not recommended for general use.

  4. Change the datasource name to jdbc/WSO2UMDB in user-mgt.xml (located in <IS_HOME>/repository/conf/) and identity.xml (located in <IS_HOME>/repository/conf/identity) of both node1 and node2.

    user-mgt.xml
    <UserManager>
      <Realm>
      <Configuration>
      ...
      <Property name="dataSource">jdbc/WSO2UMDB</Property>
      </Configuration>
      ...
      </Realm>
    </UserManager>
    identity.xml
    <JDBCPersistenceManager>
       	 <DataSource>
       		<Name>jdbc/WSO2IDENTITYDB</Name>
       	 </DataSource>
       	    	 <!-- <SkipDBSchemaCreation>false</SkipDBSchemaCreation> -->
    </JDBCPersistenceManager>
  5. Copy the JDBC driver (in this case MySQL driver) to the <IS_HOME>/repository/component/lib directory of both nodes. To do this, download the MySQL Java connector JAR from here and place it in the <IS_HOME>/repository/components/lib directory.

  6. Point all cluster nodes to same user store (to share one LDAP directory). By default, WSO2 Identity Server is started with an embedded LDAP which comes with the product. Disable the embedded LDAP of node 2 by modifying embedded-ldap.xml which can be found in the <IS_HOME>/repository/conf/identity directory.

    <EmbeddedLDAP>
    	<Property name="enable">false</Property>
    <--------------------->
    <EmbeddedLDAP>

    Point node 2 to the default user store of node1. You need to configure the connection URL in user-mgt.xml of node2 as given below (default port is 10389). By default, the connection URL given in the file is  ldap://localhost:${Ports.EmbeddedLDAP.LDAPServerPort}.

    <UserStoreManager class="org.wso2.carbon.user.core.ldap.ReadWriteLDAPUserStoreManager">
        <------------>
    	<Property name="ConnectionURL">ldap://[IP_of_node1]:10389</Property>
    	<------------>
    </UserStoreManager >

    If you are using some other external user store, make sure you point both nodes to that external user store.

  7. If both nodes will be running on the same server, set the port offset to avoid port conflicts. 

  8. Start the nodes. Use the -Dsetup option (e.g., sh wso2server.sh -Dsetup) on both nodes.
  9. Verify in the registry browser that the governance collection is shown with the symlink icon.
    1. Login to the management console.
    2. Navigate to, Home > Registry     > Browse

Setting up the dashboard

Follow the steps given below to set up the dashboard for the WSO2 Identity Server in a clustered environment.

  1. Change the service provider configuration for the dashboard in the <IS_HOME>/repository/conf/identity/sso-idp-config.xml file.

    <AssertionConsumerServiceURLs><AssertionConsumerServiceURL>https://is.wso2.com/dashboard/acs</AssertionConsumerServiceURL></AssertionConsumerServiceURLs>
    <DefaultAssertionConsumerServiceURL>https://is.wso2.com/dashboard/acs</DefaultAssertionConsumerServiceURL>
  2. Configure the  proxyHost and proxyHTTPSPort in the  <IS_HOME>/repository/deployment/server/jaggeryapps/dashboard/conf/site.json file with your IP or hostname and the port.

    "proxyHost" : "is.wso2.com",
    "proxyHTTPSPort" : "443",
  3. Configure the  proxyHost and proxyHTTPSPort in the  <WSO2IS_HOME>/repository/deployment/server/webapps/shindig/WEB-INF/web.xml file with your IP or hostname and the port.

    shindig.host=is.wso2.com
    shindig.port=443
  4. Optionally, configure the <IS_HOME>repository/conf/datasources/master-datasources.xml file to set up the user dashboard.

     Click here to view a sample datasource configuration.
    <datasources-configuration xmlns:svns="http://org.wso2.securevault/configuration">
       <providers>
          <provider>org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader</provider>
       </providers>
       <datasources>
          <datasource>
             <name>USER_DB</name>
             <description>The datasource used for users and authorization management</description>
             <jndiConfig>
                <name>jdbc/UserDB</name>
             </jndiConfig>
             <definition type="RDBMS">
                <configuration>
                   <url>jdbc:mysql://localhost:3306/USER_DB</url>
                   <username>root</username>
                   <password>root</password>
                   <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                   <maxActive>50</maxActive>
                   <maxWait>60000</maxWait>
                   <testOnBorrow>true</testOnBorrow>
                   <validationQuery>SELECT 1</validationQuery>
                   <validationInterval>30000</validationInterval>
                </configuration>
             </definition>
          </datasource>
          <datasource>
             <name>IDENTITY_DB</name>
             <description>The datasource used for WSO2 Identity Server specific data management</description>
             <jndiConfig>
                <name>jdbc/IdentityDB</name>
             </jndiConfig>
             <definition type="RDBMS">
                <configuration>
                   <url>jdbc:mysql://localhost:3306/IDENTITY_DB</url>
                   <username>root</username>
                   <password>root</password>
                   <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                   <maxActive>50</maxActive>
                   <maxWait>60000</maxWait>
                   <testOnBorrow>true</testOnBorrow>
                   <validationQuery>SELECT 1</validationQuery>
                   <validationInterval>30000</validationInterval>
                </configuration>
             </definition>
          </datasource>
          <datasource>
             <name>REG_DB</name>
             <description>The datasource used for registry- config/governance</description>
             <jndiConfig>
                <name>jdbc/RegistryDB</name>
             </jndiConfig>
             <definition type="RDBMS">
                <configuration>
                   <url>jdbc:mysql://localhost:3306/REG_DB?autoReconnect=true</url>
                   <username>root</username>
                   <password>root</password>
                   <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                   <maxActive>50</maxActive>
                   <maxWait>60000</maxWait>
                   <testOnBorrow>true</testOnBorrow>
                   <validationQuery>SELECT 1</validationQuery>
                   <validationInterval>30000</validationInterval>
                </configuration>
             </definition>
          </datasource>
          <datasource>
             <name>LOCAL_REG_DB_1</name>
             <description>The datasource used for local registry</description>
             <jndiConfig>
                <name>jdbc/WSO2CarbonDB</name>
             </jndiConfig>
             <definition type="RDBMS">
                <configuration>
                   <url>jdbc:h2:repository/database/WSO2CARBON_DB;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000</url>
                   <username>wso2carbon</username>
                   <password>wso2carbon</password>
                   <driverClassName>org.h2.Driver</driverClassName>
                   <maxActive>50</maxActive>
                   <maxWait>60000</maxWait>
                   <testOnBorrow>true</testOnBorrow>
                   <validationQuery>SELECT 1</validationQuery>
                   <validationInterval>30000</validationInterval>
                   <defaultAutoCommit>false</defaultAutoCommit>
                </configuration>
             </definition>
          </datasource>
       </datasources>
    </datasources-configuration>

Setting up the cluster with a load balancer (Nginx)

If you need to set up the above WSO2 Identity Server cluster with Nginx, you can follow the instructions given below (you must do this after setting up the cluster following the above instructions). When clustering WSO2 Identity Server with a load balancer, make sure to enable sticky sessions. This is required for the management console and the dashboard to work and if we disable temporary session data persistence in the <IS_HOME>/repository/conf/identity/identity.xml file. 

Sticky sessions for SSO

Sticky sessions are required to ensure a flawless SSO workflow when temporary session data persistence is disabled. It is recommended to use sticky sessions for SSO in order to have a higher throughput.

For more information on sticky sessions, see Sticky Sessions with Manager Nodes. The following is the deployment diagram with the load balancer.

Configuring Nginx

Use the following steps to configure NGINX Plus version 1.7.11 or NGINX community version 1.9.2 as the load balancer for the WSO2 Identity Server.

  1. Install NGINX Plus or Nginx community version in a server configured in your cluster.
  2. Configure Nginx to direct the HTTP requests to the two IS nodes via the HTTP 80 port using the  http://is.wso2.com/. To do this, create a VHost file (is.http.conf) in the /etc/nginx/conf.d  directory and add the following configurations into it.

    Nginx Community Version and NGINX Plus
    upstream wso2.is.com {
            server xxx.xxx.xxx.xx3:9763;
            server xxx.xxx.xxx.xx4:9763;
    }
    
    server {
            listen 80;
            server_name is.wso2.com;
            location / {
                   proxy_set_header X-Forwarded-Host $host;
                   proxy_set_header X-Forwarded-Server $host;
                   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                   proxy_set_header Host $http_host;
                   proxy_read_timeout 5m;
                   proxy_send_timeout 5m;
                   proxy_pass http://wso2.is.com;
     
    			   proxy_http_version 1.1;
            	   proxy_set_header Upgrade $http_upgrade;
            	   proxy_set_header Connection "upgrade";
            }
    }
  3. Configure NGINX Plus or Nginx community version to direct the HTTPS requests to the two IS nodes via the HTTPS 443 port using  https://is.wso2.com/. To do this, create a VHost file (is.https.conf) in the /etc/nginx/conf.d directory and add the following configurations into it.

    Note: The configurations for Nginx community version and NGINX Plus are different here since the community version does not support the sticky directive.

  4. Configure Nginx to access the Management Console as  https://mgt.is.wso2.com/carbon  via HTTPS 443 port. This is to direct requests to the manager node. To do this, create a VHost file ( mgt.is.https.conf) in the /etc/nginx/conf.d directory and add the following configurations into it.

    Nginx Community Version and NGINX Plus
    server {
    	listen 443;
    	server_name mgt.is.wso2.com;
    	ssl on;
    	ssl_certificate /etc/nginx/ssl/mgt.crt;
    	ssl_certificate_key /etc/nginx/ssl/mgt.key;
    
    	location / {
                   proxy_set_header X-Forwarded-Host $host;
                   proxy_set_header X-Forwarded-Server $host;
                   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                   proxy_set_header Host $http_host;
                   proxy_read_timeout 5m;
                   proxy_send_timeout 5m;
    			   proxy_pass https://xxx.xxx.xxx.xx2:9443/;
     
    			   proxy_http_version 1.1;
    			   proxy_set_header Upgrade $http_upgrade;
    			   proxy_set_header Connection "upgrade";
        	}
    	error_log  /var/log/nginx/mgt-error.log ;
               access_log  /var/log/nginx/mgt-access.log;
    }
  5. Restart the Nginx server.
    $sudo service nginx restart

    Tip: You do not need to restart the server if you are simply making a modification to the VHost file. The following command should be sufficient in such cases.
    $sudo service nginx reload  

    Also, import the ssl certificate used in the nginx to the wso2is-5.3.0/repository/resources/security/client-truststore.jks of the Identity Server nodes.

Create SSL certificates

Create SSL certificates for both the Identity Server nodes using the instructions that follow.

  1. Create the Server Key.
    $sudo openssl genrsa -des3 -out server.key 1024
  2. Certificate Signing Request.
    $sudo openssl req -new -key server.key -out server.csr
  3. Remove the password.
    $sudo cp server.key server.key.org 
    $sudo openssl rsa -in server.key.org -out server.key
  4. Sign your SSL Certificate.
    $sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

While creating keys, enter the hostname (is.wso2.com or mgt.is.wso2.com) as the common name.

Identity Server node 1 configuration

Configure the Identity Server node 1 using the following steps.

  1. Go to the <IS_HOME>/repository/conf/tomcat/catalina-server.xml file and add the proxy port as 443.

    <Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
              port="9443"
              proxyPort="443"
              ........
    
    <!--
            optional attributes:
    
            proxyPort="80"
    -->
    
    <Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
              port="9763"
              proxyPort="80"
  2. Configure deployment synchronizer in carbon.xml (autocommit=false in node 2). See Configuring SVN-Based Deployment Synchronizer for more details on how to configure this.

    Note: This is optional and you only need to do this if you configure a secondary user store manager through the management console.

    <deploymentsynchronizer>
     	<enabled>true</enabled>
     	<autocommit>true</autocommit>
     	<autocheckout>true</autocheckout>
     	<repositorytype>svn</repositorytype>
     	<svnurl>http://svnexample.wso2.com/svn/test</svnurl>
     	<svnuser>wso2</svnuser>
     	<svnpassword>wso2123</svnpassword>
     	<svnurlappendtenantid>true</svnurlappendtenantid>
    </deploymentsynchronizer>
  3. In the <IS_HOME>/repository/conf/carbon.xml directory, define the hostname for your server.

    <HostName>wso2.is.com</HostName>
    
    <MgtHostName>wso2.is.com</MgtHostName>

    This hostname is used by the IS cluster. It must be specified in the /etc/hosts file as:

    127.0.0.1   wso2.is.com

Identity Server node 2 configuration

Follow all the configuration steps that were done in node 1 for node 2 as well. 

Running the cluster
  1. Start Nginx and the Identity Server nodes.
  2. Now you can access the management console using the following URL: https://wso2.is.com/carbon/