OpenResty – A fast web app server by extending Nginx
openresty.org
openresty.org
* Classifying incoming requests based on various signals to detect DDOS patterns and moving those requests into different request limit zones. It's used in production at a bigger hosting provider.
* Rewriting incoming requests to a certain path of an existing website to a different shared blog hosting provider and changing back HTML/CSS/JS so everything worked. It didn't end up going into production, but it was pretty easy to build in under 100 lines of Lua code.
So when you're bored and want to learn something useful, have a look at http://wiki.nginx.org/HttpLuaModule. It might help you someday.
This is the really important bit about OpenResty that sometimes gets overlooked, or buried under the "full-fledged web application server" motto. The "ngx_lua" module by itself basically nullifies the need for a bunch of other modules.
As anyone running nginx for something non-trivial can attest, adding modules can quickly become a support nightmare (varying levels of quality, issues you can't figure out if they're core or module related, keeping everything updated, confusing configurations, etc.).
Right now "ngx_lua" is one of my "must have" modules, together with "headers_more" and "set_misc" (which could also be replaced by "ngx_lua" rather easily, but with a slight impact in configuration readability).
I'd hope the nginx plus folks would rather make this official instead of going out with a competing module using JavaScript. Guess Lua is not hipster enough.
Story time: Some time ago we developed a CMS for a large art/production company. One of the requirements was that everything must be access controlled including all assets (eg. images, videos). The site went live and all was good until one day when, for no apparent reason, our monitoring alreted extreme load and then the site went down. Not so good for a company that sells its tickets online... I got on the phone with them and turns out that they started using the CMS to store images used for newsletters, which they sent out to some 200K people that morning. Now normally this wouldn't be such a big problem, but since all images were ACLd, this meant that instead of serving static files all requests went to the backend and pretty much killed it. The solution we came up with was to move the initial access control check for assets directly to OpenResty using Lua and Drizzle. So whenever a request came in for an image Openresty checked if it's public and only if it was not did the request hit the backend, otherwise it was served directly. Once we pushed this live the load disappeared and never came back.
Also I wrote an init script for it (as we needed one for a DRBD setup). Maybe someone will find it useful, here it is: https://gist.github.com/pwm/d3260804b4ade0d81f29
That way your dynamic script is only responsible for access control and generating headers.
Apache supports similar functionality by setting a Location header on a 200 response from a CGI or mod_wsgi script.
https://github.com/slava-vishnyakov/lapis-example
It is impressively simple to code:
https://github.com/slava-vishnyakov/lapis-example/blob/maste...
Lapis and OpenResty (?) are actually used to power the online indie game store run and built by leafo [2].
[1]: http://leafo.net
[2]: https://itch.io
However, I find the use of Moonscript for its examples sites and the obvious preference for it in the documentation to be quite maddening. Using moonc to compile things down to Lua doesn't really make tracing through code any better when trying to gain a full understanding of the stack.
I've got very little desire to go out of my way to learn Moonscript since I will not get company approval to work in it and I cannot train my coworkers on it just so they can learn to use Lapis. Already it was a stretch adopting Lua where I am and to be quite honest, I really haven't liked what I saw of Moonscript anyway. I don't want or need classes and its associated machinery, I particularly do not want semantic whitespace.
I really hope to see more focus placed on making Lua proper a first-class citizen for the framework, including provided examples. Otherwise, Lapis does look like the right tool for the job and I liked many of the other decisions made over it.
I also like Coffeescript though. If someone doesn't like Coffeescript, they probably will not like Moonscript either.
More on this from dotScale 2015: https://youtu.be/LA-gNoxSLCE?t=7m40s
[1] https://realtimelogic.com/products/barracuda-application-ser...
I've had normal nginx with all the plugins (using the nginx-extras package, I think, from the ppa). No problem with Lua and SPDY at least in my use case (sending rendered HTML snapshots for anything with an HTML mime type).
[1] http://blog.chromium.org/2015/02/hello-http2-goodbye-spdy-ht...
https://www.techempower.com/benchmarks/#section=data-r10&hw=...
Using your same link I find this solution blowing node away in JSON serialization but the other benchmarks? Not so much. In fact complete opposite for some of them.
As far as I have found there is no "best at everything" language and framework so your binary question doesn't make much sense. I'm also not convinced of this solution in a large web application because debugging and unit testing would be nightmare .
So, it's a bit more inconclusive than you describe. I'd expect OpenResty to be much faster than Node for a lot of common web interactions. Node has better support for interacting with external services asynchronously, though.
There continually seems to be this belief that Lua is language only for game scripting; outside of that it is largely ignored.
The creator of OpenResty has expressed interest in eventually extending it to work for non-HTTP usecases though.
Try searching a driver for a not so popular db on npm and you might find two different implementations in addition to the official driver.
I'd love to see something like this on openresty.
Yeah. There are "Lua rocks" (https://luarocks.org/) for Lua, but they have a few hundreds of packages only. Compared to npm there's no comparison at all.
On the other hand you wouldn't want to use RDBMS with OpenResty anyway, I think. The whole point of using Nginx scripting (especially with LuaJIT, which is awesome) is to be as fast as possible. True, DB connections are async in Resty, but they are still going to take some time. For simple data that don't need to be persistent it's better to use ngx.shared - an in process dictionary shared between all scripts. For more complicated or persistent data, you have Redis and other fast solutions.
Additionally, Nginx offers a full non-blocking socket API to Lua scripts. You can write a "driver" for anything that wants to speak to you over a network.