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…

监控-海康威视摄像头更改OSD通道,一键更改,批量更改

监控-海康威视摄像头更改OSD通道&#xff0c;一键更改&#xff0c;批量更改 监控-海康威视摄像头更改OSD通道&#xff0c;一键更改&#xff0c;只能一次更改一个&#xff0c;支持循环 # codingutf-8 #监控-海康威视摄像头更改OSD通道&#xff0c;一键更改&#xff0c;批量更改…

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

目录 考点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;涉及到多方面的逻辑迁移和代码重构&#xff0c;才能够达到下一代产品所需要的效果。 今天这篇文章&#xff0c;就…

优选算法之滑动窗口(下)

目录 一、水果成篮 1.题目链接&#xff1a;904.水果成篮 2.题目描述&#xff1a; 3.解法&#xff08;滑动窗口&#xff09; &#x1f341;算法思路&#xff1a; &#x1f341;算法流程&#xff1a; &#x1f341;算法代码1&#xff08;使用容器&#xff09;&#xff1a; …

数模·插值和拟合算法

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

C的预编译指令

预编译指令 #include对于形如 #include "demo.h" 的指令&#xff1a;对于形如 #include <demo.h> 的指令&#xff1a; #define简单宏替换带参数的宏 #ifdef, #ifndef, #if#pragma#error#line 在C语言中&#xff0c;预编译指令用于在编译之前进行代码的预处理。…

etcd磁盘空间故障处理办法

查看etcd状态 etcdctl --cacert=/etc/kubernetes/ssl/ca.crt --cert=/etc/kubernetes/ssl/etcd_server.crt --key=/etc/kubernetes/ssl/etcd_server.key --endpoints=https://10.10.10.31:1159,https://10.10.10.32:1159,https://10.10.10.33:1159 endpoint status --write-…

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

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

24、获取NCL色标并将其保存为Excel文件

文章目录 1. 前言2. 代码 1. 前言 在数据可视化的世界里&#xff0c;色彩不仅仅是视觉的盛宴&#xff0c;更是信息的传递者。NCL&#xff08;The NCAR Command Language&#xff09;色标&#xff0c;作为气象和环境科学领域的瑰宝&#xff0c;以其丰富的色彩组合和科学的编排&…

Linux指令ros学习python深度学习bug学习笔记

## 这个文件是关于ros、linux指令&#xff0c;pytorch、python、onnx和相关problem的一些笔记 ### ROS && linux **find: 在当前路径或指定的路径下递归地搜索文件或目录&#xff0c;并可以根据不同的条件进行过滤和匹配。** find -name *.py find /home/dai/bev_…

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…

Python面试整理-字典和集合的操作

在Python中,字典(dictionary)和集合(set)是两种非常有用的数据结构,用于存储和操作数据集。字典是一种键值对的集合,而集合是一种只包含唯一元素的集合。下面详细介绍它们的常用操作: 字典操作 创建字典 person = {"name": "Alice",