View Javadoc

1   // ========================================================================
2   // Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // Licensed under the Apache License, Version 2.0 (the "License");
5   // you may not use this file except in compliance with the License.
6   // You may obtain a copy of the License at
7   // http://www.apache.org/licenses/LICENSE-2.0
8   // Unless required by applicable law or agreed to in writing, software
9   // distributed under the License is distributed on an "AS IS" BASIS,
10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  // See the License for the specific language governing permissions and
12  // limitations under the License.
13  // ========================================================================
14  
15  package org.mortbay.terracotta.servlet;
16  
17  import java.io.IOException;
18  import java.io.PrintWriter;
19  import java.util.Random;
20  import java.util.concurrent.CyclicBarrier;
21  import java.util.concurrent.ExecutorService;
22  import java.util.concurrent.Executors;
23  import java.util.concurrent.TimeUnit;
24  
25  import javax.servlet.ServletException;
26  import javax.servlet.http.HttpServlet;
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  import javax.servlet.http.HttpSession;
30  
31  import org.mortbay.jetty.HttpMethods;
32  import org.mortbay.jetty.client.ContentExchange;
33  import org.mortbay.jetty.client.HttpClient;
34  
35  /**
36   * @version $Revision: 1228 $ $Date: 2008-09-25 08:47:13 -0500 (Thu, 25 Sep 2008) $
37   */
38  public class LightLoadTest
39  {
40      public static void main(String[] args) throws Exception
41      {
42          new LightLoadTest().testLightLoad();
43      }
44  
45      public void testLightLoad() throws Exception
46      {
47          String contextPath = "";
48          String servletMapping = "/server";
49          int port1 = 8080;
50          TerracottaJettyServer server1 = new TerracottaJettyServer(port1);
51          server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
52          server1.start();
53          try
54          {
55              int port2 = 8181;
56              TerracottaJettyServer server2 = new TerracottaJettyServer(port2);
57              server2.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
58              server2.start();
59              try
60              {
61                  HttpClient client = new HttpClient();
62                  client.setConnectorType(HttpClient.CONNECTOR_SOCKET);
63                  client.start();
64  
65                  try
66                  {
67                      ContentExchange exchange1 = new ContentExchange(true);
68                      exchange1.setMethod(HttpMethods.GET);
69                      exchange1.setURL("http://localhost:" + port1 + contextPath + servletMapping + "?action=init");
70                      client.send(exchange1);
71                      exchange1.waitForDone();
72                      assert exchange1.getResponseStatus() == HttpServletResponse.SC_OK;
73                      String sessionCookie = exchange1.getResponseFields().getStringField("Set-Cookie");
74                      assert sessionCookie != null;
75  
76                      ExecutorService executor = Executors.newCachedThreadPool();
77                      int clientsCount = 10;
78                      CyclicBarrier barrier = new CyclicBarrier(clientsCount + 1);
79                      int requestsCount = 100;
80                      Worker[] workers = new Worker[clientsCount];
81                      for (int i = 0; i < clientsCount; ++i)
82                      {
83                          workers[i] = new Worker(barrier, requestsCount, sessionCookie);
84                          workers[i].start();
85                          executor.execute(workers[i]);
86                      }
87                      // Wait for all workers to be ready
88                      barrier.await();
89                      long start = System.nanoTime();
90  
91                      // Wait for all workers to be done
92                      barrier.await();
93                      long end = System.nanoTime();
94                      long elapsed = TimeUnit.NANOSECONDS.toMillis(end - start);
95                      System.out.println("elapsed ms: " + elapsed);
96  
97                      for (Worker worker : workers) worker.stop();
98                      executor.shutdownNow();
99  
100                     // Perform one request to get the result
101                     ContentExchange exchange2 = new ContentExchange(true);
102                     exchange2.setMethod(HttpMethods.GET);
103                     exchange2.setURL("http://localhost:" + port1 +contextPath + servletMapping + "?action=result");
104                     exchange2.getRequestFields().add("Cookie", sessionCookie);
105                     client.send(exchange2);
106                     exchange2.waitForDone();
107                     assert exchange2.getResponseStatus() == HttpServletResponse.SC_OK;
108                     String response = exchange2.getResponseContent();
109                     System.out.println("get = " + response);
110                     assert response.trim().equals(String.valueOf(clientsCount * requestsCount));
111                 }
112                 finally
113                 {
114                     client.stop();
115                 }
116             }
117             finally
118             {
119                 server2.stop();
120             }
121         }
122         finally
123         {
124             server1.stop();
125         }
126     }
127 
128     public static class Worker implements Runnable
129     {
130         private final HttpClient client;
131         private final CyclicBarrier barrier;
132         private final int requestsCount;
133         private final String sessionCookie;
134 
135         public Worker(CyclicBarrier barrier, int requestsCount, String sessionCookie)
136         {
137             this.client = new HttpClient();
138             this.client.setConnectorType(HttpClient.CONNECTOR_SOCKET);
139             this.barrier = barrier;
140             this.requestsCount = requestsCount;
141             this.sessionCookie = sessionCookie;
142         }
143 
144         public void start() throws Exception
145         {
146             client.start();
147         }
148 
149         public void stop() throws Exception
150         {
151             client.stop();
152         }
153 
154         public void run()
155         {
156             try
157             {
158                 // Wait for all workers to be ready
159                 barrier.await();
160 
161                 String contextPath = "";
162                 String servletMapping = "/server";
163                 Random random = new Random(System.nanoTime());
164 
165                 for (int i = 0; i < requestsCount; ++i)
166                 {
167                     boolean master = random.nextInt(2) > 0;
168                     int port = master ? 8080 : 8181;
169 
170                     ContentExchange exchange = new ContentExchange(true);
171                     exchange.setMethod(HttpMethods.GET);
172                     exchange.setURL("http://localhost:" + port + contextPath + servletMapping + "?action=increment");
173                     exchange.getRequestFields().add("Cookie", sessionCookie);
174                     client.send(exchange);
175                     exchange.waitForDone();
176                     assert exchange.getResponseStatus() == HttpServletResponse.SC_OK;
177                 }
178 
179                 // Wait for all workers to be done
180                 barrier.await();
181             }
182             catch (Exception x)
183             {
184                 throw new RuntimeException(x);
185             }
186         }
187     }
188 
189     public static class TestServlet extends HttpServlet
190     {
191         @Override
192         protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
193         {
194             String action = request.getParameter("action");
195             if ("init".equals(action))
196             {
197                 HttpSession session = request.getSession(true);
198                 session.setAttribute("value", 0);
199             }
200             else if ("increment".equals(action))
201             {
202                 // Without synchronization, because it is taken care by Jetty/Terracotta
203                 HttpSession session = request.getSession(false);
204                 int value = (Integer)session.getAttribute("value");
205                 session.setAttribute("value", value + 1);
206             }
207             else if ("result".equals(action))
208             {
209                 HttpSession session = request.getSession(false);
210                 int value = (Integer)session.getAttribute("value");
211                 PrintWriter writer = response.getWriter();
212                 writer.println(value);
213                 writer.flush();
214             }
215         }
216     }
217 }