Professional Documents
Culture Documents
Precise Java
EJB | JDBC | Servlets | JSP | Patterns | JMS
Java Web Server Web Cache File Server
Search
Overview of Servlets
Servlets represent an extension to the HTTP server. It takes http request as an input and sends the http response to the client as an output. Servlet API provides two packages they are javax.servlet and javax.http.servelt. These packages contain interfaces and classes to deal with generic and http functionality that means you can write a Servlet in java to get http request and send a http response to the client. Client is typically a browser. These interfaces are implemented by Servlet Engines. There are numerous vendors who provide Servlet Engines to work with Servlets, for example Tomcat, weblogic, webshpere etc. Servlet is loaded into the memory by Servlet Engine and it calls init() method on first request and then onwards only service() method is called for every other request by creating a separate thread for each request and finally destroy() method is called when the Servlet is removed by the Servlet Engine. Service() method can be replaced by doGet() or doPost() method. Note that this architecture is a multi threaded model which is generally followed in most of the applications. You can even work with single threaded model by implementing SingleThreadModel interface where the Servlet Engine creates a separate Servlet instance for each request. Note1: This is brief explanation of Servlet architecture. For more information on Servlets, see available books and online tutorials on Servlets. Note2: This Section assumes that reader has some basic knowledge of Servlets.
5/16/13
Here you are generating both static data and dynamic data. Instead you can modify the code as shown below
public class servlet extends HttpServlet { byte[] header; byte[] navbar; byte[] footer; byte[] otherStaticData; public void init(ServletConfig config) throws ServletException{ //create all the static data here StringBuffer sb = new StringBuffer(); // better to initialize the StringBuffer with some size to improve performance sb.append("<html>); sb.append("<head><title>Hello world</title></head>); sb.append(<body>); header = sb.toString().getBytes(); // do same for navbar if its data is static // do same for footer if its data is static } public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); ServletOutputStream out = res.getOutputStream(); out.write(header); out.write(navbar); // write dynamic data here out.write(footer); }
Here the static data is created in init() method which means that it is created only once in the life time of Servlet and it is used in service() method to pass the data to the client. When you send a large amount of static data, then you can use this technique to see a considerable increase in performance.
2/7
5/16/13
4. Initialize the PrintWriter with proper size 5. Flush the data partly
6. Minimize the amount of code in the synchronized block 7. Set the content length 1. Use StringBuffer for concatenation rather than using + operator when you concatenate multiple strings. See Concatenating Strings for detailed information. 2. println() method internally calls print() method and there is no need for new line separation when generating html pages. So a small overhead of calling one more method is reduced if you use print() method directly. 3. There is a small overhead involved in PrintWriter because it is meant for character output stream and it encodes data to bytes, rather you can directly use ServletOutputStream whenever you want to send binary data. 4. The better way of creating PrintWriter is
ByteArrayOutputStream byteArray = new ByteArrayOutputStream(12288); PrintWriter out = new PrintWriter(byteArray);
This increases the size of buffer in the PrintWriter. 5. If you want to pass the large data to the client from your servlet, user may need to wait till the ServletOutputStream or PrintWriter flushes the data. This happens generally whenever you have a number of gifs per page that you want to pass to the client. The better approach is to flush the data partly using flush() method rather than flushing whole data at a time. You can initially flush header, then navigation bar, then body content and finally footer so that the user need not wait for whole data and he sees the header data immediately and so on with navigation bar, body content and footer.
ServletOutputStream out = res.getOutputStream(); out.write(header); out.flush(); // flush the header out.write(navbar); out.flush(); // flush the navigation bar // write dynamic data here out.flush(); // flush the dynamic data out.write(footer); out.flush(); // finally flush the footer
6. Minimize the amount of code in the synchronized block that is used in the service method whenever you want to the data to be thread safe. for example, you may write like this
synchronized(this){ code line1; code line2; code line3; code line4; }
But here you might want to synchronize the data in the code line2 instead of all the lines so the better way is
code line1; synchronized(this){code line2;} code line3; code line4;
7. Whenever the client, such as a browser requests a page it establishes socket connection internally with
3/7
5/16/13
7. Whenever the client, such as a browser requests a page it establishes socket connection internally with the web server to get the requested content. Client gets the page data with multiple connections depending on the size of the data. If the data is more, such as with multiple gifs then it needs to establish multiple connection to get the data. The number of connections established will depend upon default content length of the header, and size of the content to be traversed from web server to the client. By increasing content length, you can reduce traffic and increase the performance. Here is an example
response.setContentLength(int contentSize);
This method sets the length of the content that the server can send to client by using Content-Length header.
The third technique is that your application server may support caching facility for dynamic data. All you need to do is that configure the caching properties file which is supported by your server. You can give what Servlet you need to cache and session time out value to remove cache content. For example Websphere application server supports this type of facility. Have a look at this link
http://www-4.ibm.com/software/webservers/appserv/doc/v35/ae/infocenter/was/0606000401.html
The fourth technique is that you can use Servlet API's HttpSession and ServletContext objects for caching. HttpSession object is available for a user session across multiple requests and ServletContext object is available for all the users using the application. You can set cacheable objects into these objects and get
www.precisejava.com/javaperf/j2ee/Servlets.htm 4/7
5/16/13
available for all the users using the application. You can set cacheable objects into these objects and get those objects whenever you require within their scope. The methods that support caching are:
ServletContext.setAttribute(String name, Object cacheableObject); ServletContext.getAttribute(String name); HttpSession.setAttribute(String name, Object cacheableObject); HttpSession.getAttribute(String name);
Here the Persistent mechanism means that you store the session data in the database, file storage or any other persistent storage. There are few a approaches for this mechanism, they are 1. Using your application server's persistent mechanism for session data storage 2. Using your own persistent mechanism by maintaining your own database schema If you use the first approach, generally application server converts the session objects into BLOB data type and stores in the database. If you use second approach, you need to design the schema as per your session fields and need to store the session data by writing JDBC code for that, this gives better performance than the first approach because conversion of session object to BLOB takes more time than directly storing session data. Either of persistent mechanisms give moderate to poor performance when compared to other approaches because of overhead involved in database calls through JDBC and it makes calls to database on every request in order to store that session data and finally it needs to retrieve the whole session data from database but it scales well on increasing session data and concurrent users. URL rewriting gives moderate performance because the data has to pass between the client and server for every request but there is a limitation on amount of data that can be passed through URL rewriting. It gives moderate performance because of overhead involved in network for passing data on every request. Cookies also give moderate performance because they need to pass the session data between client and server. It also has the size limit of 4k for each cookie. Like URL rewriting and Cookies, Hidden fields need to pass the data between client and server. All these three session mechanisms give moderate performance and is inversely proportional to the amount of session data. HttpSession mechanisms gives better performance when compared to other mechanims because it stores the session data in memory and reduces overhead on network. Only session id will be passed between client and the server. But it does not scale well when the session data is huge and the concurrent number of users are more because of increase in memory overhead and also increase in overhead on garbage
www.precisejava.com/javaperf/j2ee/Servlets.htm 5/7
5/16/13
users are more because of increase in memory overhead and also increase in overhead on garbage collection. Remember that choosing the session mechanism from one of the above approaches is not only depends on performance, scalability and security. The best approach is to maintain a balance between performance, security and scalability by choosing a mixed approache. Mixture of HttpSession mechanism and Hidden fields gives both performance and scalability. By putting secure data in HttpSession and non secure data on hidden fields you can achieve better security.
Control HttpSession
If you decided to use HttpSession for your session tracking, then you need to know how your application server/servlet engine implements HttpSession mechanism. You need to take care of the following points. 1. Remove session explicitly 2. Set Session time out value 3. Application server/servelt engine implementation Generally, your application server/servlet engine will have default session time out value as 30 minutes which means that if you don't remove session or manipulate that session for 30 minutes then your servlet engine removes that session from memory. If you set long session time out value such as 1 hour, then it keeps all the session objects till 1 hour. This approach effects scalability and performance because of overhead on memory and garbage collection. In order to reduce memory overhead and to increase performance, it is better to remove/invalidate session explicitly using HttpSession.invalidate() method. and also try to reduce the session time out value as per your application's requirement. Third important point is that your application server may serialize session objects after crossing certain memory limit, It is expensive and effects performance because it not only serializes the single session object but also serializes the total object hierarchy. Use 'transient' for variables to avoid unnecessary serialization. see Serialization for detailed information to improve performance. So know about your application server/servlet engine session implementation mechanism and act accordingly.
www.precisejava.com/javaperf/j2ee/Servlets.htm
Key Points
6/7
5/16/13
Key Points
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Use init() method to cache static data Use StringBuffer rather than using + operator when you concatenate multiple strings Use print() method rather than println() method Use ServletOutputStream rather than PrintWriter to send binary data Initialize the PrintWriter with proper size Flush the data partly Minimize code in the synchronized block Set the content length Release resources in destroy() method. Implement getLastModified() method to use browser cache and server cache Use application server caching facility Use Mixed session mechanisms such as HttpSession with hidden fields Remove HttpSession objects explicitly in your program whenever you finish the task Reduce session time out value as much as possible Use 'transient' variables to reduce serialization overhead if your HttpSession tracking mechanism uses serialization process. 16. Disable servlet auto reloading feature. 17. Use thread pool for your servlet engine and define the size as per application requirement.
Feed back
We appreciate and welcome your comments on this section. Email commentsZZZ@precisejavaZZZ.com (remove ZZZ which is placed to prevent spam). Please note that we may not be able to reply to all the emails due to huge number of emails that we receive but we appreciate your comments and feedback.
Copyright 2001-2005, Ravi Kalidindi and Rohini Kalidindi. All rights reserved.
www.precisejava.com/javaperf/j2ee/Servlets.htm
7/7