记录使用Netty搭建单机百万连接测试实战

该博客介绍了如何使用Netty编写服务端和客户端代码,包括服务端启动、连接数计数处理器以及客户端连接逻辑。同时,讲解了调整Linux内核参数以增大文件句柄限制,并提供了启动服务时的JVM参数设置。内容涵盖了网络编程、系统优化和Java应用配置。
摘要由CSDN通过智能技术生成

1.编写服务端代码
public class NettyServer {

public static void main(String [] args){
    new NettyServer().run(8000, 8050);
}

public void run(int beginPort, int endPort){
    System.out.println("服务端启动中");

    //配置服务端线程组
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workGroup = new NioEventLoopGroup();
    ServerBootstrap serverBootstrap = new ServerBootstrap();
    serverBootstrap.group(bossGroup, workGroup)
            .channel(NioServerSocketChannel.class)
            .childOption(ChannelOption.SO_REUSEADDR, true); 

    serverBootstrap.childHandler( new TcpCountHandler());


    for(; beginPort < endPort; beginPort++){
        int port = beginPort;
        serverBootstrap.bind(port).addListener((ChannelFutureListener) future->{
            System.out.println("服务端成功绑定端口 port = "+port);
        });
    }

}
}
2.服务端handler处理类
@ChannelHandler.Sharable
public class TcpCountHandler extends ChannelInboundHandlerAdapter {

private AtomicInteger atomicInteger = new AtomicInteger();

public TcpCountHandler(){
    Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(()->{
        System.out.println("当前连接数为 = "+ atomicInteger.get());
    }, 0, 1, TimeUnit.SECONDS);

}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
    atomicInteger.incrementAndGet();
}

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    atomicInteger.decrementAndGet();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    System.out.println("TcpCountHandler exceptionCaught");
    cause.printStackTrace();
}

}
3.编写客户端代码
public class NettyClient {

//使用阿里云可以输入自己的 阿里云IP地址
private static final String SERVER = "127.0.0.1";

public static void main(String [] args){
    new NettyClient().run(Config.BEGIN_PORT, Config.END_PORT);
}

public void run(int beginPort, int endPort){

    System.out.println("客户端启动中");

    EventLoopGroup group = new NioEventLoopGroup();

    Bootstrap bootstrap = new Bootstrap();

    bootstrap.group(group)
            .channel(NioSocketChannel.class)
            .option(ChannelOption.SO_REUSEADDR, true)
            .handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {

                }

            });
    int index = 0 ;
    int finalPort ;
    while (true){
       finalPort = beginPort + index;
        try {
            bootstrap.connect(SERVER, finalPort).addListener((ChannelFutureListener)future ->{
                if(!future.isSuccess()){
                    System.out.println("创建连接失败 " );
                }
            }).get();

        } catch (Exception e) {
            //e.printStackTrace();
        }
        ++index;
        if(index == (endPort - beginPort)){
            index = 0 ;
        }
    }
}

}
4.修改虚拟机或者阿里云linux内核参数(centos6.5/centos7.0)
局部文件句柄限制(单个进程最大文件打开数)
使用 ulimit -n 一个进程最大打开的文件数 fd
不同系统有不同的默认值
root身份编辑 vim /etc/security/limits.conf
增加下面
root soft nofile 1000000
root hard nofile 1000000
* soft nofile 1000000
* hard nofile 1000000
* 表示当前用户,修改后要重启
全局文件句柄限制(所有进程最大打开的文件数,不同系统是不一样,可以直接echo临时修改)
查看命令
cat /proc/sys/fs/file-max
永久修改全局文件句柄
vim /etc/sysctl.conf
增加 fs.file-max = 1000000
修改后生效 sysctl -p
5. 启动(修改jvm虚拟机的参数)
java -jar millionServer-1.0-SNAPSHOT.jar -Xms5g -Xmx5g -XX:NewSize=3g -XX:MaxNewSize=3g
实际到达的连接数:945630
6.注意事项
使用虚拟机测试的时候,建议虚拟机为内存为8G以上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,以下是使用Netty搭建TCP服务器的示例代码(Hello World): ```java import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; public class HelloWorldServer { private final int port; public HelloWorldServer(int port) { this.port = port; } public void run() throws Exception { // 创建两个 EventLoopGroup,一个用于接收客户端连接,一个用于处理客户端请求 EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { // 创建 ServerBootstrap 对象,用于配置服务器 ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { // 添加消息处理器 ch.pipeline().addLast(new HelloWorldServerHandler()); } }); // 绑定端口,开始接收客户端请求 ChannelFuture f = b.bind(port).sync(); // 等待服务器 socket 关闭 f.channel().closeFuture().sync(); } finally { // 释放资源 workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; new HelloWorldServer(port).run(); } } ``` 其中,`HelloWorldServerHandler` 是自定义的消息处理器,可以根据需要进行处理。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值