We have 2 core applications running on our servers on CF 8, and both have the exact same session timeout set in the application CFC (2 hours at the moment). However we're seeing that sessions are spiralling out of control for one of the applications (currently at 120,000+ on one server), lets call it AppA whereas AppB seems fine (and AppB is the one we'd expect a lot more traffic to).
So I did some further digging and found out that most of the sessions for AppA have been idle for many hours with the highest value I've seen so far being over 11 hours.
We're not actually doing that much with sessions so I'm a little confused as to why they're not being timed out as expected. Also I've dumped the this scope in the application CFC and it is showing the expected value for sessionTimeout.
The only thing I had noticed is that in one instance we're assigning a variable on the Request scope from a Session variable. If it were a different scope I would maybe think that is causing some sort of reference that GC (or whatever) can't clear.
In terms of the spiral, I'd say that's to do with some requests which aren't passing through the CFID/CFTOKEN to maintain the session. This could be web service calls, CFHTTP requests, search engine bots, etc. Sounds like one of your apps is experiencing this. If this is the case then for CFHTTP pass the CFID/CFTOKEN through to maintain sessions. Web services bit more tricky, you'll need to create a 'key' which is passed back and forth, whole separate topic! Bots can be handled by having some conditionals to set the session timeout value.
For the 11 hours, I'd say thats due to it been kept alive by something. Some continual polling? Reocurring AJAX request? It would have to be something that continues to pass the ID/TOKEN through.
I used to get server lockups in CF6.1 when I was persisting CFCs in the application or session scopes. Now I instantiate them in the request scope and the lockups stopped happening (with no noticeable performance drop). Maybe you have a similar issue.
Actually turns out the sessions were started from another App which wasn't over-riding the default value in the base Application.cfc (including the application name).
Related
Does Spring Session management take care of asynchronous calls?
Say that we have multiple controllers and each one is reading/writing different session attributes. Will there be a concurrency issue as the session object is entirely written/read to/from external servers and not the attributes alone?
We are facing such an issue that the attributes set from a controller are not present in the next read... this is an intermittent issue depending on the execution of other controllers in parallel.
When we use the session object from the container we never faced this issue... assuming that it is a direct attribute set/get happening right on to the session object in the memory.
The general use case for the session is storing some user specific data. If I am understanding your context correctly, your issue describes the scenario in which a user, while for example being authenticated from two devices (for example a PC and a phone - hence withing the bounds of the same session) is hitting your backend with requests so fast you face concurrency issues around reading and writing the session data.
This is not a common (and IMHO reasonable) scenario for the session, so projects such as spring-data-redis or spring-data-gemfire won't support it out of the box.
The good news is that spring-session was built with flexibility in mind, so you could of course achieve what you want. You could implement your own version of SessionRepository and manually synchronize (for example via Redis distributed locks) the relevant methods. But, before doing that, check your design and make sure you are using session for the right data storage job.
This question is very similar in nature to your last question. And, you should read my answer to that question before reading my response/comments here.
The previous answer (and insight) posted by the anonymous user is fairly accurate.
Anytime you have a highly concurrent (Web) application/environment where many different, simultaneous HTTP requests are coming in, accessing the same HTTP session, there is always a possibility for lost updates caused by race conditions between competing concurrent HTTP requests. This is due to the very nature of a Servlet container (e.g. Apache Tomcat, or Eclipse Jetty) since each HTTP request is processed by, and in, a separate Thread.
Not only does the HTTP session object provided by the Servlet container need to be Thread-safe, but so too do all the application domain objects that your Web application puts into the HTTP session. So, be mindful of this.
In addition, most HTTP session implementations, such as Apache Tomcat's, or even Spring Session's session implementations backed by different session management providers (e.g. Spring Session Data Redis, or Spring Session Data GemFire) make extensive use of "deltas" to send only the changes (or differences) to the Session state, there by minimizing the chance of lost updates due to race conditions.
For instance, if the HTTP session currently has an attribute key/value of 1/A and HTTP request 1 (processed by Thread 1) reads the HTTP session (with only 1/A) and adds an attribute 2/B, while another concurrent HTTP request 2 (processed by Thread 2) reads the same HTTP session, by session ID (seeing the same initial session state with 1/A), and now wants to add 3/C, then as Web application developers, we expect the end result and HTTP session state to be, after request 1 & 2 in Threads 1 & 2 complete, to include attributes: [1/A, 2/B, 3/C].
However, if 2 (or even more) competing HTTP requests are both modifying say HTTP sessoin attribute 1/A and HTTP request/Thread 1 wants to set the attribute to 1/B and the competing HTTP request/Thread 2 wants to set the same attribute to 1/C then who wins?
Well, it turns out, last 1 wins, or rather, the last Thread to write the HTTP session state wins and the result could either be 1/B or 1/C, which is indeterminate and subject to the vagaries of scheduling, network latency, load, etc, etc. In fact, it is nearly impossible to reason which one will happen, much less always happen.
While our anonymous user provided some context with, say, a user using multiple devices (a Web browser and perhaps a mobile device... smart phone or tablet) concurrently, reproducing this sort of error with a single user, even multiple users would not be impossible, but very improbable.
But, if we think about this in a production context, where you might have, say, several hundred Web application instances, spread across multiple physical machines, or VMs, or container, etc, load balanced by some network load balancer/appliance, and then throw in the fact that many Web applications today are "single page apps", highly sophisticated non-dumb (no longer thin) but thick clients with JavaScript and AJAX calls, then we begin the understand that this scenario is much more likely, especially in a highly loaded Web application; think Amazon or Facebook. Not only many concurrent users, but many concurrent requests by a single user given all the dynamic, asynchronous calls that a Web application can make.
Still, as our anonymous user pointed out, this does not excuse the Web application developer from responsibly designing and coding our Web application.
In general, I would say the HTTP session should only be used to track very minimal (i.e. in quantity) and necessary information to maintain a good user experience and preserve the proper interaction between the user and the application as the user transitions through different parts or phases of the Web app, like tracking preferences or items (in a shopping cart). In general, the HTTP session should not be used to store "transactional" data. To due so is to get yourself into trouble. The HTTP session should be primarily a read heavy data structure (rather than write heavy), particularly because the HTTP session can be and most likely will be accessed from multiple Threads.
Of course, different backing data stores (like Redis, and even GemFire) provide locking mechanisms. GemFire even provides cache level transactions, which is very heavy and arguable not appropriate when processing Web interactions managed in and by an HTTP session object (not to be confused with transactions). Even locking is going to introduce serious contention and latency to the application.
Anyway, all of this is to say that you very much need to be conscious of the interactions and data access patterns, otherwise you will find yourself in hot water, so be careful, always!
Food for thought!
Today at work I had a discussion with my co-workers and my boss about stateless / stateful beans (we just finished a project using JSF, it was the first time anyone at this company did something JSF related) and my boss said that he doesn't really like Session scoped beans (or even conversation / KeepAlive scoped ones). One of his arguments was that if we have for example 4 Tomcats and there is a request from the user then we aren't really sure that it will be "captured" by the same Tomcat every single time and the problem is that if during the first time a request comes and a session bean is created it's created only on that one Tomcat and the others don't know about it.
One of the solutions he mentioned was a so called "sticky session" which enforces requests from a given user to be handled by the same Tomcat every time. A second solution according to him would be storing all the data in the "view", but that would mean storing the whole state in the POST, somehow I don't really like that idea. Then he mentioned storing the state in the DB and querying it if a request that requires it arrives. I thought that it would be a really huge performance hit, but he said that it really wouldn't be a concern since the DBs should be prepared for such tasks.
The last solution which I'm interested in was the Terracotta Server which, from what he told us, is supposed to store the session bean for all Tomcats (which are synchronized with it and then if a requests comes in they look for session beans inside Terracotta). Seems kinda cool and scalable, but he said that he didn't really see it ever used in large professional systems, is that right? I tried some info on it but failed, is there something wrong with Terracotta that stops people from using it?
It is used by professionals, just look a their customers page.
http://www.terracotta.org/company/customers?src=/index.html
I have an application that uses coldfusion's session management (instead of the J2EE) session management.
We have one client, who has recently switched their company's traffic to us to come viaa proxy server in their network.
So, to our Coldfusion server, it appears that all traffic is coming from this one IP Address, for all of the accounts of this one company..
Of the session variables, Part 1 is kept in a cflock, and Part 2 is kept in editable session variables. I may be misundestanding, but we have done it this way as we modify some values as needed throughout the application's usage.
We are now running into an issue of this client having their session variables mixed up (?). We have one case where we set a timestamp.. and when it comes time to look it up, it's empty. From the looks of it this is happening because of another user on the same token.
My initial thoughts are to look into modifying our existing session management to somehow generate a unique cftoken/cfid, or to start using jsession_ID, if this solves the problem at all.
I have done some basic research on this issue and couldn't find anything similar, so I thought I'd ask here.
Thanks!
I've run into similar problems on and off for years.
JSession cookies seem to help (no hard data on that) but one solution that I've implemented repoeatedly is using no-cache and cache expiry headers on every page.
http://www.bpurcell.org/blog/index.cfm?entry=1075&mode=entry gives some specifics on how to implement this.
In extreme cases, we've been forced to pass the token and cfid in the links/forms, but that is a PITA to implement, so I'd try the cache expiry/prevention soluiton first.
As far as I know, there are no "cons" in using J2EE session variables, unless you really need session to be active after user closes the browser. I think you should try and see how application behaves with it and see if that saves you trouble of refactoring.
To be sure that you are using all other settings try this:
<cfdump var="#APPLICATION.GetApplicationSettings()#" label="Application settings" />
If you have sessionmanagement and client cookies turned on, everything is fine, so try j2ee session variables.
This is a bit of a throwback question, and probably relatively fundamental, but I'm at a loss.
How does IIS manage Classic ASP session state?
We have an app that stores user information in session, and when many users are using the app, it seems to be recycling session for users, even though the "expire period" has not elapsed.
We suspect that when a certain amount of memory has been used for the session state, it begins to recycle the oldest session objects or something like this.
If this is correct, is there some way to control for it with the existing application code?
Thanks!
ASP sessions are stored as simple in memory COM objects when the process hosting the ASP application are terminated so will all the sessions.
ASP does not "recycle" active sessions. However there are number of other circumstances which can affect ASP sessions.
Application Pool Idle Timeout
One phantom reason "Sessions" appear to timeout prematurely is because the "Sessions" in question are just under test during development. Hence whilst the developer is examining the content of a page or reviewing some code no further requests hit the site since its not actually a live site.
In IIS manager open the properties of the pool in which your ASP application runs. Take a look at the Performance tab. The Idle Timeout will default to 20 minutes. Hence if you have specified a session timeout of say 60 minutes and you are "testing" that timeout you actually discover your session has timed-out in 20 minutes. The lack of activity has killed the application pool.
Application Pool Recycling
IIS may recycle the application pool in which the ASP application is running in. Recycling means that the existing set of processes currently hosting the ASP application no longer accept new requests. New requests go to a new set of processes and the older processes will terminate when they have completed their outstanding requests.
There are a whole host of different settings and criteria that can be configured that trigger the recycling of an application pool. Take a look at the Recycling tab of the pool properties dialog.
If you think that there may be an excessive demand for memory then the Memory recycling section may indicate a cause.
Web Garden
An Application Pool can contain multiple processes to run the same set of applications. Back on the performance tab note the Web Garden section at the bottom. By default this is set to 1. However multiple worker processes will play havoc with ASP sessions. As noted above ASP session are simple in-memory COM objects. If subsequent requests for a specific session are dished out to different workers one worker will not have access to the session object that the other has.
Session.Abandon or Session.Clear
Logic bugs can sometimes be the cause of sessions apparently disappearing. Calling the above methods at an inappropriate point in a sessions life can cause a problem.
I have experienced the same thing. Session seems to be emptied of the data, meaning that no variables is no longer stored in the session, but since the session exists, On_SessionStart doesn't trigger.
Gives you a headache if you initialize data for a visitor that you later on depends on...
I have considered this a bug that no one seems to know about, and haven't found a solution to it. It seems related to memory-usage, as you point out, and the solution seems to be to make sure you don't have any leaks.
Implement object-caching in classic ASP memory-leaking
This issue for me turned out to be the number of worker processes under the Performance tab. It was set to 2 for some reason. We set it back to 1 and the issue went away.
The session timeout in web applications typically denotes the idle time - i.e. the period of time when the user doesn't work with the application.
Now, what if there is an automated script written that posts a request every 5 minutes - wouldn't that user's session go on endlessly? This being the case, won't this approach heavily load the application affecting its performance in the long run?
Running an automated call to the server, say via an AJAX request, will keep the session alive. Typically that's the point though. An interesting side effect of this is that if the request happens predictably and regularly, you can use it as a "ping" to determine if the user's browser is still open. If one or two pings are missed, you can close the session earlier and actually free up resources sooner than if you just let the session time out.
Yes, and Yes.
This is why if you're going to write an application for the web, you really want to find a way to implement it without using server side sessions. Usually, you will be able to find ways to implement the same functionality using cookies -- then the session data is client-side so who cares if they stay active permanently.
I did something similar for an application that relies heavily on session data.
What I did was set the IIS timeout to a relatively low number, say 10 minutes, then have a timed AJAX call that pings a blank page every 5 minutes.
This overhead on this is actually fairly low, as all you are doing is requesting a blank page, and if a person closes their browser, the session ends in 10 minutes.
You want to keep session as small as possible. That said, if everyone starts doing that, of course it will load your application, with(out) session. If you think your users are compelled to do that, consider why, as either your application is missing an important feature or is forcing them into something.
Now, regardless of that, if you are expecting lots of users to be active at the same time, so much than a single server won't do, then you would will end up having the session out of process. If the session is in Sql Server, it is just saved data, so in that case we wouldn't be talking about memory usage.
Well... I guess "It Depends" The first question you should ask yourself is whether you even need session.
If you have an automated process, my guess is that you don't really need to use session.
In that case, either turn it off or don't worry about it.
I guess your session table would be a little bit larger, but on the other hand you won't be tearing down and recreating the session. I don't see how this would "heavily load" the application. I suppose it would depend on the application itself and how much memory is used to maintain session state.
It would allow the use's session to go on endlessly, as long as they have their browser open. If need to keep a session alive for an extended period of time, you could also track the sessions via the DB and not in memory.
Also, if you are worried about the indefinite open session, you could implement a timeout from when the session opened and if there is an extended idle time.