Trying to dig into session management, load balanc...
# adobe
j
Trying to dig into session management, load balancing and CF (2021). Currently we have two boxes, using NGINX as a LB and using IP Hash so for the most part the majority of traffic hits one box... This was probably setup years ago but now our IT dept would like to setup something more robust like round robin and persist user sessions if one of the boxes goes down (fwiw this is more about disaster recovery than actual load issues) I'm looking at Redis... Can I simply setup a Redis box, point both boxes there (we're not using J2EE sessions) and switch to something like round robin? The docs mention using CF clustering as well and I'm unclear if that is required or just another option.
m
You're not gonna be at CFCamp by chance are ya? @carehart is giving a talk on exactly this subject I believe.
d
Pointing session storage in CFIDE at Redis has worked fine for us in cf2021 - runnning cf in containers on AWS Fargate behind an AWS load balancer with AWS elaticache (Redis). No special setup needed and we don’t use sticky sessions. We never had much luck with CF clustering but that was pre AWS. So in answer to your question adding a redis endpoint and pointing CF at it works well for session management but will depend on what you use to load balance the servers with.
j
@Mark Takata (Adobe) Unfortunately no - I was searching around and just saw Charlies post about CFCamp 🙂 @dougcain Thanks for the info - I'm going to spin up a Redis instance in our dev docker environment and tinker with this...
c
Yep, Jim. It's trivial to setup, especially in cf. (In Lucee, there are a couple of options and then a couple of steps, but also simple.) And yep, this will persist sessions over cf/lucee restarts. And no, no need of cf clustering at all (but it would work fine if used with it, instead of the older session replication feature, which has caused trouble for many over the years). And as Doug said, you can point more than one cf instance at the same redis db and share sessions that way. Finally yep, docker is one way to run redis. There are redis installers for Linux and Mac, and used to be for windows but no longer. Wsl or docker can suffice. Or there are also free and paid redis services, avoiding installing anything. (And FWIW, redis itself can be setup with clustering and/or replication for greater reliability.) And I've confirmed it works fine (in cf and lucee) with alternatives like valkey, memurai, dragonfly, etc. I'll address these things above and more in my talk (yep, in 45 mins), and perhaps in some posts beforehand (allowing me to spend less time on details in the talk). Let us know how it goes for you. It's because so few know about or use it that I've wanted to do this talk (and more).
👍 1
j
Thanks @carehart! I discovered our docker setup for our dev environment (which is huge) actually has Redis setup! So I just tweaked my cfconfig to use Redis, supplied the correct port and it seems to work.... App fires up and if I stop the Redis container I get an error. Need to read the Redis docs next and play around with Redis Insight to see what's actually going on under the hood. Then I'll tinker with out load balancer and see about spinning up another CF instance and go from there...
r
If using Redis for session storage how to complex variables such as objects/queries etc get stored, or do they get strored?
c
Good to hear, but really, there's not much more you need to "know". It flat just "works". (That said, with CF you do need to restart the instance for it to start using redis for the sessions. With Lucee, it starts working as soon as it's enabled in its admin.) And sure, there are tools like RedisInsight (and others) which can be valuable, and I'll also mention them in my talk (and/or blog posts). It can be helpful to see what the data (use the feature in the RedisInsight browser to show the data as java serialized), as well as to watch the performance of redis
Ryan, it can handle complex objects, as those are serialized by CF
r
Im gona try implement this. We have 4 servers load balancing 2 applications and always assumed you needed enterprise to 'cluster' the sessions
well. 2 servers per application
c
yep, you needed enterprise to use CF's clustering feature (though not to use any other clustering of CF), and to leverage the CF cluster feature's session replication. This redis sessions feature alleviates that. And of course it works with CF Standard or Enterprise (or trial or developer). Note also that you do need to NOT use CF's "j2ee sessions" feature (which the CF enterprise clustering session replication feature required), but traditional CF (non-j2ee) sessions can be configured to be as "secure" as J2EE sessions (something I have long been meaning to blog on, and plan to do before the talk).
👌 1
j
Oh snap - the "Java serialized" switch was the magic I was missing!
c
yep, it's sweet. For those wondering, when using RedisInsight and its "browser" feature to view redis db data, by default it shows up as rather useless junk ("��sr3coldfusion.runtime.session.external.SessionMetadat..."). But in the top right of that UI there is a dropdown with options, one of which is "java serialized", and on choosing that, the values are then easily readable (as JSON): "{ "fields": [ { "lastAccess...", which are also formatted nicely if you click on the data :-)
☝️ 1
One more thing for those who may start exploring this redis sessions feature for the first time (or tried it and had "problems'): I just wrote a blog post offering a workaround for a problem that some may experience (with CF2021 or 2023, not 2018 or 2016), where you may find that CF will be sending far more requests to Redis than are to be expected (many per session, per second!). This can be painfuli and/or costly. Thankfully it's easily worked around. I'd been meaning to do this post, and I'd started writing it as a comment here but decided to use it as the basis of the blog post, now posted: https://www.carehart.org/blog/2024/5/28/workaround_for_seeming_CF_Redis_sessions_bug
m
Thanks Charlie. And if you could please post the link to that ticket here when you create it in their tracker, that would be appreciated so we can vote on and follow it.
d
One other thing of note for CF redis sessions, tripped my dev stack up a few times, if CF is set to use redis for sessions and redis is not there for some reason cf fails to start with a non obvious error (I forget what it actually says now) but one to keep in mind.
1
c
and @dougcain, yep good point. I was going to cover the in the talk. It used to be that CF would not start, but that was "fixed" in an update...for better or worse. CF will still start, but requests using sessions will get an error:
Cannot invoke "coldfusion.runtime.session.SessionStorage.sessionExists(String, String)" because "coldfusion.runtime.SessionTracker.sessionStorage" is null
That's bad, of course. And FWIW, Lucee quietly ignores the error (and doesn’t use/store sessions in redis)...
And what if the redis server goes down while CF or Lucee is running? Again, as for CF users on any request using sessions users will get this error:
redis.clients.jedis.exceptions.JedisConnectionException: Failed to connect to any host resolved for DNS name
Again, Lucee quietly ignores the error and soldiers on without Redis...for better or worse. I do prefer it failing gracefully versus so badly as CF...though of course one might then not realize there's no session tracking going on and might restart Lucee, trusting the restoring of session from redis will work, when it will not. 😞
Of course, one might HOPE that anything that brought a redis instance down would be rectified in time...but not everyone will have that luxury. But hey, this sort of problem is just as bad if a db goes down...at least for requests that try to talk to that db. 🙂
m
What was really fun (and a learning opportunity for me) was using a serverless Redis product testing my local machine. Set it up to use all Redis for sessions. Funny thing... if it goes to find the Redis cache and it... isn't there (for example if it is still desperately trying to spin up) it used to absolutely *bleep*house your install.
c
fun times 🙂
1
j
Been reading Redis docs and it seems like Redis Sentinel may be a solution for what happens if your Redis box goes down. It can do notifications and failover...
Copy code
<https://redis.io/docs/latest/operate/oss_and_stack/management/sentinel/>
c
Yep, Jim. That's among the means I was thinking of when I referred to how the redis downtime might be minimized/rectified in time. Another is if it's running in k8s or the like, with health checks to spin up a new instance when needed. And as I'd mentioned in the post, redis itself can be clustered or setup for replication. It's just another animal in the zoo needing care and feeding, which may be someone else's job or could fall to us :-) And of course, what doesn't kill us makes us stronger.