If microservices are stateless , how can we manage session in JSP based projects .Assuming I am breaking age old monolith to microservices .
You can't manage session in a stateless server.
What you can do is that storage a unique token and its corresponding information into Redis/MemCache.
You need to storage the token instead of JSESSIONID in client.
The fact that most implementations of microservices in the industry communicate via HTTP does not mean that microservices are meant to be used as web servers.
A microservice:
does not have to communicate via HTTP (though most implementations do, for convenience)
is not meant to receive requests issued by a web browser (although you can use a web browser to issue requests to an HTTP-listening microservice to test it)
is certainly not meant to generate responses containing HTML that can be rendered in a browser.
For these reasons, microservices generally do not have a concept of a session.
If you absolutely must make your microservice session-aware, and retain it stateless (so that it can still be legitimately called a microservice) then you have to have it fetch all necessary session information from your persistence store each time a request arrives, and save whatever parts of it have changed back into the persistence store right before returning its response. But that's not how microservices are meant to work.
Generally, the way we use microservices on the web is as follows:
Either we have javascript running on the browser which maintains session state and issues sessionless requests to the microservice, containing authentication information if necessary, [*] or
We build a conventional web server which maintains session state the traditional way and is therefore not a microservice, and we have that web server internally issue sessionless requests to microservices in order to do its job.
Footnote:
[*] please note that my acknowledgement of the fact that many people do this does not in any way constitute an endorsement of this practice.
Related
I have web client which invokes multiple services. As soon as the user is authenticated, I want to store the email Id somewhere as it sends the email Id for each request.
I don't want to use session as I have heard that is the best practice. In REST, all data must be sent for the request and it must be stateless. What other alternatives are there? Is using DB for session management still not breaking the stateless principle of REST?
I went through If REST applications are supposed to be stateless, how do you manage sessions? but there were many contradicting opinions there. Should the email Id be stored in session storage of the browser then?
I think you should do it with a authentication header. Check out these threads:
Do sessions really violate RESTfulness?
If REST applications are supposed to be stateless, how do you manage sessions?
I have a web service which authenticates a user, and if successful gives them a JSON Web Token which they can use to persist their session.
Currently I only have one server, but would ideally like to increase that to two or more for the sake of performance, however I'm unsure as to how that'll work with different servers as they'll have different instances of maintaining who is currently logged in.
For example, my service will examine the JWT the client returns, and (assuming it's a good token), will take the user ID and session and check if there is a user logged in with that session ID.
However, if for example, the middleware that precedes the web service layer determines that the server the user was initially logged in is currently unavailable and routes the request to a different server instance of the web service, how is the authentication controller meant to evaluate if the request is valid?
A very basic version of my service can be found below, with the black arrows representing ordinary communication, and the red arrows representing communication in the event that Layer One decides to route the request to Instance Two.
Layer One, in essence is very basic and doesn't really do anything other than route traffic to the next layer dependent on the availability of the layer two instances.
One of the main advantages of JWT is that it does not need server storage because it is self-contained and stateless. If you need server sessions may be JWT it is not your best option to manage authentication. See Stop using JWT for sessions
Currently application servers use the SESSION ID to manage load balancing and redirection to the server that store the user session, including persistent storage and migration of session. Using a JWT you won't take profit of these characteristics.
Use JWT if you need a REST stateless endpoint with authentication or you need to exchange data securely between parties
We have the following setup.
STM (Stingrey Traffic Manager) does load balancing + session stickiness
Weblogic 'cluster'
Auth handled by a third party tool
Therefore I do not have to worry about session with regards to horizontal scaling/ running multiple instances of the application. STM/ Weblogic cluster makes sure that the subsequent request come to same managed server.
What we currently have is a monolithic application and we are trying to move to microservices. Also we do not wan't to move out of current infrastructure (i.e. STM/ Weblogic cluster/ Auth tool). What we have planned is:
A Gateway WAR which routes requests to other microservices
N x Microservices (WAR) for each functional sub-domain
Only the API Gateway receives user requests and other microservices are not accessible from outside
So my question is
Should API Gateway be state-full while other microsevices are stateless?
If so, how should the user session data be shared between API Gateway and microservices?
Please suggest any better alternatives and resources/links as well. Thanks.
Let me share my opinion.
First of all, if you can keep your application stateless, by all means do so :)
It will be the best solution in terms of both performance and scalability.
Now, if its impossible, then you should maintain some distributed session management layer.
The gateway responsible for authentication could generate some unique session identifier which could later be used as a key.
This key could be propagated to all the microservices and be a part of the API or something.
In order to access the session, the microservice could 'get' value by key and work with it.
In terms of implementation: I would take a look on NoSQL solutions. Some of them that can suit your need are:
Redis. Take a look on ''hset'' there
Hazelcast. Its more a in-memory grid but if the solution is java only, you can also implement the required functionality
Memcache.d. It will give you an old good map, just distributed :)
There are also other solutions I believe.
Now, the performance is crucial here, otherwise the whole solution will be just too slow. So In my understanding, using an RDBMS would be not be good here, moreover potentially it would be harder to scale it out.
Hope this helps
1)Should API Gateway be state-full while other microservices are stateless?
Yes, As in 12 Factor App guide lines all the services should be stateless.
2)If so, how should the user session data be shared between API Gateway and microservices?
Your API should be stateless therefore do not share the session state to the microservices. The recommended approach is to set up a Redis cache to store session data.
We are currently are at a stage in our product lifecycle where we are thinking about moving to Web Services. Our system is written in Java which consists of a number of client and server applications which talk to one another over TCP Sockets and also has in-line SQL to perform data retrieval and updates (yuk! I know) which uses our own SQL Connection class which then uses the java.sql.Connection to connect to a SQL Server database using the Microsoft JDBC driver.
The applications bind to one another using TCP sockets. They request data from and push data to one another. Which works perfectly fine.
Thought
So we are looking at converting all data access and TCP communication to a web service.
The web service would be designed to run on a companies secure internet site. The idea would be that users could connect their clients to the web service from home - when they are not on the company network - or at work, when they are.
The client applications would send/recieve the messages to/from the server side applications using the web service.
The client applications would retrieve and update data in the database using the web service.
Question
I would just like to know what peoples experience is of doing anything with 2 way communication (request and push) over a web service (if possible) and what the thoughts are about doing this.
Converting the data access to a web service seems straight forward enough - I can forsee some issues with performance where large data sets are retrieved in some parts of the system.
I am looking through various reading materials on the matter as it is a while since I have touched web services (using C# and ASP.NET). Currently reading "Building Web Services with Java™: Making Sense of XML, SOAP, WSDL, and UDDI". I must admit I thought web services were always stateless but have just read that they are not!
Thanks,
Andez
It helps to think of WebServices as being the same as any other web application on the transport layer. It uses HTTP/HTTPS protocols in the same way, it's just that instead of sending HTML, it sends XML according to a predefined format (SOAP). As such:
It's Request/response oriented
Can be stateful in the same way as a web-page can be stateful, using sessions (assuming you have a web-service client that supports maintaining session cookies across requests)
All requests eventually boil down to good old-fashioned servlet endpoints in the server
Keeping these limitations and features in mind, think about your requirements and how they map against each other. If you need true two-way communication (push), then web services are not ideal. They are client/server, request/response oriented. The achieve push, you would have to poll from the client. A possible alternative could be to let both the "server" and the "client" act as web service "servers". That would mean bundling some light-weight servlet engine with the client (like jetty) so the "server" could make web service calls TO the "client". Another way is to look at two-way RMI/IOOP.
Yet another way would be to keep the communication layer as you have it today. There is no inherent gain in refactoring to Web Services just for the sake of using web services. If they don't add any benefit, it's just waste. As you already mentioned yourself, Web Service comes with a load of additional overhead (verbose protocol, servlet engine etc), so it really needs to balance the extra cost and development time with a clear benefit. As the saying goes "if it's not broken, don't fix it". As you say the current solution "works perfectly fine", I would probably not change it. That's just me though.
I have Flex/AIR app that connects to a tomcat server via BlazeDS. I'm not finding that I have to integrate an old webapp (struts/jsp) and I'd like to keep that webapp untouched except for login, authentication and session handling. Also a 3rd java app that uses httpclient.
Currently I have some blazeDS remote objects to handle login/logout with a few RPC calls. In turn, FlexSession objects are created and handled. Is there a way to use httpclient and javascript to call those blazeds RPCs so I dont have to recode and have 3 different means to handle logins and sessions?
This is supposed to use single_sign_on for the 3 apps as well.
Yes, handle everything differently I'm afraid!
you should only use BlazeDS to (de)serliaise your Java objects to/from AMF. Once that's done, hand off to something else to do your business logic. This means you can add different entry points just by providing the API for your business logic.
From the Authentication / Login type stuff, you should be using something like spring security to handle this rather than writing your own. This decouples this type of logic from your business logic and transport mechanisms, and can be reused regardless of how you access your application.
For sessions, it depends on what you are storing, but using FlexSession isn't usually a good plan.