Is there anyway to user MongoDB as a central session storage for Tomcat6? If so, could we have a cluster of tomcat servers reading session data from MongoDB so that the cluster could be dinamically resized (adding more boxes on the fly) without the need of sticky sessions?
I think I found what I was looking for.
https://github.com/dawsonsystems/Mongo-Tomcat-Sessions
If anyone has used it in production, I would love to hear your experiences.
Tomcat/J2EE sessions have a getId() method which returns the session ID for the current user. You can certainly use this as a key into a sessions collection in MongoDB, and store any data you'd like.
I'm not aware of any pre-built tools to integrate specifically with Tomcat 6, but that doesn't mean they don't exist. But this is a fairly straightforward task, it might be simplest just to write your own DAO to access session data given an HttpSession or HttpServletRequest.
If your session data is the only shared state you maintain, then moving it to MongoDB (or to any off-appserver database or tool) will enable you to scale like you propose. If you have other state maintained on the application servers, then you will need to determine how to move that off of the app servers and onto a shared resource.
I think there is a better way using MongoDD to store sessions, just using Servlet-Api functions and no proprietary Appserver-features.
First of all you need to create your own implementation of an
HttpSession based on a Map for storeing attributes
You need to create an implementation of HttpServletRequest (using HttpServletRequest Wrapper) that overwrites getSession-method and
returns your implementation
You need to create a filter which replaces the given HttpRequest against your created and do the MongoDB-Handling to load and store the attribute-map
You find some code-samples (sadly in german language) here: http://mibutec.wordpress.com/2013/09/23/eigenes-session-handling-in-webapplikationen/
Related
I am developing some SPA with a backend written in Java (Spring Boot). In relational DB that backend connects to, there is a table with some dictionary values. Values can edited by users of the app, but it's done really, really rarely (almost never).
Those dictionary values are used in a lot of pages on UI and because of that I would like to "cache" them in a way. What I want to achieve is that I want to load dictionary values on startup to avoid asking DB for values during every request between UI and Backend.
Firstly, I thought about just loading it on the UI part of the app, when user enters the page for the first time. Then I ruled it out, since when one of the users changes the values, it should be reloaded.
What I think might work is just loading them on startup of Backend into some collection (that can be safely used in concurent environment, probably ConcurrentMap) and then during some GET requests asking that collection for the values (instead of DB). When the values are changed, that request just updates the DB table and reloads them into collection.
Then I thought that the collection solution won't be enough, when my backend would be scaled up to more than one instance. In that case, only one of instances will be updated and the second one will provide outdated data. We can avoid it and force refreshes i.e. every 15 minutes (instead of on demand during values update).
But what I think is the best solution is to start some redis service on a side, load dictionary values into it and after every DB update of the values just update the redis instance with the new ones. Every instance of backend would use the same instance of redis, which seems quicker than executing query (select * from _ where _ = _) on DB.
What do you think? Is my thought process is correct? Do you have any ideas that can help solve my issue?
If you are using Spring you could check out Spring Cache Abstraction. That way your cache will be up-to-date whenever some change occurs.
Out of the box few implementations are supported by Spring:
Spring provides a few implementations of that abstraction: JDK java.util.concurrent.ConcurrentMap based caches, Ehcache 2.x, Gemfire cache, Caffeine, and JSR-107 compliant caches (such as Ehcache 3.x). See Plugging-in Different Back-end Caches for more information on plugging in other cache stores and providers.
If you decide to use Memcached implementation you can check out this library (uses Xmemcached under the hood) here.
You could also check a small demo app of how to use Spring Cache Abstraction in your project (link).
I think your in the right path with your approach in terms of 'caching'. I suggest you also check Memcached for it simplicity. Redis is a good choice but still it depends on your requirements and if you need that much feature. just my 2cent
https://aws.amazon.com/elasticache/redis-vs-memcached/
https://devcenter.heroku.com/articles/spring-boot-memcache#add-caching-to-spring-boot
Thanks,
I am using Spring-MVC to build a website prototype. We have a MySQL database that we address using Hibernate.
Now, I want to add basic user session handling (user can login, do stuff on the site and logout). I thought it should be easy to do, but after a bit of research I feel a bit lost.
I have seen the spring-session project. It seems it depends on a redis server for storing session data. Is there a way I could use my existing Mysql/Hibernate setup for storing the session data?
Also, what is the most easiest way to do sesions in spring-mvc ?
Sessions will be maintained within the web/app servers like Tomcat, Weblogic etc., you need not to store session related stuff in any database.
I have 2 osgi distributed web apps A(A1, A2) and B(B1, B2), i am using shiro to share the http sessions for single sign on so that logginng in one system logs in the other too. But I want the session data to be separated between system A and B apart from the authentication/authorization data,so I need a way to share the authentication data and separate system specific session data of A and B. I am thinking to use shiro for single sign on and use a different distributed session for each system to store system specific data, the main workflow would be :
log in system A with shiro, create an another session(or some data holder object to store the session data) using the shiro session id,stores it in backend(db or cache).
do stuff in system A, put session data into the session created above, writes to backend.
When another request comes in system A, look for a session with the id matching the shiro session id, if found, use it, else create new one.
Does it make sense? Is it the right way to solve my problem? What is the best way? Please share your thoughts.
Any input is appreciated.
Thank you.
I've done something like that with a Servlet Filter. My HtppSession contains the authorization id which I then lookup and provide as security context for the request. If no security id is present, the client is forced to login. Obviously the security context can be held in a distribution mechanism so it is available from all systems in a cluster.
Make sure you use https between the client and the systems or otherwise someone can eavesdrop, read the cookie with the id, and login to one of the systems with the authorization of the victim. I.e. session hijacking.
I store data in
HttpContext.Current.Application.Add(appKey, value);
And read data by this one:
HttpContext.Current.Application[appKey];
This has the advantage for me that is using a key for a value but after a short time (about 20 minutes) it does not work, and I can not find [appKey],because the application life cycle in iis data will lose.
i want to know is that another way to store my data by key and value?
i do not want sql server,file,... and want storing data on server not on client
i store users some data in it.
thanks for your helping
Since IIS may recycle and throw away any cache/memory contents at any time, the only way you will get data persisted is to store it outside IIS. Some examples are; (and yes, I included the ones you stated you didn't want just to have the list a bit more complete, feel free to skip them)
A SQL database (there are quite a few free ones if the price is prohibitive)
A NoSQL database (same thing there, quite a few free ones and usually simpler to use for key/value)
File (which you also stated you didn't want)
Some kind of external memory cache, a'la AppFabric cache or memcached.
Cookies (somewhat limited in size and not secure in any way by default)
you could create a persistent cookie on the user's machine so that the session doesn't expire, or increase the session timeout to a value that would work better for your situation/users
How to create persistent cookies in asp.net?
Session timeout in ASP.NET
You're talking about persisting data beyond the scope of a session. So you're going to have to use some form of persistent storage (Database, File, Caching Server).
Have you considered using AppFabric. It's actually pretty easy to implement. You could either access it directly from your code using the nuget packages, or you could just configured it as a session store. (I think) doing the latter would mean you'd get rid of the session timeout issue.
Do you understand that whatever you decide to store in Application, will be available for all users in your application?
Now regarding your actual question, what kind of data do you plan on storing? If its user sensitive data, then it probably makes sense to store it in the session. If it's client specific and it doesn't contain any sensitive information, than cookies is probably a reasonable way forward.
If it is indeed an application wide data and it must be the same for every user of your application, then you can make configuration changes to make sure that it doesn't expiry after 20 minutes.
I have a series of code books in my database, and I am using plain JDBC calls to fetch them and store them in a collection. I would like to put these in some kind of a cache at application startup time in order to save time later.
I don't need any fancy stuff like automatic object invalidation, TTL etc - the code books change rarely, so I'll trigger the update myself and just reload the whole cache when the need arises.
The project where I need this uses Spring, and this is my first project using it. Is there a standard/elegant way to do this in Spring?
Thanks.
Check out Spring-cache.
Supports EHCache, OSCache and a memory cache, but allows pluggable cache providers too.