1
2
3
4
5
6
7
8
9
10
11
12
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
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
88 barrier.await();
89 long start = System.nanoTime();
90
91
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
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
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
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
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 }