簡體   English   中英

如何修復最大連接超出的問題?

[英]How to fix problem with max connections exceed?

我在異步模式下執行Lua-function,我使用NIOEventLoops。 當我嘗試獲取下一個事件循環並執行Lua函數時,我有一些例外:

com.aerospike.client.AerospikeException$Connection: Error -7 from BB967EF43270008 127.0.0.1 3000: Node BB967EF43270008 127.0.0.1 3000 event loop 5 max connections 100 would be exceeded.
   at com.aerospike.client.cluster.Node.getAsyncConnection(Node.java:657) ~[aerospike-client-4.2.2.jar:?]
   at com.aerospike.client.async.NioCommand.executeCommand(NioCommand.java:184) [aerospike-client-4.2.2.jar:?]
   at com.aerospike.client.async.NioCommand.run(NioCommand.java:146) [aerospike-client-4.2.2.jar:?]
   at com.aerospike.client.async.NioEventLoop.registerCommands(NioEventLoop.java:211) [aerospike-client-4.2.2.jar:?]
   at com.aerospike.client.async.NioEventLoop.runCommands(NioEventLoop.java:173) [aerospike-client-4.2.2.jar:?]
   at com.aerospike.client.async.NioEventLoop.run(NioEventLoop.java:156) [aerospike-client-4.2.2.jar:?]
   at java.lang.Thread.run(Thread.java:748) [?:1.8.0_181]

這是我獲取下一個事件循環的方法:

 private synchronized EventLoop getNextEventLoop() {
        EventLoop next;
        do {
            next = eventLoops.next();
        } while (next.getProcessSize() >= maxConnectionsPerEventLoop);
        return next;
    }

這就是我執行Lua函數的方式:

as.execute(getNextEventLoop()
                , new ExecuteListener() {
                    @Override
                    public void onSuccess(Key key, Object obj) {

                       ...
                    }

                    @Override
                    public void onFailure(AerospikeException exception) {
                       ...
                    }
                }
                , writePolicy
                , key
                , "lua-pack"
                , "funcName"
                , Value.get(binName), Value.get(value)
        );

我怎樣才能避免這種異常?

您正在達到ClientPolicy.maxConnsPerNode限制。 對於500個maxConnsPerNode和5個事件循環,每個事件循環可以為每個節點使用最多100(500/5)個連接。 我假設您的maxConnectionsPerEventLoop值> = 100.此外,在調用getProcessSize()之后將下一個命令發送到事件循環時,無法保證插槽仍然可用。

解決方案是在每個事件循環上限制maxCommandsInProcess 這是限制飛行命令(以及連接)的線程安全方法。

EventPolicy eventPolicy = new EventPolicy();
eventPolicy.maxCommandsInProcess = 100;  // max 100 commands per event loop.
eventPolicy.maxCommandsInQueue = 0;      // unbounded queue

int eventLoopSize = 5;
EventLoops eventLoops = new NioEventLoops(eventPolicy, eventLoopSize);

ClientPolicy clientPolicy = new ClientPolicy();
clientPolicy.eventLoops = eventLoops;
clientPolicy.maxConnsPerNode = eventPolicy.maxCommandsInProcess * eventLoopSize;

當達到maxCommandsInProcess限制時,async命令隊列用於命令。 如果傳入命令的速率始終超過處理命令的速率,則應用程序可能會耗盡內存。 要避免這種情況,您可能需要限制隊列大小。

eventPolicy.maxCommandsInQueue = 10000;

如果達到此隊列大小,則拋出AerospikeException.AsyncQueueFull異常。 您的應用程序應該通過在非事件循環線程中延遲命令來響應,直到eventLoop.getQueueSize()足夠低。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM