= Name =
nginx_ajp_module - support AJP protocol proxy with Nginx
With this module, Nginx can connect to Tomcat's AJP port directly. The backend connections are keepalive, session sticky. The motivation of writing these modules is Nginx's high performance and robustness.
syntax: ajp_buffers the_number is_size;
default: ajp_buffers 8 4k/8k;
context: http, server, location
This directive sets the number and the size of buffers, into which will be read the response, obtained from the ajp server. By default, the size of one buffer is equal to the size of pages. Depending on platform this is either 4K, 8K or 16K.
syntax: ajp_buffer_size the_size;
default: ajp_buffer_size 4k/8k;
context: http, server, location
This directive sets the buffersize, into which will be read the first part of the response, obtained from the ajp server.
In this part of response the small response-header is located, as a rule.
By default, the buffersize is equal to the size of one buffer in directive ajp_buffers
; however, it is possible to set it to less.
syntax: ajp_cache zone;
default: off
context: http, server, location
The directive specifies the area which actually is the share memory's name for caching. The same area can be used in several places. You must set the ajp_cache_path
first.
syntax: ajp_cache_key line;
default: none
context: http, server, location
The directive specifies what information is included in the key for caching, for example
<geshi lang="nginx"> ajp_cache_key "$host$request_uri$cookie_user"; </geshi>Note that by default, the hostname of the server is not included in the cache key. If you are using subdomains for different locations on your website, you need to include it, e.g. by changing the cache key to something like
<geshi lang="nginx"> ajp_cache_key "$scheme$host$request_uri"; </geshi>
syntax: ajp_cache_methods [GET];
default: ajp_cache_methods GET HEAD;
context: main,http,location
GET/HEAD is syntax sugar, i.e. you can not disable GET/HEAD even if you set just
<geshi lang="nginx"> ajp_cache_methods POST; </geshi>syntax: ajp_cache_min_uses n;
default: ajp_cache_min_uses 1;
context: http, server, location
TODO: Description.
syntax: ajp_cache_path /path/to/cache [levels=m:n];
default: none
context: http, server, location
This directive sets the cache path and other cache parameters. Cached data stored in files. Key and filename in cache is md5 of proxied URL. Levels parameter set number of subdirectories in cache, for example for:
<geshi lang="nginx"> ajp_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m; </geshi>file names will be like:
/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
syntax: ajp_cache_use_stale [updating|error|timeout|invalid_header|http_500];
default: ajp_cache_use_stale off;
context: http, server, location
TODO: Description.
syntax: ajp_cache_valid [http_error_code|time];
default: none
context: http, server, location
TODO: Description.
syntax: ajp_connect_timeout time;
default: ajp_connect_timeout 60s;
context: http, server, location
This directive assigns a timeout for the connection to the upstream server. It is necessary to keep in mind that this time out cannot be more than 75 seconds.
This is not the time until the server returns the pages, this is the ajp_read_timeout statement. If your upstream server is up, but hanging (e.g. it does not have enough threads to process your request so it puts you in the pool of connections to deal with later), then this statement will not help as the connection to the server has been made.
syntax: ajp_header packet_buffer_size;
default: ajp_header_packet_buffer_size 8k;
context: http, server, location
Set the buffer size of Forward Request packet. The range is (0, 2^16).
syntax: ajp_hide_header name;
context: http, server, location
By default, Nginx does not pass headers "Status" and "X-Accel-..." from the AJP process back to the client. This directive can be used to hide other headers as well.
If the headers "Status" and "X-Accel-..." must be provided, then it is necessary to use directive ajp_pass_header to force them to be returned to the client.
syntax: ajp_ignore_headers name [name];
default: none
context: http, server, location
This directive(0.7.54+) prohibits the processing of the header lines from the proxy server's response.
It can specify the string as "X-Accel-Redirect", "X-Accel-Expires", "Expires" or "Cache-Control".
syntax: ajp_ignore_client_abort on|off;
default: ajp_ignore_client_abort off;
context: http, server, location
This directive determines if current request to the AJP-server must be aborted in case the client aborts the request to the server.
syntax: ajp_intercept_errors on|off;
default: ajp_intercept_errors off;
context: http, server, location
This directive determines whether or not to transfer 4xx and 5xx errors back to the client or to allow Nginx to answer with directive error_page.
Note: You need to explicitly define the error_page handler for this for it to be useful. As Igor says, "nginx does not intercept an error if there is no custom handler for it it does not show its default pages. This allows to intercept some errors, while passing others as are."
syntax: ajp_next_upstream [error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off];
default: ajp_next_upstream error timeout;
context: http, server, location
Directive determines, in what cases the request will be transmitted to the next server:
- error — an error has occurred while connecting to the server, sending a request to it, or reading its response;
- timeout — occurred timeout during the connection with the server, transfer the request or while reading response from the server;
- invalid_header — server returned a empty or incorrect answer;
- http_500 — server returned answer with code 500;
- http_502 — server returned answer with code 502;
- http_503 — server returned answer with code 503;
- http_504 — server returned answer with code 504;
- http_404 — server returned answer with code 404;
- off — it forbids the request transfer to the next server Transferring the request to the next server is only possible when nothing has been transferred to the client -- that is, if an error or timeout arises in the middle of the transfer of the request, then it is not possible to retry the current request on a different server.
syntax: ajp_max_data_packet_size size;
default: ajp_max_data_packet_size 8k;
context: http, server, location
Set the maximum size of AJP's Data packet. The range is [8k,];
syntax: ajp_max_temp_file_size size;
default: ajp_max_temp_file_size 1G;
context: http, server, location, if
The maximum size of a temporary file when the content is larger than the proxy buffer. If file is larger than this size, it will be served synchronously from upstream server rather than buffered to disk.
If ajp_max_temp_file_size is equal to zero, temporary files usage will be disabled.
syntax: ajp_pass ajp-server
default: none
context: location, if in location
Directive assigns the port or socket on which the AJP-server is listening. Port can be indicated by itself or as an address and port, for example:
<geshi lang="nginx"> ajp_pass localhost:9000; </geshi>using a Unix domain socket:
<geshi lang="nginx"> ajp_pass unix:/tmp/ajp.socket; </geshi>You may also use an upstream block.
<geshi lang="nginx"> upstream backend { server localhost:1234; } ajp_pass backend; </geshi>syntax: ajp_pass_header name;
context: http, server, location
TODO: Description.
syntax: ajp_pass_request_headers [on];
default: ajp_pass_request_headers on;
context: http, server, location
TODO: Description.
syntax: ajp_pass_request_body [on] ;
default: ajp_pass_request_body on;
context: http, server, location
TODO: Description.
syntax: ajp_read_timeout time;
default: ajp_read_timeout_time 60
context: http, server, location
Directive sets the amount of time for upstream to wait for a ajp process to send data. Change this directive if you have long running ajp processes that do not produce output until they have finished processing. If you are seeing an upstream timed out error in the error log, then increase this parameter to something more appropriate.
syntax: ajp_send_lowat [on];
default: ajp_send_lowat off;
context: http, server, location, if
This directive set SO_SNDLOWAT. This directive is only available on FreeBSD
syntax: ajp_send_timeout time;
default: ajp_send_timeout 60;
context: http, server, location
This directive assigns timeout with the transfer of request to the upstream server. Timeout is established not on entire transfer of request, but only between two write operations. If after this time the upstream server will not take new data, then nginx is shutdown the connection.
syntax: ajp_store [on] ;
default: ajp_store off;
context: http, server, location
This directive sets the path in which upstream files are stored. The parameter "on" preserves files in accordance with path specified in directives alias or root. The parameter "off" forbids storing. Furthermore, the name of the path can be clearly assigned with the aid of the line with the variables:
<geshi lang="nginx"> ajp_store /data/www$original_uri; </geshi>
The time of modification for the file will be set to the date of "Last-Modified" header in the response. To be able to safe files in this directory it is necessary that the path is under the directory with temporary files, given by directive ajp_temp_path for the data location.
This directive can be used for creating the local copies for dynamic output of the backend which is not very often changed, for example:
<geshi lang="nginx"> location /images/ { root /data/www; error_page 404 = @fetch; } location @fetch { internal; ajp_pass backend; ajp_store on; ajp_store_access user:rw group:rw all:r; ajp_temp_path /data/temp; root /data/www; } </geshi>To be clear ajp_store is not a cache, it's rather mirror on demand.
syntax: ajp_store_access users:permissions [users:permission];
default: ajp_store_access user:rw;
context: http, server, location
This directive assigns the permissions for the created files and directories, for example:
<geshi lang="nginx"> ajp_store_access user:rw group:rw all:r; </geshi>
If any rights for groups or all are assigned, then it is not necessary to assign rights for user:
<geshi lang="nginx"> ajp_store_access group:rw all:r; </geshi>
syntax: ajp_temp_path dir-path [level1] ;
default: $NGX_PREFIX/ajp_temp
context: http, server, location
This directive works like client_body_temp_path to specify a location to buffer large proxied requests to the filesystem.
syntax: ajp_temp_file_write_size size;
default: ajp_temp_file_write_size ["#ajp] * 2;
context: http, server, location, if
Sets the amount of data that will be flushed to the ajp_temp_path when writing. It may be used to prevent a worker process blocking for too long while spooling data.
syntax: jvm_route $cookie_SESSION_COOKIE[|session_url] [reverse]
default: none
context: upstream
This directive comes from ngx_http_upstream_jvm_route_module.
'$cookie_SESSION_COOKIE' specifies the session cookie name(0.7.24+). 'session_url' specifies a different session name in the URL when the client does not accept a cookie. The session name is case-insensitive. In this module, if it does not find the session_url, it will use the session cookie name instead. So if the session name in cookie is the name with its in URL, you don't need give the session_url name.
With scanning this cookie, the module will send the request to right backend server. As far as I know, the resin's srun_id name is in the head of cookie. For example, requests with cookie value 'a$$$' are always sent to the server with the srun_id of 'a'. But tomcat's JSESSIONID is opposite, which is like '$$$.a'. The parameter of 'reverse' specifies the cookie scanned from tail to head.
If the request fails to be sent to the chosen backend server, It will try another server with the Round-Robin mode until all the upstream servers tried. The directive ajp_next_upstream can specify in what cases the request will be transmitted to the next server. If you want to force the session sticky, you can set 'ajp_next_upstream off'.
syntax: jvm_route_status upstream_name
default: none
context: location
This directive comes from ngx_http_upstream_jvm_route_module.
Set the location of pages return the status of the jvm_route peers. Example:
<geshi lang="nginx"> location status { jvm_route_status backend; } </geshi>syntax: keepalive <num></num> [single]
default: none
context: upstream
Switches on keepalive module for the upstream in question. This directive comes from ngx_http_upstream_keepalive_module.
Parameters:
- num: Maximum number of connections to cache. If there isn't enough room to cache new connections - last recently used connections will be kicked off the cache.
- single: Treat everything as single host. With this flag connections to different backends are treated as equal.
This directive comes from ngx_http_upstream_jvm_route_module.
Main syntax is the same as the official directive. This module add these parameters:
- 'srun_id': identifies the backend JVM's name by cookie. The default srun_id's value is 'a'. The name can be more than one letter.
- 'max_busy': the maximum of active connections with the backend server. The default value is 0 which means unlimited. If the server's active connections is higher than this parameter, it will not be chosen until the server is less busier. If all the servers are busy, Nginx will return 502.
Download the latest version of the release tarball of this module from github
Grab the nginx source code from nginx.org, for example, the version 0.7.65 (see nginx compatibility), and then build the source with this module:
<geshi lang="bash">
$ wget 'http://nginx.org/download/nginx-0.7.65.tar.gz' $ tar -xzvf nginx-0.7.65.tar.gz $ cd nginx-0.7.65/ $ patch -p1 < /path/to/nginx_ajp_module/ajp.patch
$ ./configure --add-module=/path/to/nginx_ajp_module
$ make $ make install
</geshi>
- My test bed is 0.7.65 and 0.8.40.
- For Nginx-1.1.4+, you should use the branch for_1.1.4.
- SSL
- Backends connection pool?
- Developing
- first release
- Jinti Shen(路奇) jinti.shen AT gmail DOT com
- Joshua Zhu(叔度) zhuzhaoyuan AT gmail DOT com
- Simon Liu(雕梁) simohayha.bobo AT gmail DOT com
- Matthew Ma(东坡) mj19821214 AT gmail DOT com
- Weibin Yao(姚伟斌) yaoweibin AT gmail DOT com
- Thanks 李金虎(beagem@163.com) to improve the keepalive feature with this module.
This README template is from agentzh.
I borrowed a lot of codes from Fastcgi module of Nginx. This part of code is copyrighted by Igor Sysoev. And the design of apache's mod_ajp_proxy. Thanks for their hard work.
This module is licensed under the BSD license.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.