Optimizing for the Java Servlet API Database Access

Optimizing for the Java™ Servlet API & Database Access SSE USTC Qing Ding

Agenda l l l Servlet Synchronization &Thread Model Servlet Performance Measurement Optimization Areas – – l l Synchronization Objects creation Page caching technique Avoid converstion Servlet optimization techniques Optimizing Data Access

A Review of Java Servlet Architecture l l l Servlet: An object that implements javax. servlet. Servlets get executed in a servlet container init() and destroy() get called once The container receives requests and invokes the servlet’s service() method New thread created for each request Http. Servlet provides useful starting point

Servlet Programming Is Different l Servlets are long-lived – – l Most created objects are short-lived – l Memory management matters! Out-of-memory errors Heap thrashing can kill performance Very high thread load – – Under-synchronize: erratic bugs Over-synchronize: performance suffers

Servlet Synchronization &Thread Model

Concurrency Issues on a Servlet l l The service() method of a servlet instance can be invoked by multiple clients (multiple threads) Servlet programmer has to deal with concurrency issue – – l shared data needs to be protected this is called “servlet synchronization” 2 options for servlet synchronization – – use of synchronized block use of Single. Thread. Model

Many Threads, One Servlet Instance

Use of synchronized block l Synchronized blocks are used to guarantee only one thread at a time can execute within a section of code synchronized(this) { my. Number = counter + 1; counter = my. Number; }. . . synchronized(this) { counter = counter - 1 ; }

Single. Thread. Model Interface l l Servlets can also implement javax. servlet. Single. Thread. Model The server will manage a pool of servlet instances Guaranteed there will only be one thread per instance This could be overkill in many instances Public class Single. Thread. Model. Servlet extends Http. Servlet implements Single. Thread. Model {. . . }

Single. Thread. Model

Best Practice Recommendation l Do use synchronized block whenever possible – Single. Thread. Model is expensive (performance wise)

Invoker Servlet

What is Invoke Servlet? l l Executes anonymous servlet classes that have not been defined in a web. xml file Mostly used for debugging and testing purpose

How to Use Invoke Servlet?

How to Use Invoke Servlet?

Servlet Performance Measurement

Basic Measurements: Pages/Second l l Test with an external program Apache ab is a good start Test with simultaneous requests Browse website during test to look

Basic Measurements: Seconds/Page l l l Test from within your program Check System. current. Time. Millis() at start/end of critical sections Report to System. err, but not too frequently Good: Track min/avg/max Better: Keep counts for time ranges

Other Useful Measurements l l l Database requests per page System load average Heap usage: Runtime. total. Memory()Runtime. free. Memory() – – Too high: Risk out-of-memory problems Too low: Not caching enough

Synchronization

Synchronization l l l Symptom: Wrong output under load Diagnosis: Unsynchronized changes to shared data Solution: Don’t use shared data – – l Be wary of instance data Use the stack: Arguments and locals are safer Solution: Synchronize access to shared data

Over-Synchronization l l l Symptom: Many threads waiting on a single monitor Diagnosis: Excessive synchronization Solution: Reduce synchronization – Use local variables and arguments

Object Creation

The “Textbook” Approach String build. Form(args) { String. Buffer b = new String. Buffer(); Two heap allocations b. append(. . . . ); b. append(. . ); return b. to. String(); One heap allocations }

Minimize Object Creation void build. Form(String. Buffer b, args) { b. append(. . . . ); b. append(. . ); No heap allocations unless } String. Buffer needs to resize its internal storage

Reducing Heap Activity Matters l l l Reduced garbage collection Heap allocation is synchronized Reducing heap activity leads to big performance gains

Page Caching Technique

Cache Page Components Page Cache Piece Cache Data Cache

Piece Cache l l l HTML/XML output is built up from pieces Don’t rebuild pieces unnecessarily Store pieces as bytes whenever possible

Cache Database Results

Basic Fast Servlet class Fast. Servlet extends Http. Servlet { void do. Get(request, response) { String uri=request. get. Request. URI(); Servable servable; if(!cache. contains(uri)) { servable=generic. Response(uri); cache. put(uri, servable); } servable=cache. get(uri); Output. Stream out; out=response. get. Output. Stream(); servable. emit(out); } }

Page Cache class Fast. Servlet extends Http. Servlet { void do. Get(request, response) { String uri=request. get. Request. URI(); Servable servable; if(!cache. contains(uri)) { servable=generic. Response(uri); cache. put(uri, servable); } servable=cache. get(uri); Output. Stream out; out=response. get. Output. Stream(); servable. emit(socket); Cache implements Hash. Map } }

What Goes Into the Page Cache?

What Goes Into the Page Cache? class Fast. Servlet extends Http. Servlet { void do. Get(request, response) { String uri=request. get. Request. URI(); Servable servable; if(!cache. contains(uri)) { servable=generic. Response(uri); cache. put(uri, servable); } } }

Servable Interface Servable is something that can be sent as an HTTP response interface Servable { void emit(Output. Stream); String get. Content. Type(); } l

Text Servable = “Page” l l Page: Servable that holds a text response Create page at top level, pass down into methods that add text Page is mostly a String. Buffer Use placeholder objects for dynamic elements

Page Class class Page implements Servable { void append(String); void append(int); void append(double); void append(Object o); void add. Dynamic(Servable) { //Store placeholder at current pos } void emit(Output. Stream) { //Write bytes to socket, //Invoke emit() for each placeholder } }

Placeholders for Performance l l l Want to avoid rebuilding pages Solution: cache full pages But, what about dynamic elements? Placeholder objects get invoked each time a page is served Result: Most page-building is avoided, but dynamic elements are always fresh

Avoid Conversions

Optimization: Avoid Conversions l l l Converting chars to bytes is very slow Always use Output. Stream, never Print. Writer Store bytes, not characters

Basic Fast Servlet class Fast. Servlet extends Http. Servlet { void do. Get(request, response) { String uri=request. get. Request. URI(); Servable servable; if(!cache. contains(uri)) { servable=generic. Response(uri); cache. put(uri, servable); } servable=cache. get(uri); Output. Stream out; out=response. get. Output. Stream(); servable. emit(out); } }

Performance Improvement Tips (Quoted from precisejava. com)

Generic Coding Techniques in service() Method l l l l Use String. Buffer over String and + Use print() over println() Use Servlet. Output. Stream over Print. Writer Initialize Print. Writer with proper buffer size Flush data partly for large amount of data Minimize the synchronization block Set the content length

One-time Resource Allocation and Deallocation l Use init() method for one time (per servlet instance) resource allocation – – l Database connection Socket Use destroy() method for resource

Caching Techniques l l Use init() to cache static data Utilizing browser caching Caching dynamic data at the server Utilizing HTTPSession and Servlet. Context objects as cache

Use init() method as Cache l l l init() method is called only once service() method gets many times Create and cache static data in init() method once Dynamic data get generated in service() Useful when large amount of static data need to be returned repeatedly

Example: Bad Practice public void service(Http. Servlet. Request req, Http. Servlet. Respnse res) throws Servlet. Exception, IOException { res. set. Content. Type(“text/html”); Printwriter out = req. get. Writer(); out. print("<html>”); out. print("<head><title>Hello world</title></head>”); out. print(“<body>”); // send the dynamic data here out. print(“</body>”); out. print("</html>”);
![Example: Good Practice public class servlet extends Http. Servlet { byte[] header; byte[] navbar; Example: Good Practice public class servlet extends Http. Servlet { byte[] header; byte[] navbar;](http://slidetodoc.com/presentation_image_h/2d38577dbfa38acc7924067b4694a2aa/image-48.jpg)
Example: Good Practice public class servlet extends Http. Servlet { byte[] header; byte[] navbar; byte[] footer; byte[] other. Static. Data; public void init(Servlet. Config config) throws Servlet. Exception{ //create all the static data here String. Buffer sb = new String. Buffer(); // better to initialize the String. Buffer with to improve performance sb. append("<html>”); sb. append("<head><title>Hello world</title></head>”); sb. append(“<body>”); header = sb. to. String(). get. Bytes(); // do same for navbar if its data is static // do same for footer if its data is static } public void service(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/html"); Servlet. Output. Stream out = res. get. Output. Stream(); out. write(header); out. write(navbar); // write dynamic data here out. write(footer); } }

Utilize Browser Caching l l Browser has the page in its cache Servlet implements get. Last. Modified() method (of HTTPServlet class) – – – l l Browser send “if modified since” header Servlet engine calls get. Last. Modified() If not modified, servlet engine responds with “Not Modified” (304 status code) Avoids calling service() if the output content has not changed Useful when client hits reload on his browser

Caching Data at the Server l Cache servlet's output at the server – l Can send it to different clients Servlet implements get. Last. Modified() method (of HTTPServlet class) – Servlet engine calls get. Last. Modified()

Utilizing HTTPSession and Servlet. Conext Objects as Cache l HTTPSession – l Shared by multiple requests per session Servlet. Context – Shared by all users using the application

Choose Right Session Mechanism l Options – – l Http. Session Hidden fields Cookies URL rewriting Factors to consider – – Amount of session data Number of concurrent users

Use and Optimize Thread Pool l Servlet engine creates a thread for each request by default Avoid “creation” and “destruction” of threads by having a thread pool Set minimum and maximum number of thread pool based on # of concurrent users – Product dependent feature

Control HTTPSession l Remove session explicitly using HTTPSession. invalidate() – l l Otherwise session object stays in memory until timeout Set optimal session timeout value Optimize serialization of Session object via Transient

Optimize Database Access (Quoted from precisejava. com)

Choose Right Driver l Use Type 4 driver (Java driver) whenever possible – l Best performance since no conversion of JDBC calls to ODBC or native calls Between Type 1 and Type 2, use Type 2

Optimize Connection Properties l l l Set optimal row pre-fetch value Use connection pool Control transaction Choose optimal isolation level Close connection when closed

Set Optimal Row Pre-fetch Value l l Depends on application Example code java. util. Properties props = new java. util. Properties(); props. put("default. Row. Prefetch", "30"); props. put("default. Batch. Value", "5"); Connection con = Driver. Manger. get. Connection(url, props);

Use Connection Pool l l Open/close DB connection takes time Pool holds several open connections Components get connection from pool Pool should expire/reopen connections Pool should support multiple DBs

Control Transaction l Do batch transaction instead of Autocommitting (commit call after each Statement execution) – Reduce the number of commit calls to the database

Example: Batch Transaction try{ connection. set. Auto. Commit(false); Prepared. Statement ps = connection. preare. Statement( "UPDATE employee SET Address=? WHERE name=? "); ps. set. String(1, "Austin"); ps. set. String(2, "RR"); ps. execute. Update(); Prepared. Statement ps 1= connection. prepare. Statement( "UPDATE account SET salary=? WHERE name=? "); ps 1. set. Double(1, 5000. 00); ps 1. set. String(2, "RR"); ps 1. execute. Update(); connection. commit(); connection. set. Auto. Commit(true); } catch(SQLException e){ connection. rollback(); } finally{ if(ps != null){ ps. close(); } if(ps 1 != null){ps 1. close(); } if(connection != null){connection. close(); } }

Choose Optimum Isolation Level l l 5 Isolation levels – TRANSACTION_NONE – TRANSACTION_READ_COMMITTED – TRANSACTION_READ_UNCOMMITTED – TRANSACTION_REPEATABLE_READ

Close Connection When Finished l Let garbarge collector to recollect memory as soon as possible

Optimization with Statement l l Choose right Statement interface Do batch update Do batch retrieval using Statement Close Statement when finished

Choose Right Statement Interface l 3 Statement interfaces – – – l l Statement Prepared. Statement Callable. Statement Use Prepared. Statement when a Statement is executed repeatedly with different input value Use Callable. Statement when a single request has complext Statements

Do Batch Update l l Reduces number of JDBC calls Example statement. add. Batch( "sql query 1"); statement. add. Batch(" sql query 2"); statement. add. Batch(" sql query 3"); statement. execute. Batch();

Resources l Java performance documents – l J 2 EE performance improvement tips – l java. sun. com/docs/performance www. precisejava. com Servlet cache schemes
- Slides: 67