3

を使用して実装された単純な HTTPS サーバーが、この PHP プロキシ(curl を使用)com.sun.net.httpserver.HttpServer経由で呼び出されると、正常に動作します。しかし、プロキシを使用せずに Web フォームを変更して、ブラウザーが要求をサーバーに直接送信するようにすると、サーバーが不安定になり、応答しなくなることがあります。その後、クライアントはタイムアウトになるまで応答を待ちます。この問題は再現が難しく、ライブ システムで数時間後に発生することがあります。これらはすべて、非標準ポート (現在は 8081) で HTTPS 経由で行われます。私のサーバーは XML を返します。

サーバーが応答しなくなったときに表示されるスタックトレース (" kill -QUIT [pid]" 経由):

"Thread-2" prio=10 tid=0x0000000017fc4800 nid=0x1c2b runnable
    [0x00002ba5ec97c000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:218)
at sun.nio.ch.IOUtil.read(IOUtil.java:191)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:359)
    - locked <0x00000000fd1e4b98> (a java.lang.Object)
at sun.net.httpserver.SSLStreams$EngineWrapper.recvAndUnwrap(SSLStreams.java:334)
    - locked <0x00000000fd1e4c58> (a java.lang.Object)
at sun.net.httpserver.SSLStreams.recvData(SSLStreams.java:409)
at sun.net.httpserver.SSLStreams$InputStream.read(SSLStreams.java:524)
at sun.net.httpserver.SSLStreams$InputStream.read(SSLStreams.java:593)
at sun.net.httpserver.Request.readLine(Request.java:84)
at sun.net.httpserver.Request.<init>(Request.java:54)
at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:529)
at sun.net.httpserver.ServerImpl$DefaultExecutor.execute(ServerImpl.java:156)
at sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:424)
at sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:389)
at java.lang.Thread.run(Thread.java:722)

私がすでに試したこと: http ヘッダーの送信Connection: close- 役に立ちませんでした。複数のスレッドを使用してサーバーに並行してクエリを実行する Java テスト ケースを作成すると、問題なく動作します。

質問は次のとおりです: ブラウザは私のプロキシと何が違うのですか? また、それによってサーバー プロセスがハングするのはなぜですか?

ソース:これは HttpHandlerソースであり、これはそのハンドラーを使用するサーバーのソースです

背景:プロキシをインストールせずに、誰でも自分の Web ページから REST サービスを使用できるようにしたい (Javascript クロスオリジン ポリシーを回避する必要がある)。そのために、サーバーはAccess-Control-Allow-Origin: *ヘッダーを送信します。Java が提供するクラスを使用して、Jetty や Tomcat Embedded と比較してオーバーヘッドを最小限に抑えています。

4

1 に答える 1

7

プロキシとプロキシなしの動作が異なるのはなぜですか?

  • プロキシなしでより多くの接続
  • 実際のブラウザのユーザーは、リクエストを開始してからキャンセル/戻るボタン/新しいリクエストなど、面白いことを行うことができます。

ソケットのタイムアウトを設定する必要があります。残念ながら、API ドキュメントでは、プログラムでこれを行う方法は提案されていません。

ただし、JVM システム プロパティを使用して、リクエストとレスポンスのタイムアウトを設定できます。

http://www.javaworld.com/community/node/8424
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/sun/net/httpserver/ServerConfig .java
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6563368

次のシステム プロパティを設定します。

sun.net.httpserver.clockTick デフォルト値 = 10000、つまり 10 秒

sun.net.httpserver.timerMillis デフォルト値 = 1000、つまり 1 秒

sun.net.httpserver.maxReqTime デフォルト値 = -1、つまり永久に。

デフォルト > 0 はタイムアウト = デフォルト * (clockTick または timerMillis のいずれか) 秒を与える

sun.net.httpserver.maxRspTime デフォルト値 = -1、つまり永久に。

デフォルト > 0 はタイムアウト = デフォルト * (clockTick または timerMillis のいずれか) 秒を与える


明らかに、HttpHandler.handle() メソッドで、応答ヘッダーに応答コードを設定していることを確認してください。

  httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length());  
  final OutputStream os = httpExchange.getResponseBody();  
  os.write( response.getBytes() );  
  os.close(); 
于 2013-04-18T02:51:09.933 に答える