Netty NIO 框架性能压测 – 长链接
来源:互联网 发布:mysql 去掉时分秒 编辑:程序博客网 时间:2024/06/01 09:04
压测准备
- 需要将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 框架性能压测 – 长链接
- Netty NIO 框架性能压测 – 长链接
- Netty Java NIO 高性能Socket 开发框架
- Java异步NIO框架Netty实现高性能高并发
- Java异步NIO框架Netty实现高性能高并发
- Netty:高性能、高可用的NIO通信框架
- NIO框架------Netty
- NIO流行框架 Netty
- java nio框架Netty
- Java NIO框架Netty教程(一) – Hello Netty
- Java NIO框架Netty教程(一) – Hello Netty
- Java NIO框架Netty教程(一) – Hello Netty
- Java NIO框架Netty教程(一) – Hello Netty
- Java NIO框架Netty教程(一) – Hello Netty
- Java NIO框架Netty教程(一) – Hello Netty
- Java NIO框架Netty教程(一) – Hello Netty
- Java NIO框架Netty教程(一) – Hello Netty
- Java NIO框架Netty教程(一) – Hello Netty
- 《认知与设计:理解UI设计准则》读书笔记
- HTTP505错误
- Oracle中recyclebin的保留策略
- Linux下消息队列和socket绝对速度比拼
- VirtualBox中centos网络配置
- Netty NIO 框架性能压测 – 长链接
- java.lang.StackOverflowError
- python 总结(一)
- 在二维码中插入logo
- 【recyclebin】彻底禁用 Oracle回收站功能
- 第三次作业
- 多线程(1)
- 游戏制作学习资料
- Notepad++ 使用技巧之关键字高亮、自动补全