An applicationâs scalability is defined by how it responds to meet the demand of increased workload. An application needs to be able to maintain its availability, reliability, and performance while the load is increasing.
In this series of articles, you will explore various IBM WebSphere sMash features that help you build scalable Web 2.0 applications. Part 1 provides an overview of the REST principles associated with scaling, and specific parts of WebSphere sMash that must be addressed when stretching an application beyond a single JVM (Java™ Virtual Machine). This article will also discuss generic topologies for scaling WebSphere sMash applications. Follow-on articles will provide technical details of implementing selected scaling patterns with WebSphere sMash.
The term REST describes a design pattern for implementing networked systems. REST is neither a technology nor a standard; it's an architectural style for exposing resources over the Web. The RESTful architecture adheres to several principles:
- Requests are client-server and, by nature, use a pull-based interaction style. Consuming components "pull" representations of state from the server.
- Requests are stateless. Each request from client to server must contain all the information needed to understand the request and cannot take advantage of any stored context on the server.
REST does not necessarily mean there is no state on the middle tier; it means the state to fulfill the request for a resource is not dependent on that state:
- Clients and server adhere to a uniform interface. All resources are accessed with a generic interface in the Web-extended SOA world -- HTTP along with the HTTP methods: GET, POST, PUT, DELETE.
- Clients interact with named resources. The system comprises resources that are named using a URL, such as an HTTP URL.
REST is the key technology for representing services on the Web. Since REST is resource-oriented, it is natural to expose data services via REST. These data services can then be mixed and matched to build new applications (often called mashups). The following example shows how a client sees a RESTful service:
- GET: Returns list of customers
- POST: Creates Customer record
- GET: Returns Roland customer record
- PUT: Updates Roland record
In this example, the resource being exposed is Customer. The Customer is represented by the URI /customer. Specific customers are represented by appending an identifier to Customer, such as /customer/ims. The HTTP methods define the intent of accessing the resource.
Scalability principals of REST
REST adheres to several principles with regard to scalability:
- REST relies on an HTTP infrastructure
REST enables you to leverage your initial investments of the Web. Since REST is constrained around HTTP patterns, you can leverage your existing infrastructure to host RESTful services.
- REST promotes stateless servers
Most meaningful applications have state; however, what differentiates one framework from another is how state is managed. REST, unlike traditional Web architectures, keeps the state in the client and transfers any required state with the request. Adhering to this principle relieves the server side components of the responsibility of sharing information between service instances and requests. This enables different servers to handle initial and subsequent requests from the same client, and new servers can be added to the system cluster to support increasing load demand.
This is in contrast to stateful applications that require server side state management where replication across the horizontally-deployed service instances is used to maintain consistency. A significant amount of extra processing is simply removed from the architecture.
However, complete statelessness is also unrealistic for certain Web usage scenarios. Some business logic cannot be exposed to the client, thus requiring you to maintain some information about the client on the server. Because intermediate state needs to be replicated, this is usually where scalability becomes an issue in some areas. Later, in the programming model overview, you will learn about the sMash global context and its role in maintaining states.
- REST is cacheable
Caching is yet another REST architectural constraint that can help performance and scalability by letting clients or intermediaries cache responses that servers mark as cacheable. RESTful services require that the data within a response to a request be implicitly or explicitly labeled as cacheable or non-cacheable. For the Web, Roy Fielding calls out a perfect style in his doctoral report: client-caching-server-stateless.
Within Web architecture, caching can be implemented in different layers of a Web application. Figure 1 highlights this.
Figure 1. Caching
- Some data can just be kept in the Web browser. Typically, client specific data for a particular session, UI widgets and layout, and other similar things are cached.
- Web server or proxy server can cache certain server side information (Apache Web Server based caching will be discussed in Part 2). This is sometimes referred to as edge caching. Often, results from Read Only or Read Mostly HTTP requests are cached. Examples are HTML static pages, and HTTP data responses, such as XML, SOAP, or JSON data.
- The server application can cache data. For example, within a WebSphere sMash application, you can cache data in between requests. Configuration or read only data used by the application is usually cached here.
- External data caches can cache data. These caches are often linked to the data sources, such as databases, and do things like partition data across various processes, sometimes referred to as a data grid. IBM WebSphere eXtreme Scale is an example of such a technology.
- Databases usually have a level of caching that enable quicker access.
Application-centric versus server-centric design
In the enterprise, platforms (such as Java EE-based servers) follow a server-centric mindset. Web applications are built and deployed onto an application server platform. Server platforms, such as IBM WebSphere Application Server, provide all the qualities of service that the Java EE specification demands. Examples of these services include queue-based messaging, distributed transactions, or protocol management. Often, the application server runs several applications on the same JVM. Architects design applications around the notion of sharing software and data resources with other applications, and using services provided by the application server (even if they were not being used, in some cases). Even if applications are deployed in isolated application servers, the servers themselves often still carried all the available services. Application servers enable an enterprise level of integration. Characteristics of enterprise integration include distributed transactions across various systems, queue-based messaging for critical data delivery, or various other types of services. Platforms in the enterprise are designed around managing various protocols and middleware. Usually, they talk to enterprise databases that service many applications. The JVM that runs enterprise Java servers are optimized around long-lived applications.
The Web 2.0 world involves a class of less-critical integration at the HTTP level. Applications usually are designed around a set of data, meant to be mixed with other data sets, to create new applications that perhaps the data provider does not anticipate. WebSphere sMash is designed around the notion of being application centric. You build the application and run it. You do not package an application and deploy it to a multi-application server, like a WAR file inside another Java EE container. Each application runs in its own process (JVM). The WebSphere sMash runtime is designed to support patterns like recycling after a specified number of requests or an idle timeout. WebSphere sMash is a full stack runtime. Everything needed to run the application is built into the process, including the HTTP stack. No external proxy or Web server is required, although an external proxy is used for clustering and multi-application routing.
IBM Fellow Jerry Cuomo writes about IBM's "New Reality" runtime (NRR) in his blog. He stated that NRR is a new JVM implementation designed for lightweight, RESTful Web services, developed using simple, dynamic languages. This is consistent with the Web 2.0 runtime requirement: the runtime has to provide the ability to run many applications for a low and fixed investment. It also needs to support for billing based on application and traffic counts, and so predictability matters. WebSphere sMash is using such a JVM as the runtime.
WebSphere sMash enables organizations to deploy and run thousands of small nimble applications that can be started and stopped as demand necessitates, on demand. With the new reality runtime, applications can be started or stopped very quickly; an instant-on feature. WebSphere sMash JVMs are optimized around quick start and stop semantics. As you will learn in the next section, WebSphere sMash uses the global context to maintain server-side state, and the WebSphere sMash runtime will persist data as needed when the application recycles.
Understanding the WebSphere sMash programming models
Before discussing scaling WebSphere sMash applications, it is important for you to understand how WebSphere sMash applications look. This is because certain design decisions in the application can affect its scalability. The Developer's Guide provides more details on these concepts.
Scripting and Java as the system language
A major trend in simplified development is scripting languages. WebSphere sMash aims to help reduce the overhead of developing services by providing simplified application program interfaces (APIs) around scripting. The default scripting language is Groovy, which is based on Java and enables Java programmers to easily transition to Groovy. WebSphere sMash also supports PHP as a scripting language for those developers arriving with a PHP background.
WebSphere sMash is an event-based system. All the key behavior of the system is exposed to the application as a set of events, with the appropriate event state. As an application developer, your main job is to provide a set of event handlers that hook into the well-known system events to achieve the desired behavior. Standard events are meaningful activities of interest to applications.
For example, an HTTP request through the system causes a set of events to be fired; developers can write event handlers. Figure 2 shows this concept, with opportunities to hook into events to handle security aspects or a particular HTTP method (such as GET or POST) event. (For more on event handling, see the event-processing section of the Developerâs Guide.)
Figure 2. Events
You can write an event handler in various ways, as shown in Figure 3. If you use a scripting language like Groovy or PHP, you do not need to provide configuration information to register the event handler. This is because WebSphere sMash provides various conventions that, when followed, eliminates the need for configuration. This is accomplished by enabling you to place scripts in certain directories where WebSphere sMash will automatically register them as event handlers. In Figure 3, for example, the scripts are placed in a directory called public, which serves as the root location for Web serving. If the script file is called hello.groovy, then you can invoke an HTTP GET on http://<host>/hello.groovy. Since it is in the public directory, WebSphere sMash will invoke the script in response to any HTTP method. (Conventions will be discussed later.)
Figure 3. Event handler examples
Event handlers in WebSphere sMash do not have explicit input and output parameters, such as request and response. Because event handlers in WebSphere sMash are stateless, they do not maintain state across invocations. WebSphere sMash provides the global context as a means to access and maintain all state. Global context provides all of the interesting data about the current event to the application, as well as the mechanism to store and share information between components of the application.
Global context is divided into a set of zones, where each zone maintains data with different visibility and with a different lifecycle. For example, the request zone contains the state of the currently active request, it is visible only to components executed for that request, and the state is only maintained until the end of that request. Figure 4 shows an overview of event handlers accessing the global context to access data.
Figure 4. Global context
In WebSphere sMash, there are seven default zones. Some zones are persistent, which means that the data survives application restarts or recycling, depending on the persistent zones. Non-persistent zones are in memory only, and do not survive JVM shutdown.
- Non-persistent zones
- Config zone: Data here represents configuration data, such as datasource definitions or security rules. Config zone data is loaded from configuration files and is globally visible and available for the lifetime of the application. The config zone can be modified, but the changes will be lost on application recycle or shutdown when the contents are re-initialized from configuration files.
- Request zone: Data here is visible to the thread that is processing the HTTP request. The request zone is available from the time a request enters the system until the response is completed. If you are familiar with servlet programming, the request zone provides a union of functionality offered by HttpServletRequest and HttpServletResponse. It includes access to incoming data (request parameters, headers, cookies, POST body, input stream) and outgoing data (outgoing headers, outgoing cookies, output steam).
- Event zone: Data here is visible to the thread that is processing the event for the duration of that event. WebSphere sMash provides an event processing framework to enable loosely coupled components that publish and subscribe to these events. If an event is delivered to multiple event handlers, all the event handlers have access to the original event data from the event zone.
- Tmp zone: Data here is visible globally to all threads of an application. It provides a scratch pad area that the application can use to store any objects.
- Persistent zones
The persistent zones persist across application recycle. These zones enable customization of the persistent store and serialization providers. (Changing the persistent store and serialization providers will be described in subsequent articles.)
- User zone: This zone is provided for applications that are programmed in WebSphere sMash but do not strictly adhere to REST. Data here is visible to all threads of an HTTP session. HTTP session is identified by the value of the zsessionid cookie found on the request. The user zone is preserved across application recycles. When an HTTP session times out after a period of inactivity, the data is deleted from the zone. The idle timeout is configured by setting /config/userZoneIdleTimeout in zero.config. Session also times out and is invalidated after the zsessionid cookie expires.
- App zone: Data here is visible globally to all threads of an application. It provides a scratch pad area that the application can use to store serializable objects. This zone is persistent across application recycles, but does not persist across restarts of the application.
- Storage zone: Data here is visible globally to all threads of an application. It provides permanent storage for data. This zone is persistent across application recycles and restarts.
The global context is available from all parts of an application. The method of access depends on the language being used. The Java API to the GlobalContext defines the access characteristics. Bindings are provided to this API through Groovy and PHP. As an example, the request variable is bound to the request zone, which means you can use a dot-notation like request.myData to access myData in the request zone. The global context looks like a map with access through key-value pairs. You can get, put, list, and delete different keys from the global context. Figure 5 shows some examples of how an event handler can access the global context.
Figure 5. Accessing the global context
The global context provides simplified access to certain data structures called
Value Pathing. The GlobalContext understands maps, list, objects, XML, and JSON
Conventions and the application directory structure
The WebSphere sMash environment provides several conventions that, when followed, greatly simplify application development and minimize the configuration information that must be specified. One of the goals of WebSphere sMash is to have as little configuration information as possible. Some of the conventions are common and expected. For example, you can place a script in the public folder, as mentioned earlier, and run that script in response to an HTTP request with no configuration required. Figure 6 shows this example. In the figure, you see a script called hello.groovy with an event handler method for a GET event. This script will be executed when a GET is invoked for http://<application_host>/hello.groovy.
Figure 6. public directory
Other conventions are more tailored to a particular pattern. Figure 7 shows an example of storing a Groovy script, called incentive.groovy, under a particular folder. This approach automatically registers the methods in this folder to respond to events triggered by HTTP REST requests.
Figure 7. Virtualized directory for RESTful resources
Now that you have an understanding of WebSphere sMash applications, letâs discuss strategies for scaling WebSphere sMash applications.
WebSphere sMash scalability concerns
Scaling refers to adding hardware or additional processes to increase the performance, throughput, and availability of an application. There are many things to consider when scaling WebSphere sMash applications:
- HTTP load balancers should use client-based affinity (or stickiness). This will reduce the number of times applications create intermediate state, if the application does create such state. The settings will depend on the proxy. (For example, Part 2 of this series will cover an example using Apache Mod Proxy.)
- Cache in the browser when appropriate. Ajax frameworks like Dojo (which is shipped with WebSphere sMash) enable client side data stores. In Web 1.0 style applications, Web applications would use HTTP sessions to maintain things like multi-page wizards. Ajax-based applications can use the browser as a much richer client to contain much of this logic. Some data would be better off in the browser than in the user zone of the global context.
- Use Single-sign on. Often, when applications are replicated or you are dealing with mashups, applications need to maintain identity across JVMs. Sometimes applications maintain the identity of a user in session. Applications should rely on tokens and recreate user session information lazily based on the user credentials.
- Know your requirements. Applications have different levels of requirements. It is usually inexpensive for applications to be 95% reliable, but the final 5% costs a lot. WebSphere sMash is optimized around quick delivery of applications and Web 2.0 style use cases, like mashups. It is centered on HTTP, and although WebSphere sMash applications can invoke other applications over protocols like JMS or SMTP, it is intended to host Web 2.0 rich Internet applications and REST services. The reliable transport extension adds some support for messaging, but specifically for Web-based scenarios.
If your application requires enterprise messaging, distributed transactions across different data sources and components, long running processes, or other such features, then a Java EE server is preferred. If you are building Web 2.0 style services and applications, accessing data sources and some remote services to create new situations, then WebSphere sMash can do this and you can achieve the desired scalability.
With an understanding of some basic scalability concerns, letâs look at some typical topologies. Figure 8 highlights a simple topology where you can use a sprayer to distribute requests across several WebSphere sMash JVMs.
Figure 8. Simple load balancer
You can use a variety of load balancers:
- WebSphere sMash can use an Apache Web server to proxy requests. (Part 2 will cover this in more detail.)
- You can use an appliance like IBM WebSphere DataPower® to proxy requests. DataPower can add qualities of service, such as credential mapping, XML threat protections, and other such services.
- IBM WebSphere Virtual Enterprise is specialized software for handling request processing based on business rules and other advanced features.
- Hardware sprayers can also be used to spray requests.
You will often need multiple sprayers to avoid a single point of failure scenario in your infrastructure. Figure 9 shows an example of having highly available sprayers fronting other load balancers; this is when requirements demand higher availability.
Figure 9. Multiple sprayers
In addition to sprayers, you must consider how to maintain intermediate state. As mentioned earlier, applications should be written to recreate session state. If this is the case, then you might have a topology like that shown in Figure 10, in which WebSphere sMash applications recreate state from databases or from specialized caching software, like WebSphere eXtreme Scale.
Figure 10. External caching
Part 1 of this series on scaling WebSphere sMash applications provided an overview of the WebSphere sMash programming model as background to understanding how and where state comes into play. You learned about some practices to help you make sure your applications function in a scaled environment, and also got an introduction to various WebSphere sMash topologies. Part 2 will continue to illustrate these ideas with a specific example that uses an Apache Web server to spray requests across WebSphere sMash applications.
The authors would like to thank Michael Fraenkel and Alex Polozoff for their suggestions on improving this article.
- WebSphere sMash and Project Zero information
- WebSphere sMash Developerâs Guide
- Exploring WebSphere sMash with WebSphere Virtual Enterprise
- Apache Web Server
- WebSphere DataPower product information
- WebSphere Virtual Enterprise product information
- WebSphere eXtreme Scale product information
- Performance Analysis for Java Websites, Stacy Joines, Ruth Williamborg, and Ken Hygh; Addison Wesley, 2002