When a web backend does more than simply reply to requests, how should my application be structured?
My first thought is that you could use a service oriented architecture to separate these tasks.  Each of these services could run a Flask app on a separate port (or machine (or pool of machines)) and communicate to each other using simple HTTP.  The breakdown might go something like this:

GameService: Handles incoming connections from players and communicates with them through socketio.
GameFinderService: Accepts POST requests from GameService to start looking for games for player X.  Accepts GET requests from GameService to get the next best game for playerX.  You could use Redis as a backing store for this short-lived queue of games per connected player that gets updated each time GameStatusService (below) notifies us of a change.
GameStatusService: Monitors in-progress games via UDP and when a notable event occurs e.g. new game created, player disconnects, etc it notifies GameFinderService of the change.  GameFinderService would then update its queues appropriately for each connected player.

Redis is really nice because it serves as a data structure store that allows you to maintain both short and long lived data structures such as queues without too much overhead.
I'm creating a website that allows players to queue to find similarly skilled players for a multiplayer video game. Simple web backends only modify a database and create a response using a template, but in addition to that, my backend has to:

Communicate with players in real-time (via gevent-socketio) while they queue or play
Run calculations in the background to find balanced games, slowly compromising game quality as waiting time grows (and inform players via SocketIO when a game has been found)
Monitor in progress games via a UDP socket (and if a player disconnects, ask the queue for a substitute) and eventually update the database with the results

I know how I would do these things individually, but I'm wondering how I should separate these components and let them communicate. I imagine that my web framework (Flask) shouldn't be very involved at all in these other things.
Since I already must use gevent, I'm currently planning to start separate greenlets for each of these tasks. This will work for all my tasks (with the possible exception of the calculations) because they will usually be waiting for something to happen. However, this won't scale at all because I can't run more Flask instances. Everything would be dependent on the greenlets running in just a single thread.
So is this the best way? Is there another way to handle separating these tasks (especially with languages I might use in the future that don't have coroutines)? I've heard of RabbitMQ/ZeroMQ and Celery and other such tools, but I wasn't sure how and whether to use them to solve this problem.