netty 自定义客户端连接池和channelpool

目录标题

  • 客户端池化
  • 运行
  • 分析
  • 问题修复

客户端池化

通信完成之后,一般要关闭channel,释放内存。但是与一个服务器频繁的打开关闭浪费资源。
通过连接池,客户端和服务端之间可以创建多个 TCP 连接,提升消息的收发能力,同时利用池化技术,可以重用连接,防止反复申请和释放连接,提高连接的使用率。
下例就是启动时建立100个连接,然后去给服务端发消息。

    public static void main(String[] args) throws Exception {List<Channel> CLIENT_LIST = new ArrayList<>();for (int i = 0; i < 100; i++) {NioEventLoopGroup eventExecutors = new NioEventLoopGroup();Bootstrap bootstrap = new Bootstrap();bootstrap.group(eventExecutors).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {}});ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6666).sync();Channel channel = channelFuture.channel();CLIENT_LIST.add(channel);channel.closeFuture().addListener(future -> {eventExecutors.shutdownGracefully();});}for (Channel channel : CLIENT_LIST) {ByteBuf buffer = Unpooled.buffer().alloc().buffer(1024);// 模拟业务操作// 数据发送for (int j = 0; j < 1024; j++) {buffer.writeByte((byte) j);}channel.writeAndFlush(buffer);}}

运行

visualVM执行情况如下
在这里插入图片描述

分析

客户端的eventloopgroup负责建立连接以及后续的IO请求,默认线程数是(CPU * 2)。
代码中每建立一个客户端连接,就创建一个group,每个group又有若干线程。在这个例子中,即使每个group只使用了一个线程,但初始化时是children = new EventExecutor[nThreads];又白白浪费了很多内存。

问题修复

  1. 只需要循环connect即可。让所有的TCP连接共享同一个group。
    这样里面的eventloop也是共享的,所以发生异常时不能关闭enventloop或者group,否则会影响其他客户端。不推荐。
      for (int i = 0; i < 100; i++) {ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6666).sync();Channel channel = channelFuture.channel();CLIENT_LIST.add(channel);channel.closeFuture().addListener(future -> {// eventExecutors.shutdownGracefully();此处不能关闭});}
  1. netty自带的channelpool
    他有两个实现,一个无界,一个有界。
    实际使用中,是一个map,key是目标端的地址和端口,value就是池子。这里不涉及多个服务器,所以用channelpool即可。客户端的group
  NioEventLoopGroup eventExecutors = new NioEventLoopGroup();Bootstrap bootstrap = new Bootstrap();bootstrap.group(eventExecutors).channel(NioSocketChannel.class).option(ChannelOption.SINGLE_EVENTEXECUTOR_PER_GROUP, false).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {}}).remoteAddress("127.0.0.1", 6666);ChannelPool channelPool = new FixedChannelPool(bootstrap, new ChannelPoolHandler() {@Overridepublic void channelReleased(Channel ch) throws Exception {System.out.println("pool release");}@Overridepublic void channelAcquired(Channel ch) throws Exception {System.out.println("pool: occur acquire operation");}@Overridepublic void channelCreated(Channel ch) throws Exception {System.out.println("pool channel create");ch.closeFuture();}}, 50);for (int i = 0; i < 100; i++) {Future<Channel> acquire = channelPool.acquire();acquire.addListener(future -> {ByteBuf buffer = Unpooled.buffer().alloc().buffer(100);// 模拟业务操作// 数据发送buffer.writeBytes("hello hello hello hello hello hello hello hello".getBytes());((Channel) future.get()).writeAndFlush(buffer).sync();// buffer不需要释放,传递到headcontext自动释放channelPool.release(((Channel) future.get())); // 把该channel还给池子});}}

参考:netty进阶-李林峰
本文作者:WKP9418
原文地址:https://blog.csdn.net/qq_43179428/article/details/140562757

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

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

相关文章

【深度学习】VGG-16原理及代码实现

1.原理及介绍 2.代码实现 2.1model.py import torch from torch import nn from torchsummary import summary import torch.nn.functional as Fclass VGG16(nn.Module):def __init__(self):super(VGG16, self).__init__()self.block1 nn.Sequential( # 用一个序列&#xf…

51单片机嵌入式开发:13、STC89C52RC 之 RS232与电脑通讯

STC89C52RC 之 RS232与电脑通讯 第十三节课&#xff0c;RS232与电脑通讯1 概述2 Uart介绍2.1 概述2.2 STC89C52UART介绍2.3 STC89C52 UART寄存器介绍2.4 STC89C52 UART操作 3 C51 UART总结 第十三节课&#xff0c;RS232与电脑通讯 1 概述 RS232&#xff08;Recommended Stand…

Github报错:Kex_exchange_identification: Connection closed by remote host

文章目录 1. 背景介绍2. 排查和解决方案 1. 背景介绍 Github提交或者拉取代码时&#xff0c;报错如下&#xff1a; Kex_exchange_identification: Connection closed by remote host fatal: Could not read from remote repository.Please make sure you have the correct ac…

HTML5大作业三农有机,农产品,农庄,农旅网站源码

文章目录 1.设计来源1.1 轮播图页面头部效果1.2 栏目列表页面效果1.3 页面底部导航效果 2.效果和源码2.1 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_4…

计算机三级嵌入式笔记(一)—— 嵌入式系统概论

目录 考点1 嵌入式系统 考点2 嵌入式系统的组成与分类 考点3 嵌入式系统的分类与发展 考点4 SOC芯片 考点5 数字&#xff08;电子&#xff09;文本 考点6 数字图像 考点7 数字音频与数字视频 考点8 数字通信 考点9 计算机网络 考点10 互联网 考纲&#xff08;2023&am…

2、如何发行自己的数字代币(truffle智能合约项目实战)

2、如何发行自己的数字代币&#xff08;truffle智能合约项目实战&#xff09; 1-Atom IDE插件安装2-truffle tutorialtoken3-tutorialtoken源码框架分析4-安装openzeppelin代币框架&#xff08;代币发布成功&#xff09; 1-Atom IDE插件安装 正式介绍基于web的智能合约开发 推…

【Vue3】响应式数据

【Vue3】响应式数据 背景简介开发环境基本数据类型对象数据类型使用 reactive 定义对象类型响应式数据使用 ref 定义对象类型响应式数据 ref 和 reactive 的对比使用原则建议 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0…

牛客:TOP101链表相加(二)

文章目录 1. 题目描述2. 解题思路3. 代码实现 1. 题目描述 2. 解题思路 按照我们习惯的加法运算&#xff0c;肯定是要从个位开始相加&#xff0c;然后十位……&#xff0c;但是在链表中如果我们先运算后面的&#xff0c;那么接下来我们是无法找到前一位的。想要解决这个问题也很…

数模·插值和拟合算法

插值 将离散的点连成曲线或者线段的一种方法 题目中有"任意时刻任意的量"时使用插值&#xff0c;因为插值一定经过样本点 插值函数的概念 插值函数与样本离散的点一一重合 插值函数往往有多个区间&#xff0c;多个区间插值函数样态不完全一样&#xff0c;简单来说就…

【系统架构设计 每日一问】二 MySql主从复制延迟可能是什么原因,怎么解决

主从复制的架构设计如下图所示&#xff1a; 同步原理 具体到数据库之间是通过binlog和复制线程操作的&#xff1a; Master的更新事件(update、insert、delete)会按照顺序写入bin-log中。当Slave连接到Master的后,Master机器会为Slave开启&#xff0c;binlog dump线程,该线程…

H3CNE(计算机网络的概述)

1. 计算机网络的概述 1.1 计算机网络的三大基本功能 1. 资源共享 2. 分布式处理与负载均衡 3. 综合信息服务 1.2 计算机网络的三大基本类型 1.3 网络拓扑 定义&#xff1a; 网络设备连接排列的方式 网络拓扑的类型&#xff1a; 总线型拓扑&#xff1a; 所有的设备共享一…

Vue3 --- 路由

路由就是一组key-value的对应关系&#xff1b;多个路由&#xff0c;需要经过路由器的管理。 1. 基本切换效果 安装路由器 npm i vue-router /router/index.ts // import { createRouter, createWebHistory } from vue-router import Home from /components/Home.vue import…

萝卜快跑爆火的背后,美格智能如何助力无人车商业化?

近期&#xff0c;“订单量超过600万单”等夺人眼球的信息&#xff0c;让无人驾驶出租车“萝卜快跑”从江城武汉爆火出圈&#xff0c;在2024年的炎炎夏日为这座大火炉再添了一把火。热度背后&#xff0c;不少地方主管部门&#xff0c;近期也纷纷针对无人驾驶出租车、无人驾驶运输…

基于术语词典干预的机器翻译挑战赛笔记Task2 #Datawhale AI 夏令营

上回&#xff1a; 基于术语词典干预的机器翻译挑战赛笔记Task1 跑通baseline Datawhale AI 夏令营-CSDN博客文章浏览阅读718次&#xff0c;点赞11次&#xff0c;收藏8次。基于术语词典干预的机器翻译挑战赛笔记Task1 跑通baselinehttps://blog.csdn.net/qq_23311271/article/d…

C++树形结构(2 树的直径)

目录 1.定义&#xff1a; 2.直径的性质&#xff1a; 3.树的直径求解方法&#xff1a; 4.直径端点求解方法&#xff1a; 朴素方法&#xff1a; 优化方法&#xff1a; 5.例题&#xff1a; 6.直径公共点&#xff1a; 7.例题&#xff1a; 8.去掉再加上&#xff1a; 9.例…

最新版kubeadm搭建k8s(已成功搭建)

kubeadm搭建k8s&#xff08;已成功搭建&#xff09; 环境配置 主节点 k8s-master&#xff1a;4核8G、40GB硬盘、CentOS7.9&#xff08;内网IP&#xff1a;10.16.64.67&#xff09; 从节点 k8s-node1&#xff1a; 4核8G、40GB硬盘、CentOS7.9&#xff08;内网IP&#xff1a;10…

框架使用及下载

Bootstrap5 安装使用 | 菜鸟教程 (runoob.com) https://github.com/twbs/bootstrap/releases/download/v5.1.3/bootstrap-5.1.3-dist.zip&#xff08;下载链接&#xff09; Staticfile CDN&#xff08;html的所有框架合集&#xff09; 直接在w3cschool里面看参考文件进行搜索自…

RHCSA —— 第八节 (编辑器、编辑命令等)

Vi/vim编辑器 vim 编辑器 就是相当于在windows中创建一个记事本&#xff0c;一个word文档里面进行编辑所需要的内容。在linux中编辑文本文件&#xff0c;包括但不限于编辑源代码、配置文件、日志文件等文件内容。 三种模式 这是在编辑器中存在三种模式&#xff1a;命令模式、…

[经验] 驰这个汉字的拼音是什么 #学习方法#其他#媒体

驰这个汉字的拼音是什么 驰&#xff0c;是一个常见的汉字&#xff0c;其拼音为“ch”&#xff0c;音调为第四声。它既可以表示动词&#xff0c;也可以表示形容词或副词&#xff0c;意义广泛&#xff0c;经常出现在生活和工作中。下面就让我们一起来了解一下“驰”的含义和用法。…

Deepfake detection【Datawhale AI夏令营】数据增强方法

deepfake detection比赛链接https://www.kaggle.com/competitions/multi-ffdi 训练分类模型判别图片是否为AI生成图片&#xff0c;探究不同数据增强方法对模型表现的影响。 1、数据增强方法 图像分类任务中常见的数据增强方法&#xff1a; &#xff08;1&#xff09; 几何变换…