Caucho maker of Resin Server | Application Server (Java EE Certified) and Web Server


 

Resin Documentation

Aug 2012: Resin outscales C-based web server nginx in AutoBench benchmark
Feb 2012: NetCraft survey says Resin experiencing strong growth in last year and used in number of the Million Busiest Sites.
home company blog wiki docs 
app server web server 
health cloud java ee pro 
 Resin Server | Application Server (Java EE Certified) and Web Server
 

resin.xml: overview


Full Resin customization is configured by the resin.xml. The resin.xml overview describes resources, clustering, HTTP hosts and URL dispatching, and custom CanDI configuration.

Concepts and naming conventions

  • cluster - a collection of identically-configured servers.
  • environment - isolated class-loader contexts with shared resources: server, host and web-app are the main environments.
  • host - a HTTP virtual host.
  • proxy cache - HTTP proxy cache.
  • resource - drivers or services available to the application though JNDI or CDI like databases, JMS queues, custom CDI-configured service. Resin-specific resources include security, authenticators, health-checks and the rewrite/dispatch system.
  • rewrite/dispatch - the configuration for dispatching HTTP URLs to servlets and response codes like Apache's mod_rewrite.
  • server - a Resin JVM instance. There may be multiple servers on a machine.
  • watchdog - a JVM instance which watches over the Resin server and restarts the server if necessary.
  • web-app - a HTTP web-application which runs servlets.

resin.xml outline

Example: resin.xml outline
<resin xmlns="http://caucho.com/ns/resin"
          xmlns:resin="urn:java:com.caucho.resin">

  <cluster-default>          
    <!-- shared configuration across all clusters -->
    
    <resin:import path="classpath:META-INF/caucho/app-default.xml"/>
    
    <resin:import path="${__DIR__}/health.xml" optional="true"/>
  </cluster-default>          
    
  <cluster id="my-cluster">

    <server-default>
      <!-- thread limits, JVM config, keepalives, ports, HTTP -->

      <http port="8080"/>
    </server-default>

    <server id="server-a" address="192.168.1.10" port="6800"/>
    <server id="server-b" address="192.168.1.11" port="6800"/>

    <host id="www.myhost.com" root-directory="hosts/myhost.com">

      <resin:MovedPermanently regexp="/old-file" target="/new-path"/>
    
      <web-app-deploy path="webapps"
           expand-preserve-fileset="WEB-INF/work/**"/>

      <web-app id="/custom">
      </web-app>
      
    </host>
  
  </cluster>
          
</resin>

<cluster> is an environment container for servers, HTTP virtual hosts, and common resources. All Resin servers in a cluster share configuration.

defaults: server-default, cluster-default, web-app-default

When configuration is the same across several servers, like a thread-max or http ports, you can save typing by putting the common configuration in a server-default. Similarly, if all your clusters share common configuration, or all virtual-hosts are organized in the same way, you can use a cluster-default, host-default, and web-app-default to group the shared configuration.

The following example from the sample resin.xml uses a cluster-default and a <resin:import> to share common web-app configuration and the health-system configuration across all clusters in the system.

Example: cluster-default for health
<resin xmlns="http://caucho.com/ns/resin"
          xmlns:resin="urn:java:com.caucho.resin">

  <cluster-default>
    <resin:import path="classpath:META-INF/caucho/app-default.xml"/>
    
    <resin:import path="${__DIR__}/health.xml" optional="true"/>
  </cluster-default>

  <cluster id="my-cluster-a">
    ...
  </cluster>

  <cluster id="my-cluster-b">
    ...
  </cluster>

</resin>  

Server: configuring a JVM instance

See server configuration for more details on configuring the server.

The <server> tag configures specific JVMs in a cluster, the server-specific configuration, not the shared cluster configuration. Because the watchdog uses the <server> tag to launch the Resin JVM, the <server> tag also configures JVM parameters.

  • the server id used to identify the server.
  • the IP local address and port for communication within the server.
  • JVM parameters like -Xmx
  • thread limits like thread-idle-min and thread-idle-max.
  • TCP ports including the HTTP ports, keepalive timeouts and the cluster port.
  • load balancing configuration, including timeouts and weighting.
  • user-name and group-name for Unix setuid security.

The <server> tags configure the servers in a cluster. Dynamic servers launched with the --elastic-server and --cluster command-line arguments will use the same <server-default> configuration as other servers.

The first three servers in the cluster automatically form the triad which is Resin's triple-redundant cluster hub. If you have fewer than three servers, Resin will create a smaller hub.

Watchdog: protecting the server

The watchdog JVM watches over a Resin server and automatically restarts it when something goes wrong. The watchdog is responsible for setting the JVM arguments for the Resin server, logging its output, and handling the Unix setuid for user-name and group-name.

The configuration for the watchdog itself is inside the <server> that it manages like <watchdog-port>.

Cluster: multiple servers performing a common task

See clustering configuration for more details on configuring the clustering.

A Resin cluster gathers a set of servers to perform a common task, like serving HTTP requests, or load balancing, or processing a JMS queue. All Resin servers belong to a cluster. Even if you have one server, it belongs to a cluster of one.

The shared task is configured inside the <cluster> tag, whether it's traditional HTTP requests or JMS queues or SOA-style services. While HTTP has special configuration tags like <host> and the rewrite system, non-HTTP resources can use CanDI-style configuration for their services.

Example: cluster for http servlets
<resin xmlns="http://caucho.com/ns/resin">
  ...

  <cluster id="http">
    <server id="a" address="192.168.1.10" port="6800">
      <http port="8080"/>
    </server>

    <host id="">
      <web-app-deploy path="webapps"
           expand-preserve-fileset="WEB-INF/work/**"/>
    </host>
  </cluster>
</resin>

A Resin cluster can also serve non-HTTP resources. The JVM lifecycle, watchdog restarts, health checks, and cluster communication will be managed by Resin, while the service itself will be managed by application code.

Example: cluster for http servlets
<resin xmlns="http://caucho.com/ns/resin"
       xmlns:myservice="urn:java:com.mycom.myservice">
  ...

  <cluster id="http">
    <server id="a" address="192.168.1.10" port="6800"/>

    <myservice:MyService address="${resin.address}">
      ... <!-- CanDI configuration for the service -->
    </myservice:MyService>

  </cluster>
</resin>

The <cluster> tag forms a class-loader resource environment that is shared across all hosts and web-apps on the server. Shared CDI resources like databases, queues, and caches can be configured in the <cluster> tag and will be visible in all environment contexts.

Host: HTTP virtual hosts

See virtual host configuration for more details on configuring the virtual host.

A HTTP virtual host is configured with the <host> tag. The host name is given by the "id" attribute or the "host-name" attribute. The host with an empty name, like id="", is the default host.

Hosts can be configured with a specific <host> tag or implicitly with a <host-deploy> tag. Hosts share common configuring using the <host-default> tag. <host-deploy> specifies a "hosts" directory which implicitly creates hosts like the "webapps" directory for <web-app-deploy>.

The <host> tag dispatches HTTP urls to a virtual host. The host will typically contain one or more web-apps, which will be configured with the <web-app-default>, <web-app> and <web-app-deploy> tags.

For clustered deployment, the <host-deploy is used as a destination for a command-line deployment. The command-line deployed host will expand across the cluster into the "hosts" directory for each server in the cluster.

Since the host defines a resource environment, it can define shared resources like databases, caches, CDI services, and queues. The host can also define rewrite-dispatch URL rules.

Web-App: HTTP/servlet applications

See deploy configuration for more details on configuring the web-app.

A web-app is an application based around HTTP requests using and servlets to process the request. Web-apps are typically configured with a WEB-INF/web.xml and a WEB-INF/resin-web.xml and are typically deployed with a my-web-app.war file either by a command-line cluster deploy or by placing it directly in a webapps directory.

Web-apps can be configured with a specific <web-app> tag in a resin.xml <host> or implicitly with a <web-app-deploy> tag. Web-apps share common configuring using the <web-app-default> tag. <web-app-deploy> specifies a "webapps" directory.

Since the web-app defines a resource environment, it can define shared resources like databases, caches, CDI services, and queues. The host can also define rewrite-dispatch URL rules.

Rewrite: controlling URL dispatch

See rewrite/dispatch configuration for more details on configuring the rewrite/dispatch.

When you need to control URL formatting and dispatching, because URLs moved, or for better-looking URLs or for marketing tests, Resin's rewrite tags can help. The rewrite capabilities are similar to Apache's mod_rewrite and are integrated with Resin's HTTP and servlet dispatching.

As a simple example, sites like wikis often change readable URLs into a servlet URL and a query string. The following example passes through *.php, *.gif, etc. files and any URL that maps to a file. It rewrites any other URL to use the /index.php file.

Example: dispatch for a wiki
<web-app xmlns="http://caucho.com/ns/resin"
            xmlns:resin="urn:java:com.caucho.resin">
            
<resin:Dispatch target="\.(php|gif|css|png|js)"/>
<resin:Dispatch>
  <resin:IfFileExists/>
</resin:Dispatch>

<resin:Dispatch regexp="^" target="/index.php"/>

</web-app>

Resin's load balancing, http proxying and fast-cgi is configured with the rewrite-dispatch configuration. This means you can forward HTTP requests for a single web-app to a separate cluster of backend servers.

Example: load balancing
<web-app xmlns="http://caucho.com/ns/resin"
            xmlns:resin="urn:java:com.caucho.resin">
            
<resin:LoadBalance regexp="^/test" cluster="backend-cluster"/>

</web-app>

Load balancing: using backend servers for HTTP

See load balancing configuration for more details on configuring the load balancer.

HTTP load balancing is integrated in Resin using adaptive round-robin scheduling with failover to spread the HTTP traffic across backend servers. Because it is integrated with Resin's clustering, the load-balancer will automatically be informed when servers are added or removed elastically.

The load balancer is dispatched with a standard rewrite action. The socket parameters and timeouts are configured as part of the target <server>. The load-balancer will read the server's keepalive, timeouts and weights.

Example: load balancing dispatch
<web-app xmlns="http://caucho.com/ns/resin"
            xmlns:resin="urn:java:com.caucho.resin">
            
<resin:LoadBalance regexp="^/test" cluster="backend-cluster"/>

</web-app>
Example: load balancing timing configuration
<resin xmlns="http://caucho.com/ns/resin"
            xmlns:resin="urn:java:com.caucho.resin">

<cluster id="backend-cluster>            
  <server id="a" address="192.168.1.10" port="6800">
    <load-balance-socket-timeout>60<load-balance-socket-timeout>
    <load-weight>200<load-balance-weight>
  </server>

  ...

Logging: JDK java.util.logging

See logging configuration for more details on configuring logging.

Resin's logging configuration is based on the JDKs java.util.logging capabilities. In addition, the watchdog saves the standard output from the JDK in a log/jvm-server.log file.

JDK logging has two components: log handlers and loggers. Log handlers take log messages and process them. Resin's primary log handler formats messages and saves them to a log file. JDK loggers are used by Java code to send messages. Each logger has a name, often the same as the Java class name that logs the message, like "com.caucho.util.ThreadPool".

Logging is configured by attaching log-handler to logger names and enabling logging levels. The logging level for both a log-handler and the logger must match for the item to be logged. So some handlers might accept all logging messages, but the loggers only receive "info" messages.

The following log-handler sends all logging messages to the JVM's standard output. It also enables all loggers at the "info" level and the MyBean logger at the "finer" level. So the standard output will contain both the info and the finer logs.

Example: basic logging configuration
<resin xmlns:resin="urn:java:com.caucho.resin">

  <log-handler name="" level="all" path="stdout:"
               timestamp="[%y-%m-%d %H:%M:%S.%s] {%{thread}} "/>

  <logger name="" level="info"/>
  <logger name="com.foo.MyBean" level="finer"/>

  ...
</resin>

Resources: databases, queues, caches, and custom

See database configuration for more details on configuring databases.

Resources can be configured using a general XML syntax that will support any Java-based resource, for example an ActiveMQ queue. Resin will register the resource with CDI or JNDI, letting your application pick up the resource.

Some common resources like databases have their own Resin configuration tags. Most will use a CDI-based syntax.

Resources are stored in class-loader environments like the web-app, host or cluster. Since the environments are isolated from each other, a database "foo" configured in web-app /foo will not affect a web-app /bar.

The CDI-style configuration is a straight mapping between XML and Java classes. You can instantiate Java beans, configure their CDI annotations and properties, and even inject other beans using JSP/EL.

For example, the following configures a Resin clustered jcache, making it available as a CDI injection for any application with the same @Inject @Named. In other words, your application can be written using standard CDI injection with standard jcache and use Resin's configured implementation.

The ClusterCache implementation shares cache data across the cluster.

Example: jcache configuration
<web-app xmlns="http://caucho.com/ns/resin"
        xmlns:resin="urn:java:com.caucho.resin"
        xmlns:ee="urn:java:ee">

  <resin:ClusterCache ee:Named="test-cache" resin:Jndi="cache/test">
    <expire-timeout>1h</expire-timeout>
  </resin:ClusterCache>        
   
</web-app>

Health: monitors, actions, and reports

See health configuration for more details on configuring the health system.

Resin's health system continually monitors the server's health.

  • sensors: gather data from Resin internal state.
  • meters: save sensor and JMX data in an internal database.
  • health-checks: evaluate the health of a Resin system.
  • actions: take actions based on the Resin health like sending mail, gathering more detailed information, or restarting the server.
  • reports: prints pdf reports for the server's history.

Health Checks

Health checks are run every few minutes, check the JVM state, and return a simple response whether the health is OK, WARNING, CRITICAL or FATAL. If you've used the Nagios administration tool, the concept is similar. Resin has several built-in health checks, and it's straight-forward to write a custom health check.

The health check results will be logged if they are not okay, and can be used to trigger actions like sending mail or restarting the server.

In the following example, the JvmDeadlockHealthCheck asks the JVM to check for thread deadlocks. If a deadlock is detected, the health check returns a fatal. The MemoryTenuredHealthCheck looks at the JVM's free memory. If the free memory is too low, it will force a heap garbage-collection, and if that fails it will return a "critical" result.

Example: Health Checks
<resin xmlns="http://caucho.com/ns/resin"
          xmlns:resin="urn:java:com.caucho.resin">
<cluster-default>
  
  <health:JvmDeadlockHealthCheck/>

  <health:MemoryTenuredHealthCheck>
    <memory-free-min>1m</memory-free-min>
  </health:MemoryTenuredHealthCheck>

</cluster-default>

</resin>

Health Actions

Health actions can be triggered based on the health check results, JMX values, or as timed events. Each minute Resin will run through the health actions and will execute any that match their predicates.

Built-in actions include restarting, generating reports, sending mail, and gathering information like thread dumps, executing custom PHP pages. Custom actions are straightforward to implement.

The following Restart action will force a Resin restart if any health check returns a fatal or if the health checks are critical for more than five minutes.

Example: Restart Actions
<resin xmlns="http://caucho.com/ns/resin"
          xmlns:resin="urn:java:com.caucho.resin">
<cluster-default>
  
  <health:Restart>
    <health:Or>
      <health:IfHealthFatal/>
      <health:IfHealthCritical time="5m"/>
    </health:Or>
  </health:Restart>

...  
</cluster-default>
...
</resin>

Health Meters

Health meters gather data every minute and record the data in an internal database for graphing in the /resin-admin or reporting as a PDF.

Two examples from the standard health.xml configuration store JDK data from internal JDK MBeans. The first is a direct meter which saves the operating system's physical memory. The second is a delta meter which saves the JIT compilation time for the 60s interval.

Example: JMX meters
<resin xmlns="http://caucho.com/ns/resin"
          xmlns:resin="urn:java:com.caucho.resin">
<cluster-default>
  
  <health:JmxMeter>
    <name>OS|Memory|Physical Memory Free</name>
    <objectName>java.lang:type=OperatingSystem</objectName>
    <attribute>FreePhysicalMemorySize</attribute>
  </health:JmxMeter>
  
  <health:JmxDeltaMeter>
    <name>JVM|Compilation|Compilation Time</name>
    <objectName>java.lang:type=Compilation</objectName>
    <attribute>TotalCompilationTime</attribute>
  </health:JmxDeltaMeter>

...  
</cluster-default>
...
</resin>

Health Reports

The PDF reports can be customized to select the graphs and meters displayed. Each graph consists of a set of meters. For example, a graph about threads might show the JDK thread state counts (runnable, blocked, etc) or it might show the state of the Resin thread pool.

Example: Summary Report
<resin xmlns="http://caucho.com/ns/resin"
          xmlns:resin="urn:java:com.caucho.resin">
<cluster-default>
  
  <health:MeterGraphPage>
    <name>Summary</name>
    <period>6h</period>
    <columns>3</columns>
      
    <graph name="Request Count">
      <meter>Resin|Http|Request Count</meter>
    </graph>
      
    <graph name="Threads">
      <meter>JVM|Thread|JVM Thread Count</meter>
      <meter>Resin|Thread|Thread Count</meter>
      <meter>Resin|Thread|Thread Idle Count</meter>
      <meter>JVM|Thread|JVM Runnable Count</meter>
      <meter>JVM|Thread|JVM Blocked Count</meter>
      <meter>JVM|Thread|JVM Native Count</meter>
      <meter>JVM|Thread|JVM Waiting Count</meter>
    </graph>
    
</cluster-default>
</resin>

Security: Authenticators and Contraints

See security configuration for more details on configuring security.

Security can be configured using CanDI-style resources or with the standard servlet <security-constraints.

  • authenticator: checks credentials (password) for users.
  • login: gets credentials from HTTP/servlet and passes to the authenticator.
  • constraints: allows or disallows access to resources.

The following example uses form-based login to protect a /admin.jsp page. Only users with the "admin" role are allowed access. The <resin:XmlAuthenticator> configures a file-based authenticator. The <resin:FormLogin> configures form-based login. And <resin:Allow> restricts access to the page.

Example: form-based authentication
<web-app xmlns:resin="urn:java:com.caucho.resin">
  
  <resin:XmlAuthenticator>
    <user name="admin"
             password="{SSHA}h5QdSulQyqIgYo7BIJ3YfnRSY56kD847"
             role="user,admin"/>
  </resin:XmlAuthenticator>

  <resin:FormLogin>
     <login-page>/login.jsp</login-page>
     <error-page>/form_error.jsp</error-page>
  </resin:FormLogin>

  <resin:Allow url-pattern="/admin.jsp">
     <resin:IfUserInRole role="admin"/>
  </resin:Allow>
  
</web-app>

Copyright © 1998-2012 Caucho Technology, Inc. All rights reserved. Resin ® is a registered trademark. Quercustm, and Hessiantm are trademarks of Caucho Technology.