235 comments

[ 4.7 ms ] story [ 239 ms ] thread
This would take the place of something like tomcat or uwsgi, right?
Java is a notable omission on the diagram on their landing page...
Under Features / Multi-language support:

> Full support for Go, PHP, and Python; Java and Node.JS support coming soon

No Ruby support :<
Also "coming soon" according to their github page
The day I can toss Tomcat to the bin and replace it with something written in C that allows zero-downtime restarts will be a fine day indeed.
The concept of XUnit is so ingrained in my head that I assumed it was a unit testing framework for NGINX.

The rest of the headline cleared it up of course, but I was curious for a minute how that would look.

EDIT: When discussing a new product, I would think the name is a fair point of discussion.

Furthermore after this thread's title changed, it now requires a clickthrough to dispel similar misunderstandings.

Yeah, given the title, I thought it was about a unit testing framework for Nginx. Kinda like ServerSpec, but more specific: http://serverspec.org/
Looks to be a good candidate to replace omnipresent nginx based API routers
I have a small flask application which basically is a rest get post API server. I'm struggling to make deployment easy. With PHP, i just push to the application server and rsync that folder into var www html for Apache httpd but what would I do for flask python 3?
Ansible? Puppet? A five line bash script?
rsync && ssh target -t 'cd ~/app/; ...' and it's a one-liner.
Here will go their REST config api to force reloads.

BTW, it is a good idea to always do API versioning on production runs. That will eliminate the possibility that different API versions (files stuck in the cache, or simply people who kept browser open for a long time) use the same endpoint

Yes, I have a baseurl/v0/... in the naming scheme for now. (:
Use a webserver that proxies requests to a wsgi server. We tend to put Caddy in front of Gunicorn which works really well. Also, look into running Gunicorn under supervisord.
You can run gunicorn (that loads your flask app) as a service using systemd on e.g. port 9000 and then have nginx (also run as a systemd service) proxy port 80 traffic to that port and handle static files etc.
As with most things, there is more than one way to do it. Push to the application server and hook it to your flask application using [uWSGI](http://flask.pocoo.org/docs/0.12/deploying/uwsgi/), for example.

[Here's](https://www.digitalocean.com/community/tutorials/how-to-serv...) an old guide for running Flask with uWSGI and nginx on Ubuntu. There are several more recent, detailed instructions online.

Personally, I have an AWS instance running a Node.JS server on (blocked) port 8000, a Django uWSGI app on 8001, and a static resume site, all being reverse-proxy served by nginx. So I don't really see the advantages of Nginx Unit yet.

All too hard. Use "bottle" (I think it's much the same as flask) - you just call 'run' and it does it's thing.

https://bottlepy.org/docs/dev/

I think that's more intended as demo server to get you started quickly while you're developing.

You'll probably want to switch to uwsgi or gunicorn before you actually deploy anything.

I haven't actually used Bottle, but with Flask the development web server seems to fall over if a client cancels ones of its HTTP requests, for example. It's really just a simple, light thing for mucking around with.

the answer to this is usually "use docker". If you want to deploy your nginx as well, then you need docker-compose.yml and use "docker stack deploy".

If you are only looking to deploy your python code (and nginx/apache is constantly running on the server), then follow these steps

1. install docker on server 2. create an account on https://hub.docker.com/ 3. https://docs.docker.com/engine/swarm/stack-deploy/#deploy-th...

your docker workflow in the future looks like this: 1. test the application on your laptop inside a docker container 2. push container to docker hub 3. "docker update" your stack

Any report of the perf (VS uWSGI for example) ?
So it looks like they basically rewrote uwsgi and slapped a rest api on top of it.. (as a big fan of uwsgi, that seems like a reasonable thing to do...)
badly need settings like restart works every X requests or harakiri after # seconds timeout.
I recently tried to deploy a python flask application, and it was quite a mess. It relied on some services I had never heard of, and the documentation was a mess (not the documentation of Flask but of how to deploy it properly).

If Nginx Unit could host flask applications, it would be great news.

how does it compare to openresty/luajit ?
AFAIK nginx unit would still require to have an nginx in front, so they are in different weight category with openresty.

It looks like it's more of a replacement to good old NGINX+Apache set up where there would be mod_php, mod_cgi, mod_perl and .htaccess on backend to serve the app.

Confusing description. After seeing the Github README (https://github.com/nginx/unit#integration-with-nginx), it looks to be Nginx's alternative to low-level, language-specific, app servers, e.g. PHP-FPM or Rack, with the benefit that a single Unit process can support multiple languages via its dynamic module architecture, similar to Nginx web server's dynamic modules.

It's still intended to run behind Nginx web server (or some other web server), much like you'd run something like PHP-FPM behind a web server.

It's a polyglot app server with microservice orchestration. It's definitely needed.

Some things to look for, such as registration/discovery of services, intra-cluster load balancing (where it started, no doubt), identity propagation & authn/z

The biggest issue to my mind though is distributed transactions and logging/debug/development. My biggest stumbling blocks with this sort of thing.. stepping through code over microservices is such a PITA.

You seem to be very experienced in this area. Can you explain a bit about why you think an "app server with microservice orchestration" is needed?
because you can work with individual microservices across clusters without a ton of overhead (or use a monolithic app server), aiding in deployment, rollback, debugging, development.
So in what circumstances would you need the polyglot bit? (I guess I'm assuming a container/VM architecture here).
How exactly does having an app server reduce overhead, compared to running each service directly without app server? And how does having an app server compare to putting each microservice in its own Docker container and orchestrating them in Kubernetes, which is what more and more companies seem to be doing?
At a glance, I think this is an alternative to docker/kubernetes. The general idea seems to be to cut the middleman/topman out and let the bottom man (app server) be the "unit" of configuration. Like a sort of integrated docker/<YourLang>-runtime.
No, this thing is more like inetd, while kubernetes is more like an OS for containers and docker is a package manager.
having to deal with e.g. php-fpm, fcgi, tomcat, and unicorn separately in the same stack is a nightmare. even if they run in separate locations/clusters/nodes/machines, it's still several different configuration and deployment paradigms you have to deal with.

some people simply don't like containers or aren't tooled for it.

there's more than one way to do it (TMTOWTDI).

You would be able to merge your services under a single server and have them talk to each other internally sans latency overhead. It also allows you to easily scale up and down and segment things on demand.
It is in beta, but I hope this won't become a commerical-only product.
https://github.com/nginx/unit

It's open source at the moment at least and I think it's reasonable to expect at least that the parts that are open source today will remain so in the future. Certainly they could have a commercial version with extra features like they do with Nginx, but as long as they have a useful version of this Nginx Unit available open source I will be happy to use it.

So, it's an application server?
This looks pretty cool, and makes me sad that Mongrel2 never became popular. In short: Mongrel2 solves the same problem, but does it by letting your application handle requests and websocket connections over ZeroMQ instead of eg FastCGI.

I guess it lost momentum when ZeroMQ did. Anyone know why? Sounds like a dream solution in the current microservice hype.

http://mongrel2.org/

Mongrel2 was indeed a nice idea on paper.

It never had much momentum though -- but what it lost and killed it was Zed's interest.

Wait, zeromq lost momentum ? When did that happen ?
When was the last time you heard something about it?
I'm using it for a project now. It's a bit weird, but it does work. Cool thing: you can slot a file descriptor into the zmq provided poll ... point is that you can poll on both zmq and sockets in the one loop.

Pro Tip: Use 'cbor' for serialising.

> you can poll on both zmq and sockets in the one loop

Which is magnificent. The ZMQ poller is tons of fun. (Although I think this doesn't work on Windows.)

Thanks for the tip. In which language(s) do you use CBOR? I want to like it, but the various C APIs look a bit cumbersome and lacking docs.
When was the last time you heard something about zlib? At a certain point - libraries are basically done. They are widely distributed, everyone knows what they are, there is no reason to talk about them but they are still maintained and heavily used.
This morning when I used it.

I don't use zmq nearly has much.

Libraries can be done, but that has got nothing to do with momentum. Momentum depends on mindshare, on the willingness of people to use and to keep using it. Most programmers don't choose technology based purely on merits, they choose it based on "I heard X talk about Y and s/he said good things, so I guess I'll use it". We programmers aren't as rational as we think.
Like it or not, popularity and momentum are important merits of a technology. They lead to all sorts of benefits, like healthy maintenance and further development, better documentation, and support when you run into trouble. It is rational to consider these things when choosing technology.
Dunno, I spent close to a week trying to get it to compile with and without encryption on Windows to no avail.

Ended up using a Linux container on Docker to get the thing working.

That is troubling. I always thought of zeromq as having as good Windows support as anything not written exclusively for Windows.
So did I, that's why I selected it. Did my development on OSX and Linux and thought that deploying a static binary on Windows would be a breeze.

It wasn't, turned out to be a Class 4 hurricane :P

Looks like there is a path hardcoded in the build files causing problems. After some reflection on the msvc/README, renaming the project directory to libzmq (was: zeromq-4.2.2 from the release or libzmq-master from github zip download), and launching cmd.exe using the Developer Command Prompt for VS2015 link, libzmq/builds/msvc/build/build.bat successfully builds all configurations.
I think it happened in 2012 when this came out http://250bpm.com/blog:4

Before that, I used to hear people talking about it all the time.

Cool article! I guess that's why Go does its error handling without exceptions.
It has the same momentum, but too much mass and not enough velocity.
In which direction do you want it do move, if you want velocity that is.

I more often find platforms have too much velocity. And if not too little mass, then too little solidity.

When the main developer decided that it wasn't good enough and started working on nanomsg (http://nanomsg.org/)
zeromq is still very much in wide use. nanomsg doesn't have nearly as much documentation and community support as zeromq does.
I recently switched from zeromq to straight libuv sockets with jsonl (\n-separated json) payloads. Because I'm working inside a Node process, combining zmq's threading model with Node's threading model was a pain. Now, there's a single IO thread which is the same as the Javascript engine thread, and I can use uv_work to run CPU-intensive tasks on multiple cores.
Do you not allow \n inside your JSON or encode your JSON as base64? If not you might have problems with disambiguating frame ends from line breaks inside frames.

A common way for framing is to prepend each frame with it's encoded length. That's easier, faster and less error-prone than searching for ASCII delimeters.

If you do the JSON serialization yourself, there's no reason for newlines to be in the JSON. (Newlines within strings are encoded as \n.)
(comment deleted)
a newline is encoded as the two characters "\n" in json and would not be confused with a literal \n (aka \x0a) character
Erm...JSON allows whitespace last I checked. \n (ie the actual \x0a) is a whitespace character, and so can appear as a discarded token in JSON. So you would basically have to restrict to a subset of JSON -- it's not actually JSON anymore at that point.
I'm generating the JSON, either with custom C++ marshaling routines or with JSON.stringify which doesn't include newlines unless you give it extra arguments. I believe that any valid JSON can be converted to a single line by changing any '\n' bytes to ' '. Literal '\n' bytes are not allowed inside strings, and outside strings any whitespace is equivalent.
Unfortunately, the founder of ZeroMQ, Pieter Hintjens passed away (due to cancer) [1]. He was a regular on HN [2].

ZeroMQ still works great and the open source community is still maintaining it on GitHub [3]. I just think people are also looking at other technologies. A lot of interest popped up in things like Apache Kafka and Samsa. I still think ZeroMQ holds a unique place due to its lightweight and simple nature.

[1] https://news.ycombinator.com/item?id=11547212

[2] https://news.ycombinator.com/user?id=PieterH

[3] https://github.com/zeromq

Yes, I am aware that Peter had passed away. I thought that it was implied that the project is not maintained anymore, which is not true.
I have been curious how the community would hold up after Pieter's death. This project is a unique case because of how much work went into building community and welcoming contributions. That said, the world is a different place than in zeromq's heyday. Other commenters refer to Martin leaving the project, C++ regret, and a poor fit with node.js. Maybe in the face of all those changes zeromq's mature community is primarily why it lives as a project.
microservices on their face seem cool, but in reality not so much. really, it's just SOA taken to an unnecessary extreme.
It's really SOA without the XML based service bus.
Oh the "service bus" <strike>xml</strike> json is coming back... its called lambda architecture.

And again nothing new except someone else takes care of some server software for you with the promise of reduced price and maintenance but the reality eventually becomes tight proprietary coupling and eventual price gauging.

Amazon's own Lambda is that, yes. But the Lambda architecture it inspired is the opposite: a de-facto standard (based on the way Amazon's works, but probably eventually an open standard) for servers any org can use to stand up their own public or private FaaS cloud, which developers can deploy Lambda functions onto rather than having to build an entire container/VM just to slot it into OpenStack.
I doubt it will ever be a standard. Amazon loves vendor lock in. Plus most of the cloud services love to do their own thing for each service type. The main exception seems to be Kubernetes. Google has it in GCE, and Amazon has said they are working on their own Kubernetes service. If that happens, I bet Azure will follow if they aren't already working on it.
I (and others) are not so much imagining a standard between cloud vendors, as we're imagining a standard "FaaS server function API" (sort of like how the web has a standard DOM API) supported by several FOSS FaaS server implementations (sort of like how the web has several FOSS Javascript engines.)

Given such a standard API and compatible servers, you'd then deploy a FaaS server cluster to your public/private cloud of choice, the same way you deploy e.g. a Kubernetes cluster, or a Riak cluster.

There would likely by small public clouds attempting to be "FaaS native" by exposing only such servers in a multitenant configuration (like small public clouds like Hyper are currently doing with CaaS.) Their implementations wouldn't always be exactly compatible, and might have some lock-in.

However, once FaaS "caught on" with the enterprise, a FaaS server would likely make its way into the OpenStack architecture.

At that point, you'd see medium-sized public cloud providers like OVH and DigitalOcean set up their own multitenant FaaS clusters as well, probably with custom code, but built to be compatible with the OpenStack FaaS tooling, to allow enterprises the freedom to move FaaS functions freely between public and private clouds.

And, eventually, the other major cloud providers would feel the need to support the API.

---

This path has already been followed: it's what happened to Amazon S3—first cloned (but not compatibly) in FOSS by tools like Riak CS; then standardized by OpenStack Swift; then cloned compatibly in FOSS by tools like Minio; then picked up by medium-scale clouds like Rackspace; and then, eventually, picked up by Azure and GCP as secondary APIs to address their equivalent offerings (that originally had quite different APIs.)

You can definitely do microservices that way but in reality they tend to be more granular both functionality wise and density-wise.

With old skool SOA you'd typically have a monolith app with a bunch of endpoints. With microservices, especially in a containerized environment they tend to be more lightweight.

Microservices is just SOA rebranded for the cool kids. The fact that modern orchestration and tooling makes it easier to have more granular services changes the equation for how you factor the services, to be sure, but it's an evolution not a revolution.
That is a really cool idea, do you know of other projects like it?
Yeah, Mongrel2 looked like a good idea… but turns out it's kinda pointless. Why talk to your app via HTTP-reencoded-as-ZMQ when you can just talk straight up HTTP? Pretty much all languages have very fast and concurrent HTTP servers these days.
I thought it was because there's a lot about http that's overhead and/or tough to get right, which can then be delegated to the server.

Also, websockets actually map pretty badly to http, conceptually, and fit zeromq much better IMO.

Regarding websockets (admittedly off-topic re Mongrel though), I recently found out about Pushpin[0], which seems to be an elegant way to translate WS into HTTP, should it be of interest to someone. Basically a proxy-server that takes care of accepting either websockets or HTTP on the front, and talking only HTTP on the other side.

[0] http://pushpin.org

Pushpin uses Mongrel2 under the hood to handle incoming WebSocket connections, so not entirely off topic. :)

It's pulled in as a dependency and launched in the background.

I thought PushPin was based on Qt?
It's multi-process. The core logic is a Qt application, but it delegates the external protocol I/O to separate processes. Mongrel2 handles inbound and Zurl handles outbound (Zurl is a project of ours that is basically the inverse of Mongrel2).
Parts of mongrel2 were sadly a solution in search of a problem. Mostly the "let's redo FastCGI via ZMQ". Was still immensely fun working on and with it.
I'm having a hard time seeing what niche this fills. It seems to be both a process manager and TCP proxy. What am I missing here? What makes this better than, for example, using docker-compose?

I think a "how it works" or "design doc" would be really helpful.

That said, the source files do make for pleasant reading. The nginx team has always set a strong example for what good C programming looks like.

EDIT: Their blog post [0] makes this more clear... nginx unit is one of four parts in their new "nginx application platform" [1]

[0] https://www.nginx.com/blog/introducing-nginx-application-pla...

[1] https://www.nginx.com/products/

>What makes this better than, for example, using docker-compose?

Not having to use docker would be a huge plus for me.

yes, infinitely more lightweight. but docker compose and friends are cool
> It is not recommended to expose unsecure Unit API

why do people always use "not recommended" when they actually mean "do not ever do this or you'll end up the laughing stock in the tech press"

Exposing this otherwise awesome API to the public will amount to a free RCE for everybody. So not ever expose this to the public, not even behind some authentication.

It's very cool that by design it's only listening on a domain socket. Don't add a proxy in front of this.

Technically, you can expose the Unit API within an internal network.
Why that still might not be a good idea: https://research.google.com/pubs/pub43231.html
Thanks for linking that. Typically, if you know what you are doing, a setup of this nature would be segmented out from the rest of internal network.

I did compliance work for a lot of start-ups and never came across a company that understood this concept. The majority thinks that their wireless router is already doing this via the Guest account.

Technically, NOT RECOMMENDED is the same as SHOULD NOT in RFC2119 - i.e. "the full implications should be understood and the case carefully weighed before implementing any behavior described with this label". Not that this document uses those definitions, but.
> why do people always use "not recommended" when they actually mean "do not ever do this or you'll end up the laughing stock in the tech press"

For the same reason they say, "non-trivial" when they really mean "nearly impossibly difficult". :)

[honest question, not being negative] what real use-case is not already being addressed by existing technologies?
For almost every new product you see, the answer is: none.

It's not about making something impossible possible. It's about improving possible things in some dimension - like speed, safety, flexibility, or - in this case - standardization and integration with already used tool.

Great answer! I wondered about this myself for a moment :)
Honest question, not being snarky: when did the existence of other products handling the same use-cases ever stopped people from creating another?

For one, it's not just "handling a use-case" it's also _how_ you handle it. And within what ecosystem you handle it. And what kind of support etc you offer with it. Etc...

> Full support for Go, PHP, and Python;

Does it do WSGI then? Did they write the equivalent of mod_wsgi?

yes, from docs it appears the Python app type in Unit provides a WSGI host
I'm happy to see this. nginx itself is excellent software, I'll be happy to use similar tech for the application server as well (instead of uwsgi).

There are a couple of options I'd like to see added to the Python configuration though before I could try it:

- Ability to point it at a virtualenv.

- Ability to set environment variables for the application.

lol.. nginx en-masse configuration is a nightmare. i can point to a fortune 50 company that it's destroying for relying on it. I won't name names :)
Any pointers for those interested in the story who have no clue?
What does "en-masse configuration" even mean?
That they deployed a broken config file & forcefully stop-started nginx instead of reloading it (and bypassing nginx's built-in protection: it will test a config and refuse to load it if it's broken on reload. on restart it's stuck with whatever busted config you give it).
So they deployed a bad config file to all nodes and restarted the service, which then failed to start.

How is this specific to Nginx? This same mistake is possible with any other software ever written.

nginx is faster at stop/starting?
downvoters: I'm deadly serious. I've seen plenty of deployment systems which were unbearably slow because it gave more time for a human to spot a bad deploy and cancel it, and who were afraid to replace it with something faster because it would lack this safety net.
Is this like AWS Lambda you could put in your own cloud?
> Is this like AWS Lambda

No

> you could put in your own cloud?

Yes

This type of question is indication that NGINX Inc. salesmen did fail horribly to conceive of what the product actually is in layman engineering terms. Too much buzzword compliance.
Yup.

I came to the comments specifically to try to figure out what the heck this thing does.

The page itself never gets to the point of "Here's what it does".

The logo makes it as if it's read "N Unit", which is probably confusing as a popular unit testing with such name exists: http://nunit.org/
So, Nginx follows exactly the way of Apache HTTP: remember mod_php, mod_perl etc?
This is not Nginx, it's a separate project developed by the same company. You could put any frontend proxy in front of it.
I initially thought it would allow to dynamically handle upstreams list (and other configuration) like hipache is doing [1], which would be awesome for dokku or other container management systems which rely on system nginx. But after seeing languages mentioned, I'm confused.

Is it supposed to replace language specific servers, like unicorn and puma for rails (but then, I'm confused about what such kind of support would be for Go, since the server is directly embedded in the program)? Does it embeds interpreter for interpreted languages, like mod_* did for apache?

[1] https://github.com/hipache/hipache

Dynamic upstreams are available in nginx, but only in the enterprise/paid offering.
I didn't see this mentioned but is there any way to upgrade the versions of the modules such as Go and PHP indepedendently of the core Unit package?
How is it different from Envoy?
I came to ask the same question. The landing page is terrible it says pretty much nothing.
So is still standalone or do you still need to run this behind the regular Nginx, like you would a language-specific application server?
Sounds like uWSGI based on the description. I wonder how it'll play along with certain environments like Kubernetes.
Same. I really want to like (and use) uWSGI, for many reasons, but I find it's lacking severely in the department of documentation (searching "uwsgi" on Amazon gives zero hits!).

A properly edited book would be awesome. I would pay for it of course.

Yep. Somewhat tricky when you have 896 runtime options. That said, have been happy running uwsgi in production for a lot of python (and php) services.

Yelp.com runs behind uwsgi, and effectively all of the python services behind it do as well. Some use more uncommon features like gevent support.

> I really want to like (and use) uWSGI, for many reasons, but I find it's lacking severely in the department of documentation (searching "uwsgi" on Amazon gives zero hits!).

uWSGI definitely needs more concise tutorials on how to accomplish some tasks (e.g. creating Hello World with python and uWSGI, or how the uWSGI emperor works).

However I disagree with "lacking severely in the department of documentation"

Sure, it's not as easy as some other projects to dive into (e.g. Django) but IMHO the documentation is not lacking, it's just not forthcoming.

If you sit down and read through the uWSGI documentation, you'll discover a lot of very useful functionality and a reasonable description of how to utilise it.

What's lacking is the tl;dr way to bash something out quick and dirty.

https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.h... it seems very quick and straight to the point (yet complete, it even starts with apt-get)

https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html - has config snippets too

Or maybe you mean detailed step by step instructions, a'la howtoforge?

> Or maybe you mean detailed step by step instructions, a'la howtoforge?

Yes, this is what I meant when I said

> IMHO the documentation is not lacking, it's just not forthcoming.

I think their documentation is quite thorough. It's just as the other commenter indicated an app that extensible doesn't have cookie cutter simplistic configs out of the box.
It's perhaps thorough, but it's not particularly organized or edited.
>Same. I really want to like (and use) uWSGI, for many reasons, but I find it's lacking severely in the department of documentation (searching "uwsgi" on Amazon gives zero hits!).

Agreed. After recently testing out Python for a web dev project I was really dismayed at the fragmentation and lack of usability in the landscape of application servers. Here's hoping this might lead to some standardization.

Whoa. How did I never notice that uWSGI grew up beyond just WSGI!
More like a replacement for any wsgi server.