I'm migrating my current application to multi-tenant setup.
Now I've multiple rabbitmq workers to process async job, publish and consume integration events, and other stuffs. I'm planning to use vhosts in RMQ (1 vhost per tenant per service).
Right now, I'm still not convinced about what approach to take to implement this multi tenancy setup. Here're the options that I've:
One docker container per tenant (which runs 1 consumer process) -> This sounds overkill to me. Also, I've to figure out, how to read active_tenants from a central tenant config service to spawn containers dynamically, in docker-compose.
Use multiprocessing module in Python to spawn one worker process each for one tenant. I've tried this out, and have one process fork dynamically multiple tenant process. I'm confused about monitoring stuff here. Also, to be able to handle signals for each tenant process (so that we can track & restart individual tenant process on failure), is there some standard approach? Like some fixed set of signals to worry about? Should I even do it manually, or let something like supervisor to take care of that?
Use supervisord inside docker to manage multiple tenant processes. But this will require pre-configured supervisor config. Can't read active tenant_id from a central tenant service probably?
Now out of these options, what really should be most robust approach? We don't really have that much scale issue. Ours is subscription based tenant model. Number of tenants probably is not going to be more than 15 or 20 in near future.
I'm also worried about lots of processes now being spawned per service, which also increases are server load requirement.
Another approach which I don't think I should take is multi-threading approach. Is it a good idea to have long running thread for each tenant under a process. Well, of course, given it's Python, it won't really scale well.
Also, is there already something available to have my rabbitmq workers spawn multiple workers for given set of connection string? I didn't find any in last 3-5 days.
Language and Frameworks used currently:- Python, Flask, Kombu (for RMQ), Postgres. And, Docker for containerization.
Let me also explain our current deployment approach, as it could it relevant in getting optimal solution:
- Every app has defined their
Dockerfile
with their repository. - When CI/CD kicks in, jenkins builds the docker images for the app, and pushes it to docker hub.
- We've environment specific
docker-compose
files (This possibly could be merged) - We are storing build_env (required to inject variables in docker compose), separately, and pass that to production machines, in order to run
docker-compose
- With this, jenkins now connects to prod machines, copies the deployment related files as tar archive to machine, and then runs
docker-compose
command on the machine.