2

HTTPBuilder を使用して、NoSQL データベースの REST API 用のクライアントを構築しています。大規模なデータセットを処理する場合を除いて、正常に機能します。多数の呼び出しの後、クライアントは次の例外をスローします。

java.net.SocketException: No buffer space available (maximum connections reached?): connect
at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:127)
at  org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:640)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:446)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:417)
at groovyx.net.http.HTTPBuilder.request(HTTPBuilder.java:366)
at groovyx.net.http.HTTPBuilder$request.call(Unknown Source)
at scripts.groovy.prototypes.NeoClient.getRelationship(NeoClient.groovy:70)
at com.gsgenetics.genie.trait.Node$Edge.getTargetNode(Node.java:108)
at com.gsgenetics.genie.trait.Node$Edge.compareTo(Node.java:145)
at com.gsgenetics.genie.trait.Node$Edge.compareTo(Node.java:67)
at com.gsgenetics.genie.trait.Node.getEdges(Node.java:32)
at com.gsgenetics.genie.trait.Node.iterator(Node.java:384)
at com.gsgenetics.genie.GenomeStructuredGraph.add(GenomeStructuredGraph.java:131)
at com.gsgenetics.genie.GenomeStructuredGraph.add(GenomeStructuredGraph.java:197)
at com.gsgenetics.genie.GenomeStructuredGraph$add.call(Unknown Source)
at scripts.groovy.prototypes.read-ccds$_run_closure3.doCall(read-ccds.groovy:53)
at scripts.groovy.prototypes.read-ccds.run(read-ccds.groovy:50)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

一部のリソースがリリースされていないようですが、正確に何をどのようにリリースするかを理解できません。これを Windows 7 で実行していますが、Linux で実行すると同様のエラーが発生します。

HTTPBuilder をインスタンス化して使用しているコードは次のとおりです。

import groovyx.net.http.*
import net.sf.json.JSONArray
import net.sf.json.JSONObject

import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*

class NeoClient {

    static final URL = 'http://some IP address'
//    static def http = new HTTPBuilder( URL )
    static net.sf.json.JSONObject query(statement, params=null, success=null, error=null) {
        def http = new HTTPBuilder( URL )
        net.sf.json.JSONObject returnJson = []
        http.request( POST, JSON ) {
            uri.path = '/db/data/cypher/'
            headers.'X-Stream' = 'true'
            requestContentType = JSON
            body =  [ query : statement , params : params ?: [:] ]


            response.success = { resp, json ->
                if (success) success(json)
                else {
                    println "Status ${resp.statusLine} Columns ${json.columns}\nData: ${json.data}"
                }
                returnJson = json
            }

            response.failure = { resp, message ->
                def result=[status:resp.statusLine.statusCode,statusText:resp.statusLine.reasonPhrase]
                result.headers = resp.headers.collect { h -> [ (h.name) : h.value ] }
                result.message = message
                if (error) {
                    error(result)
                } else {
                    println "Status: ${result.status} : ${result.statusText} "
                    println "Headers: ${result.headers}"
                    println "Message: ${result.message}"
                }
                throw new Exception("Neo Client Exception");
            }
        }
    }
}

静的クラス NeoClient に HTTPBuilder の単一のインスタンスを作成し、「クエリ」への呼び出しごとに HTTPBuilder の新しいインスタンスを作成しようとしたことに注意してください。いずれの場合も同じ例外が発生します。

どんなアイデアでも大歓迎です。

ありがとう

4

1 に答える 1

3

このインスタンスが保持しているシステム リソースを解放するには、 HTTPBuilder.shutdownメソッドを使用する必要があります。

さらに、HTTPBuilder要求ごとに新しいを作成することは、パフォーマンスとリソース管理の点で最善の方法ではありません。より良いアプローチは、HttpBuilder複数のリクエストを処理する単一のインスタンスを持つことです。HttpBuilderこれを行うには、スレッド セーフな接続マネージャーを使用するように の既定の動作をオーバーライドする必要があります。

private static class CustomHttpBuilder extends HttpBuilder {
    protected AbstractHttpClient createClient( HttpParams params ) {
       def connManager = new MultiThreadedHttpConnectionManager()
       def connManagerParams = new HttpConnectionManagerParams()
       connManagerParams.maxTotalConnections = 50 // default is 20
       connManagerParams.defaultMaxConnectionsPerHost = 50 // default is 2
       connManager.params = connManagerParams
       new HttpClient(connManager)
   }
} 

このコード例はGrails ユーザー フォーラムから入手しました。CustomHttpBuilderこれにより、複数のリクエストに対して の 1 つのインスタンスを使用できます。

于 2013-09-18T14:14:28.413 に答える