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
 

server: server tag configuration


The <server> tag configures a JVM instance in a cluster. It configures HTTP and cluster sockets, keepalives and timeouts, thread pooling, load balancing, and JVM arguments.

<accept-listen-backlog>

default 4000

<accept-listen-backlog> configures operating system TCP listen queue size for the port.

When a browser connects to a server, the server's operating system handles the TCP initialization before handing the socket to the server's application. The operating system will hold the opened connections in a small queue, until the application is ready to receive them. When the queue fills up, the operating system will start refusing new connections.

<accept-thread-max>

default 10

<accept-thread-max> configures the maximum number of threads listening for new connections on this port. <accept-thread-max> works with <accept-thread-min> to handle spiky loads without creating and destroying too many threads.

Socket connections are associated with a thread which handles the request. In Resin, a number of threads wait to accept a new connection and then handle the request. <accept-thread-max> specifies the maximum number of threads which are waiting for a new connection.

Larger values handle spiky loads better but require more threads to wait for the connections. Smaller values use less threads, but may be slower handling spikes.

<accept-thread-min>

<accept-thread-min> configures the minimum number of threads listening for new connections on this port <accept-thread-min> works with <accept-thread-max> to handle spiky loads without creating and destroying too many threads.

Socket connections are associated with a thread which handles the request. In Resin, a number of threads wait to accept a new connection and then handle the request. <accept-thread-min> specifies the minimum number of threads which are waiting for a new connection. If many connections appear rapidly with a small value of <accept-thread-min>, the application may pause until a new thread is available for the new connection.

Larger values handle spiky loads better but require more threads to wait for the connections. Smaller values use less threads, but may be slower handling spikes.

<address>

child of server
default 127.0.0.1

The server <address> defines the IP interface for Resin cluster communication and load balancing. It will be an internal IP address like 192.168.* for a clustered configuration or 127.* for a single-server configuration. No wild cards are allowed because the other cluster servers and load balancer use the address to connect to the server.

server address
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="web-tier">
    <server-default>
      <http port="80"/>
    </server-default>

    <server id="web-a" address="192.168.1.1" port="6800"/>
    <server id="web-b" address="192.168.1.2" port="6800"/>

    ...
  </cluster>

  <cluster id="app-tier">
    <server id="app-a" address="192.168.2.11" port="6800"/>
    <server id="app-b" address="192.168.2.12" port="6800"/>

    ...
  </cluster>
</resin>

<group-name>

child of server

<group-name> configures the operating system group Resin should run as. Since the HTTP port 80 is protected in Unix, the web server needs to start as root to bind to port 80. For security, Resin should switch to a non-root user after binding to port 80.

resin.xml with user-name
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="app-tier">

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

      <user-name>resin</user-name>
      <group-name>www</group-name>
    </server-default>

    <server id="web-a"/>
    ...
  </cluster>
</resin>

<http>

child of server

<http> configures a HTTP or HTTPS port listening for HTTP requests.

When configuring multiple JVMs, each <http> will have a unique <server-id> which allows the -server command-line to select which ports the server should listen to.

note
Note
The virtual-host attribute overrides the browser's Host directive, specifying the explicit host and port for request.getServerName() and getServerPort(). It is not used in most virtual host configurations. Only IP-based virtual hosts which wish to ignore the browser's Host will use @virtual-host.
<http> Attributes
ATTRIBUTEDESCRIPTIONDEFAULT
address/hostIP address of the interface to listen to*
portport to listen torequired
accept-listen-backlogconfigures operating system TCP listen queue size for the port4000
accept-thread-idle-timeoutconfigures minimum spare accept-thread idle timeout120s
accept-thread-minconfigures the minimum number of threads listening for new connections 1
accept-thread-maxconfigures the maximum number of threads listening for new connectionsunbound
keepalive-connection-time-maxconfigures an absolute max time for keepalive connections600s
keepalive-maxconfigures the maximum number of sockets which can be used directly for keepalive connections256
keepalive-select-enableenables the select manager for keepalivestrue
keepalive-select-thread-timeoutconfigures a short timeout allowing the select manager to wait for a keepalive before detaching the thread1s
keepalive-timeoutconfigures how long a keepalive connection should wait for a new request before closing120s
suspend-reaper-timeoutconfigures check interval for suspended (async)connections60s
suspend-time-maxconfigures timeout for suspended (async) connections600s
socket-timeoutconfigures timeout for accepted socket's write and read operations120s
throttle-concurrent-maxconfigures maximum concurrent requests (Resin Pro)unlimited
tcp-no-delaysets the NO_DELAY socket parametertrue
socket-listen-backlogThe socket factory's listen backlog for receiving sockets100
virtual-hostforces all requests to this <http> to use the named virtual hostnone
opensslconfigures the port to use OpenSSLnone
jsse-sslconfigures the port to use JSSE for SSLnone
<http> schema
element http {
  (id | server-id)
  & (address | host )?
  & port?
  & accept-listen-backlog?
  & accept-thread-idle-timeout?
  & accept-thread-min?
  & accept-thread-max?
  & connection-max?
  & keepalive-connection-time-max?
  & keepalive-max?
  & keepalive-select-enable?
  & keepalive-select-thread-timeout?
  & keepalive-timeout?
  & secure?
  & socket-timeout?
  & suspend-reaper-timeout?
  & suspend-time-max?
  & tcp-no-delay?
  & throttle-concurrent-max?
  & virtual-host?
  & (openssl | jsse-ssl)?
}

<jvm-arg>

child of server

<jvm-arg> configures JVM arguments to be passed to Resin on the command line, typically -X memory parameters and -D defines.

standard jvm-args
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="web-tier">
    <server-default>
      <jvm-arg>-Xmx512m</jvm-arg>
      <jvm-arg>-Xss1m</jvm-arg>
      <jvm-arg>-verbosegc</jvm-arg>
    </server-default>

    <server id="app-a" address="192.168.2.10"/>

    ...
  </cluster>
</resin>

<jvm-classpath>

child of server

<jvm-classpath> adds a classpath entry when starting the JVM.

adding a classpath
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="web-tier">
    <server-default>
      <jvm-classpath>/tmp/test-classpath;/jvm-classpath>
    </server-default>

    <server id="app-a" address="192.168.2.10"/>

    ...
  </cluster>
</resin>

<keepalive-max>

child of server
default 100

<keepalive-max> configures the maximum number of sockets which can be used directly for keepalive connections. In Resin Professional, the select manager allows for a much larger number of keepalive sockets, since it can detach threads from connections. Without the select manager, each connection is associated with a thread.

A value of -1 disables keepalives.

Keepalives are an important TCP technique used with HTTP and Resin's load-balancing to avoid the heavy network cost of creating a new socket. Since an initial HTTP request is usually immediately followed by extra requests to load files like images and stylesheets, it's generally more efficient to keep the socket open for a short time instead of creating a new one. The socket keepalive is even more important for Resin's load balancing, to avoid creating extra sockets between the web-tier and the app-tier and to make distributed sessions more efficient.

Higher values of <keepalive-max> improve network efficiency but increase the number of threads waiting for new client data.

keepalive-thread-max in resin.xml
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="web-tier">
    <server-default>
      <http port="80"/>

      <thread-max>512</thread-max>

      <keepalive-max>100</keepalive-max>
    </server-default>

    <server id="web-a" address="192.168.0.10"/>
        ...
  </cluster>
</resin>

<keepalive-select-enable>

child of server
default true

<keepalive-select-enable> enables the select manager for keepalives. The select manager is a Resin Professional feature allowing more keepalives by detaching threads from sockets.

Normally, this should be left enabled.

<keepalive-select-thread-timeout>

child of server
default 1s

<keepalive-select-thread-timeout> is a short timeout allowing the select manager to wait for a keepalive before detaching the thread. This value would not normally be changed.

<keepalive-timeout>

child of server
default 15s

<keepalive-timeout> configures how long a keepalive connection should wait for a new request before closing.

Keepalives are used both for HTTP connections and for load-balancing and clustering connections. HTTP connections generally have a single HTML page, followed by a number of image requests. By using keepalives, all the requests can use a single socket. The <keepalive-timeout> should be long enough to catch all the HTTP burst requests, but can close after the burst is complete. A value of 5s or 15s is generally sufficient.

The load-balancing and clustering keepalives have a different timeout behavior. Since load-balancing sockets are reused for multiple clients, they can have longer timeouts.

keepalive-thread-max in resin.xml
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="web-tier">
    <server-default>
      <http port="80"/>

      <thread-max>512</thread-max>

      <keepalive-max>100</keepalive-max>
      <keepalive-timeout>15s</keepalive-timeout>
    </server-default>

    <server id="web-a" address="192.168.0.10"/>
        ...
  </cluster>
</resin>

<load-balance-connect-timeout>

child of server
default 5s

<load-balance-connect-timeout> configures the maximum time a client connection to a cluster-port should take. The load balance and persistent sessions use load-balance-connect-timeout to connect to backend or peer servers in the cluster.

Lower values detect failed servers more quickly, but a too-low value can timeout too quickly for a live server with some network congestion.

load-balance-connect-timeout
<resin xmlns="http://caucho.com/ns/resin">
    <cluster id="app-tier">
        <server-default>
          <load-balance-connect-timeout>2s</load-balance-connect-timeout>
        </server-default>

        <server id="a" address="192.168.0.10" port="6800"/>
        <server id="b" address="192.168.0.11" port="6800"/>

        <host id="">
          ...
    </cluster>
</resin>

<load-balance-recover-time>

child of server
default 15s

<load-balance-recover-time> is the maximum time the load balancer will consider the server dead after a failure before retrying the connection.

Resin uses the load-balance-recover-time to avoid wasting time trying to connect to an unavailable app-tier server.

Lower values let the load balancer use a restarted app-tier server faster, but lower values also increase the overhead of trying to contact unavailable servers.

load-balance-recover-time
<resin xmlns="http://caucho.com/ns/resin">
    <cluster id="app-tier">
        <server-default>
          <load-balance-recover-time>10s</load-balance-recover-time>
        </server-default>

        <server id="a" address="192.168.0.10" port="6800"/>
        <server id="b" address="192.168.0.11" port="6800"/>

        <host id="">
          ...
    </cluster>
</resin>

<load-balance-idle-time>

child of server
default keepalive-timeout - 1s

<load-balance-idle-time> is the maximum time the load balancer and distributed sessions will leave an idle socket before closing it.

The default value is normally sufficient, since it tracks the keepalive of the cluster port.

load-balance-idle-time must be less than the keepalive value of the target cluster-port.

The load balancer and distributed sessions reuse sockets to the cluster peer and app-tier servers to improve TCP performance. The load-balance-idle-time limits the amount of time those sockets can remain idle.

Higher values may improve the socket pooling, but may also increase the chance of connecting to a closed server.

<load-balance-warmup-time>

child of server
default 60s

The time the load balancer uses to throttle connections to an app-tier server that's just starting up.

Java web-applications often start slowly while they initialize caches. So a newly-started application will often be slower and consume more resources than a long-running application. The warmup-time increases Resin's reliability by limiting the number of requests to a new app-tier server until the server has warmed up.

Larger values give the application a longer time to warm up.

load-balance-warmup-time
<resin xmlns="http://caucho.com/ns/resin">
    <cluster id="app-tier">
        <server-default>
          <load-balance-warmup-time>60s</load-balance-warmup-time>
        </server-default>

        <server id="a" address="192.168.0.10" port="6800"/>
        <server id="b" address="192.168.0.11" port="6800"/>

        <host id="">
          ...
    </cluster>
</resin>

<load-balance-weight>

child of server
default 100

load-balance-weight assigns a load-balance weight to a backend server. Servers with higher values get more requests. Servers with lower values get fewer requests.

In some cases, some app-tier servers may be more powerful than others. load-balance-weight lets the load-balancer assign more connections to the more powerful machines.

Test and profiling servers can also use load-balance-weight to receive a small number of connections for profiling purposes.

Larger values tell the load-balancer to assign more requests to the app-tier server.

load-balance-weight
<resin xmlns="http://caucho.com/ns/resin">
    <cluster id="app-tier">
        <server id="a" address="192.168.0.10" port="6800"/>
        <server id="b" address="192.168.0.10" port="6800"/>

        <server id="test" address="192.168.0.100" port="6800">
            <load-balance-weight>1</load-balance-weight>
        </server>

        <host id="">
          ...
    </cluster>
</resin>

<memory-free-min>

child of server
default 1m

<memory-free-min> improves server reliability by detecting low-memory situations caused by memory leaks and forcing a clean server restart. Since Resin's watchdog service reliably restarts the server, a website can improve stability by forcing a restart before memory becomes a major problem. The memory-free-min restart will also log a warning, notifying the developers that a potential memory leak needs to be resolved.

When free heap memory gets very low, the garbage collector can run continually trying to free up extra memory. This continual garbage collection can send the CPU time to 100%, cause the site to become completely unresponsive, and yet take a long time before finally failing to an out of memory error (forcing an unclean restart). To avoid this situation, Resin will detect the low-memory condition and gracefully restart the server when free memory becomes too low.

The ultimate solution to any memory leak issues is to get a memory profiler, find the leaking memory and fix it. <memory-free-min> is just a temporary bandage to keep the site running reliably until the memory leak can be found and fixed.

memory-free-min resin.xml
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="web-tier">
    <server-default>
      <thread-max>512</thread-max>

      <memory-free-min>1m</memory-free-min>
    </server-default>

    <server id="web-a" address="192.168.0.10"/>
        ...
  </cluster>
</resin>

<port>

child of server
default 6800

The server <port> defines the TCP port for Resin cluster communication and load balancing. Most server instances will use a common port like 6800, while machines with multiple servers may use multiple ports like 6800 and 6801.

multiple servers on a machine
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="app-tier">
    <server id="app-a" address="192.168.1.11" port="6800"/>
    <server id="app-b" address="192.168.1.11" port="6801"/>

    <server id="app-b" address="192.168.2.12" port="6800"/>
    <server id="app-c" address="192.168.2.12" port="6801"/>

    ...
  </cluster>
</resin>

<port-default>

child of server

Defines default port parameters for all <http>, <protocol>, and <cluster-port>.

<protocol>

<protocol> configures a remoting protocol for a Java bean. The bean is configured with the <servlet> and <servlet-mapping> tags, since it will process HTTP URL requests.

Protocol drivers extend the com.caucho.remote.server.AbstractProtocolServletFactory interface and can register a URI alias to simplify configuration.

<protocol> Attributes
ATTRIBUTEDESCRIPTION
classClassname of the protocol driver implementing ProtocolServletFactory
initOptional IoC initialization for the protocol driver
uriProtocol configuration shortcut
Current drivers
URI SCHEMEDESCRIPTION
burlap:The burlap XML protocol
cxf:The CXF SOAP implementation
hessian:The Hessian protocol
xfire:The XFire SOAP implementation
<protocol> schema
element protocol {
  (class | uri)
  & init?
}

<server>

child of cluster

<server> configures a JVM instance in the cluster. Each <server> is uniquely identified by its id attribute. The id will match the -server command line argument.

The server listens to an internal network address, e.g. 192.168.0.10:6800 for clustering, load balancing, and administration.

The current server is managed with a ServerMXBean. The ObjectName is resin:type=Server.

Peer servers are managed with ServerConnectorMXBean. The ObjectName is resin:type=ServerConnector,name=server-id.

<server> Attributes
ATTRIBUTEDESCRIPTIONDEFAULT
idunique server identifierrequired
addressIP address of the cluster port127.0.0.1
portThe cluster port6800
server
<resin xmlns="http://caucho.com/ns/resin">
    <cluster id="web-tier">
        <server id="a" address="192.168.0.10" port="6800">
          <http port="8080"/>
        </server>

        <server id="b" address="192.168.0.11" server-port="6800">
          <http port="8080"/>
        </server>

        <server id="c" address="192.168.0.12" server-port="6800">
          <http port="8080"/>
        </server>

        <host id="">
          ...
    </cluster>
</resin>

Main configuration for the server, configuring ports, threads and virtual hosts.

  • Common resources for all virtual hosts and web-apps.
  • Thread pooling
  • HTTP and Server/Cluster ports
  • Caching
  • virtual host configuration and common web-app-default

The <server> will generally contain a <class-loader> configuration which loads the resin/lib jars dynamically, allowing for system-wide jars to be dropped into resin/lib. <server> configures the main dynamic environment. Database pools common to all virtual hosts, for example, should be configured in the <server> block.

The <server> configures the <thread-pool> and a set of <http> and <server> ports which share the thread pool. Requests received on those ports will use worker threads from the thread pool.

<server> Attributes
ATTRIBUTEDESCRIPTIONDEFAULT
alternate-session-url-prefixa prefix to add the session to the beginning of the URL as a path prefix instead of the standard ;jsessionid= suffix. For clients like mobile devices with limited memory, this will allow careful web designers to minimize the page size.null
keepalive-maxthe maximum number of keepalive connections512
keepalive-timeoutthe maximum time a connection is maintained in the keepalive state15s
alternate-session-url-prefix
<server>
  ...
  <alternate-session-url-prefix>/~J=</alternate-session-url-prefix>
  ...

EL variables and functions

EL variables defined by <server>
VARIABLECORRESPONDING API
serverIdserver.getServerId()
root-dirserver.getRootDirectory()
server-rootserver.getRootDirectory()
EL functions defined by <server>
FUNCTIONCORRESPONDING API
jndiJndi.lookup(String)

<server-default>

child of cluster

<server-default> defines default values for all <server> instances. Since most <server> configuration is identical for all server instances, the shared configuration belongs in a <server-default>. For example, <http> ports, timeouts, JVM arguments, and keepalives are typically identical for all server instances and therefore belong in a server-default.

server
<resin xmlns="http://caucho.com/ns/resin">
    <cluster id="web-tier">
        <server-default>
           <thread-max>512</thread-max>

           <jvm-arg>-Xmx512m -Xss1m</jvm-arg>

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

        <server id="a" address="192.168.0.10" port="6800"/>
        <server id="b" address="192.168.0.11" port="6800"/>
        <server id="c" address="192.168.0.12" port="6800"/>

        <host id="">
          ...
    </cluster>
</resin>

<shutdown-wait-max>

child of server

<shutdown-wait-max> configures the maximum time the server will wait for the graceful shutdown before forcing an exit.

default 60s
<shutdown-wait-max> schema
element shutdown-wait-max {
  r_period-Type
}

<socket-timeout>

default 60s

<socket-timeout> is the maximum time a socket load balancer and distributed sessions will wait for a read or write to a cluster socket.

Crashed servers may never respond to a read request or accept a write. The socket-timeout lets Resin recover from these kinds of crashes.

Lower values can detect crashes more quickly, but too-low values may report bogus failures when the server machine is just a little slow.

socket-timeout
<resin xmlns="http://caucho.com/ns/resin">
    <cluster id="app-tier">
        <server-default>
          <socket-timeout>60s</socket-timeout>
        </server-default>

        <server id="a" address="192.168.0.10" port="6800"/>
        <server id="b" address="192.168.0.11" port="6800"/>

        <host id="">
          ...
    </cluster>
</resin>

<thread-idle-max>

child of server
default 10

<thread-idle-max> configures the maximum number of idle threads in the thread pool. <thread-idle-max> works with <thread-idle-min> to maintain a steady number of idle threads, avoiding the creation or destruction threads when possible.

<thread-idle-max> should be set high enough beyond <thread-idle-min> so a spiky load will avoid creating a thread and then immediately destroying it.

thread-idle-max in resin.xml
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="web-tier">
    <server-default>
      <thread-max>512</thread-max>

      <thread-idle-min>10</thread-idle-min>
      <thread-idle-max>20</thread-idle-max>

      <jvm-arg>-Xss1m -Xmx1024m</jvm-arg>
    </server-default>

    <server id="web-a" address="192.168.0.10"/>
        ...
  </cluster>
</resin>

<thread-idle-min>

child of server
default 5

<thread-idle-min> configures the minimum number of idle threads in the thread pool. <thread-idle-min> helps spiky loads, avoiding delays for thread requests by keeping threads ready for future requests. When the number of idle threads drops below <thread-idle-min>, Resin creates a new thread.

<thread-idle-min> should be set high enough to deal with load spikes. Since idle threads are relatively inexpensive in modern operating systems, having a number of idle threads is not a major resource hog, especially since these threads are idle, waiting for a new job.

<thread-idle-min> works together with <thread-idle-max> to avoid thread allocation thrashing, i.e. avoiding creating a new thread because of <thread-idle-min> and then quickly destroying it because of <thread-idle-max>.

thread-idle-min in resin.xml
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="web-tier">
    <server-default>
      <thread-max>512</thread-max>

      <thread-idle-min>10</thread-idle-min>
      <thread-idle-max>20</thread-idle-max>

      <jvm-arg>-Xss1m -Xmx1024m</jvm-arg>
    </server-default>

    <server id="web-a" address="192.168.0.10"/>
        ...
  </cluster>
</resin>

<thread-max>

child of server
default 4096

<thread-max> configures the maximum number of threads managed by Resin's thread pool. Resin's thread pool is used for connection threads, timers, and Resin worker threads for JMS, JCA and EJB. Since Resin's thread pool only manages Resin threads, the actual number of threads in the JVM will be higher.

Modern operating systems can handle a fairly large number of threads, so values of 512 or 1024 are often reasonable values for thread-max. The main limitation for thread-max is virtual memory. Since each thread takes up stack space (configured with -Xss), a 32-bit system might have a thread limit based on virtual memory.

For example, on Linux the user space is only 2G. If the heap memory is 1024m (-Xmx1024m) and the stack size is 1m (-Xss1m), the maximum number of threads is somewhat less than 1024.

In general, JVMs do not handle running out of threads very well, either freezing or throwing out of memory errors. Although it may be necessary to limit the number of threads to avoid running out of memory, <thread-max> should generally be set to a high value.

thread-max in resin.xml
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="web-tier">
    <server-default>
      <thread-max>512</thread-max>

      <jvm-arg>-Xss1m -Xmx1024m</jvm-arg>
    </server-default>

    <server id="web-a" address="192.168.0.10"/>
        ...
  </cluster>
</resin>

<user-name>

child of server

<user-name> configures the operating system user Resin should run as. Since the HTTP port 80 is protected in Unix, the web server needs to start as root to bind to port 80. For security, Resin should switch to a non-root user after binding to port 80.

resin.xml with user-name
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="app-tier">

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

      <user-name>resin</user-name>
    </server-default>

    <server id="web-a"/>
    ...
  </cluster>
</resin>

<watchdog-arg>

child of server

The <watchdog-arg> configures arguments for the watchdog process. The watchdog improves reliability by monitoring the Resin instance, restarting it if necessary.

The <watchdog-arg> typically is used to enable jconsole for the watchdog JVM.

resin.xml
<resin xmlns="http://caucho.com/ns/resin">
  <cluster id="app-tier">
    <server-default>

      <watchdog-arg>-Dcom.sun.management.jmxremote</watchdog-arg>

    </server-default>

    ...
       
  </cluster>
</resin>

<watchdog-port>

child of server
default 6700

<watchdog-port> configures the administration port for the watchdog JVM. The watchdog launches the server JVM and monitors its health, restarting the JVM when necessary to improve site reliability. The command line arguments use the watchdog-port for the "start" and "stop" commands to tell the watchdog to start and stop the server JVM. The administration also uses the watchdog port for watchdog administration.

The watchdog port will use the same <address> as the server, so it will always be an internal network address, never an external internet address.


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