aspose file tools*
The moose likes JSF and the fly likes Horizontal scaling of JSF 2.0 application Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » JSF
Bookmark "Horizontal scaling of JSF 2.0 application" Watch "Horizontal scaling of JSF 2.0 application" New topic
Author

Horizontal scaling of JSF 2.0 application

Alex Averbuch
Greenhorn

Joined: Apr 16, 2012
Posts: 6
Given that JavaServer Faces is inherently stateful on the server side, what methods are recommended for horizontally scaling a JSF 2.0 application?

If an application runs multiple JSF servers, I can imagine the following scenarios:

  • Sticky Sessions: send all requests matching a given session to the same server.
    Question: what technology is commonly used to achieve this?
    Problem: server failure results in lost sessions... and generally seems like fragile architecture, especially when starting fresh (not trying to scale an existing application)


  • State (Session) Replication: replicate JSF state on all JSF servers in cluster
    Question: what technology is commonly used to achieve this?
    Problem: does not scale. total memory of cluster = total memory on smallest server


  • Instruct JSF (via configuration) to store its state on an external resource (e.g. another server running a very fast in-memory database), then access that resource from the JSF servers when application state is needed?
    Question: is this possible?


  • Instruct JSF (via configuration) to be stateless?
    Question: is this possible?
  • Tim Holloway
    Saloon Keeper

    Joined: Jun 25, 2001
    Posts: 16058
        
      21

    JSF itself has no interest in clustering technologies. It leaves all that up to the webapp server itself, so the options and settings are entirely done at the server level and JSF code is clean. So your options are basically whatever options the server provides.

    It is very difficult to make JSF apps stateless, since the JSF postback mechanism tends to make a lot of things stateful that wouldn't be stateful when done in other frameworks. One of the major frustrations people encounter

    You can, however, make the state be client-side rather than server-side. That's a basic configuration setting for JSF webapps done in web.xml. The caveats are that because the state is shipped to/from the client, it's extra network overhead, and somewhat less secure than if the information never left the server, but the advantage is a lot less continuous memory usage on the server.

    You can also take advantage of the fact that JSF is not a "greedy" technology to mix and match. For example, a shopping site might use JSF for the shopping cart, but use lighter-weight technologies for the catalog browsing.

    JSF is at its best when used for heavily-intellectual applications and applications that do a lot of forms. It is not ideal for "display-mostly" applications, especially those with thousands or millions of simultaneous users.


    Customer surveys are for companies who didn't pay proper attention to begin with.
    Alex Averbuch
    Greenhorn

    Joined: Apr 16, 2012
    Posts: 6
    Hi Tim, thanks for the detailed reply.
    Regarding your comments, I have a few questions, but I'm new to enterprise Java, so please bare with me...
    Tim Holloway wrote:JSF itself has no interest in clustering technologies. It leaves all that up to the webapp server itself, so the options and settings are entirely done at the server level and JSF code is clean. So your options are basically whatever options the server provides.

    OK, but what is the common way for JSF developers to horizontally scale their applications?
    For example, if a server technology provides the clustering ability, how does it know what state to replicate?
    And, how would a developer specify that the component tree (for example) needs to be replicated?
    Tim Holloway wrote:You can, however, make the state be client-side rather than server-side. That's a basic configuration setting for JSF webapps done in web.xml. The caveats are that because the state is shipped to/from the client, it's extra network overhead, and somewhat less secure than if the information never left the server, but the advantage is a lot less continuous memory usage on the server.

    I guess you mean this setting:

    And perhaps this to reduce the amount of data being sent around:

    Using these two settings, will the application be truly stateless (i.e. any server in the cluster can serve any incoming request)?
    If not, what state remains?

    Thanks again,
    Alex
    Tim Holloway
    Saloon Keeper

    Joined: Jun 25, 2001
    Posts: 16058
        
      21

    Bear in mind that I haven't been called on to actually provide this level of service, either from a high-reliability standpoint or from a high-performance standpoint. Sadly, most of the stuff I get handed is more like "we need this ASAP", and the actual user community rarely exceeds a dozen simultaneous users

    Probably the easiest way to provide high reliability is to employ shared sessions. That is, the HttpSession object is replicated automatically between server instances. You can assist this process (and scale the number of users) by keeping only the core data in session objects and having the application code fetch the rest on-demand - preferably from cached resources. This is similar to the passivation mechanism developed for EJBs, where the long-term object was a handle that could quickly be converted to obtain the actual object.

    You could also employ more explicit frameworks, but I'm not up-to-date on options there. Once you buy into something like that, it tends to own you, so it's not something I do lightly.

    You are correct about the STATE_SAVING_METHOD. However, JSF state saving and HTTPSessions are 2 different things, so each part of the equation has to be dealt with separately. You still need session-scope objects when using stateful Model components (such as DataModel). View Scope is merely Session Scope with automatic removal. The JSF state is independent of that, and it manages the JSF component tree. If memory serves, the server-side version is kept in the server's temporary directory, not in J2Ee objects and is therefore probably not safely replicable. The client-side version allegedly eliminates that issue and therefore (in theory) can be bounced between servers in a cluster.
    Alex Averbuch
    Greenhorn

    Joined: Apr 16, 2012
    Posts: 6
    Tim Holloway wrote:Probably the easiest way to provide high reliability is to employ shared sessions. That is, the HttpSession object is replicated automatically between server instances.
    [...]
    JSF state saving and HTTPSessions are 2 different things, so each part of the equation has to be dealt with separately. You still need session-scope objects when using stateful Model components (such as DataModel). View Scope is merely Session Scope with automatic removal. The JSF state is independent of that, and it manages the JSF component tree.

    OK, this is new to me!
    If I get you right...
  • JSF component tree = all of (and only) the view-related state, i.e. the text to place in outputLabel, etc.
  • HttpSession = cached model-related state. does that mean backing bean state is stored in HttpSession?
  • Tim Holloway
    Saloon Keeper

    Joined: Jun 25, 2001
    Posts: 16058
        
      21

    Pretty much spot on. The stateful component tree is pretty much a black-box "set it and forget it" feature, and its exact makeup is subject to change (considerably change when going from JSF1 to JSF2, but the apps mostly didn't know it).

    The Model components for JSF are all based on traditional J2EE scope objects: request, session, and application (JSF doesn't use Page scope). Request scope is inherently stateless. Application scope is global to that particular application instance, so the heavy lifting is mostly in session scope objects, and sessions can be replicated.

    There are certain restrictions. To get session data from one app instance to another, the session must be serialized from the originator into the recipient (via java.io.Serialization). If any object in the collection (including dependent objects) is not serializable, the session will replicate imperfectly, or not at all. In traditional J2EE, people ran into problems particularly with JDBC Connections, since java.sql.Connection is an interface, not a serializable class. In JSF, injected objects - especially Spring-injected objects - can be an issue. This one can be a real pain, since when you serialize, neither object factories nor constructors are employed when a bean is deserialized - the offending objects just magically come up as NULL without warning. Ideally, there should be some sort of annotation that could be applied to warn the deserializer, but at the moment, there's nothing.
    Alex Averbuch
    Greenhorn

    Joined: Apr 16, 2012
    Posts: 6
    Thanks again Tim,
    If/when I have more questions I'll get back to you!
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Horizontal scaling of JSF 2.0 application