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/.

Multi Tenant Architecture

Please note that the contents of this page are currently being revised!

This section describes the multi tenant architecture of the WSO2 Carbon. This architecture supports the deployment of applications, web applications, web services, ESB mediators and mashups. The multi tenancy architecture of WSO2 aims to achieve the following:

  • Tenant isolation: This involves allowing each tenant to have its own domain which cannot be accessed by other tenants.
  • Data isolation: This involves allowing each tenant to manage its data. 
  • Execution isolation: This involves allowing each tenant to carry out business processes and workflows independent of other tenants. No action of a tenant should be triggered or inhibited by another tenant.
  • Performance Isolation: This involves ensuring that no tenant has an impact on the performance of another tenant.

Architecture

CarbonRuntime (server) is the complete server space which is referred to as the super tenant. Separate spaces within this server space is allocated to individual tenants.

The super tenant has it's own configuration and context module. Similarly, each individual tenant also has its own configuration and context module.  Each tenant has its own security domain. A domain has a set of users, and permissions for those users to access resources. Thus, a tenant is restricted by the users and permissions of the domain assigned to it. The artifact repositories of the tenants are separated from each other.

An individual tenant can carry out the following activities within the boundaries of its own configuration and context module:

  • Deploying artifacts
  • Applying security
  • User management
  • Data management

WSO2 Carbon provides a number of Admin services which have special privileges to manage the server. These admin services are deployed in the super tenant. Other tenants can make use of these admin services to manage their deployment. The admin services operate in a tenant aware fashion. Thus, privileges and restrictions that apply to any client using an admin service are taken into account.

Resource sharing

WSO2 Carbon supports the following methods for sharing resources among tenants:

  • Private Jet mode: This method allows the load of a tenant ID to be deployed in a single tenant mode. A single tenant is allocated an entire service cluster. The purpose of this approach is to allow a tenant special privileges  such as priority processing and improved performance.
  • Separation at hardware level: This method allows different tenants to share a common set of resources, but each tenant has to run its own operating system. This approach helps to achieve a high level of isolation, but it also incurs a high overhead cost.
  • Separation at JVM level: This method allows tenants to share the same operating system. This is done by enabling each tenant to run a separate JVM instance in the operating system.
  • Native multitenancy:  This method involves allowing all the tenants to share a single JVM instance. This method minimises the overhead cost.

Lazy loading

Lazy loading is a design pattern used specifically in cloud deployments to prolong the initialisation of an object or artifact until it is requested by a tenant or an internal process. 

Tenants

  Lazy loading of tenants is a feature that is built into all WSO2 products, which ensures that in an environment with multiple tenants, all tenants are not loaded at the time the server starts. Instead, they are loaded only when a request is made to a particular tenant. If a tenant is not utilised for a certain period of time (30 minutes by default), it will be unloaded from memory.

You can change the default time period allowed for tenant inactiveness by adding -Dtenant.idle.time=<time_in_minutes> java property to the product's startup script ( ./wso2server.sh file for Linux and wso2server.bat   for Windows) as shown below:

JAVA_OPTS \
    -Dtenant.idle.time=30 \
Artifacts

Lazy loading of artifacts is a feature that is used by some Carbon products, which can be enabled via the Carbon server configuration file ( carbon.xml ). The deployer that handles lazy loading of artifacts is called the GhostDeployer. A flag to enable or disable the Ghost Deployer is shown below. By default, this is set to false because the Ghost Deployer works only with the HTTP/S transports. Therefore, if other transports are used, we do not have to enable the Ghost Deployer.

<GhostDeployment>
   <Enabled>false</Enabled>
   <PartialUpdate>false</PartialUpdate>
</GhostDeployment>

When a standalone WSO2 product instance is started with lazy loading enabled, its services, applications and other artifacts are not deployed right away. They are first loaded in Ghost form and the actual artifact is deployed only when a request for the artifact is made. In addition, if an artifact has not been utilized for a certain period of time, it will be unloaded from the memory.

When lazy loading of artifacts is enabled for PaaS deployments, lazy loading applies both for tenants as well as a tenant’s artifacts. As a result, for a tenant in a cloud environment, lazy loading is applicable on both levels. Therefore, the associated performance improvements and resource utilization efficiencies are optimal.

Restrictions

The following restrictions are imposed to ensure that each individual tenant has the required level of isolation and maintains fine grained security control over its own services without affecting the other tenants.

  • Only the super tenant can modify its own configuration. In addition, it can add, view and delete tenants.
  • When a tenant logs into the system, it can only access artifacts deployed under its own configuration. One tenant cannot manipulate the code of another tenant.
  • The super admin or tenant admin can add user stores to their own domain. Dynamic configurations are possible only for secondary user stores and the 'primary' user store is not configurable at run time. This is because primary user stores are available for all tenants and allowing changes to the configuration at run time can lead to instability of the system. So the primary user store is treated as a static property in the implementation and must be configured prior to run time.
  • A tenant's code cannot invoke sensitive server side functionality. This is achieved via Java security.
  • Tenants share the transports provided by the system. They are not allowed to create their own transports.

Request dispatching

This section describes how the multi tenancy architecture described above works in a request dispatching scenario.

When a Carbon server receives a request, the message is first received by the handlers and dispatchers defined for the server configuration (i.e. super tenant). The server configuration may include handlers that implement cross tenant policies and Service Level Agreement (SLA) management. For example, a priority based dispatcher can be applied at this stage to offer differentiated qualities of service to different clients. Once the relevant handlers and dispatchers are applied, the request is sent to the tenant to which it is addressed. Then the message dispatchers and handlers specific to that tenant will be applied. See Viewing Handlers in Message Flows for further information on message handlers and dispatchers.

The following example further illustrates how message dispatching is carried out in a multi tenant server.

For example, two tenants named foo.com and bar.com may deploy a service named MyService. When this service is hosted on the two tenants, they would have the following URLs.

http://example.com/t/foo.com/services/MyService 
http://example.com/t/bar.com/services/MyService

The name of the tenant in the URL allows the tenant to be identified when the Carbon server receives a message which is addressed to a specific client. Alternatively, you may configure a CNAME record in DNS (Domain Name System) as an alias for this information.

If a request is addressed to the MyService service hosted by foo.com, the message handlers and dispatchers of the super tenant will be applied and the tenant foo.com will be identified by the tenant name in the URL. Then the request will be sent to foo.com where it will be processed.