Session management using InProc in azure roles is dangerous
thing!!!
Why
InProc is dangerous?
Create an azure cloud service project and add a web role in
it. Then I added a sample page named as Session demo in it. To test the session
data saving and retrieval I added following control in the <form> control
present on the page –
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="btnAddToSession" runat="server" OnClick="btnAddToSession_Click" Text="Add To Session!!" />
<br />
<br />
<asp:Button ID="btnReadFromSession" runat="server" OnClick="btnReadFromSession_Click" Text="Read From Session!!" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<br />
<br />
<asp:Label ID="lblInstanceId" runat="server" Text="Label"></asp:Label>
On the code behind I added below simple code to add values in session
and retrieve it. Also in page load event I am retrieving the id of role
instance to check that, my current request is being served from which instance.
public partial class SessionDemo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
lblInstanceId.Text = "You are being served from - "+ RoleEnvironment.CurrentRoleInstance.Id;
}
protected void btnAddToSession_Click(object sender, EventArgs e)
{
Session["MySession"] =
TextBox1.Text;
}
protected void btnReadFromSession_Click(object sender, EventArgs e)
{
if (Session["MySession"] != null)
Label1.Text = Session["MySession"].ToString();
}
}
In web.config file as shown below, I have configured my
session state as InProc under <system.web> tag –
<sessionState mode="InProc"/>
Now right click on cloud Service project, select Properties and set the application to
run in full emulator and full IIS as shown below -
Note – The
option to run the cloud service project locally in Full Emulator mode is
applicable till the Azure SDK 2.3 only. In Azure SDK 2.4, full emulator is
deprecated. I don’t know the reason why they have deprecated full emulator mode
in Azure SDK 2.4.
Now we always should set the number of instances for an azure
role as minimum of 2. Therefore right click on web role node present in cloud
service project and in properties set the instance count as 2.
We all set to see how InProc session management in Azure web
role is devil. Set the cloud service project as startup project and I have set
the Sessiondemo.aspx page as startup page and here I click F5. And here what I
see on my page and in my IIS –
So as you can see, in IIS there are two instances got created
as expected and below that the UI shows simple design to test sessions. Also if
you see in IE, my current request is being server from INSTACE 0.
Now let’s say I add the value to session as “kunal” by
clicking on button “Add to Session”
and retrieve it from session by clicking on button “Read from Session” and I found that, my requests are still getting
served from INSTACE 0 and session value is being retrieved correctly. Now I
right click on instance 0 website in IIS and then I select the options as Manage Web Site | Stop. This actually
stops the 0th instance running in IIs. Remember, my project is still
running in debug mode. I just stopped one of the role instances of my azure
application.
Once the IIS website is stopped you can view the black icon on
the web site as shown. This confirms that my website is stopped.
Now I refresh my browser 2-3 times. This means now my request
will start getting served from INSTANCE
1 of IIS website because instance 0 is stopped and here is what I see –
As you can see above, my request is being served from INSTACE 1 and my Session value is not retrieved
on refresh. Therefore I click on button “Read
from session” again and DAMN!!!
I am not
receiving the value “kunal” that I had added in my session. This is the problem!!! Ideally I should
have received my session values irrespective from which instance of role my
request is getting served.
In Azure environment there is always possibility that, the
instance of role gets recycled due to hardware failures or other errors. Means
if you configure only 1 instance for your role then there is possibility that,
your role instance is down and you DON”T GET HIGH AVAILABILITY for your
application. Therefore it is always BEST PRACTICE TO HAVE ATLEAST 2 INSTANCE
for your azure role.
But
again, if you have 2 instance configured for your web role then session
management using INPROC will not work as shown above!!!
What is
the Solution?
You
should always store the session state outside your role environment. How do I
do that?