[阶段4 企业开发进阶] 5. Netty

news2024/11/28 0:31:41

文章目录

  • 1 Netty
    • 1.1 Netty介绍
    • 1.2 Netty应用场景
  • 2 Java BIO编程
    • 2.1 IO模型
    • 2.2 BIO、NIO、AIO 适用场景分析
    • 2.3 BIO
  • 3 Java NIO编程
    • 3.1 NIO基本介绍
    • 3.2 NIO和BIO的比较
    • 3.3 NIO三大核心原理

1 Netty

1.1 Netty介绍

在这里插入图片描述

  • Netty 是由 JBOSS 提供的一个 Java 开源框架
  • Netty 是一个异步的、基于事件驱动的网络应用框架,用以快速开发高性能、高可靠性的网络IO程序
  • Netty 主要针对在 TCP 协议下,面向 Clients 端的高并发应用,或者 Peer-to-Peer 场景下的大量数据持续传输的应用
  • Netty 本质是一个 NIO 框架,适用于服务器通讯相关的多种应用场景

1.2 Netty应用场景

使用到Netty的开源项目S

互联网行业

  • 互联网行业:在分布式系统中,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少,Netty作为异步高性能的通信框架,往往作为基础通信组件被这些 RPC 框架使用
  • 典型的应用有:阿里分布式服务框架 Dubbo 的 RPC 框架使用 Dubbo 协议进行节点间通信,Dubbo协议默认使用 Netty 作为基础通信组件,用于实现各进程节点之间的内部通信

游戏行业

  • Netty 作为高性能的基础通信组件,提供了 TCP/UDP 和 HTTP 协议栈,方便定制和开发私有协议栈,账号登录服务器
  • 地图服务器之间可以方便的通过 Netty 进行高性能的通信

大数据行业

  • 经典的 Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架,默认采用 Netty 进行跨界点通信
  • 它的 Netty Service 基于 Netty 框架二次封装实现。

2 Java BIO编程

2.1 IO模型

Java 共支持 3 种网络编程模型/IO 模式:BIO、NIO、AIO

Java BIO

  • 同步并阻塞(传统阻塞型)
  • 服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理
  • 如果这个连接不做任何事情会造成不必要的线程开销

在这里插入图片描述

Java NIO

  • 同步非阻塞
  • 服务器实现模式为一个线程处理多个请求(连接),即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有 I/O 请求就进行处理

在这里插入图片描述

Java AIO (NIO.2)

  • 异步非阻塞

  • AIO 引入异步通道的概念,采用了 Proactor 模式,简化了程序编写,有效的请求才启动线程

  • 它的特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长的应用

2.2 BIO、NIO、AIO 适用场景分析

BIO 方式

  • 适用于连接数目比较小且固定的架构
  • 该方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序简单易理解。

NIO 方式

  • 适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,弹幕系统,服务器间通讯等
  • 编程比较复杂,JDK1.4 开始支持。

AIO 方式

  • 适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS 参与并发操作

  • 编程比较复杂,JDK7 开始支持。

2.3 BIO

BIO基本介绍

  • Java BIO 就是传统的 java io 编程,其相关的类和接口在 java.io

  • BIO(blocking I/O) : 同步阻塞,服务器实现模式为一个连接一个线程

    • 即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制改善(实现多个客户连接服务器)
  • BIO 方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,程序简单易理解

BIO 工作机制

在这里插入图片描述

BIO编程梳理

  1. 服务器端启动一个 ServerSocket
  2. 客户端启动 Socket 对服务器进行通信,默认情况下服务器端需要对每个客户 建立一个线程与之通讯
  3. 客户端发出请求后, 先咨询服务器是否有线程响应,如果没有则会等待,或者被拒绝
  4. 如果有响应,客户端线程会等待请求结束后,在继续执行

应用实例

需求

  1. 使用 BIO 模型编写一个服务器端,监听 6666 端口,当有客户端连接时,就启动一个线程与之通讯
  2. 要求使用线程池机制改善,可以连接多个客户端
  3. 服务器端可以接收客户端发送的数据(telnet 方式即可)

编码

public class BIOServer {
    public static void main(String[] args) throws Exception {
    	// 线程池机制
        // 思路
        //1. 创建一个线程池
    	//2. 如果有客户端连接,就创建一个线程,与之通讯(单独写一个方法)
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        // 创建 ServerSocket
        ServerSocket serverSocket = new ServerSocket(6666);
        System.out.println("服务器启动了");
        while (true) {
        	System.out.println(" 线 程 信 息 id =" + Thread.currentThread().getId() + " 名字="+Thread.currentThread().getName());
        	// 监听,等待客户端连接
        	System.out.println("等待连接....");
        	final Socket socket = serverSocket.accept();
        	System.out.println("连接到一个客户端");
        	// 就创建一个线程,与之通讯(单独写一个方法)
        	newCachedThreadPool.execute(new Runnable() {
        		public void run() {  
        			// 可以和客户端通讯
        			handler(socket);
        		}
            });
        }
    }
    
 	// handler 方法,和客户端通讯
    public static void handler(Socket socket) {
        try {
        	System.out.println(" 线 程 信 息 id =" + Thread.currentThread().getId() + " 名字="+Thread.currentThread().getName());
        	byte[] bytes = new byte[1024];
        	// 通过 socket 获取输入流
        	InputStream inputStream = socket.getInputStream();
        	/ /循环的读取客户端发送的数据
        	while (true) {
                System.out.println(" 线 程 信 息 id =" + Thread.currentThread().getId() + " 名字="+Thread.currentThread().getName());
                System.out.println("read....");
                int read = inputStream.read(bytes);
                if(read != -1) {   
                    System.out.println(new String(bytes, 0, read
                )); //输出客户端发送的数据
                } else {
                	break;
                }
        	}
        } catch (Exception e) {
        	e.printStackTrace();
        } finally {
        	System.out.println("关闭和 client 的连接");
            try {
            	socket.close();
            }catch (Exception e) {
            	e.printStackTrace();
            }
        }
    }
}

分析

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

3 Java NIO编程

3.1 NIO基本介绍

  • Java NIO 全称 java non-blocking IO,是指 JDK 提供的新 API
  • 从 JDK1.4 开始,Java 提供了一系列改进的输入/输出的新特性,被统称为 NIO(即 New IO),是同步非阻塞
  • NIO 相关类都被放在 java.nio 包及子包下,并且对原 java.io 包中的很多类进行改写
  • IO 有三大核心部分:Channel(通道),Buffer(缓冲区), Selector(选择器)
  • NIO 是面向缓冲区 ,或者面向块编程的。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动,这就增加了处理过程中的灵活性,使用它可以提供非阻塞式的高伸缩性网络
  • Java NIO 的非阻塞模式,使一个线程从某通道发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情
  • HTTP2.0 使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级

3.2 NIO和BIO的比较

  • BIO 以的方式处理数据,而 NIO 以的方式处理数据,块 I/O 的效率比流 I/O 高很多
  • BIO 是阻塞的,NIO 则是非阻塞
  • BIO 基于字节流和字符流进行操作,而 NIO **基于 Channel(通道)和 Buffer(缓冲区)**进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择器)用于监听多个通道的事件(比如:连接请求,数据到达等),因此使用单个线程就可以监听多个客户端通道

3.3 NIO三大核心原理

Selector 、 Channel 和 Buffer 的关系图

在这里插入图片描述

  • 每个 channel 都会对应一个 Buffer
  • Selector 对应一个线程, 一个线程对应多个 channel(连接)
  • 该图反应了有三个 channel 注册到该 selector //程序
  • 程序切换到哪个 channel 是有事件决定的,Event 就是一个重要的概念
  • Selector 会根据不同的事件,在各个通道上切换
  • Buffer 就是一个内存块 , 底层是有一个数组
  • 数据的读取写入是通过 Buffer,这个和 BIO ,BIO 中要么是输入流,或者是输出流,不能双向,但是 NIO 的 Buffer 是可以读也可以写,需要 flip 方法切换 channel 是双向的,可以返回底层操作系统的情况,比如 Linux,底层的操作系统通道就是双向的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/88383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

技术分享 | 做为测试,那些必须掌握的测试技术体系

软件测试技术是软件开发过程中的一个重要组成部分,是贯穿整个软件开发生命周期、对软件产品(包括阶段性产品)进行验证和确认的活动过程。其目的是尽快尽早地发现在软件产品中所存在的各种问题,与用户需求、预先定义的不一致性。检…

Revit 中柱子附着屋顶小技巧和“柱断墙梁”方法

一、Revit 中柱子附着屋顶小技巧 Revit 中如何正确的使柱子附着于屋顶? 有的朋友绘制完结构柱后想要附着到屋顶上,这时候大家会选择把柱子顶部拉上去或者选择“附着顶部/底部”命令。但是这样会出现如图 1所示情况 此时柱子并未与屋顶完全相交,这时候有…

seata分布式事务AT模式原理解析

文章目录TC相关的表解析AT 模式如何做到对业务的无侵入写隔离读隔离AT模式特点TC相关的表解析 global_table:全局事务表,每当有一个全局事务发起后,就会在该表中记录全局事务的ID。branch_table:分支事务表,记录每一个…

一个简单实用的 JavaScript 日历控件源代码,不依赖第三方库,支持日期、月份、年份视图切换;支持单选、多选、范围和星期选

一个简单实用的 JavaScript 日历控件!原生 JavaScript 编写,不依赖任何第三方库。支持日期、月份和年份试图切换;支持单选、多选、范围和星期选择模式;界面简介、配置简单、使用方便! 完整代码下载地址:一个…

java计算机毕业设计ssm招聘信息管理平台9kvyw(附源码、数据库)

java计算机毕业设计ssm招聘信息管理平台9kvyw(附源码、数据库) 项目运行 环境配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff0…

终于有P8大佬把困扰我多年的《计算机网络原理》全部讲明白了

前言 为什么网络协议这么重要呢?集群规模一大,我们首先想到的就是网络互通的问题;应用吞吐量压不上去,我们首先想到的也是网络互通的问题。所以,要成为技术牛人,搞定大系统,一定要过网络这一关&…

投影仪可以当电视看吗?告诉你好用的电视应用市场,建议收藏

当初在买投影仪和买电视中纠结了很久,最终选择了投影仪,现在又想看电视了……但是又不想再买个电视,那么问题来了,投影仪可以当电视用吗?经过本人一番研究,终于找到投影仪看电视的最简单方法:安…

Go C 编程 第3课 魔法自动机

慧通教育 慧通教育 30.画奔驰车标志(魔法学院第3课) 难度:1 登录 31.画拱型(魔法学院第3课) 难度:1 登录 32.画正三角形(魔法学院第3课) 难度:1 登录 33.画棱形(魔法学院第3课) 难度:1 登录 魔法学院的奇幻之旅:…

「安全狗漏洞通告」Fortinet SSL VPN远程代码执行漏洞解决方案

安全狗应急响应中心监测到,Fortinet发布了FortiOS SSL-VPN的风险通告,漏洞等级:高危,漏洞评分:9.3。漏洞编号:CVE-2022-42475。 安全狗应急响应中心建议广大用户做好资产自查以及预防工作,以免遭…

理解DDR Part 1

DDR x4 x8 x16 x4 x8 x16 指的上图黑色的chip输出的位宽,正常的DDR bus width 需要64bit,所以 chip width x4 x8 x16 黑色chip数量 16 8 4 上图是最常见的x8,也就有8个黑色的chip颗粒。x16的性能和x8的性能相比怎么样呢? 更差&…

html悬浮事件(表格th)

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body> <h4>一行三列:</h4> <table border"1"> <tbody class"fileLi…

UE5笔记【十三】蓝图系统-血量控制系统

上一篇我们讲解了&#xff0c;蓝图中的函数功能。可以将蓝图中重复的代码&#xff0c;再次利用。演示了Smasher的效果。 这一篇中&#xff0c;我们讲解Smasher造成伤害之后&#xff0c;如何保存和计算角色的血量状态。 我们的设计思路是&#xff1a;smasher每次碰到角色是&am…

GCSE英语语言考试-角色定位

What is characterisation? 什么是角色定位&#xff1f; Characterisation is the way writers create characters and make them believable. When writing about texts, it is easy to treat characters as real people. Try to remember that the author is creating chara…

大数据 finalshell免密登录

私有云 查看私有云创建的虚拟机 本机用FinalShell连接三个虚拟机 使用浮动IP地址创建连接 设置主机名 maser虚拟机 slave1虚拟机 slave2虚拟机 IP地址与主机名映射 master虚拟机 slave1虚拟机 slave2虚拟机 ##关闭防火墙 关闭防火墙&#xff1a;systemctl stop f…

LeaRun.net代码生成器 一键生成前后端代码

自动代码生成是指根据自然语言的功能描述来生成代码。在项目开发过程中&#xff0c;有很多业务模块的代码是具有一定规律性的&#xff0c;例如controller控制器、service接口、service实现类、mapper接口、model实体类等等&#xff0c;这部分代码可以使用代码生成器生成&#x…

一种通过刷写替换boot的方法

写在前面的废话 众所周知,ECU软件包括BOOT和APP两部分,一般来说,boot是固化的软件,改动可能性很小,一般用来更新APP,但是,如果有一天boot真的需要更新呢,而且是大批量的更新,真的需要一个个的开盖烧录吗,有没有一种便捷的方式去实现boot的替换呢?下面提供一种boot替…

手把手教你使用SpringBoot做一个员工管理系统【配置篇】

手把手教你使用SpringBoot做一个员工管理系统【配置篇】1.导入资源2.编写pojo层3.编写dao层4.首页实现5.页面国际化1.导入资源 导入前端文件&#xff1a; 管理系统前端源码下载地址 将下载的前端文件导入到SpringBoot资源目录&#xff1a; 导入Maven依赖&#xff1a;&#x…

iOS微信8.0.31更新,带来7个功能

近日&#xff0c;iOS微信更新了8.0.31正式版。经过几天的深入体验&#xff0c;我发现了7个新特性。如果你还没有升级&#xff0c;我们就往下看吧。 功能一&#xff1a;优化编辑按钮 微信发图片&#xff0c;发送前可以编辑&#xff0c;底部的编辑按钮变了。新版画笔工具变成了钢…

数据驱动测试-从方法探研到最佳实践

作者&#xff1a;刘红妍 导读 在自动化测试实践中&#xff0c;测试数据是制造测试场景的必要条件&#xff0c;本文主要讲述了在沟通自动化框架如何分层&#xff0c;数据如何存储&#xff0c;以及基于单元测试pytest下如何执行。并通过实践案例分享&#xff0c;提供数据驱动测…

qq录制视频保存到哪了?qq录制视频怎么没了?找回方法在这

相信很多小伙伴都跟小编一样&#xff0c;使用qq录屏录制好后&#xff0c;结果就怎么也找不到录屏的文件了。经过小编一番研究&#xff0c;终于找到了qq录屏后视频文件的所保存的文件路径了。qq录制视频保存到哪了&#xff1f;别担心&#xff0c;下面小编就带大家一起来找找看。…