I am relatively new to the concept of clustering of IS. If I expect my services on the IS to work in a clustered environment, does it mean that I need to set the ‘Stateless’ property of each of my service to ‘false’. In other words what is the use this property and what are the do-s and donts of it.
Thanks for the response, but the thread you referred me to lead to a slightly different conversation. What I am trying to understand is the relationship between state of a service and the IS clustering.
The state setting of a service is independent of clustering. A stateless service simply is one where no session is created for the user. Stateless and stateful services can both be used in a clustered environment with failover. Read up on this in the wM clustering guide.
Session/state information is stored in the repository, which should be shared when you have clustering enabled. All servers in a cluster will therefore have access to the same session/state infomation.
Thanks for your inputs. Yes, I certainly do need to read up the guide, but I am glad that my misconception is dispelled upfront. I was under the impression that using the clustered environment would require keeping the services as stateful, because the failover makes use of the state of the services that is stored in the repo. So am I right to derive from your replies that the state of a service referred to by the ‘Stateless’ property is different from the one being saved in the repo? If not, then doesn’t it mean that making a service stateless would keep any info relating to its state, from being stored in the repo, thus rendering the clustering useless?
Bear in mind that IS fail-over has some pretty stringent requirements on what sort of clients can be failed over. It’s pretty much restricted to IS clients that use the Java API and the TContext class. And the clients have to have prior knowledge of all the servers in the IS cluser for fail-over of in-flight interactions to work.
A stateless service has no state information maintained in any form. In this case, failover doesn’t have to do much/any work to redirect the client to another server–the client just connects to a different server and the service is run.
Stateful services are useful when a client connects to an IS and runs 1 or more services in a single session. Credentials are passed one time, with the session information stored on the server maintaining who the user is (via cookies and such). If fail-over is to be supported, then all servers in the cluster must have access to the session data. This is achieved by storing the session data in a repository and all servers sharing said repository.
Note that clustering supports load-balancing too. So while stateless services do not benefit much from clustering for fail-over (the client hits one server, passing credentials, sees the failure then tries another, passing credentials, and so on), they get the benefit of being load-balanced (though external load balancers are usually the better approach).
To sum up: Stateless services don’t store anything in the repo and don’t have state (so nothing to store in the repo). The main benefit of clustering for these is load-balancing and simple fail-over (“I’m too busy or I just failed, try another server”). Stateful services maintain session data on the server for communication efficiency. Fail-over of stateful services and retaining state requires that the session info be stored in a shared location.
This topic is a bit of a hot button for me as well (I can be quite the efficiency freak :-). So just to expand on the situation a bit, can we discuss the merits of making internal services stateful/stateless?
From the conversation so far it sounds like most of the state information maintained is session info (credentials, active/inactive, etc.). This would lead me to believe statefulness is only relevant to top-level services, as opposed to internally invoked services, since I don’t believe internal invokes create sessions. Any of this true/false?
For better or worse it seems that 90+% of the services I deal with lately are internal. So if checking the box for stateless isn’t doing me any good I can save a bunch o’clicks by leaving the default settings alone. Any thoughts appreciated.
I believe that the setting applies only to top-level services, though I cannot confirm with 100% certainty. The Developer’s Guide, pg 133, has a description of stateless. The GEAR 6 Performance Tuning White Paper has this to say: “If your service calls are atomic and they do not use sessions or the repository to persist state (like certain RosettaNet services do, for example), make your services stateless, by checking the “Stateless” checkbox in the Settings tab. (Most services fall into this category.)”
This is getting interesting and with each post from you guys, I am getting enlightened. Thank you all. Thanks Rob for those fantastic details on state of a service vis-a-vis clustering failover and load balancing.
Brian, I agree the knowledge sharing is great for everyone involved. It’s a really good bunch here, glad to have you aboard.
Rob, I went looking for some info on this in the docs previously and found the blurb in the Developer’s Guide. I hadn’t seen that bit in GEAR, though. Interesting to see that they also feel most services can be stateless. So my question then is, why isn’t this the default? Some time ago I posted this to the Advantage Wish List, but haven’t heard anything more on it there.
To explore this just a little more, I’d imagine that it might be necessary to maintain state for a service that’s called by a client that supports checkpoint/restart functionality. However, this is again not typical, and would only apply to the services that maintain the checkpoints.
So I’m personally going to plan on only setting my top-level services to stateless as a rule, and then handling state as necessary where it seems required. Given the potential complexity of understanding the impact of this setting, it would be nice if the docs did a better job of addressing it. Maybe another one for the Wish List :-).
The defaults are often set to keep people from hurting themselves, rather that to the values that a majority of the users may like. A good wish would be to be able to have Developer configured for your particular preferred defaults for a bunch of the common object types. For instance, I want Flow Exit to automatically set the exit from property to $flow.
Here are a few more comments on stateless services:
If there is a subservice called from a stateless service, the session will become stateful, so you don’t have to worry about knowing what your dependent or referenced services are doing, only if that one service needs the session around.
It was rather common in the B2B Server 3.x days for services to stash stuff in the Session object for use by a later invoked service on that ssnid. Think of it as a shopping cart that is persisted across the cluster. Cool, but has it’s own set of pros and cons.
When a top level stateless service exits the session is immediately destroyed. This has two implications:
a. you don’t have to wait for sessions to timeout. if you have lots and lots of independent clients that have a reasonably short life in IS, you don’t have to buy a large number of concurrent sessions license (I don’t know if the software is licensed this way anymore).
b. destroying a session takes more time than not destroying a session in pure single invoke throughput terms. When stateful, the session times out and is destroyed while some other guy’s service is running, so your invoke doesn’t pay for it. Destroying it on the way out of IS as the stateless service exits takes time on that particular invocation - particularly if the Session object has to be removed from the cluster store. If you aren’t reusing sessions than you got to pay sooner or later.
Mike, Brian - It depends on the situation, but generally, it is important to have top-level document receive services stateless.
There has been some good advice on this thread, particurly from Rob. My understanding below is based on 4.6, but it should be the same for 6.1.
Lets say you create a HTTP receive service and keep it’s default state setting (i.e. keep it a ‘stateful’ service). When the service is invoked by an external HTTP client, IS will try and establish a “long-term” session (as opposed to a short-term session that terminates immediately after the invoke – as Fred pointed out).
IS uses cookies to establish and manage sessions – it will sends back a ‘set-cookie’ HTTP response header back to the HTTP client. This contains the cookie to be used subsequent connections.
Now, the HTTP client may or may not use this cookie - if it resends the cookie, it reuses an existing session on the server. If not, each of it’s subsequent HTTP requests creates a new ‘long-term’ session on the server (which will eventually time-out). These sessions consume server resources - furthermore on 4.6, I have seen the server ‘pause’ when a huge number of sessions time-out all at once.
Hence, if the service performs a unitary function, it is best practise to keep the top level external receive service stateless. For eg: wm.tn:receive is marked stateless
The stateful setting on lower level services does not matter.
Most simple HTTP clients do NOT resend the cookie – such clients cannot exploit server state even if the service is stateful. The webMethods HTTP client does resend cookie by default (there is a server.cnf setting you can use to turn this off). Ironically, this feature, in conjunction with an IS 4.6 “session timeout” bug caused major problems only when webMethods clients would connect to webMethods servers (non-WM to WM was OK!) . The bug was fixed by 4.6 IS FIX 125 if I recall correctly.
OK, thanks. Let me say (if necessary) that I’m not trying to be a wise guy, I just want to get to the bottom of this. At long last, I think that goal is now in reach. Thank you all.
Sonam, let me come back to one point. I can appreciate that checking the stateless box may benefit resource consumption (if not performance) for top-level services. However, according to Fred’s comments as soon as that service invokes a subservice it becomes stateful. I don’t think I’ve ever seen a top-level service that doesn’t invoke a subservice (or more likely several). So this would seem to invalidate the idea of stateless services in all but the most specific situations, would it not?
“1. If there is a subservice called from a stateless service, the session will become stateful,…”
“3. When a top level stateless service exits the session is immediately destroyed.”
Fred, can you clarify? One could infer that while the session becomes stateful during the invoke of other services, the top-level service will destroy the session anyway.
When a top level stateless service exits and the session has not been made stateful by invocation of a stateful service, the session is immediately destroyed.
It is reasonable to make services stateless. I haven’t done any benchmarks to see if destroying the session takes noticable time. I just speculate because it is some work done inline that is done by a reaper thread when stateful services sessions timeout. Note that for non-clustered systems destroying a session should be fast.
Mike - Fred’s point #1 is incorrect (at least on IS 4.6 SP2).
Fred - You said:
If there is a subservice called from a stateless service, the session will become stateful, …
I tried this out by setting up a stateless test service on an IS 4.6 server (SP2 installed). This service in turn invoked a WmPublic service (pub.web:stringToDocument) which is stateful by default. Tailing the session log (“tail -f”) showed the session ending as soon as it began:
2005/04/05 0010:43:17 Begin 102BgS… sonam 10.20.100.100
2005/04/05 0010:43:17 End 102BgS… rpcs=0 age=22
Each subsequent request created two more such entries.
Note, to try this yourself, restart the browser and make then make the first request directly to the stateless URL. Otherwise an existing stateful browser session can interfere with the test.
Hi, I am using webMethods 6.1 (unix). I have written a statefull java service using the developer. I saw from Sonam Chauhan’s reply that -“IS uses cookies to establish and manage sessions”. Now my question is, is there any way by which we can make a service to manage the user session using URL-REWRITING?
Any guidance on this is appreciated,
shenzy