我试图在我的程序中嵌入一个码头服务器,它似乎在每个线程到达服务器一个请求后挂起。我写的测试用例代码是:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.thread.QueuedThreadPool;
public class EmbeddedJetty
{
public static void initServer(int port) throws Exception
{
final AtomicLong counter = new AtomicLong();
final Server server = new Server(port);
server.setThreadPool(new QueuedThreadPool(3));
Context context = new Context(server, "/", Context.SESSIONS);
context.addServlet(new ServletHolder(new HttpServlet()
{
@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException
{
PrintWriter writer = resp.getWriter();
String msg = "Served page #" + counter.incrementAndGet() +
" at " + new Date();
writer.print(msg);
writer.close();
System.out.println("[Server] " + msg);
}
}), "/*");
server.start();
System.out.println("[Server] Started Jetty server");
}
public static void initClient(final int port)
{
new Thread()
{
public void run()
{
String urlString = "http://localhost:" + port + "/myBT";
while (true)
{
try
{
System.out.println("[Client] Sending request to " +
urlString);
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(urlString);
HttpResponse response = httpclient.execute(httpget);
StatusLine statusLine = response.getStatusLine();
System.out.println("[Client] Got response [" +
response.getProtocolVersion() + "] [" +
statusLine.getStatusCode() + "] [" +
statusLine.getReasonPhrase() + "]");
HttpEntity entity = response.getEntity();
if (entity != null)
{
entity.consumeContent();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}.start();
}
public static void main(String[] args) throws Exception
{
int port = 8090;
initServer(port);
initClient(port);
}
}
这个程序的输出是:
$ java -cp build/libs/sqlcache.jar EmbeddedJetty
2012-10-04 23:24:30.797:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
2012-10-04 23:24:30.842:INFO::jetty-6.1.x
2012-10-04 23:24:30.945:INFO::Started SocketConnector@0.0.0.0:8090
[Server] Started Jetty server
[Client] Sending request to http://localhost:8090/myBT
[Server] Served page #1 at Thu Oct 04 23:24:31 PDT 2012
[Client] Got response [HTTP/1.1] [200] [OK]
[Client] Sending request to http://localhost:8090/myBT
[Server] Served page #2 at Thu Oct 04 23:24:31 PDT 2012
[Client] Got response [HTTP/1.1] [200] [OK]
[Client] Sending request to http://localhost:8090/myBT
然后它挂起。
线程转储看起来像:
Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.10-b01-428 mixed mode):
"454514340@qtp-703447155-2" prio=5 tid=1029f2000 nid=0x10aa38000 runnable [10aa37000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at org.mortbay.io.ByteArrayBuffer.readFrom(ByteArrayBuffer.java:382)
at org.mortbay.io.bio.StreamEndPoint.fill(StreamEndPoint.java:114)
at org.mortbay.jetty.bio.SocketConnector$Connection.fill(SocketConnector.java:198)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:290)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
"DestroyJavaVM" prio=5 tid=102928000 nid=0x100501000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE
"Thread-5" prio=5 tid=1029d5800 nid=0x10a935000 runnable [10a934000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:130)
at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:127)
at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:233)
at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:98)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:210)
at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:271)
at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:233)
at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:209)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:292)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:126)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:483)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
at EmbeddedJetty$2.run(EmbeddedJetty.java:67)
"Timer-0" daemon prio=5 tid=101b8f800 nid=0x10a820000 in Object.wait() [10a81f000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <7f42b20d0> (a java.util.TaskQueue)
at java.util.TimerThread.mainLoop(Timer.java:509)
- locked <7f42b20d0> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:462)
"Poller SunPKCS11-Darwin" daemon prio=1 tid=10286e800 nid=0x10a71d000 waiting on condition [10a71c000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at sun.security.pkcs11.SunPKCS11$TokenPoller.run(SunPKCS11.java:692)
at java.lang.Thread.run(Thread.java:680)
"1753620260@qtp-703447155-1 - Acceptor0 SocketConnector@0.0.0.0:8090" prio=5 tid=1019af800 nid=0x10a5ec000 runnable [10a5eb000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
- locked <7f42b2238> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at org.mortbay.jetty.bio.SocketConnector.accept(SocketConnector.java:99)
at org.mortbay.jetty.AbstractConnector$Acceptor.run(AbstractConnector.java:708)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
"1169804875@qtp-703447155-0" prio=5 tid=101a12000 nid=0x10a4e9000 runnable [10a4e8000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at org.mortbay.io.ByteArrayBuffer.readFrom(ByteArrayBuffer.java:382)
at org.mortbay.io.bio.StreamEndPoint.fill(StreamEndPoint.java:114)
at org.mortbay.jetty.bio.SocketConnector$Connection.fill(SocketConnector.java:198)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:290)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
"Low Memory Detector" daemon prio=5 tid=1018a8000 nid=0x10a013000 runnable [00000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=9 tid=1018a7000 nid=0x109f10000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=9 tid=1018a6800 nid=0x109e0d000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=9 tid=1018a5800 nid=0x109d0a000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE
"Surrogate Locker Thread (Concurrent GC)" daemon prio=5 tid=1018a4800 nid=0x109c07000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=8 tid=10189c000 nid=0x1098ea000 in Object.wait() [1098e9000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <7f42c92e0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <7f42c92e0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=10 tid=10189b000 nid=0x1097e7000 in Object.wait() [1097e6000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <7f42b02a8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <7f42b02a8> (a java.lang.ref.Reference$Lock)
"VM Thread" prio=9 tid=101896800 nid=0x1096e4000 runnable
"Gang worker#0 (Parallel GC Threads)" prio=9 tid=101802800 nid=0x102201000 runnable
"Gang worker#1 (Parallel GC Threads)" prio=9 tid=101803000 nid=0x102304000 runnable
"Concurrent Mark-Sweep GC Thread" prio=9 tid=10184d800 nid=0x1093f0000 runnable
"VM Periodic Task Thread" prio=10 tid=1018b9800 nid=0x10a116000 waiting on condition
"Exception Catcher Thread" prio=10 tid=101801800 nid=0x1017fa000 runnable
JNI global references: 1726
Heap
par new generation total 19136K, used 3756K [7f3000000, 7f44c0000, 7f44c0000)
eden space 17024K, 9% used [7f3000000, 7f319b348, 7f40a0000)
from space 2112K, 100% used [7f42b0000, 7f44c0000, 7f44c0000)
to space 2112K, 0% used [7f40a0000, 7f40a0000, 7f42b0000)
concurrent mark-sweep generation total 63872K, used 350K [7f44c0000, 7f8320000, 7fae00000)
concurrent-mark-sweep perm gen total 21248K, used 9994K [7fae00000, 7fc2c0000, 800000000)
我正在使用Jetty 6.1.26。
是什么导致服务器挂起?
编辑:添加超时,如:
SocketConnector connector = new SocketConnector();
connector.setMaxIdleTime(1000);
connector.setSoLingerTime(-1);
connector.setPort(port);
server.setConnectors(new Connector[] { connector });
似乎解决了这个问题,但我想首先了解出了什么问题。