How can I do this? How do I prevent instances of the same app from being started in the same region? I am less concerned about tying each instance to a particular region and more with ensuring two instances of a given app don’t share a region…
When you add multiple regions, we spread instances out as much as possible. If you add, say, 5 regions and then run 4 instances, you should always get one per region on a deploy.
You can get really tight control over regions by adding volumes, if you need to. That would prevent a second instance from ever running in the same region.
Excellent! I’ll make sure I have more regions added than running instances.
I’m so pleased that everything is working out and I found my new app hosting platform!
Hey, has there been any movement on either session or IP affinity since this post? I’m considering some changes to one of my apps and some kind of request affinity would really help. I often run more app instances than there are regions (often 25 or 30 containers) so regional affinity wouldn’t work for me.
No worries if no work has been done here yet! It’s useful to know either way so I can change my approach as necessary.
Thanks!
We haven’t done anything here yet! You can likely do this yourself with two apps:
- Haproxy or nginx with session affinity configured
- App instances listening on 6pn
Haproxy makes it very easy to configure load balancing across <region>.<appname>.internal
, we use this for our postgres clusters: postgres-ha/haproxy.cfg at main · fly-apps/postgres-ha · GitHub
--max-per-region
is a neat command shared with me for future readers.
Full command looks like fly scale count 6 --max-per-region 1
Sorry to bring up an old thread, but I was wondering whether any further work had been done to enable Session Affinity within Fly? I’m sure a number of your customers (including me!) would find this particularly useful. Even a “soft” implementation would be of great help (not guaranteed, but highly likely). Thanks!
(cc @kurt)
Kurt has previously written about achieving “sticky sessions” with Nginx’s hash-based load balancing here: The 5-hour CDN · The Fly Blog
I’m running into the same need. I tried the 1 machine per region approach, but requests are being load balanced across different regions, even when I use a VPN to put myself very close to a specific region. Any ideas?
Sorry for the lame reply, but same here. It would be super handy to add a
handlers = http, sticky
to do this without private network nginx setup.
would also love this feature for session affinity, we would be able to launch some features much sooner if it were available (and speed of building is why we love using fly!)
Any useful materials around this need? I’m also considering setting up private load balancer between my machines but I have no idea where to start.
Something that is not in the docs but what I could figure out searching this forum:
You can use the request header fly-force-instance-id
to make the router pick a specific instance (even though load balancing would suggest another?).
This has the caveat that if the instance doesn’t respond the router doesn’t bother further and the request will just be dropped. And it needs to be a http-based / websocket protocol for the router to look at the headers in the first place.
But with this it should be easy to let a web-frontend hold a session with a process running on a specific machine.
Seems this wasn’t mentioned before (and I surely didn’t find it) but it’s in the docs: Session Affinity (a.k.a. Sticky Sessions) · Fly Docs
Fwiw, here’s a simple sticky handler in Golang: Go fly.io sticky session handler · GitHub
@andig Can I have your permission to add that example to the blueprint?
Yes, sure
One thing I’m not sure about and that isn’t mentioned in the docs is how a non-existing machine is handled:
If the cookie does not match the environment variable, then a response containing a Fly-Replay header is created. This will cause the Fly.io proxy to replay the request to the desired machine.
What happens if I fly-replay
to redirect to the sticky machine but that machine does no longer exist? It would be helpful if the Fly proxy was able to add a cookie that shows that to allow client application to start a new session. Maybe something like fly-replay: invalid
or similar?
@rubys would you know what happens/ how to handle this situation?
There are people looking into making the proxy more useful - I’m focused on frameworks and deployments; but I also happen to be a user of fly.io.
If the machine is merely stopped, the proxy will restart the machine and then route the request to it.
If the machine no longer exists, the request will fail after about a minute. If your application knows that the machine is no longer there, it can delete or reset the cookie rather than replying with a Fly-Replay response header.
There are people looking into making the proxy more useful
@rubys that’s great to know! It would be nice if it were possible to join the discussion if there’s a public thread?
If the machine no longer exists, the request will fail after about a minute.
Thought so. At this time unfortunately, a (web) client would continue sending the outdated header.
If your application knows that the machine is no longer there, it can delete or reset the cookie rather than replying with a Fly-Replay response header.
Thats an option but it does imho limit the purpose of fly-replay
. If I need to track internal services (Consul…) I can just as well talk to the required backend service directly. The nice part of fly-replay
is that the proxy already knows which machines are available (assumption). It would be nice- using the current approach- if we could instruct it which header to clean if the target machine is gone. Something like:
fly-replay: <past-machine-id>
fly-replay-clear: fly-machine-id # your header name here