Prudence
The Scalable REST/JVM
Web Development Platform

Creative Commons License

Prudence Clusters

Several Prudence instances can work together as a cluster, allowing them to share state and tasks. Clusters can be deployed on a dedicated grid of servers or in "clouds" of disposable virtual machines. A cluster can help you scale, as well as provide you with better uptime via redundancy.
Prudence instances in a local network automatically form a Hazelcast cluster, discovering each other, as well as detecting member failures, via IP multicasting. You can see log messages about members being added to or removed from the cluster in the "prudence.log" files from the logger named "com.hazelcast.cluster.ClusterManager".
IP multicast discovery is the default behavior, but Hazelcast is otherwise very configurable, providing you with fine-grained control over member discovery, data distribution and fault tolerance. Edit your "/configuration/hazelcast.conf" file according to the Hazelcast documentation.
How far can Prudence clusters take you? Consider that Hazelcast has been tested and works just fine in cloud clusters of 100 members. So, Prudence can take you very far indeed: however, you must be sure that the other parts of your architecture scale. See our "Scaling Tips" article for an in-depth treatment.

Distributed Tasks

You can use application.distributedTask to execute tasks anywhere (and even everywhere) in the cluster. Use the "where" argument to control exactly where you want the task to run.

Distributed State

Use application.distributedGlobals to share state, with support for cluster-wide atomic operations.

Distributed Cache

By default, Prudence chains an in-process memory cache over a Hazelcast cache, so you are already reaping the benefits of the cluster.
Prudence also supports memcached, MongoDB, and even SQL-database based distributed caches. Of course, you can chain several distributed backends together. See document.cache for more information and examples.

Load Balancing

You can run many instances of Prudence behind a load balancer. This offers fault tolerance, maintenance options, and the possibility of dramatically scaling up the number of requests you can support. Your application can tolerate failure of any number of instances, as long as you have one running, because load balancers will automatically route to working instances. Similarly, load balancing allows you to bring some instances down for maintenance while keeping your application up and running.
Scaling up can be straightforward: simply add more and more instances behind the load balancer, which will make sure to distribute requests among them, while monitoring their responsiveness to accommodate for how well they handle their load. More complex systems can involve different kinds of instances, with the load balancer being in charge of routing requests to the appropriate pool of instances. This "partitioning" can be according to features (one pool handles chat room, one pool handles file downloads), geography (one pool handles England, one pool handles France), or other clever ways to keep the whole system efficient and responsive. See Scaling Tips for an in-depth treatment.

PerlBal

Prudence supports load balancing using HTTP proxies. There are many great load balancers out there, but we especially like Perlbal. Here's an example "perlbal.conf" in which we use Perlbal to handle secure connections for us. (See secure servers on how to configure Prudence to handle secure connections directly.)
CREATE POOL pool
  SET nodefile = /etc/perlbal/nodes
​
CREATE POOL secure_pool
  SET nodefile = /etc/perlbal/secure_nodes
​
# HTTP
CREATE SERVICE balancer
  SET listen          = 0.0.0.0:80
  SET role            = reverse_proxy
  SET pool            = pool
  SET verify_backend  = on
​
# HTTPS
CREATE SERVICE secure_balancer
  SET listen          = 0.0.0.0:443
  SET role            = reverse_proxy
  SET pool            = secure_pool
  SET verify_backend  = on
  SET enable_ssl      = on
  SET ssl_key_file    = /etc/perlbal/server.key
  SET ssl_cert_file   = /etc/perlbal/server.crt
  # This is recommended to workaround a bug in older versions of IE
  # (the default is ALL:!LOW:!EXP)
  SET ssl_cipher_list = ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
​
# Internal management port
CREATE SERVICE mgmt
  SET role   = management
  SET listen = 127.0.0.1:60000
​
ENABLE balancer
ENABLE secure_balancer
ENABLE mgmt
The nodes file is a list of IP addresses (not hostnames!) with ports. We'll add three Prudence instances running at the default server port:
192.168.1.10:8080
192.168.1.11:8080
192.168.1.12:8080
The secure_nodes file is the same for SSL connections. Let's have our Prudence instances run a separate server at port 8081 for secure requests:
192.168.1.10:8081
192.168.1.11:8081
192.168.1.12:8081
In our Prudence instances, we'll use "/instance/servers.*" to create a server at port 8081 (JavaScript flavor):
document.execute('/defaults/instance/servers/')
​
var secureServer = new Server(Protocol.HTTP, 8081)
secureServer.name = 'secure'
component.servers.add(secureServer)
And we'll use "/instance/hosts.*" to create separate virtual hosts for each port:
importClass(org.restlet.routing.VirtualHost)
​
var host = new VirtualHost(component.context)
host.name = 'default'
host.hostPort = '8080'
component.hosts.add(host)
​
var secureHost = new VirtualHost(component.context)
secureHost.name = 'secure'
secureHost.hostPort = '8081'
component.hosts.add(secureHost)
​
component.defaultHost = host
By default, an application would bind to the default host. To bind an application to the secure virtual host, set the hosts settings in its /settings.*:
hosts = [[secureHost, '/myapp/']]