Amazon EC2 ELB directing load to other instances and session stores - session

If we scale up (add an instance to ELB), could we redirect some existing requests to the new instance. So that, The users that we force to a new server will be asked to login again
If we scale down (remove an instance from ELB), then all users from that server will automatically be redirected by ELB to other remaining servers. These user should not be aked to login again.
Is this possible (including the redirect of request)? How?
Any ideas are welcome but I presume this can be solved using a central session store. I just don't know how to implement it .
And what are the options in using a central session store? simpledb? redis? memcached?
Our application is just a simple web application hosted in apache. We have two instances of it added unto the Amazon ELB, and we are using PHP.
Any ELB php specific suggestions? when a scale down/up happens that no user-visible symptomps should be shown?

For the most part, this should be completely transparent to your end users without many changes on your end.
The biggest aspect to look at on your side will be ensuring that sessions are persisted / available through the addition / removal of instances.
You can do this by setting a cookie on the client (default behavior in session_start() and ensuring all of your web servers with PHP have the facility to obtain information about the session id.
Some people will use memcached to do this ... and there is native integration in PHP for sessions to be stored in memcached ...

There are quite a bunch of ways to have a centralized session management. Some of them are listed below:
DB:
http://ocklin.org/session_management_cluster.html
Memcache:
http://www.migrate2cloud.com/blog/how-to-configure-memcached-on-aws-ec2-a-starters-guide (make sure the hosts are able to connect without any problem),
http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/
http://php.net/manual/en/memcached.sessions.php
Msession:
http://in.php.net/manual/en/ref.msession.php

Related

Shared http session lifetime

We have several web applications using the same identity provider (which we also manage), most of them (including identity provider) are using .NET core.
Requirement is that if user is logged in in two or more applications at the same time (in one browser), and is actively using one app, it automatically extends the session lifetime in all of the applications.
So while he's using at least one application, he doesn't get logged out of neither of them. Which is another requirement: auto-logout after certain time of inactivity (this part is easy of course)
I thought of using Redis server to manage this shared session lifetime, using SessionId that each app would receive from identity server via claims. So each time user does some action, backend contacts Redis and check if user's session is still active and extend the session lifetime if it is. Logout user if it's not.
Problem is, applications are not allowed to access this Redis server directly (security reasons). So I thought of adding a separate web service for these apps to contact using standard HTTP endpoint. So basically just a middleman between Redis and web app.
Is there any better way to do it? Not sure how common of a requirement is this.
Redis usually belongs in the Distributed cache, which means that it is located on another server farm. Therefore, your application has restrictions because it is not allowed to access an external server.
If your application is under development or if it is still in the growth phase my recommendation is to use InMemory cache or consider response caching middleware.
Also, these are very small amounts of data, and if you are going to store only that in the cache for a start you would definitely consider InMemory.
Of course, I understand your need for a Redis and that is it:
Is coherent (consistent) across requests to multiple servers.
Survives server restarts and app deployments. And that's because
your cache is usually in a different location (e.g. Azure)
Doesn't use local memory.
Is scalable
etc.
For larger applications Consider replacing InMemory cache with the Distributed memory cache. It is mostly similar to the InMemory cache because both the InMemory and the Distributed cache are located on the server farm where the application was run. Only the InMemory cache requires a sticky session, and the Distributed memory cache does not.

WildFly 10 HA deploy: not losing sessions

I have been reading posts and documentation all day long about that topic, and still can't find something easy to understand and trust on.
I currently have my webapp deployed on WildFly 10, as a simple war file.
It's an e-commerce website, in production for a few weeks, and every time we need to deploy a new release, well... that's very annoying, because some customers could be shopping right now, and deployment will obviously make them lose their sessions, and that's very bad.
I need a solution to deploy a new war without restarting the application server. At first, I read the docs about clustering (domain configuration over standalone configuration), but I'm not sure that's enough for me...
Imagine the same customer with a few items in the shopping cart (http session), accessing the first node of the cluster.
Then I put it down, because I'm deploying.
OK, the customer will be redirected to the second node of the cluster but... will the session data still be available? Will he 'lose' the shopping cart items?
I read about sticky sessions, but nothing about configuring them in WildFly. I am on Amazon AWS, so I can use ELB (load balancer), too.
Can you help me understand exactly what I need to learn and use?
Each WildFly instance will have it's own session id that it keeps in the cookie. This id will only restore the session on the particular node it came from.
Sticky sessions mean that the ELB will always redirect the user to the same node in your cluster so that won't quite solve your problem.
Some things to think about:
Clustering
Clustering may help (doesn't need to be domain mode). With HA enabled, the session will be transferred between the nodes automatically so that cookie on the clients browser will be able to restore the session on either node. This of course has the issue where if you upgrade one of the war files first you may have an object that can no longer be de-serialized because it changed.
Clustering WF on AWS is a little tricky as well because you can't use UDP broadcast to discover each other. We use a database connection to keep track of nodes and do clustering.
Roll your own
One option you could do is to roll your own solution to keep just the minimum amount of information on the client as required. Something like:
create a record in the database with a GUID.
set the GUID to a cookie
Save the items in their cart in the database based on the GUID
have a filter that checks for the GUID cookie and can restore their cart each time they hit the site.
I've used an approach like this for e-commerce apps in the past. It has another side effect that you now have the person's shopping cart saved in your database and it's easy to see exactly what people were interested in buying.
Use Tomcat parallel deployment
Does your application require a full app server? If it is just servlet based you could try using Tomcat and it's parallel deployment functionality. It allows you to deploy your new .war file on top of your old one. It will then keep serving old sessions to the old war but new sessions will go to the new war file.
Parallel deployment is very cool if your app is simple enough to be able to use tomcat.

How does Ofbiz handle sessions?

Sorry for any silly question but I am just about to learn about the web.
I have an application (called OFBench) that uses the Selenium library to simulate user browsing behavior of website. The web site is built on the Ofbiz template (nothing more added). I have 2 EC2 servers on Amazon Web Service that running the ofbiz website template and one client on my laptop generating workload (simulating users on website) for the 2 servers. The browser instance used is firefox.
The 2 servers are sit behind a Elastic Load balancer (ELB) and the ELB is configured with application based session stickiness. When the application simulated a login and then do a "Home" request (clicking the home link on the website) the login state is gone which causes following requests fail. Looks like the ofbiz website does not has session cookie. I am not sure where the problem is, but I need to know how session is handled in ofbiz ? Where does it stored ?
I observed that when I open the home page of the ofbiz website there is a session created (reported by server: xxxxxxx.jvm1 generated) and sessions are generated quite often. Not sure why it is the case. I though only when you login or putting stuff in shopping basket should the session being created.
Thank you very much for answering my question !
Just for the benefits of anyone who having the similar problem. When setting up application based session stickiness with ELB you need to give the name of session that actually generated by your web application, in my case, I saw that there are two kinds of session (JSESSIONID, Ofbiz,Visitor) I used JSESSIONID as session cookieName in ELB and the login state is maintained. Please do correct me if there is anything that might goes wrong. Or anything that I did is happen to work. Many thanks

Does Varnish Handle User Web Sessions

I've had 2 sysadmins from 2 large hosting organizations tell me that Varnish will handle session sharing between web servers. I can find nothing online to support this and in fact found this where the guy specifically says it does not. I cannot tell if the guy is a Varnish employee or just a contributor or what.
Just looking for more verification on this point.
A session allows you to store many things (shopping carts, logged in user, etc), and is commonly identified by a cookie (e.g. sessionid). A web server knows how to get a session using this sessionid (and can access/update your shopping cart), but varnish only handles cookies. Varnish can do load-balanced lookups to backends, regardless of the cookie values or based on some rules (you need to write you own varnish config).
However, a challenge in session sharing between web servers is whether a web server can access sessions created/updated by another web server. In many Java Web Containers, sessions are by default stored in memory (of only one web server), with load balancers implementing some kind of 'sticky session' mechanism (sending a user with a session to a specific back-end all the time, can be easily setup with varnish). Another option is to store the (serialized) session values in a shared database, so they can be retrieved by any backend (and will keep working if a web server goes down). A third option is to completely serialize the session into a cookie and stop using sessionids, but this is complex (limited size, bandwidth, security requires some signing mechanism, but scaling is great).
All approaches have advantages and disadvantages. You have to choose, varnish supports any option but will not 'automagically' do what you want, so prepare to write a bit of varnish configuration...
If you would describe how you want to load balance, or what you try to achieve, you could get a more specific answer.

Will an out of proc session survive a windows azure VIP swap?

If I'm hosting a site in windows azure with an out of proc session provider and perform a VIP swap, will the session persist through the VIP swap since the session is being provided out of process?
I will come back and answer the question after I perform a test but I'm pretty sure someone will have the answer here asap and azure deployments take a while.
I see no reason why it shouldn't work.
It should be no different than hitting different instances that are part of the same deploy.
If you use the Azure Cache for your session, it should not. The browser is using the same domain, so the same cookie would be sent, and a VIP swap does not affect the cache server.
If you are not using Azure Cache for session I recommend it, they even have a NuGet package.

Resources