FrameBuffer為AbstractNonblockingServer類的內部類,TThreadedSelectorServer繼承了AbstractNonblockingServer:
通過研究代碼,發現FrameBuffer的read方法的代碼中有如下片段,
// pull out the frame size as an integer. int frameSize = buffer_.getInt(0); if (frameSize <= 0) { LOGGER.error("Read an invalid frame size of " + frameSize + ". Are you using TFramedTransport on the client side?"); return false; } // if this frame will always be too large for this server, log the // error and close the connection. if (frameSize > MAX_READ_BUFFER_BYTES) { LOGGER.error("Read a frame size of " + frameSize + ", which is bigger than the maximum allowable buffer size for ALL connections."); return false; }
MAX_READ_BUFFER_BYTES這個值即為對讀取的包的長度限制,為AbstractNonblockingServer類的屬性,其值又取自內部類AbstractNonblockingServerArgs的maxReadBufferBytes屬性,默認值為long型的最大值;
即只要修改maxReadBufferBytes的值就可以起到限制的作用,修改服務啟動的代碼如下:
TThreadedSelectorServer.Args args = new TThreadedSelectorServer.Args(transport).processor( processor).workerThreads(this.serverWorkerThreads); // The maximum amount of memory we will allocate to client IO buffers at a time. // set 1MB. args.maxReadBufferBytes = 1024 * 1024L; server = new TThreadedSelectorServer(args); server.setServerEventHandler(new DataIfaceServerEvent()); LOG.info("DataIfaceServer start, port={}.", this.serverPort); server.serve();
args.maxReadBufferBytes = 1024 * 1024L; --設置為1M
通過對我的thrift的服務進行抓包調研,我的方法調用請求數據包沒有超過200字節的,所以1M的長度限制是足夠了。
通過測試如上的修改沒有問題,並且對服務繼續發送http get請求不會導致直接內存增加。並且報出錯誤日志:
Read a frame size of XXX, which is bigger than the maximum allowable buffer size for ALL connections.
至此問題解決;
問題的分析過程:http://my.oschina.net/shipley/blog/422204
