At work, we use Python 2.7 for all our micro-services. Most of our services have very little business logic but enough not to use all ready made plug n play framework. So mostly it's REST/CRUD for our front end react dashboard. So we use:
Python 2.7
- ha proxy to round robin the calls between servers and services.
- nginx on each server to parse and call uwsgi
- uwsgi to handle multi processes ( of course our code is not thread safe) - 2 processes per cpu, 1 thread per process.
- pyramid to route the calls internally SQL alchemy to plug with MySQL server.
- elastic search
- couchbase
- spring Python for dependency injection
- a bunch of home made wrapper to bind all this and make it usable.
- json everywhere
We also have workers and rpc plugged with rabbitmq.
As I said, most of the job for the server is to: parse request/ json, do a sql or elastic search query, format for the front, and respond. So lot of slow IO when performing the request. Now we have more and more inter-services call and we use either http calls or rmq-rpc with rabbitmq. We designed a wrapper to call our routes so they can be called in http or rmq-rpc without any difference.
Having a c# / go background, I am used to having efficient webservers that can handle async without many problems, and that can scale even though we do a lot of IO requests during an http call. But using uwsgi makes this almost impossible, and because each time we call MySQL through sql-alchemy it blocks the entire thread/process, we can't scale that much, we just add more servers. We could add more processes per cpu, but that feels wrong and just delaying the pb and we might run into memory issues (we have local caches to make things faster.)
So I read about async stuff in python, gevent, tornado, twisted, etc and that looked great but didnt seem to work well with sql alchemy. Stuff about flask, Django. But we don't need fancy complicated web frameworks, just simple http routing.
The stack is 3 years old and we can't change everything. The goods news, we have a very loose coupling to uwsgi and pyramid, but spring Python and SQL alchemy are very very tightly coupled. We can find a way to make our routes thread safes.
So my question is, given all I said, what stack would you recommend, with those hard constraints?
- http - rpc should be handled the same.
- rpc doesn't have to go through rabbitmq.
- json ( we can't move to protobuf for instance). most of our routes are just wrappers around calls to a "database"( sql or elastic or couchbase), so we are mostly IO bound.
- we have lot of legacy code , so no starting from scratch
I am planning to test around some ideas, but if you could point me in the right direction, that might save me a lot of time.
BONUS: If you had to start from scratch, what would you use? (still using python 2.7 and sql alchemy)
Thx for your help.
DISCLAIMER: I know this is some kind of open-ended question, but the last questions about the subject on stack are at least 3 years old. I posted the same question on reddit without luck.