1.什么是Netty

2.Netty的使用场景

3.Netty的学习顺序

4.BIO基本介绍

5.BIO的流程梳理

6.BIO应用实例说明

7.BIO优缺点分析

1.什么是Netty
在我们的日常开发中,按照正常的工作模式,一般都是确定好业务逻辑之后,提供接口给客户端端,然后进行调用即可,也就是说调用普通的接口,生产者和消费者的角色是固定的,永远都是客户端是消费者,服务器端是生产者。

但是我们试想一下这种情况,客户端需要和服务器端保持长链接,并且会互相推送消息(比如说聊天服务器),这个时候,像这种点对点,且互相发送信息的情况下,普通的接口调用已经无法满足我们的业务要求,我们需要一个与服务器通讯相关的框架。

再比如,有非常多的客户端连接到我们的服务器,我们如何将这些连接请求合理地进行编排,让线程得到充分的利用,而不是阻塞。

Netty就非常合适。

Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。

2.Netty的使用场景

2.1)分布式系统的框架中
在分布式系统中,服务和服务之间如何保持连接,如果进行远程服务调用,高性能的RPC框架必不可少,Netty作为异步高性能的通信框架,作为通讯的基础组件被这些框架使用。
2.2)通讯行业
在通讯行业中,往往会有大量的用户同时在线,并且发送信息,如果高效地处理这些链接,并且高效的分发数据,Netty提供了解决方案。

3.Netty的学习顺序

刚开始学习Netty,我们不宜讲太多Netty的概念,因为初听这些词汇非常难懂,我们要从BIO开始,再学习NIO学会NIO三大核心工具),学完后我们会对网络编程有一个初步的了解,也会对服务器中处理连接的模式有一个大概的印象,等到这些基础都学会之后,接下来我们就可以系统地学习Netty。

4.BIO基本介绍

我们先看一下BIO的概念同步阻塞

每当服务器有连接请求的时候,客户端都会启动一个线程去处理(可以通过线程池改善)。
image.png

服务器端在准备数据的时候,服务器的这个连接线程是不会去做任何事情的阻塞状态)。

image.png

由此我们可以得出:
BIO适用于连接数目比较小且固定的架构,对服务器资源要求高。

5.BIO的工作流程梳理

5.1)服务器端启动一个ServerSocket

5.2)客户端启动Socket对服务器进行通信,默认情况下每个客户端请求都需要建立一个连接与之通讯

5.3)客户端发出请求后, 先咨询服务器是否有线程响应,如果没有则会等待,或者被拒绝

5.4)如果有响应,客户端线程会等待请求结束后,在继续执行

5.5)客户端在处理读写请求的时候直至业务逻辑处理完返回数据以前,连接客户端的线程会阻塞,不会去做其它事情,一直是阻塞状态

5.6)服务器端处理完数据返回给客户端。

6.BIO应用实例说明

@Slf4j
public class BIOServer {

    public static void main(String[] args) throws Exception {
        //如果有客户端连接,就创建一个线程,与之通讯
        ThreadPoolExecutor threadPoolExecutor
                = new ThreadPoolExecutor(2,//常驻核心线程数
                5,//最大核心线程数
                1L,//多余的空闲线程的存活时间
                TimeUnit.SECONDS,//多余空闲线程存活时间单位
                new ArrayBlockingQueue<Runnable>(10),//阻塞队列
                Executors.defaultThreadFactory(),//生成线程池中工作线程的线程工厂
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略


        ServerSocket serverSocket = new ServerSocket(6677);
        log.info("服务器启动");
        while (true) {
            log.info("线程id" + Thread.currentThread().getId() + "名字=" + Thread.currentThread().getName());
            //等待客户端连接
            log.info("等待客户端连接");
            //没有连接会阻塞在这里
            Socket accept = serverSocket.accept();
            log.info("有客户端连接了!");
            //处理的业务逻辑
            threadPoolExecutor.execute(() -> handler(accept));

        }

    }

    public static void handler(Socket socket) {
        try {
            log.info("线程id" + Thread.currentThread().getId() + "名字=" + Thread.currentThread().getName());
            //通过socket连接获取输入流
            InputStream inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            while(true){
                int read = inputStream.read(bytes);
                if (read != -1) {
                    System.out.println(new String(bytes, 0, read));//输出客户端发送的数据
                } else {
                    break;
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

我们通过telnet连接服务器:
image.png

image.png

随意输入字符串发送信息:

image.png

7.BIO优缺点分析

优点:
1)开发简单。

缺点:
1)每个请求都要创建线程,浪费资源。

2)连接建立后,如果服务端的数据还没有准备好,则服务端线程不会去处理别的请求,会阻塞,造成资源浪费。

我们将会用NIO等方式来解决以上的缺点。


苏凌峰
73 声望38 粉丝

你的迷惑在于想得太多而书读的太少。