Cluster Deployment Overview
The main concept of clustered Webswing is to divide the former Webswing Server into separate modules which handle web requests (Webswing Cluster Server) and application processing (Webswing Session Pool). In addition Admin console with its REST interface has been extracted into Admin Console Server module. With this setup you are able to deploy one Webswing cluster, handling multiple applications with:
- 1 .. N Webswing Cluster Servers
- 1 .. N Webswing Session Pools
- 0 .. 1 Webswing Admin Console Server
In a minimal setup you need 1 Cluster Server and 1 Session Pool. You can use multiple Cluster Servers for redundancy, but it should not be necessary to have more than 2 Cluster Servers in most cases. Session Pools can be scaled dynamically, depending on your needs of resources or connected users. Note that it is not possible to connect more than 1 Admin Console Server in the cluster.
You can deploy your cluster manually in a static way or you can use Docker images and Kubernetes with custom auto-scaling. For more information about Docker and Kubernetes deployment please contact support@webswing.org.
Installation
To install Webswing Cluster first unzip the distribution zip file. In the folder you will find webswing.war
archive, which is used to start both Cluster Server and Session Pool. There is a separate startup script for each module. To simplify your deployment, you can make a copy of the unzipped distribution folder for each module (Cluster Server or Session Pool) you want to deploy and start the module accordingly, using webswing.sh/webswing.bat
for Cluster Server or sessionpool.sh/sessionpool.bat
for Session Pool.
If you are using a headless Linux with X virtual frame buffer (Xvfb
), xvfb is needed only in case of Session Pool.
It is highly recommended that you do not share the configuration files between multiple modules. Every Cluster Server and every Session Pool should at least have its own *.config
file. If you plan to have multiple Cluster Servers or Session Pools, create a separate installation folder for each of them. Also consider using Docker images which can easily contain your single module deployments.
Cluster Server
Cluster Server is similar to Webswing Server with the difference that it is not able to start an application instance itself. Therefore it is a lightweight module, which basically resends messages between application instance and browser. It also decides on which Session Pool the instance will be started, holds session statistics and metrics for Admin Console Server and does some other necessary communication with Session Pools.
Cluster Server is a stateless web server, which means that if you have multiple Cluster Servers it doesn't matter which server you connect to from the browser, even on refresh, the browser connection will always find the way to its application instance. If you have multiple Cluster Servers deployed and one of the Cluster Servers terminate, all the browser connections to this server can be reconnected through the other running Cluster Server without terminating the application instance.
Inside Cluster Server is a built-in mechanism - a Session Pool load balancer. This mechanism is responsible for finding a free Session Pool where a new instance will be started. By default the load balancer uses a simple round-robin algorithm. You can change the load balancing algorithm to Active Sessions Count
by adding following to webswing.properties
in the Webswing Server for the activeSessions load balancing:
org.webswing.server.api.services.sessionpool.loadbalance.LoadBalanceResolver = org.webswing.server.api.services.sessionpool.loadbalance.ActiveSessionsCountLoadBalanceResolver
Everything in your application that is related to web is configured and provided through the Cluster Server. This includes security (SSL, authentication, logout), translations, fonts or custom web resource handling. On the other hand, everything related to your application binary is configured and handled in Session Pool. Because of this the webswing.config
file needs to be divided into 2 separate configuration files - webswing-server.config
which is used by Cluster Server and webswing-app.config
which is used by Session Pool. You can read more about this in next sections.
Cluster Server installation includes:
- webswing.war
- webswing-server.config
- jetty.properties
- webswing.properties
- webswing.bat / webswing.sh
- ssl configuration
- security module configuration / libs
- lang
- web related files for apps, e.g. custom index.html
Here is an example of a webswing-server.config
file:
{
"/" : {
"path" : "/",
"security" : {
"module" : "EMBEDED",
"config" : {
"users" : [ {
"username" : "admin",
"password" : "pwd",
"roles" : [ "admin" ]
}, {
"username" : "support",
"password" : "pwd",
"roles" : [ "support" ]
}, {
"username" : "user",
"password" : "pwd"
} ]
},
"classPath" : [ ]
},
"langFolder" : "${webswing.configDir}/lang",
"homeDir" : "${user.dir}",
"allowedCorsOrigins" : [ "*" ],
"dataStore": {
"module": "FILESYSTEM",
"config": {
"threadDumpsFolder": "C:/work/dataStore/threadDumps",
"recordingsFolder": "C:/work/dataStore/recordings",
"transferFolder": "C:/work/dataStore/transfer"
}
}
},
"/webswing-demo" : {
"path" : "/webswing-demo",
"name" : "Webswing Demo",
"webFolder" : "${webswing.rootDir}/apps/WebswingDemo/webroot",
"security" : {
"module" : "INHERITED",
"config" : null,
"classPath" : [ ]
},
"icon" : "${webswing.rootDir}/apps/WebswingDemo/icon.png",
"webHomeDir" : "${webswing.rootDir}/apps/WebswingDemo",
"langFolder" : "${webswing.configDir}/lang",
"uploadMaxSize" : 5,
"maxClients" : 100,
"sessionMode" : "CONTINUE_FOR_BROWSER",
"allowStealSession" : true,
"autoLogout" : true
}
}
Configuration of a Cluster Server is similar to the configuration of Webswing Server, please refer to this section for configuration options in webswing.properties
.
Session Pool
Session Pool is a simple JAR application. The main purpose of this module is to start, manage and communicate with an application instance. It connects to a Cluster Server via a WebSocket and it is always connected to all Cluster Servers in the Cluster. It is not desired that there is a connection problem between a Session Pool and a Cluster Server and this kind of problem should be resolved ASAP.
Unlike Cluster Server, Session Pool is stateful. When a Session Pool encounters a fatal error which leads to termination, all of the application instance processes that this Session Pool has created will be terminated as well.
Session Pool can be configured using webswing-sesionpool.properties
file. The table below describes the properties used in the file.
Property | Description | Default value |
---|---|---|
webswing.connection.secret |
Secret string for securing user sessions and websocket connections used by Webswing server. Should be a 128 characters long string. Use the same secret for every module inside cluster. | |
webswing.connection.secret.file |
Alternative way to specify secret string in a file. | |
sessionpool.id |
Id of the session pool. Will be generated if not provided. | |
sessionpool.priority |
Optional priority. Higher number means higher priority, you can use this value in a custom session pool load balancer algorithm in cluster server. | 1 |
sessionpool.instances.max |
Maximum pool size. This is an overall maximum of all instances in the session pool. Set -1 for infinite. | -1 |
sessionpool.reconnect.interval |
Reconnect interval (seconds) if session pool loses connection to cluster server. Use -1 for infinite interval. Session pool will shut down if there are no active connections to cluster server. |
60 |
sessionpool.reconnect.retries |
Number of retries to reconnect to a cluster server after session pool loses connection. Session pool will shut down if there are no active connections to cluster server. |
5 |
sessionpool.reconnect.delay |
Delay (milliseconds) between reconnects. | 3000 |
webswing.websocketUrlLoader.type |
Type of websocket URL loader - define how should session pool get the websocket connection URL to cluster server(s). (use propertyFile_noReload to disable reloading) |
propertyFile |
webswing.websocketUrlLoader.interval |
Websocket URL loader reloading interval in seconds. | 5 |
webswing.server.websocketUrl |
Comma-separated list of websocket URLs to cluster servers. (use with loader type propertyFile and propertyFile_noReload ) |
ws://localhost:8080 |
webswing.websocketUrlLoader.script |
Script that loads a comma-separated list of websocket URLs. (use with loader type script ) |
|
webswing.logsDir |
Path where session pool logs should be stored. | logs/ |
Cluster Session Pool handles everything related to the application instance, therefore it needs access too application binaries, libraries, fonts and application configuration (webswing-app.config
).
Cluster Session Pool installation includes:
- webswing.war
- webswing-app.config
- webswing-sessionpool.properties
- sessionpool.bat / sessionpool.sh
- application jar binaries and libraries
- fonts
Here is an example of a webswing-app.config
file:
{
"/webswing-demo" : {
"allowUpload" : true,
"allowDownload" : true,
"isolatedFs" : true,
"sessionLogging" : false,
"allowJsLink" : true,
"javaFx" : true,
"javaFxClassPathEntries" : [ "${webswing.rootDir}/apps/javafx/*.jar" ],
"homeDir" : "${webswing.rootDir}/apps/WebswingDemo",
"theme" : "Murrine",
"directdraw" : true,
"debug" : true,
"jreExecutable" : "${java.home}/bin/java",
"javaVersion" : "${java.version}",
"launcherType" : "Desktop",
"launcherConfig" : {
"mainClass" : "org.webswing.demo.WebswingDemoApp"
},
"swingSessionTimeout" : 300,
"timeoutIfInactive" : false,
"allowDelete" : true,
"allowAutoDownload" : true,
"allowLocalClipboard" : true,
"allowServerPrinting" : false,
"dockMode" : "ALL",
"allowStatisticsLogging" : true,
"testMode" : false,
"jsLinkWhitelist" : [ "*" ],
"transferDir" : "${user}/upload",
"clearTransferDir" : true,
"sessionLogFileSize" : "${webswing.sessionLog.size:-10MB}",
"transparentFileSave" : true,
"sessionLogMaxFileSize" : "${webswing.sessionLog.maxSize:-1000MB}",
"transparentFileOpen" : true,
"fontConfig" : { },
"classPathEntries" : [ "*.jar" ]
}
}
Migration of webswing.config
If you are migrating from version older than 20.2, you need to make some changes to your webswing.config
file in order to use it in Webswing Cluster. First thing you should do is run Webswing Server 20.2 (non-cluster version) with your old webswing.config
file. Once the server is started and the configuration is loaded, the config file automatically converts to a newer version and is stored. In version 20.2 some of the fields are moved from "swingConfig": {...}
to app root (web config), e.g. "/webswing-demo": {}
.
Having this webswing.config
converted to a new version, you can create configuration files used in Cluster. Rename webswing.config
to webswing-server.config
and create new empty webswing-app.config
file.
In webswing-app.config
file create the structure of application paths like in this example:
{
"/webswing-demo": {
},
"/javafx": {
}
}
Now cut content from webswing-server.config
from "swingConfig"
:
{
"/webswing-demo": {
"swingConfig": {
<cut this>
}
}
}
and paste into the created structure in webswing-app.config
:
{
"/webswing-demo": {
<paste here>
}
}
Note that in webswing-app.config
you do not provide any configuration for root path "/"
.
After you have cut and pasted all your application configurations into webswing-app.config
, you can remove empty "swingConfig"
fields from webswing-server.config
. The configuration that is left in this file is your webswing-server.config
.
Admin Console
Please refer to this guide for more information about Admin Console setup. The only difference in Cluster is that you need to provide websocket URLs for all Cluster Servers in your deployment.
Security
Modules inside your Cluster deployment are connected through WebSocket. To make sure that no other malicious servers connect to your Cluster Servers, all modules must share the same secret key which is used in handshake when establishing the websocket communication. The secret key is defined in webswing.properties
, webswing-sessionpool.properties
and webswing-admin.properties
as property webswing.connection.secret
. Please change this secret key to your random value before going into production. This secret key is also used for signing JWT tokens that are used for user session cookies. Make sure you use only alphanumeric characters in the secret key, please do not use any special characters.
Data Store
Some of the data that application uses or produces must be available in different parts of the cluster (Session Pool, Cluster Server). This includes transfer (upload, download), thread dumps and recordings. Data store is a single point of access to these data. It is configurable in server (web) config and is inheritable similar to security module configuration. Default implementation is the FILESYSTEM
data store module. If you need to implement another way of storing data in your cluster (e.g. in database) please contact support@webswing.org.
The easiest way to configure data store in your Cluster is to map a shared folder that is accessible by every module (Cluster Server, Session Pool) in your Cluster.
If it is not possible to have a shared folder in your deployment, you can workaround this by enabling the directTransfer
flag in data store configuration. Direct transfer ensures that file transfers from client (browser) to the application instance and vice versa are done via websocket instead of HTTP request/response. Note that directTransfer does not work with recordings and thread dumps, therefore these features may not work in Admin Console as expected.
Using Admin Console
Cluster Overview
One of the main benefits of having an Admin Console in your Cluster is that you can see the cluster overview.
In this view you can see all cluster servers with statistics and also with an option to switch on/off verbose mode or show server logs. Session pools section shows every session pool with details, options to switch on/off drain mode, verbose mode or stop the session pool. Also you can see which applications you have deployed on which session pools and how many users are connected. If you have many session pools you can switch the card view to the compact table view and you are able to switch on/off drain mode for all session pools.
Sessions Overview
In the sessions overview you can see and manage each session from the whole cluster.
Available features for sessions:
- View session details and metrics of usage
- View all the warnings of each session
- View all the logs for each session
- Request a thread dump of each session
- Session Mirror view with a privacy consent option
- Full control of the application
- Possibility to record the session with a privacy consent option
- Shutting down the session
Web Configuration
In configuration view you can manage your configurations on Cluster Servers (webswing-server.config
) and Session Pools (webswing-app.config
).
Note that if you are using multiple Cluster Servers, Web Configuration (webswing-server.config
) must be identical on all Cluster Servers, because they are stateless. Therefore you see only one configuration form for Web Configuration and when you save your changes it is propagated and stored on each Cluster Server.
App Configuration
Unlike Web Configuration, App Configurations can be different per Session Pool. If you are using multiple Session Pools you can select one and create a different configuration. This is in most cases not recommended as you could lose track of what is configured where, but you can use this possibility for A/B testing. If you want to update all Session Pool configurations at once, simple make your changes in the default All Session config
on the top of the options panel, then your changes will be propagated and stored on each Session Pool.
Note that if you edit single session pool config field and switch to all config, value won't show and field will be disabled, because you would overwrite changes everywhere.
You can also decide that you want to dedicate a Session Pool to a single application. In this case, you can simply turn on/off a Session Pool in the App Configuration Session Pool selector. Note that this will not only "disable" the application in the Session Pool but will also delete the app configuration from Session Pool's webswing-app.config
. If you enable the application in the Session Pool again, the configuration values fallback to defaults. The recommended way is to prepare this kind of configuration of Session Pool before actually running it.
REST interface
If you previously used Webswing REST interface from Webswing Server, you now need to point your requests to Admin Console Server. The REST interface has been moved to this module and Cluster Server nor Session Pool provide this service.
Verbose
In Overview section of Admin Console you can switch Cluster Server and Session Pool to verbose mode. In this mode the default log level is set to DEBUG
. Turning verbose mode off sets the log level to INFO
.
You can also start Cluster Server and Session Pool with verbose mode enabled at startup using the -v
startup option.
Drain mode
Drain mode is useful when you want to shutdown a Session Pool or do some maintenance and you don't want to interfere with running sessions on that Session Pool. Drain mode will simply not allow to connect any more sessions. Note that drain mode does not automatically shutdown the Session Pool after all sessions finish.
Session Pool resilience
When session pool crashes, all sessions running on this session pool are lost and cannot be recovered. To be able to recover running sessions you can use the following configuration in webswing-sessionpool.properties
.
# enables instance resilience - session pool can recover connection to app instance processes after restart
# NOTE: recovered session pool MUST have the same sessionpool.id
sessionpool.instanceResilience.enabled = true
# path where instance descriptors and process streams are stored
sessionpool.instanceResilience.descriptors.dir = descriptors
# how long should instance wait for session pool to become available again after session pool goes down (in seconds)
sessionpool.instanceResilience.heartbeatTimeout.instance = 60
To be able to recover the sessions Webswing redirects the process I/O streams to files. Stream files with process/session descriptors are stored in descriptors directory. You can also setup the timeout how long will the session wait to be recovered after session pool crashes. Note that the restarted session pool must have the same id as the previous session pool that crashed, otherwise sessions cannot be recovered.