In this video, I’ll demonstrate how to do streaming HTTP response body output in OpenResty.
We create the sub-directory structure as always.
mkdir logs conf html
We write the boilerplate configuration quickly.
And make the following edits in this file:
- We create an HTTP server listening on the 8080 port.
- Add a
- It is important to specify this
application/octet-streamMIME type to make the Chrome web browser happy.
- Add some Lua code via the content_by_lua_block directive.
- We output one line of output every one second.
- We need to call the ngx.flush method explicitly to flush nginx’s write buffers. This is a 100% nonblocking call.
- And we use ngx.sleep to sleep for one second in each loop iteration. This is nonblocking as well.
- Then we create a root location for the
Let’s check the whole directory tree right now.
Now start this OpenResty application.
openresty -p $PWD/
Time to query our HTTP location with
Cool, it is indeed generating one line of per second!
To verify if everything is indeed nonblocking, we can load this HTTP API with the
weighttp utility. Note that it will take a while because we have intentionally slow responses here.
weighttp -c 500 -k -n 500 127.0.0.1:8080/test
So with 500 concurrent requests, we can still achieve more than 120 requests per second! Note that each request takes 4 seconds to complete. And here we are using only a single worker process and a single operating system thread.
We can still increase the concurrency level a lot. But we will need to tweak the nginx configuration accordingly.
Like tuning the worker connections to a larger value.
Better performance can also be achieved by enabling the access log buffering. We can also reduce the request memory pool size.
Now let’s create an HTML page to test it out in a web browser.
We make the following edits in this file.
- Add a
DIVtag to hold the output.
- We fetch out
- Make sure there is new data.
- Append our new data to the
DIVelement. Here we are lazy. We do not bother escaping special HTML characters.
- And we check new incoming response data every second.
- Firefox supports a more clever way but we have to support Chrome as well.
- Finally, we handle the end of the response body stream.
- Check the response data for one last time.
- Remove our periodic timer.
- And append the final output to the web page.
- We omit error handling here for brevity.
Let’s check the whole directory tree again.
We don’t need to reload or restart the OpenResty server since it is just a static HTML page.
ps aux|grep nginx|grep -v /tmp/
Time to point chrome to this HTML page.
It works! This is all I want to cover today.
If you like this tutorial, please subscribe to this blog site and our YouTube channel. Thank you!
This article and its associated video are both generated automatically from a simple screenplay file.
Yichun Zhang is the creator of the OpenResty® open source project. He is also the founder and CEO of the OpenResty Inc. company. He contributed a dozen open source Nginx 3rd-party modules, quite some Nginx and LuaJIT core patches, and designed the OpenResty XRay platform.
We welcome interested readers to contribute translations in other natural languages as long as the full article is translated without any omissions. We thank them in advance.
We always welcome talented and enthusiastic engineers to join our team at OpenResty Inc.
to explore various open source software’s internals and build powerful analyzers and
visualizers for real world applications built atop the open source software. If you are
interested, please send your resume to
firstname.lastname@example.org . Thank you!