手把手构建Netty

news2025/1/17 1:13:18

1.Netty基础

Netty是一个提供了易于使用的API的客户端、服务器框架;
并发高-NIO(非阻塞IO)
传输快-零拷贝:
分析:
使用了NIO的零拷贝;java中内存是分为堆和栈,还有字符串常量池等等;
如果有一些数据需要从IO中读取,并且放到堆里面;中间会经历一些缓冲区;也就是说,读的过程会分为两个步骤:从IO流中读取出来,放到缓存区;缓冲区读取放到堆里面;
当它需要去接受数据或者是传输数据。会去开辟一个新的堆内存;然后数据直接从IO读取到新的堆内存中去

对于协议的支持如下;
在这里插入图片描述
BIO:同步阻塞IO

Server会有一个专门的线程acceptor;专门来监听客户端之间的请求;
客户端增多的时候,就会频繁的创建和销毁相应线程,就要考虑线程池;

NIO:同步非阻塞IO

BIO、NIO与AIO的区别与理解:
三者的区别详细可参考如下链接:
https://blog.csdn.net/TOMORROW6COME/article/details/140048654

使用NIO所遇到的问题:
类库;api相对较为复杂;需要具备java多线程的技能;
断线重连,网络阻塞等问题的处理方式,实现难度较大;NIO内置使用存在一些bug;

Netty优点:高效;简单;支持主流协议;可定制性强;性能高;
Dubbo使用的是Netty;

2.Netty三种线程模型

Reactor线程模型;
在这里插入图片描述
只能用于小型的应用场景;
不适用于高负载高并发场景;因为一个NIO线程要去同时处理成百上千的请求;
性能支撑不了;即便给予服务器负载;对于海量的消息处理,编解码,处理跟发送消息
无法满足;超时,然后不断轮训;会造成恶性循环;

在这里插入图片描述
主从线程模型:一组线程池接受请求;一组线程池处理IO
在这里插入图片描述

3.Netty快速入门

(1)构建Netty的聊天服务器
使用主从线程池构建聊天服务器:
在这里插入图片描述
在启动的时候会返回一个实例;为ChannelFuture;
他的解释如下:大概意思就是因为NIO;所以会立即返回一个结果;同时,可能没有信息;
所以使用ChannelFuture,替代作为一个结果返回;
在这里插入图片描述

public static void main(String[] args) throws Exception {
    // 构建主从线程池
    // 定义主线程池,用于接受客户端的连接;但是不做任何处理,比如老板会谈业务,拿到业务就会交给workerGroup进行处理
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    // 定义从线程池,处理主线程池交代的任务;公司业务员开展业务,完成老板交代的任务
    EventLoopGroup workerGroup = new NioEventLoopGroup();

    try {
        // 构建Netty服务器
        ServerBootstrap server = new ServerBootstrap();         // 服务启动类;
        server.group(bossGroup,workerGroup)                     // 把主从线程池组放入到启动类中
                .channel(NioServerSocketChannel.class)          // 设置NIO双向通道
                .childHandler(null);                            // 设置处理器,用于处理workerGroup业务
        // 启动server,并且绑定端口号875,同时启动方式为同步
        ChannelFuture channelFuture = server.bind(875).sync();   //.sync是保证服务启动后一直运行;不写sync,代码一运行完就没有了

        //监听关闭的channel
        channelFuture.channel().closeFuture().sync();
    } finally {
        // 优雅关闭线程池组
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
}

(2)设定channel的初始化器
Pipeline需要开发者自己去编写;handler助手类:用于处理请求;
在这里插入图片描述

/**
 * Created by nly
 *
 * 初始化器,channel注册后,会执行里面的响应的初始化方法
 **/
public class HttpServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        // 通过SocketChannel 获得对应的管道
        ChannelPipeline pipeline = channel.pipeline();

        /**
         * 通过管道,添加handler处理器
         */

        // HttpServerCodec 是netty 自己提供的助手类,此处可以理解为管道中的拦截器
        // 当请求到服务端,我们需要进行做解码,相应到客户端做解码
        pipeline.addLast("",new HttpServerCodec());

        // 添加自定哦助手类,当请求访问,返回"hello,netty"
        pipeline.addLast("",null);

    }
}

(3)编写HTTP自定义助手类
先处理http;先不构建Netty服务器;
HttpObject是处理的泛型;
先构建基本的逻辑与框架;
通过上下文对象ctx去获取channel;拿到channel之后,就能获取到跟客户端
相关的信息了
概念缓冲区:bytebuf:定义数据发送的消息;读写数据;

/**
 * 创建自定义助手类
 *
 **/
public class HttpHandler extends SimpleChannelInboundHandler<HttpObject> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx,
                                HttpObject msg) throws Exception {
        // 获取channel
        Channel channel = ctx.channel();

        // 打印客户端的远程地址
        System.out.println(channel.remoteAddress());

        // 通过缓冲区定义发送的消息,读写数据都是通过缓冲区进行数据交换的
        ByteBuf content = Unpooled.copiedBuffer("hello netty!", CharsetUtil.UTF_8);

        // 构建http的response
        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK,
                content);
        // 为响应添加数据类型和数据长度
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE);
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());

        // 把响应数据写到缓冲区再刷到客户端
        ctx.writeAndFlush(response);
    }
}

(3)Netty服务的生命周期
关注到netty的生命周期问题;
ChannelInboundHandlerAdapter
在这里插入图片描述

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

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

相关文章

28、美国国家冰雪中心(NSIDC)海冰密集度月数据处理:方法二

文章目录 1. 前言2. polarstereo-lonlat-convert-py 介绍2.1 安装方法3. 代码4. 其他1. 前言 在前文中已经详细介绍了如何使用Python对NSIDC的海冰密集度数据进行处理,将其从极地投影转换成常用的经纬度投影,但是方法较为麻烦,本文将基于另一个库,使用更加简便的方法对其进…

JVM—垃圾收集算法和HotSpot算法实现细节

1、分代回收策略 分代的垃圾回收策略&#xff0c;是基于这样一个事实&#xff1a;不同的对象的生命周期是不一样的。因此&#xff0c;不同生命周期的对象可以采取不同的收集方式&#xff0c;以便提高回收效率。 分代垃圾回收采用分治的思想&#xff0c;进行代的划分&#xff0…

π 随机数计算圆周率

如下图&#xff0c;圆与正方形面积比值等于圆内的点和总点数的比值 Disatance是点到原点的距离&#xff1a;SQRT(A2xA2B2xB2) 以下是在Excel中1.5万个点计算圆周率的结果。 InCircle公式&#xff1a;IF(C2<1,1,0) π计算公式&#xff1a;4*SUM(D2:D15000)/COUNT(D2:D15000)

leetcode 2181.合并零之间的结点

1.题目要求: /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* mergeNodes(struct ListNode* head){struct ListNode* cur head;int count 0;//1.遍历结点&#xff0c;求出结点数while(cur){co…

前后端demo-WarehouseManagement

前端 数据库 其他 1.git下来&#xff0c;解决依赖问题&#xff0c;前端报错因为字体文件丢失&#xff0c;下载字体放到fonts文件夹字体.zip官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘 2.后端login验证&#xff0c;前端需要账号格式&#xff0c;linqq.com 3.自己…

【React】实现消息列表的删除

工作小记&#xff0c;第一次接触react项目 1.增加删除对话项的函数 hooks\use-conversation.ts // 删除对话项的函数const deleteConversation (id: string) > {setConversationList(prevList > prevList.filter(item > item.id ! id))}return {deleteConversation,.…

OZON户外运动装备热卖产品

OZON平台上的户外运动装备热卖产品涵盖了多个类别&#xff0c;这些产品不仅满足了俄罗斯消费者对户外运动的需求&#xff0c;还体现了市场趋势和消费者偏好的变化。以下是一些主要的热卖户外运动装备产品&#xff1a; OZON户外运动装备热卖产品地址&#xff1a;D。DDqbt。COm/…

第十九天培训笔记

上午 1 、构建 vue 发行版本 [rootserver eleme_web]# nohup npm run serve& // 运行 vue 项目 [rootserver eleme_web]# mkdir /eleme [rootserver eleme_web]# cp -r /root/eleme_web/dist/* /eleme/ // 将项目整体 移动到 /eleme 目录下 [rootserver eleme_web]# …

区间贪心2

问题引入 上一节我们学习了贪心的基本概念、基本思路以及证明方法&#xff0c;下面我们一起来学习区间类贪心类问题&#xff0c;这里我们学习的重点依然是贪心的策略和证明。 算法原理区间贪心&#xff1a; 是指在区间上做贪心。区间贪心一般都是按左端点或者右端点排序&…

最短路问题中的朴素版Dijkstra算法

最短路问题的朴素版Dijkstra算法 题目 最短路问题需要用到下面的算法&#xff08;n代表点的数量&#xff0c;m代表边的数量&#xff09; 朴素版和堆优化版的Dijkstra算法的区别是&#xff0c;朴素版比较适合稠密图&#xff0c;堆优化版适合稀疏图&#xff0c;稠密图代表它的边…

模型优化—动量梯度下降

一、mini-batch 梯度下降&#xff08;gradient descent&#xff09;&#xff1a; SGD&#xff08;stochastic GD&#xff09;随机梯度下降&#xff1a;对一个样本做梯度下降 batch梯度下降&#xff1a;使用所有样本做梯度下降&#xff08;做一次又叫epoch&#xff09; mini…

人工智能算法工程师(高级)课程9-自然语言处理之词嵌入的介绍与代码详解

大家好,我是微学AI,今天给大家介绍一下人工智能算法工程师(高级)课程9-自然语言处理之词嵌入的介绍与代码详解。 词嵌入是一种将文本中的词语转换为数值向量的技术,广泛应用于自然语言处理领域。它通过将词语映射到多维向量空间,使得相似意义的词语在向量空间中距离较近,从…

【无标题配置jdk环境和tomcat环境

一&#xff0e;接着昨天的发布vue项目 npm run serve 构建项目 npm run build ls ls dist/ vim dist/index.html [rootweb eleme_web]# cd /usr/local/nginx/conf/ [rootweb conf]# ls 将静态的项目移动到nginx中 [rootweb nginx]# cd conf.d/ [rootweb conf.d]# ls…

用Python打造精彩动画与视频,3.3 添加音频和简单效果

3.3 添加音频和简单效果 在本节中&#xff0c;我们将学习如何使用 MoviePy 库为视频添加音频和一些简单的效果。这些操作可以让你的视频更具吸引力和个性化。 准备工作 首先&#xff0c;确保你已经安装了 MoviePy 和 pydub 库。你可以通过以下命令安装&#xff1a; pip ins…

Qt 实战(2)搭建开发环境 | 2.4、查看 Qt 源码

文章目录 一、查看 Qt 源码1、获取 Qt 源码2、添加源码路径3、配置定位器4、查看源码 前言&#xff1a; Qt 是一个跨平台的 C 图形用户界面应用程序开发框架&#xff0c;广泛应用于开发 GUI 程序以及非 GUI 程序&#xff0c;如控制台工具和服务器。查看 Qt 的源码不仅可以帮助你…

故障案例:网络访问慢

现象描述 FW作为中间设备的场景下&#xff0c;用户访问网页慢&#xff0c;报文延时大等。 相关告警与日志 相关告警 无 相关日志 ARP/4/ARP_DUPLICATE_IPADDR 原因分析 图1 网络访问慢故障定位思路 丢包 报文在网络链路上传输时&#xff0c;可能会有部分报文在链路中被丢…

用深度学习改进乳腺癌MRI诊断| 文献速递--AI辅助的放射影像疾病诊断

Title 题目 Improving breast cancer diagnostics with deep learning for MRI 用深度学习改进乳腺癌MRI诊断 01 文献速递介绍 乳腺磁共振成像&#xff08;MRI&#xff09;是一种检测乳腺癌的高度敏感的方式&#xff0c;报告的敏感性超过80%。传统上&#xff0c;其在筛查…

【算法】动态规划-斐波那契数列模型

目录 1、第N个泰波那契数 1.1 算法原理讲解 1.1.1 状态表示 1.1.2 状态转移方程 1.1.3 初始化 1.1.4 填表顺序 1.1.5 返回值 1.2 代码实现 1.3 空间优化 2、三步问题 2.1 算法原理讲解 2.1.1 状态表示 2.1.2 状态转移方程 2.1.3 初始化 2.1.4 填表顺序 2.1.5 返…

(四十一)大数据实战——spark的yarn模式生产环境部署

前言 Spark 是一个开源的分布式计算系统。它提供了高效的数据处理能力&#xff0c;支持复杂的数据分析和处理任务&#xff0c;是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。Spark Core&#xff1a;实现了Spark的基本功能&#xff0c;包含任务调度、内存管理、错误…

上线前端系统

上线一个静态的前端系统&#xff08;续&#xff09; 在eleme服务器上 启动服务 启动rpcbind [rooteleme-static ~]# systemctl restart rpcbind 启动nfs [rooteleme-static ~]# systemctl restart nfs 重启服务 启动smb [rootstatic-server img]# systemctl start smb…