Netty网络编程——Netty的基本介绍与BIO

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的概念:同步阻塞。
每当服务器有连接请求的时候,客户端都会启动一个线程去处理(可以通过线程池改善)。
Netty网络编程——Netty的基本介绍与BIO
文章图片

服务器端在准备数据的时候,服务器的这个连接线程是不会去做任何事情的(阻塞状态)。
Netty网络编程——Netty的基本介绍与BIO
文章图片

由此我们可以得出:
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(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连接服务器:
Netty网络编程——Netty的基本介绍与BIO
文章图片

Netty网络编程——Netty的基本介绍与BIO
文章图片

随意输入字符串发送信息:
Netty网络编程——Netty的基本介绍与BIO
文章图片

7.BIO优缺点分析
优点:
1)开发简单。
缺点:
1)每个请求都要创建线程,浪费资源。
2)连接建立后,如果服务端的数据还没有准备好,则服务端线程不会去处理别的请求,会阻塞,造成资源浪费。
【Netty网络编程——Netty的基本介绍与BIO】我们将会用NIO等方式来解决以上的缺点。

    推荐阅读