<document>
<header>
<title>User Guide: Administration</title>

<description>

<p>Overview and introduction to Resin from an administration perspective.
</p>

</description>
</header>

<body>

<localtoc/>

<s1 title="Terminology">

<ul>
<li><b>cluster</b> - A set of <em>servers</em> configured to serve
identical content.  Even a solo server will belong to its own
cluster.</li>
<li><b>default host</b> - A virtual host configured to handle any
requests not maching a specified host.</li>
<li><b>host</b> - An internet domain like www.slytherin.com whose content
is handled by a cluster.  Also called virtual host.</li>
<li><b>keepalive</b> - A HTTP connection kept open after a request finishes
so the next request to the server will be more efficient.</li>
<li><b>load-balancer</b> - A Resin <em>server</em> which forwards requests
to an application cluster for increased scalability and reliability.</li>
<li><b>machine</b> - A physical computer.  Multiple <em>servers</em> can run on the same machine.</li>
<li><b>port</b> - A server's internet connection handling a specific protocol,
e.g. a HTTP port 80 or HTTPS port 443 or XMPP (Jabber) port 5222.</li>
<li><b>proxy cache</b> - A content cache in front of a web application,
storing the content and returning it quickly without running the application.
Speedups for some applications can be 10x or 100x.</li>
<li><b>server</b> - A Resin instance running on a single JVM.  One or
more servers can run on the same <em>machine</em>.</li>
<li><b>servlet</b> - A Java program responsible for serving web content.  All
content is handled by a servlet, including static files,
JSPs and PHP content.</li>
<li><b>thread</b> - An active execution of a Java program.  Because Java
is multithreaded, multiple Java programs are running simultaneously.
For example, each HTTP user/request is handled by its own Java thread.</li>
<li><b>watchdog</b> - A Resin Java process responsible for starting and
restarting Resin <em>servers</em> for reliability.</li>
<li><b>webapp</b> - A web application is a content collection, like a
Drupal or Mediawiki site.  All content belongs to a webapp.</li>
</ul>

<figure src="cluster-load-balance.png"/>

<p>In the previous figure:</p>
<ul>
<li>The <em>servers</em> are "web-a", "app-a" and "app-b".</li>
<li>The <em>clusters</em> are "web-tier" and "app-tier".</li>
<li>The <em>virtual hosts</em> are "foo.com" and "bar.com".</li>
<li>The <em>webapps</em> are "/", "/wiki" and "/drupal".</li>
<li>Both <em>servers</em> "app-a" and "app-b" in the <em>cluster</em>
"app-tier" serve identical content, i.e. the same <em>virtual
hosts</em> and <em>webapps</em>.</li>
<li>web-a has a <em>proxy-cache</em> and <em>load balancer</em>.</li>
<li>web-a listens to HTTP <em>port</em> 80.</li>
<li>app-a and app-b listen to cluster <em>port</em> 6800 and 6801.</li>
<li>All three <em>servers</em> could be on the same <em>machine</em> or
on separate <em>machines</em>.</li>
</ul>

</s1>

<s1 title="Dispatching Content">

<p>All HTTP content in Resin is ultimately handled by a servlet.  If
Resin can't find a servlet for a URL, it will return
a <code>404 Not Found</code> to the browser.  So, if you see an
unexpected <code>404 Not Found</code>, you not only need to check that
the file exists, but make sure that the servlet and its URL mapping is
properly configured.  If you turn on logging to "finer", you can
trace the request to figure out why the servlet is not getting
called.</p>

<p>To match up the URL to its final servlet and the content, you need
all of the following properly configured:</p>

<ol>
<li><b>Server</b>.  The Resin server must be active to do anything.
Because servers belong to a cluster, you'll automatically have a
cluster even if it only has a single server.</li>
<li><b>HTTP port</b>.  The server must be listening to the internet
for HTTP requests just to get started.  If the HTTP port is missing or
misconfigured, you will get connection failure messages because the
browser cannot connect to your server at all.</li>
<li><b>Host</b>.  Resin must first match the
<a href="host-tags.xtp">&lt;host></a> specified by the
HTTP request, e.g. www.slytherin.com.  If no hosts match, Resin will
use the default host.  If no default host exists, Resin will
return a <code>404 Not Found</code> to the browser.</li>
<li><b>WebApp</b>.  Inside the host, Resin finds a
web-application to handle the request by looking for the
<a href="webapp-tags.xtp#webapp">&lt;web-app></a> with the longest URL
prefix. So, <code>http://www.slytherin.com/drupal/index.php</code>
might match the <code>/drupal/</code>.  The ROOT web-app matches all
URLs.  If Resin can't find a web-app, it will return
<code>404 Not Found</code> to the browser.</li>
<li><b>servlet-mapping</b>.  Inside the web-app, Resin searches for a
<a href="webapp-tags.xtp#servlet-mapping">&lt;servlet-mapping></a> matching
the URL.  For example, <code>test.php</code> would match the
<code>QuercusServlet</code> and <code>test.jsp</code> would match
the JSP servlet.   If none match, Resin will try the default mapping,
which is normally the <code>FileServlet</code> to handle static pages.
If the default servlet isn't configured, Resin will return a <code>404
Not Found</code> to the browser.</li>
<li><b>Servlet</b>.  Finally, the selected servlet processes the
request and returns the content.  The servlet itself might not find
the requested content, e.g. if <code>/foo.php</code> does not exist in
the expected location.  The servlet itself is responsible for error
handling, but most servlets will return a <code>404 Not Found</code>
if any expected files are missing.</li>
</ol>

<p>Based on Resin's dispatching flow, here's a minimal
resin.xml to serve some content out of <code>/var/www/htdocs</code>.
Resin's philosophy of configuration files is that 1) for maintainability,
all configuration should be traceable to the resin.xml, i.e. no magic
defaults or hidden state are allowed and 2) for security, if something
is not configured, it doesn't exist.  In Resin, you need to enable
things explicitly, not disable hidden defaults.  The slight extra
verbosity is outweighed by the improved security and
maintainability.</p>

<p>The following resin.xml specifies an Apache-style structure where
all content is served from the <code>/var/www/htdocs</code> directory,
and is useful when upgrading from an old PHP site to use Quercus
for security and performance.  When organizing a site from scratch,
you'll typically use a more structured dynamic
hosting directory structure.</p>

<example title="Example: minimal /etc/resin/resin.xml for HTTP">
&lt;resin xmlns="http://caucho.com/ns/resin"
       xmlns:resin="http://caucho.com/ns/resin/core">
	
  &lt;cluster id="app-tier">
    &lt;development-mode-error-page/>

    &lt;server id="" address="127.0.0.1" port="6800">
      &lt;http port="8080"/>
    &lt;/server>

    &lt;resin:import path="/etc/resin/app-default.xml"/>

    &lt;host id="">
      &lt;web-app id="">
        &lt;root-directory>/var/www/htdocs&lt;/root-directory>
      &lt;/web-app>
    &lt;/host>
  &lt;/cluster>

&lt;/resin>
</example>

<ul>
<li><a href="resin-tags.xtp#resin">&lt;resin></a> starts a Resin
configuration file and declares the validation namespaces.
</li>
<li><a href="cluster-tags.xtp#cluster">&lt;cluster></a> encloses the
single-server cluster containing our content.</li>
<li><a
href="cluster-tags.xtp#development-mode-error-page">&lt;development-mode-error-page></a>
reports configuration and runtime errors to the browser, which is
very helpful during development.  On a production server, you may
want to remove this tag so errors don't expose information to the
internet.</li>
<li><a href="server-tags.xtp#server">&lt;server></a> configures the
Resin server, including its ports.  The <var>id</var> matches the
command-line <var>-server</var> argument at startup.  The
<var>address</var> and <var>port</var> open Resin's cluster port,
which is used for deployment, management, clustering, and
distributed caching.</li>
<li><a href="server-tags.xtp#http">&lt;http></a> listens for HTTP
requests.  Production servers will change the port to 80.</li>
<li><a href="env-tags.xtp#import">&lt;resin:import></a> defines the
standard servlet like JSP, PHP and the static file servlet.  If you
omit this &lt;resin:import>, Resin will return <code>404 Not
Found</code> because the <a
href="webapp-tags.xtp#servlet-mapping">&lt;servlet-mapping></a> and
servlets would not be defined.</li>
<li><a href="host-tags.xtp#host">&lt;host></a> defines a default
virtual host.  The default host will handle any host domain given by
a HTTP request.</li>
<li><a href="webapp-tags.xtp#web-app">&lt;web-app></a> defines a ROOT
web-app, serving all URLs for the host.  The servlets in the web-app
are defined by the <code>app-default.xml</code> specified by the &lt;resin:import>.</li>
<li><a href="webapp-tags.xtp#root-directory">&lt;root-directory></a>
specifies the content directory, here matching a standard Apache
directory.
</li>
</ul>

<s2 title="rewrite-dispatch replaces mod_rewrite">

<p>For many applications like Drupal and Mediawiki, it's important to
rewrite a user-friendly URL to an internal servlet or PHP URL.
Resin's <a href="rewrite-tags.xtp">&lt;rewrite-dispatch></a> replaces
the capabilities of mod_rewrite for Apache.</p>

<example title="Example: WEB-INF/resin-web.xml Drupal rewriting ">
&lt;web-app xmlns="http://caucho.com/ns/resin">

  &lt;rewrite-dispatch>
    &lt;dispatch regexp="\.(php|gif|css|jpg|png|ico|js|htm|html)"/>
    &lt;forward regexp="^/" target="/index.php?q="/>
  &lt;/rewrite-dispatch>

&lt;/web-app>
</example>

<ul>
<li><a href="webapp-tags.xtp#web-app">&lt;web-app></a> configures the
<code>/drupal</code> web-application.</li>
<li><a
href="rewrite-tags.xtp#rewrite-dispatch">&lt;rewrite-dispatch></a>
starts the URL rewriting configuration.</li>
<li><a
href="rewrite-tags.xtp#dispatch">&lt;dispatch></a>
passes the URL untouched for content handling, e.g. static files or php.</li>
<li><a
href="rewrite-tags.xtp#forward">&lt;forward></a>
rewrites the URL and forwards.</li>
</ul>

</s2>

</s1>

<s1 title="Resin Processes">

<ul>
<li><b>command-line</b> - the command-line process
(<code>ResinBoot</code>) only exists long
enough to send a message to the <em>watchdog</em> or the Resin
process, like a "start", "deploy", or "stop".  If necessary, the
command-line process will start the watchdog.</li>

<li><b>watchdog</b> - the <a href="resin-watchdog.xtp">watchdog
process</a> manages and monitors <em>Resin server</em> processes.
If the Resin server exits, the watchdog will automatically restart
Resin, providing extra reliability in case of server failure.</li>

<li><b>Resin server</b> - the Resin server handles the HTTP requests
and serves the content.</li>

</ul>

<figure src="startup-watchdog.png"/>

<p>Because the Resin server is started as a child of the watchdog
process, its own JVM arguments come from the resin.xml,
not from the command-line of <code>ResinBoot</code>.  The JVM
configuration arguments are supplied as <a
href="server-tags#jvm-arg">&lt;jvm-arg></a> in the &lt;server>
configuration.</p>

</s1>

<s1 title="Files and Directories">

<p>Resin's configuration allows for great flexibility in choosing a
directory structure for your site, or adapting Resin to your existing
site configuration if you're upgrading from Apache/PHP for a Drupal or
MediaWiki site.  There are three main directory styles:</p>

<ul>
<li><b>Resin dynamic virtual host</b> - the most general solution,
letting you easily add virtual hosts without modifying the
configuration files.</li>
<li><b>Apache upgrade</b> - all content is placed in
a <code>/var/www/htdocs</code> directory.</li>
<li><b>Servlet war style</b> - all content is deployed with .war files
in a webapps directory.  The .war file is automatically expanded and
deployed from the webapps.</li>
</ul>

<s2 title="Dynamic Virtual Host">

<p>In the dynamic virtual host configuration, your content is placed
in <code>/var/www/hosts/foo.com/webapps/ROOT</code>.
<code>/var/www</code> is the standard location for HTTP documents.
<code>hosts/foo.com</code> contains your virtual host root directory.
<code>webapps/ROOT</code> contains the root web-app for the virtual
host.</p>

<p>Adding a new virtual host is easy just by adding a new
<code>hosts/bar.com</code> directory.  The special directory
<code>hosts/default</code> creates a default virtual host, which will
serve pages for anything not matching a specific host.  If you
need to configure the host, or add <a
href="host-tags.xtp#host-alias">&lt;host-alias></a> tags, you can add
them to a <code>hosts/bar.com/host.xml</code> file.</p>

<p>Deploying a web-application is also straightforward by adding
a .war file to <code>webapps/foo.war</code> or
<code>webapps/ROOT.war</code>.  <code>webapps/ROOT</code> is a special
web-app which handles the root URL, "/".</p>

<p>In a standard Unix deployment, your configuration files go in
<code>/etc/resin</code> and typically includes the
<code>resin.xml</code> and the <code>app-default.xml</code>.
<code>app-default.xml</code> contains standard configuration like the
static file servlet, JSP, PHP servlets, as well as the standard
mime-type mappings.</p>

<p>The Resin jars, JNI libraries and licenses go in
<code>/usr/lib/resin</code>, typically owned
by root.  The <code>resin</code> directory itself will normally be a
symbolic link to the Resin version, so you can upgrade easily.</p>

<example title="Example: Unix dynamic virtual host">
/etc/resin/
  resin.xml                 - main Resin configuration file
  app-default.xml           - default servlet configuration
  admin-users.xml           - /resin-admin users

/etc/init.d/resin           - startup script

/usr/lib/resin/             - ${resin.home}
   lib/*.jar                - Resin's Java classes
   libexec/*.so             - native JNI libraries
   libexec64/*.so           - JNI for 64-bit systems
   licenses/*               - Resin Pro licenses
   win32/*.dll              - Win32 JNI
   win64/*.dll              - Win64 JNI
   
/var/www/                   - ${resin.root}
   admin/                   - Resin database and cache storage
   doc/admin/               - /resin-admin source
   ivy2/                    - ivy2 jar repository
   lib/                     - Shared application jars
   log/                     - watchdog and Resin debug logging
   hosts/foo.com/           - dynamic host contents
     log/                   - access logging per virtual host
     host.xml               - optional host-specific configuration
     webapps/ROOT/          - web-app content
       index.php            - web-app content
       WEB-INF/             - web-app classes and configuration
         web.xml            - servlet-standard configuration
	 resin-web.xml      - Resin-specific configuration
	 lib/*.jar          - application jars
	 classes/**/*.class - application classes
	 work/              - work directory for JSP, PHP, etc.
</example>

<example title="Example: /etc/resin/resin.xml">
&lt;resin xmlns="http://caucho.com/ns/resin"
       xmlns:resin="http://caucho.com/ns/resin/core">
  &lt;root-directory>/var/www&lt;/root-directory>
  
  &lt;cluster id="">
    &lt;server id="" address="127.0.0.1" port="6800">
      &lt;http port="8080"/>
    &lt;/server>

    &lt;resin:import path="/etc/resin/app-default.xml"/>

    &lt;host-default>
      &lt;resin:import path="host.xml" optional="true"/>
    
      &lt;web-app-deploy path="webapps"/>
    &lt;/host-default>

    &lt;host-deploy path="hosts"/>
  &lt;/cluster>
&lt;/resin>
</example>

</s2>

<s2 title="Apache Upgrade">

<p>In an Apache upgrade, you have an existing site that you're
upgrading to use Quercus or just evaluating the performance
improvement for an existing side.  The content is placed
in <code>/var/www/htdocs</code> directory, and there's only a single
virtual host and single root web-app.</p>

<p>For Apache-style sites with multiple virtual hosts, you can add new
<a href="host-tags.xtp#host">&lt;host></a> tags for each host, and add
a <a href="host-tags.xtp#root-directory">&lt;root-directory></a> to
set the host's root.</p>

<example title="Example: Unix Apache upgrade">
/etc/resin/
  resin.xml                 - main Resin configuration file
  app-default.xml           - default servlet configuration

/etc/init.d/resin           - startup script

/usr/local/share/resin/     - ${resin.home}
   lib/*.jar                - Resin's Java classes
   ...
   
/var/www/                   - ${resin.root}
   admin/                   - Resin database and cache storage
   log/                     - watchdog and Resin debug logging
   logs/                    - HTTP access logging
   htdocs/
     index.php              - web-app content
     WEB-INF/               - web-app classes and configuration
       resin-web.xml        - Resin-specific configuration
       lib/*.jar            - application jars
       classes/**/*.class   - application classes
       work/                - work directory for JSP, PHP, etc.
</example>

<example title="Example: /etc/resin/resin.xml">
&lt;resin xmlns="http://caucho.com/ns/resin"
       xmlns:resin="http://caucho.com/ns/resin/core">
  &lt;root-directory>/var/www&lt;/root-directory>
  
  &lt;cluster id="">
    &lt;server id="" address="127.0.0.1" port="6800">
      &lt;http port="8080"/>
    &lt;/server>

    &lt;resin:import path="/etc/resin/app-default.xml"/>

    &lt;host id="">
    
      &lt;web-app id="" root-directory="htdocs"/>
      
    &lt;/host>
  &lt;/cluster>
&lt;/resin>
</example>

</s2>

<s2 title="Java App-Server directory structure">

<p>A common Java app-server deployment structure looks like a
mixture of the full dynamic host configuration and the Apache-style
static configuration.  The virtual hosts are configured statically
like Apache, but webapps are created dynamically by dropping .war
files in a <code>webapps</code> directory.</p>

<example title="Example: Java app-server structure">
/etc/resin/
  resin.xml                 - main Resin configuration file
  app-default.xml           - default servlet configuration

/etc/init.d/resin           - startup script

/usr/local/share/resin/     - ${resin.home}
   lib/*.jar                - Resin's Java classes
   ...
   
/var/www/                   - ${resin.root}
   admin/                   - Resin database and cache storage
   log/                     - watchdog and Resin debug logging
   logs/                    - HTTP access logging
   webapps/
     ROOT/                  - web-app for "/"
       index.php            - web-app content
       WEB-INF/             - web-app classes and configuration
         resin-web.xml      - Resin-specific configuration
         lib/*.jar          - application jars
         classes/**/*.class - application classes
         work/              - work directory for JSP, PHP, etc.
     wiki/                  - web-app for "/wiki"
       ...
     drupal/                - web-app for "/wiki"
       index.php
</example>

<example title="Example: /etc/resin/resin.xml">
&lt;resin xmlns="http://caucho.com/ns/resin"
       xmlns:resin="http://caucho.com/ns/resin/core">
  &lt;root-directory>/var/www&lt;/root-directory>
  
  &lt;cluster id="">
    &lt;server id="" address="127.0.0.1" port="6800">
      &lt;http port="8080"/>
    &lt;/server>

    &lt;resin:import path="/etc/resin/app-default.xml"/>

    &lt;host id="">
    
      &lt;web-app-deploy path="webapps"/>
      
    &lt;/host>
  &lt;/cluster>
&lt;/resin>
</example>

</s2>
</s1>

<s1 title="Threads, Memory and Sockets">

<p>A Resin server needs to have enough memory, threads, and sockets to
handle the user load.  For the most part, the defaults provide a good
starting point, but it's a good idea to become familiar with the
primary resources.</p>

<ul>
<li><b>memory</b> - divided into heap, thread stack, PermGen space,
and some specialized JVM/JNI space.  With a 32-bit machine, you are
likely to run into virtual memory limits.  Even with a 64-bit machine,
you need enough swap to handle your virtual memory size.</li>
<li><b>sockets</b> - a TCP connection to the browser.  Each user uses
one or sockets as long as the browser is connected.  Sockets use up
<b>file descriptors</b> on Unix, which are also used by database
connections, and open files.  The <em>netstat</em> command is
important for threading.</li>
<li><b>threads</b> - an program execution, taking up CPU and virtual
memory (for the thread stack).  Active requests use CPU, while even
blocked threads take up memory.</li>
</ul>

<s2 title="Memory">

<p>Memory is the most important configuration item for the machine.
You need enough virtual memory to handle heap, stack, and permanent
memory, and enough physical memory to avoid swapping.  If the JVM
runs out of memory, it may throw <code>OutOfMemoryError</code> and
force a restart of the server.</p>

<ul>
<li><b>heap</b> - Java memory used for all application objects.  Heap
memory is garbage collected periodically, causing the JVM to stop or
slow while finding unused memory.  The maximum heap is set by the
<code>-Xmx512m</code> command-line argument in <a
href="server-tags.xtp#jvm-arg">&lt;jvm-arg></a>.</li>

<li><b>PermGen (permanent generation)</b> is JVM memory for permanent
data like Java class code, JNI code, shared libraries, mmapped memory
(jars), and the JVM itself.  Configured by
<code>-XX:PermGen=128M</code>.  The JVM default usually needs
to be increased.</li>

<li><b>thread stack</b> - Each thread takes up virtual memory for its
execution stack.  Since the default is 1M and having 1000 threads is
fairly common, you can use 1G of virtual memory just for the thread
stack.  The thread stack is configured by <code>-Xss1m</code></li>

<li><b>virtual memory</b> is total memory allocated to the JVM by the
operating system.  VM = heap + stack + PermGen.  For a 32-bit system,
you might have as little as 2G
for all the heap, stack, and PermGen.  You also need to have
enough <b>swap</b> memory to handle your virtual memory, especially if
you have a large heap, lots of threads, or even lots of large
jars.</li>

</ul>

</s2>

</s1>

<s1 title="Notifications">

<p>Resin can notify you by email when it detects something wrong with the
server.  The main mechanism is adding a new logging handler sending mail
for warning and severe messages.  When a log entry is added at the WARNING
or SEVERE level, Resin will send a mail containing the log information.  You
can then look at the administration console to debug any problems.</p>

<p>The configuration is described in the <a href="config-log.xtp#mail">logging configuration</a> section.</p>

<example title="Example: resin.xml with mail logging">
&lt;resin xmlns="http://caucho.com/ns/resin">

  &lt;log-handler name="" level="warning" uri="mail:">
    &lt;init>
      &lt;to>admin@foo.com&lt;/to>
      &lt;properties>
        mail.smtp.host=127.0.0.1
        mail.smtp.port=25
      &lt;/properties>
    &lt;/init>
  &lt;/log-handler>
  
&lt;/resin>
</example>

</s1>

  </body>
</document>
