On December 28 of last year, we released the third beta version of NGINX Unit, our new dynamic web and application server. In this blog post, we discuss the latest changes in detail.
If you installed Unit 0.2 from our package repositories, use your package manager to upgrade. If you are performing a fresh installation, see the installation documentation at https://unit.nginx.org/installation/. (We now provide prebuilt packages for more operating systems.)
NGINX Unit is under active development. It’s likely that at the time you read this blog post, even more recent releases will be available. Check https://unit.nginx.org/CHANGES.txt for details on the latest release.
HTTP persistent connections, or HTTP keepalives, is the technology used to keep TCP connections open between requests. This reduces latency and improves website. NGINX Unit now uses keepalive connections by default (no configuration is necessary on the Unit side).
Keepalive functionality is managed by the HTTP headers Connection
and Keep-Alive
. Unit sets the keepalive timeout to 65 seconds. The value will become configurable in a future release.
When Unit is installed behind NGINX, to use HTTP keepalives you need to configure NGINX as shown below. Specifically, you need to:
keepalive
directive in the upstream
blockproxy_http_version
to 1.1
so that HTTP/1.1 is used for proxying requests to the upstream servers, as required for keepalivesConnection
headers that might be included in client requestsSee the following short example of NGINX configuration with these directives in use.
http { upstream unit {
server 127.0.0.1:8080;
keepalive 32;
}
server {
location / {
proxy_pass http://unit;
proxy_set_header Connection '';
proxy_http_version 1.1;
}
}
}
With Python, you can create isolated virtual environments for your applications. This feature is useful for creating multiple apps that use different versions of Python, different packages, and/or different libraries, and that need to run simultaneously on the same system. Running a virtual environment also, in many cases, eliminates the need for developers to have root
access to the system. With Unit 0.3, you can use virtual environments across multiple Python applications.
You can use the virtualenv tool to create a virtual environment. Once you create a virtual environment, you can define it with the Unit API, using the home
parameter of your application. If you did not configure PYTHONPATH
inside your virtual environment, you still need to set up the path
and home
parameters in the configuration of your application through the Unit API. They might refer to the same, or to different directories.
Here’s a sample Unit configuration:
{ "listeners": {
"*:8080": {
"application": "example-myblog"
}
},
"applications": {
"example-myblog": {
"type": "python 3",
"workers": 2,
"module": "wsgi",
"user": "nick",
"group": "nick",
"path": "/home/nick/myblog-virtualenv/scripts",
"home": "/home/nick/myblog-virtualenv"
}
}
}
This example shows how to configure the following environment:
nick
in the directory /home/nick/myblog-virtualenvAlternatively, you can set both path
and home
relative to the value of working_directory
:
..."working_directory": "/home/nick/myblog-virtualenv",
"path": "scripts",
"home": ".",
...
To change an existing application object to use virtual environments, use the Unit API to change one parameter directly. You don’t have to reload or restart the server. The current state of Unit is preserved automatically. Here’s an example:
$ curl -X PUT -d '"/home/nick/myblog-virtualenv"' --unix-socket /path/to/control.unit.sock http://localhost/applications/example-myblog/home
To display the current value of the home
parameter, send a GET
request to the API:
$ curl -X GET --unix-socket /path/to/control.unit.sock http://localhost/applications/example-myblog/home
The atexit module in Python defines a single function to register clean‑up functions. The functions run when an application process performs a normal shutdown. Unit now supports atexit behavior. You don’t have to change anything in the application or in Unit configuration in order to use atexit. See https://github.com/nginx/unit/issues/65 and https://github.com/nginx/unit/commit/be36cf52c8b092ebb688784a1c10626cac2138d7 for implementation details.
The Go package name for Unit has changed from unit to nginx/unit. This name is more consistent with other packages in the Go ecosystem. Prior to compiling your Go app for Unit, compile and install the package. For supported systems, you can install the unit-go package from our repositories. Then, in the source of the Go app, import the nginx/unit package, together with the net/http package:
import ( "fmt"
"net/http"
"nginx/unit"
)
Unit can now respond with an HTTP error to the client when workers exceed their execution timeout. With version 0.3, the application start time and time in the queue are no longer included in the timeout calculation.
To enable timeouts for workers, use the API to change the limits.timeout
property of the application.
$ curl -X PUT -d '{"timeout": 10}' --unix-socket http://localhost:8088/applications/example-myblog/limits
The timeout value is defined in seconds.
A full application object example with the timeout
value defined looks like the following.
{
"type": "python 3",
"workers": 2,
"module": "wsgi",
"user": "nick",
"group": "nick",
"path": "/home/nick/myblog-virtualenv/scripts",
"home": "/home/nick/myblog-virtualenv",
"limits": {
"timeout": 10
}
}
Timeouts can be enabled for all supported application languages: PHP, Python, and Go.
In larger deployments, various URLs, scripts, or workflows might need different timeout restrictions. In that case, define the different paths as different locations in the NGINX reverse proxy, then create several different applications in Unit. You can have different applications use the same directories and application files, or various directories and application files.
Unit can now limit the number of requests executed in one worker process of the application. When the number is exceeded, it will restart the worker. This feature is particularly useful when applications tend to leak memory, or otherwise misbehave after too many requests.
To enable this, use the API to change the limits.requests
property of the application.
$ curl -X PUT -d '{"requests": 1000}' --unix-socket http://localhost:8088/applications/example-myblog/limits
A full application object example, with the number of requests per worker enabled, looks like the following.
{
"type": "python 3",
"workers": 2,
"module": "wsgi",
"user": "nick",
"group": "nick",
"path": "/home/nick/myblog-virtualenv/scripts",
"home": "/home/nick/myblog-virtualenv",
"limits": {
"timeout": 10,
"requests": 1000
}
}
This limit can be enabled for all supported application languages: PHP, Python, and Go.
In addition to the features described above, we added a number of smaller bug fixes and minor changes. These include:
If you want to see where the project is going and read the roadmap, take a look at the Progress and Next Steps blog post.
The full changelog for Unit development is available in the source code repositories https://hg.nginx.org/unit/file/tip/CHANGES, https://github.com/nginx/unit/blob/master/CHANGES, and the Unit documentation website: https://unit.nginx.org/CHANGES.txt.
Watch our code repository on GitHub and join the discussions and development: https://github.com/nginx/unit.
If you wish to become a full‑time engineer for NGINX, check our job board.
"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."