Content-type: text/html Manpage of userver

userver

Section: User Commands (1)
Updated: 1 Aug 2003
Index Return to Main Contents
 

NAME

userver - Micro-server
(A fairly simple web server designed for experimentation)  

SYNOPSIS

userver

[-A|--accepts-only] [-A|--close-after-accept] [-B|--block-for-send_events] [-C|--caching-on] [-D|--debug-mask 0xN] [-E|--send-events] [-F|--reset-on-close] [-G|--use-getpid] [-H|-h|-?|--help] [-I|--rcv-sock-low-wat N] [-J|--snd-sock-low-wat N] [-K|--kdebug-mask 0xN] [-L|--full-read N] [-M|--multi-accept] [-N|--send-loop] [-O|--select-timeout N] [-P|--count-sigpipes] [-Q|--ecb-hi-water N] [-R|--read-sockbuf-size N] [-S|--dont-intr-select] [-T|--port N] [-U|--auto-accept] [-W|--write-sockbuf-size N] [-Y|--send-io-events] [-a|--async-mode] [-b|--ecb-buf-entries N] [-c|--max-conns N] [-d|--delay N] [-e|--extra-accepts N] [-f|--max-fds N] [-g|--accept-on-close] [-i|--interactive] [-j|--kernel-info] [-k|--sigio-use-procmask] [-l|--listenq N] [-m|--accept-count N] [-n|--no-accepts] [-n|--listen-only] [-o|--process-fd-order [up|down|writes-down|writes-up|lru|lifo|fifo]] [-p|--procs N] [-q|--ecb-low-water N] [-r|--eager-reads] [-s|--conns-in-server-loop] [-t|--free-fd-threshold N] [-u|--track-max-fd N] [-w|--eager-writes] [-x|--sigio-accepts] [-y|--memcpy] [-z|--rejection-rate] [--close-after-sock-init] [--close-after-read] [--close-after-parse] [--send-polls-for-accepts] [--cache-table-size N] [--cache-max-bytes N] [--cache-max-file-size N] [--cache-max-load-factor N] [--cache-table-print] [--cache-lock-pages] [--cache-for-spec] [--use-sendfile] [--use-accept-send] [--use-madvise] [--trace-summary] [--trace-summary-only] [--use-poll] [--use-epoll]

 

DESCRIPTION

userver is a micro web server that is meant to be used to experiment with the design and implementation of web servers. In particular the original intention was to permit experimental comparisons of different event dispatch mechanisms within the same appliication framework. For this reason there are lots and lots and lots of parameters. They are mainly used to control the behaviour of the server.

Some of the design philosophy and experimental results obtained using this server are described in [Brecht-2001]. One of note is that all data structures are allocated at initialization and are not resized (grown). This helps to ensure that experiments can be repeated because with dynamic sizing of data structures different loads could result in different server behaviour.

IMPORTANT: This micro web server is not meant to be a full-blown web server. It is specifically designed for conducting performance experiments. For that reason design decisions were made in favour of producing repeatable experiments.

 

EXAMPLES

userver
This starts the userver with it's all of its default options.

userver --max-conns 300 --accept-count 25
This command causes the userver server to limit the number of simultaneous connections to 300. When an event indicating that a new connection is requested accept is called continuously until either 25 new connections are accepted, or there are no more outstanding connections.

userver --max-conns 300 --accept-count 0
This command causes the userver server to limit the number of simultaneous connections to 300. When an event indicating that a new connection is requested accept is called repeatedly until there are no more outstanding connections. (Note that --accept-count=0 means an infinite number of connections, i.e., no limits).

userver --port 6800 --max-conns 300 --listenq 128
This command causes userver to listen for incoming connection requests on port 6800. It uses a listen queue of length 128 and it will permit up to 300 simultaneous connections. Once there are 300 open connections it will not accept new connections until an existing connection is closed.

userver --port 6800 --max-conns 300 --listenq 128 --use-poll
This is the same as above except using select() calls to get events the userver will use poll().

userver --port 6800 --max-conns 300 --listenq 128 --use-epoll
This is the same as above except using poll() calls to get events the userver will use epoll().

userver -C --cache-table-size=10000 --cache-max-bytes=262144000 --cache-max-file-size=1048576
Caching is turned on. Caching parameters limit the number of files that are cached to 10000, the total number of bytes cached to 250 MB, and the size of the largest file that can be cached to 1 MB.

 

OPTIONS

The operation of userver can be controlled through a number of options. The tool supports both short (one-character) and long (arbitrary-length) option names. Short options are prefixed with a single leading dash (-), long options with a double-dash (--). Multiple short options can be grouped together (e.g., ``-rw'' is equivalent to ``-r -w'') and long options can be abbreviated so long as they remain unique. Parameters to options can be specified either by following the long option name with an equal sign and the parameter value (e.g., --port=6800) or by separating the option name and value with whitespace (e.g., --port 6800).

 

OPTIONS (GENERAL)

-c N
--max-conns=N
The maximum number of simultaneous connections the server will handle. Note that this is typically limited by the number of open file descriptors permitted. Once the maximum number of open connections is reached incoming connection requests are refused until an existing connection is close. Note that idle connections can be timed out eventually (but this hasn't been tested lately). This is also used to size a number of internal data structures that are allocated at initialization time.

-f N
--max-fds=N
The maximum number of open file descriptors permitted. I can't recall if this is actually enforced but it is used to size internal data structures. Note that there is a relationship between --max-conns and --max-fds. If files are not being cached you could (in the extreme case) have one fd used for the socket connection and one fd used for the open file. So one needs to set --max-fds = more than 2 x --max-conns. Note: it should be greater because of some descriptors that are used up by stdin, out, err, and a few open files, etc.

-m N
--accept-count=N
Call accept repeatedly until either, --max-conns is reached, accept() returns EWOULDBLOCK, or N new connections have been accepted. Note that the value of N can make a substantial difference in the performance of event dispatch mechanisms under heavy loads. See [Brecht-2001].

-T N
--port=N
Specify the port number that the server should listen for connections on.

-l N
--listenq=N
Specify the length of the appliation's listen queue. This specifies how many connection requests are allowed to be queued in the application before the kernel rejects incoming connection requests.

-L[1 | 2]
--full-read=[1 | 2]
Affects how calling read works. If this is set to 1 the server will loop on reading the socket until the read fails. This mainly happens either because there is nothing left to read because the other end has been closed or until it would have blocked (EWOULDBLOCK).

If a value of 1 is used the loop on reads will only occur on calls to read that occur as a result of an event indicating that the first read should be done. If a value of 2 is used the loop on reads occur as above but if --eager-reads is also set the server will loop on eager reads (i.e., those that will be done immediately following a the acceptance and setup of a connection).

-H
-h
-?
--help
Print out the usage message.

-M N
--multi-accept=N
Use the multiaccept() system call to perform accepts. NOTE: this was a system call that we added to and experimented with in Linux. The idea here is that since we are repeatedly calling accept() to accept a bunch of connections, why not provide a system call that allows up to a maximum of N connections to be accepted in one system call.

-S
--dont-intr-select
Disable asynchrnous event notification when calling select(). I believe that this was initially meant to work for SIGIO and for SEND.

-d N
--delay=N
The idea was to introduce a delay that might simulate work being done by the server (like some computation and/or a dynamic request). I couldn't find a good method for delaying for a specified amount of time (note that it should be small) with a enough accuracy.

-e N
--extra-accepts=N
While in the middle of processing events that have been obtained (e.g., from select, or some other mechansim) periodically poll for new connection requests. In this case every time N descriptors are processed we check for new connection requests. Note that this open was never used effectively. I found it easier to use and tune the --accept-count option.

-g
--accept-on-close
When a connection is closed check to see if there are any outstanding connection requests. Note: that this only occurs if the maximum number of connections was reached and now a closed connection will reduce the number of connections below --max-conns.

-o [up|down|writes-down|writes-up|lru|lifo|fifo]
--process-fd-order

[up|down|writes-down|writes-up|lru|lifo|fifo]

Change the order in which file descriptors are handled. They are numbered from 0 to N so the uptions are:

up:
from 0 to N
down:
from N to 0
writes-down:
to writes from N to 0, then reads from N to 0
writes-up:
to writes from 0 to N, then reads from 0 to N
lru:
least recently descriptor touched first
lifo:
first descriptor (connection) added to the set first
filo:
first descriptor (connection) added to the set last

-p N
--procs=N
Start N copies of the server. Note that this option hasn't been tested in a long time and is almost certain to cause problems.

-s
--conns-in-server-loop
Add an additional poll for new connections each time through the server loop.

-t N
--free-fd-threshold=N
When the maximum number of connections --max-conns is reached the server stops checking for incoming connections. This options controls when the server starts checking again. It starts checking again after N connections can be accomodated before reaching --max-conns.

-u
--track-max-fd
The server currently keeps track of the maximum fd ever used and uses that as a parameter to calls like select. This option implements code to dynamically keep track of the maximum file descriptor currently used. Note that this requires a bit of extra processing but it's probably not noticable, especially if it can save estra overhead on copying fdsets and processing time in event mechanisms (e.g., select).

-r
--eager-reads
try to eagerly read from new connections. Call read() to try to read the request as soon as the new connection is accepted. In this mode the server optimistically assumes that data will be available for reading when a connection is made on a new socket (or very shortly after). If the assumption is incorrect, the read call simply returns with the error EWOULDBLOCK. Later the event notification mechanism will indicate when the socket is readable.

-w
--eager-writes
try to eagerly perform writes to new connections when the response is available. Both --eager-read and --eager-write also try to take advantage of any potential locality effects by working on the most recently used file descriptor and socket.

-y
--memcpy
Use the memcpy library call to copy interest sets before calling select. This is done rather than doing a straight assignment. This exists because the size of the interest set could be large and I don't know how clever a compiler would be about assigning large data structures. NOTE: it currently copies the side of an fd_set. This should be changed to only copy the amount of data required for the maximum fd of interest.

-z
--rejection-rate
Use the rejection-rate is not yet implemented. The ideas would be to specify the frequency with which new connection requests should be rejected.

--use-sendfile
Use the sendfile() call on systems that have it available. This is only used for uncached files.

--use-madvise
Use madvise() calls to provide the kernel with hints that files are being read sequentially and when they should no longer be cached.

--use-poll
Use poll() to get events instead of select.

--use-epoll
Use epoll() to get events instead of select.

 

OPTIONS FOR CONTROLLING SOCKETS

-F
--reset-on-close
Calls shutdown() instead of close().
WARNING do not use this for a real system!!!

-I N
--rcv-sock-low-wat=N
Sets the sockets receive buffer's low water mark to N. Not available on all systems.

-JN
--snd-sock-low-wat=N
Sets the sockets send buffer's low water mark to N. Not available on all systems.

-O N
--select-timeout=N
Set the timeout option to the select() system call.

-R N
--read-sockbuf-size=N
-W N
--write-sockbuf-size=N
Set the size of the read or write socket buffers. Note that increasing these may help significantly for large transfers.

--use_tcp_cork
Cork the TCP queue when writing the header for the reply. Currently only implemented for the sendfile portion of the code.

 

OPTIONS FOR USE WITH SIGIO

-a
--sigio-accepts
Use asynchronous notification via SIGIO to accept new connections. Asynchronous notification may sound costly at first but consider that some form of asynchronous notificaion may be the only way for an application that is in the middle of something (e.g., computation) to find out about a connection requests.

-k
--sigio-use-procmask
To disable and later enble asynchronous notification of incoming requests when using SIGIO one can use fcntl() to turn off and on asynchronous notification or use sigprocmask(). Be careful of race conditions. By default the server uses fcntl() but this option says to use sigprocmask() instead.
 

OPTIONS FOR CACHING

-C
--caching-on
Turns caching on.

--cache-table-size=N
Specifies the size of the hash table used to cached files. One entry is used per cached file. NOTE: if the --cache-max-load-factor is exceeded the server will print a message and exit. We do not automatically increase the size of the hash table because we want to ensure identical and repeatable behaviour from one experiment to the next.

--cache-max-load-factor=N
Specifies the maximum number of entries that can be filled in the hash table, expressed as a percentage of the table size. For example --cache-max-load-factor = 70 will not permit the hash table to become greater than 70% full. If it does, a message is printed and the server exits.

--cache-max-bytes=N
Specifies the maximum number of bytes cached.

--cache-max-file-size=N
Don't cache files larger than N bytes.

--cache-table-print
When the program ends, print out the contents of the hash table used for caching.

--cache-for-spec
This enables a special hash function that does perfect hashing on URLs requested by SpecWeb99. This is intended for experimentation only.

--cache-lock-pages
Lock all cached pages into memory (must run as root for this to work).

 

OPTIONS FOR DEBUGGING

-D 0xN
--debug-mask=0xN]
Specify a debug mask. For maximum debugging detail use --debug-mask = 0xffffffff. To turn debugging messages off use --debug-mask = 0x0. See debug.h for details. Note: that to compile without debugging also see debug.h.

--trace-summary
Keep track of information regarding system calls and print a summary. If tracing is enabled a list of each event being traced will be dumped to a trace output file.

--trace-summary-only
Keep track of information regarding system calls and print a summary. If this option is enabled individual events are not actually recorded but instead information to produce a summary of each event type is tracked. For example, minimum, maximum and average call times for each system call being traced.

-i
--interactive
Turns on interactive mode. The server stops between calls to process events and prompts the user for input. This permits the user to query some of the state of the server or to step through server execution. At the prompt type 'h' or '?' for a list of commands.

-P
--count-sigpipes
Install a signal handler that simply counts the number of SIGPIPE signals received.
 

OPTIONS FOR EXPERIMENTS RELATED TO BOUNDING PERFORMANCE

These options are designed to have the server stop processing a request at various stages of a requests life. It stops handling the request by closing it's end of the socket and not working on that request anymore. I've attempted to list these in the order of earliest time to drop the request to latest. The idea is that by running a series of experiments by using each of these options one might be able to get a sense of how much additional stage costs.

-n
--no-accepts
--listen-only
This puts the server into a mode where it only ever listens to requests. It never makes any attempt to process requests. So it never even accepts any requests. The believe is that this might be used to provide insights into the amount of overhead incurred when kernel TCP SYN queues and application listen queues become full.

-A
--accepts-only
--close-after-accept
In this mode the server accepts and closes incoming connection requests as quickly as possible. At the time this was done close() would block until the call completed (despite the fd being in non blocking mode). So immediately after calling accept() the connection terminated by calling close().

--close-after-sock-init
The server accepts a connection, initializes the socket (setting socket options like socket buffer sizes, non blocking mode, etc) and then it closes the connection.

--close-after-read
The server accepts a connection, initializes the socket reads the request and then closes the connection.

--close-after-parse
The server accepts a connection, initializes the socket reads the request, parses the requests and then closes the connection.
 

OPTIONS FOR USE WITH THE SEND ENHANCED KERNEL

WARNING: these options are highly experimental and subject to continuous change.

These options specify how the userver interacts with new Linux Scalable Event Notification and Delivery (SEND) kernel mechanisms. See [Ostrowski-2000] for more details on SEND.

-K 0xN
--kdebug-mask=0xN]
Specify a debugging mask which is passed to the evtctl system call to set a kernel debugging mask for the SEND related parts of the kernel.

--send-polls-for-accepts
The send loop polls for new connections.

-B
--block-for-send_events
When there are not more events to process, block and wait for one or more new events by calling evtctl().

-E
--send-events
Use send events. This version does not do notification.

-G
--use_getpid
If we aren't blocking to wait for events (by calling evtctl) we may wish to make a system call to give the kernel a chance to deliver events to the application (since they are delivered when returning from a syscall. In this case we use getpid() because it is likely fast.

-Y
--send-io-events
Use send events. This version does do notification.

-N
--send-loop

Use the send loop. Can potentially get and process send events even while using select. This bypasses the use of the select call.

-b N
--ecb-buf-entries=N
How many events can be stored in the application's event control buffer (ecb).

-Q N
--ecb-hi-water=N
Set the high water mark used for the event control buffer (ecb). One of the things we've tried is to turn event delivery off when the --ecb-hi-water mark is reached and then to turn delivery back on when the --ecb-low-water mark is reached.

-q N
--ecb-low-water=N
Set the low water mark used for the event control buffer (ecb). One of the things we've tried is to turn event delivery off when the --ecb-hi-water mark is reached and then to turn delivery back on when the --ecb-low-water mark is reached.

-U
--auto-accept
Turn on the SEND kernel's auto accept mechanisms. When new connection requests arrive the kernel automatically accepts them (auto accepts 'em) and notifies the application with an event containing the new connection's fd.

--use-accept-send
Use a special version of accept that returns event information related to the accepted connection/socket.

-j
--kernel-info
Experimental: was to tell the application that the kernel has an interface available for obtaining more information about the size and number of entries in some of the kernel queues (e.g., the TCP SYNQs and the application's listenq).
 

OUTPUT

This section describes portions of the output produced during the execution of the userver.

The first portion of output lists the program name and the command line parameters. The second portion of output lists the setting of all options. This is the most reliable way to find out the default settings for some options.

The next two sections identify operating system and per user or process limits.

The remainder of the output provides more information about default settings of various parameters and a large number of statistics about the execution of the server.

 

AUTHORS

userver was developed by Tim Brecht by starting with some micro web servers originally developed by Abhishek Chandra and David Mosberger [Chandra-2001]. David Pariag contributed the current caching engine. One of the hash functions is from Bob Jenkin's web site.

 

BUGS

Probably many.

NOTE: very few if any checks are performed to see if the combination of options being used makes sense. For example, the behaviour from using both the --select-loop and --send-loop options is undefined.

Always be sure to double-check results and don't fall prey to measuring client-performance instead of server performance! The tool httperf is very good at generating loads.

Many of the single letter options are difficult to relate to anything meaningful. As the number of options grew I eventually started to run out of alphabet and added long options.

The user-interface definitely could be improved. A simple configuration file might be more suitable than the many command-line options.

 

REFERENCES

[Brecht-2001]
Tim Brecht and Michal Ostrowski, Exploring the Performance of Select-based Internet Servers, HP Labs Technical Report HPL-2001-314, November, 2001.

[Chandra-2001]
A. Chandra and D. Mosberger, Scalability of Linux Event-Dispatch Mechanisms, Proceedings of the 2001 USENIX Annual Technical Conference, June 2001.

[Ostrowski-2000]
Michal Ostrowski, A Mechanism for Scalable Event Notification and Delivery in Linux, M.Math Thesis, Department of Computer Science, University of Waterloo, November, 2000.


 

Index

NAME
SYNOPSIS
DESCRIPTION
EXAMPLES
OPTIONS
OPTIONS (GENERAL)
OPTIONS FOR CONTROLLING SOCKETS
OPTIONS FOR USE WITH SIGIO
OPTIONS FOR CACHING
OPTIONS FOR DEBUGGING
OPTIONS FOR EXPERIMENTS RELATED TO BOUNDING PERFORMANCE
OPTIONS FOR USE WITH THE SEND ENHANCED KERNEL
OUTPUT
AUTHORS
BUGS
REFERENCES

This document was created by man2html, using the manual pages.
Time: 14:48:52 GMT, August 01, 2003