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; 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