一起学netty(1)简单的bio模型与性能分析

weblog 1201 0 0

一、什么是bio?

bio即:同步阻塞式IO。 就是传统的java io网络模型。java bio有两个阻塞的地方,第一个地方是需要阻塞的监听端口,等待客户端链接。第二个需要阻塞Socket的read方法,等待客户端发送消息。

先看一个bio最简单的例子:

    public static void main1(String[] args) throws IOException {
        //绑定端口
        ServerSocket serverSocket = new ServerSocket(9000);
        //阻塞 等待链接
        Socket accept = serverSocket.accept();
        System.out.println("建立链接");
        byte[] bytes = new byte[1024];
        //阻塞 等待接收发来的数据
        int read = accept.getInputStream().read(bytes);
        if(read != -1){
            System.out.println("收到数据:"+new String(bytes,0,read));
        }
    }

这是一个最简单的socket的例子,这个例子只能让客户端建立一个链接,接受一次消息。

所以一般的优化方案就是加两个循环,1.循环监听等待客户端链接,2.循环监听等待客户端发送的消息。

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9000);
        while (true){
            //阻塞 等待链接
            Socket accept = serverSocket.accept();
            System.out.println("建立链接");
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true){
                        byte[] bytes = new byte[1024];
                        //阻塞 等待接收发来的数据
                        int read = 0;
                        try {
                            read = accept.getInputStream().read(bytes);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        if(read != -1){
                            System.out.println("收到数据:"+new String(bytes,0,read));
                        }
                    }
                }
            }).start();
        }
    }

因为每个客户端链接都需要一个Socket对象循环监听客户端发送的消息,所以对于每个客户端的链接只能开启一个线程,去循环监听客户端是否发送数据。即使客户端不发送数据,这个线程也需要阻塞。这也是这种网络模型会出现性能瓶颈的主要原因。因为线程是很宝贵的系统资源,线程的上下文切换也很耗费性能。虽然还是可以通过线程池的方式进行优化,但是依然不能解决大量客户端链接(大量线程)带来的性能瓶颈问题。

二、Java BIO 主要性能瓶颈分析/(主要问题)

  • 每个请求都需要创建独立的线程,与对应的客户端进行数据 Read,业务处理,数据 Write 。
  • 当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大。
  • 连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在 Read 操作上,造成线程资源浪费。

猜你喜欢
official 1297 在上节《netty(6)》文章中,要说明了用nio原生代码写程序些不足和问题,以及netty在nio基础上大致做了那些工作。其中提到点就是当活跃客户端数量太多,线程处理时所带
java虚拟机(jvm) 4780 jvm内存(1)已经对内存进行了个宏观概括http://www.jiajiajia.club/weblog/blog/artical/82那么下边具体下方法执行过程还是以
official 1944 篇《netty(2)nio及多路复用器》中已经介绍了nio,以及多路复用器概念,并了解nio是非阻塞网络,以及bio区别。本篇将继续深入理解nio,以及select
official 1462   基于javanio+netty+websocket+protobuf+javascript等技术实现前后端高实时数据传输demo。  github地址:https
official 1039 、最nio程序publicstaticvoidmain(String[]args)throwsException{ ListSocketChannellist=newArrayList
official 1391 之前文章中提到了java中nio是同步非阻塞网络io,本文就主要说明下同步、异步、阻塞、非阻塞概念来帮助理解nio。io操作IO两阶段(旦拿到数据后就变成了数据操作,不再是IO
official 1215 什么是心跳?顾名思义,所谓心跳,即在TCP长连接中,客户端和服务器之间定期发送种特殊数据包,通知对方自己还在线,以确保TCP连接有效。为什么需要心跳?因为网络不可靠,有可在TCP保持
official 1043 根据前几篇文章对bio、nio网络叙述,我们可大概已经了解了io网络演化过程,以及在演化过程中各个阶段各自解决了那些问题,以及是如何提高。随着select、poll
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。