Lead Image © Kirill Kurashov, 123RF.com

Lead Image © Kirill Kurashov, 123RF.com

The OpenResty distribution for Nginx

Secret Agent's Suitcase

Article from ADMIN 19/2014
By
Event-based request processing makes Nginx an agile web server. With the OpenResty packages, it becomes a fast application server based on the Lua scripting language.

OpenResty [1] is the Nginx server [2] bundled with many useful modules. Developed almost single-handedly by Yichun "agentzh" Zhang while living and working in Beijing, China, then San Francisco, California, OpenResty converts Nginx into a superfast web application server.

The majority of OpenResty comprises modules for the Lua scripting language, which is popular as an embedded language because of its low resource consumption and good performance. The Apache web server has also added Mod-Lua to its core distribution [3].

The OpenResty modules make it possible to use Lua instructions in the configuration files. This allows for complex and dynamic configurations, which can be used, say, to implement web services. The distribution includes some modules for integrating memcache and databases such as MySQL/Drizzle, PostgreSQL, and Redis.

Lua Included

With OpenResty, Lua scripts can intervene in all stages of processing and editing an HTTP request, creating responses, and modifying headers. The combination of Lua and Nginx and the event-based request processing characteristic of Nginx places OpenResty high in TechEmpower's web framework benchmarks (Figure 1) [4], and it is even faster with the Lua just-in-time compiler (LuaJIT) included with OpenResty.

Figure 1: OpenResty ranked among the top in TechEmpower benchmarks.

OpenResty is not included with the popular Linux distributions; in other words, you need to build it from the source code. To do this, you also need to install some packages and libraries: Perl 5.6.1 or later, libreadline, libpcre, and libssl. Then, download the source package from the OpenResty site, unzip it and run ./configure, preferably with the --with-luajit option.

By default, the modules for the Drizzle, PostgreSQL, and Iconv databases are also disabled. You can enable them with the appropriate configure options if need be;

./configure --help

reveals more details. Although the binaries and modules are built with make, OpenResty has no make install, which is why it is advisable to get the checkinstall package and then install OpenResty using:

checkinstall make install

The installed files can then be removed, if not needed, using your distribution's package manager.

Manual Installation

By default, the Nginx files are installed in /usr/local/openresty. If you do not want this, you can choose a different directory using the --prefix configure option. However, the default setting is not bad, because it does not collide with any Nginx packages installed by your Linux distribution. The last task is to run the Nginx server at boot time, which the two configuration files in Listing 1 (Upstart) and Listing 2 (systemd) do for you. A call to nginx -t checks the configuration before the server process starts. If an error occurs, nginx -V gives you an overview of the existing modules.

Listing 1

/etc/init/openresty.conf (Upstart)

01 # openresty
02
03 description "nginx openresty stack"
04 author "Oliver Frommel <ofrommel@gmail.com>"
05
06 start on (filesystem and net-device-up IFACE=lo)
07 stop on runlevel [!2345]
08
09 env DAEMON=/usr/local/openresty/nginx/sbin/nginx
10 env PID=/var/run/nginx.pid
11
12 expect fork
13 respawn
14 respawn limit 10 5
15
16 pre-start script
17         $DAEMON -t
18         if [ $? -ne 0 ]
19                 then exit $?
20         fi
21 end script
22
23 exec $DAEMON

Listing 2

/lib/systemd/system/nginx.service (systemd)

01 [Unit]
02 Description=OpenResty Stack for Nginx
03 After=syslog.target network.target remote-fs.target nss-lookup.target
04
05 [Service]
06 Type=forking
07 PIDFile=/var/run/nginx.pid
08 ExecStartPre=/usr/local/openresty/nginx/sbin/nginx -t
09 ExecStart=/usr/local/openresty/nginx/sbin/nginx
10 ExecReload=/bin/kill -s HUP $MAINPID
11 ExecStop=/bin/kill -s QUIT $MAINPID
12 PrivateTmp=true
13
14 [Install]
15 WantedBy=multi-user.target

By the way, modules for well-known configuration management software are also available that help you deploy OpenResty on servers. For example, GitHub has some modules for Puppet [5], a Chef recipe can be found directly on the Opscode site [6]. The Chef module is well maintained and was last updated in early November 2013.

In the simplest case, it is now possible to embed Lua code directly in the configuration files using the content_by_lua keyword:

content_by_lua '
   ngx.say("test")
';

Lua also handles request rewrites or authentication with rewrite_by_lua: Similarly, rewrite_by_lua_file and content_by_lua_file load Lua code from a file. In this case, the web server normally loads the Lua code only once, which clearly reduces overhead. To disable this behavior (e.g., if you are developing scripts), set lua_code_cache to off.

You can achieve similar results without Lua code, as an example by Richard Nyström shows [7]; it implements a web service with SQL statements in the Nginx configuration.

For example, the following snippet from the configuration returns all the articles in a database for a GET request:

postgres_query  HEAD GET "SELECT * FROM articles";

Often the interesting data does not reside directly on the web server but is outsourced to other computers that run a directory service, a database, or the like.

OpenResty supports such service-oriented architectures (SOAs) by means of subrequests. Thus, an incoming HTTP request triggers further requests that obtain the missing data, either from other computers or services on a server that is running Nginx. An example of this is the Auth-Request module, which uses subrequests for authentication.

This approach allows a modular access protection design and combinations of various services:

location /private/ {
  auth_request /auth;
   ...
}

Even parallel subrequests can be issued if you call capture_multi. At a lower level, an interface equivalent to the Lua TCP API works directly with network sockets, but it is non-blocking by default.

Real-time web applications are no problem with OpenResty. They can be used, for example, with WebSocket support – the stable version [8] of which (v1.4.0) was added to Nginx. However, this downgrades Nginx to a WebSocket proxy. Something else has to process the data. With OpenResty, a Lua module could handle this. Because socket programming is relatively uncomplicated, you can achieve this with a few lines of code. Aapo Talvensaari demonstrates how to do this in his blog [9].

An interesting module, ngx_echo, is well suited for debugging or developing web applications or services. It extends the configuration vocabulary to include shell-like instructions such as echo, sleep, time, and exec. This means you can set up URLs to test clients without needing to write error-prone code on the server, as in this example application:

location /echodelay {
        echo hello;
        echo_flush;
        echo_sleep 2.5;
        echo world;
      }

First, the block of code returns the hello string, which immediately becomes visible after flushing the output buffer echo_flush. The server then waits 2.5 seconds before it continues to output world.

Describing the many opportunities OpenResty offers for programming with Lua is well beyond the scope of this article; however, you can gain an overview of all the supplied modules in Table 1.

Table 1

OpenResty Modules

Module Function
ArrayVarNginxModule Array variables for Nginx configuration files
AuthRequestNginxModule Authentication with subrequests
CoolkitNginx Module collection with small Nginx add-ons
DrizzleNginx Connector for Drizzle and MySQL databases
EchoNginxModule Shell-style utilities for debugging
EncryptedSessionNginxModule Encrypted session data
FormInputNginxModule Processing of forms in the Nginx configuration
HeadersMoreNginxModule Advanced header processing
IconvNginxModule Conversion of character sets
StandardLuaInterpreter Standard Lua interpreter
MemcNginxModule Memcached protocol
Nginx Nginx distribution
NginxDevelKit Nginx SDK
LuaCjsonLibrary Fast JSON module for Lua
LuaJIT Just-in-time compiler for Lua
LuaNginxModule Lua module for Nginx
LuaRdsParserLibrary Parser for Resty DBD stream in database modules
LuaRedisParserLibrary Parser for Redis responses
LuaRestyDNSLibrary DNS library
LuaRestyLockLibrary Nonblocking mutex locks
LuaRestyMemcachedLibrary Driver for memcached
LuaRestyMySQLLibrary Driver for MySQL
LuaRestyRedisLibrary Driver for Redis
LuaRestyStringLibrary String library
LuaRestyUploadLibrary Library for HTTP uploads
LuaRestyWebSocketLibrary Library for WebSockets
PostgresNginxModule Connector for PostgreSQL
RdsCsvNginxModule Converts Resty-DBD streams to CSV format
RdsJsonNginxModule Converts Resty-DBD streams to JSON
RedisNginxModule Redis module; provides processed responses
Redis2NginxModule Redis module; provides unprocessed responses
SetMiscNginxModule Various settings (MD5, JSON, etc.)
SrcacheNginxModule Transparent caching
XssNginxModule Support for cross-site Ajax requests

Conclusions

If you already use Nginx or are thinking about switching horses, you should definitely take a look at OpenResty.

It not only contains the standard modules, but also a number of useful extensions – mostly with the Lua scripting language – that can be learned easily. This means that even complicated web service setups are no problem, and high performance is guaranteed.

Infos

  1. OpenResty: http://openresty.org/
  2. "Nginx" by Jeremy Garcia, Linux Pro Magazine , issue 107, October 2009, pg. 28: http://www.linuxpromagazine.com/Issues/2009/107/Nginx
  3. "Lua for Apache" by Tim Schürmann, ADMIN , issue 09, pg. 42: http://www.admin-magazine.com/Articles/Lua-for-Apache/
  4. TechEmpower benchmarks: http://www.techempower.com/benchmarks/
  5. Puppet module for OpenResty: https://github.com/propertybase/puppet-openresty
  6. Chef cookbook for OpenResty: http://community.opscode.com/cookbooks/openresty
  7. Simple API with Nginx and PostgreSQL: http://rny.io/nginx/postgresql/2013/07/26/simple-api-with-nginx-and-postgresql.html
  8. Nginx WebSockets: http://nginx.org/en/docs/http/websocket.html
  9. WebSockets with OpenResty: https://medium.com/p/1778601c9e05

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus