您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Netty NIO框架性能壓測之如何實現長鏈接,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
需要將ulimit -n 改大,否則nio鏈接開不大。
準備4臺機器(1臺netty服務器,3臺壓測機)
使用apache的ab做壓測工具
壓測代碼:
package org.dueam.sample.netty; package org.dueam.sample.netty; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.util.HashMap; import java.util.Map; import java.util.Random; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.DynamicChannelBuffer; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.channel.ChannelHandler.Sharable; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; public class ChatServer { public static void main(String[] args) throws Exception { if(args.length <1){ args = new String[]{"9876","true"}; } ChannelFactory factory = new NioServerSocketChannelFactory(Executors .newCachedThreadPool(), Executors.newCachedThreadPool()); ServerBootstrap bootstrap = new ServerBootstrap(factory); ChatServerHandler handler = new ChatServerHandler(); ChannelPipeline pipeline = bootstrap.getPipeline(); pipeline.addLast("chat", handler); bootstrap.setOption("child.tcpNoDelay", true); bootstrap.setOption("child.keepAlive", true); int port = Integer.valueOf(args[0]); bootstrap.bind(new InetSocketAddress(port)); boolean fillChat = "true".equals(args[1]); if (fillChat) { ChannelManagerThread cmt = new ChannelManagerThread(); cmt.start(); } BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); while (true) { String command = br.readLine(); if ("dump".equals(command)) { System.out.println("當前活著的數量:" + channel.size()); } else if ("help".equals(command)) { System.out.println("命令列表:"); System.out.println("dump:打印當前情況"); System.out.println("help:幫助文檔"); } } } final static Random random = new Random(); static int max = 0; static class ChannelManagerThread extends Thread { @Override public void run() { while (true) { try { if(max < channel.size()){ max = channel.size() ; System.out.println("live:"+channel.size()); } for (Channel s : channel.values()) { if (random.nextInt(100)>70) { ChannelBuffer cb = new DynamicChannelBuffer(256); cb.writeBytes("Hey!有人來找你了!".getBytes()); s.write(cb); } } sleep(500); } catch (InterruptedException e) { } } } } final static Map<Integer, Channel> channel = new HashMap<Integer, Channel>(); static void log(String message) { System.out.println(message); } @Sharable static class ChatServerHandler extends SimpleChannelHandler { @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) { Channel ch = e.getChannel(); ChannelBuffer cb = new DynamicChannelBuffer(256); cb.writeBytes("Hell!你來了啊!".getBytes()); ch.write(cb); channel.put(e.getChannel().getId(), e.getChannel()); } @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { e.getCause().printStackTrace(); channel.remove(e.getChannel().getId()); log("remove channel by exception! id:" + e.getChannel().getId()); e.getChannel().close(); } @Override public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { channel.remove(e.getChannel().getId()); log("remove channel by exception! id:" + e.getChannel().getId()); } } }
壓測方式:
#加大超時和并發量,并使用keep-alive的方式保持住端口 ./ab -n 20000 -c 20000 -k -t 999999999 -r http://192.168.216.30:9876/
內存損耗:
[root@cap216030 ~]# free -k -t -s 10 -- 原始內存 total used free shared buffers cached Mem: 4149076 189828 3959248 0 13196 95484 -/+ buffers/cache: 81148 4067928 Swap: 2096472 208 2096264 Total: 6245548 190036 6055512 -- 執行 chat server之后 total used free shared buffers cached Mem: 4149076 207236 3941840 0 13216 96244 -/+ buffers/cache: 97776 4051300 Swap: 2096472 208 2096264 Total: 6245548 207444 6038104 -- 59471 個nio連接之后 total used free shared buffers cached Mem: 4149076 474244 3674832 0 13328 96132 -/+ buffers/cache: 364784 3784292 Swap: 2096472 208 2096264 Total: 6245548 474452 5771096
結論:
Netty nio 可以輕松將鏈接開到6W,每個線程大概損壞5k左右的系統內存
編寫Java客戶端做內容實時雙向推送
使用100臺機器每臺機器起1000個線程來模擬客戶端進行壓測
關于“Netty NIO框架性能壓測之如何實現長鏈接”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。