正确地利用Netty建立连接池
为什么80%的码农都做不了架构师?>>>
一、问题描述
Netty是最近非常流行的高性能异步通讯框架,相对于Java原生的NIO接口,Netty封装后的异步通讯机制要简单很多。
但是小K最近发现并不是所有开发人员在使用的过程中都了解其内部实现机制,而是照着葫芦画瓢。
网上简单搜索下,在客户端使用Netty建立连接池的文章也是比较少。今天小K给大家简单介绍下使用Netty建立连接池的方法。
首先我们来看下Netty官方给出的客户端sample实例:
//创建一个EventLoopGroup,可以简单认为是Netty框架下的线程池,默认最大线程数量是处理器数量的2倍EventLoopGroup group = new NioEventLoopGroup();try { //Netty建立连接的辅助类Bootstrap b = new Bootstrap(); //配置属性,向pipeline添加handlerb.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ChannelPipeline p = ch.pipeline();if (sslCtx != null) {p.addLast(sslCtx.newHandler(ch.alloc(), HOST, PORT));}//p.addLast(new LoggingHandler(LogLevel.INFO));p.addLast(new EchoClientHandler());}});//启动建立连接ChannelFuture f = b.connect(HOST, PORT).sync();//block直到连接被关闭f.channel().closeFuture().sync();
很简单?没错,确实如此。那么现在问题来了,如果你现在需要连接100个服务器,你会怎么做呢?
下面这样处理怎么样呢?我们在外层加了一个for循环
for(Host host : hosts){//创建一个EventLoopGroup,可以简单认为是Netty框架下的线程池,默认线程数量是处理器数量的2倍EventLoopGroup group = new NioEventLoopGroup();try {//Netty建立连接的辅助类Bootstrap b = new Bootstrap();//配置属性,向pipeline添加handlerb.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ChannelPipeline p = ch.pipeline();if (sslCtx != null) {p.addLast(sslCtx.newHandler(ch.alloc(), HOST, PORT));}//p.addLast(new LoggingHandler(LogLevel.INFO));p.addLast(new EchoClientHandler());}});//启动建立连接ChannelFuture f = b.connect(HOST, PORT).sync();//block直到连接被关闭f.channel().closeFuture().sync(); }
问题很明显,如果每一个channel都对应一个NIOEventLoopGroup,那么我们实际上构建了一个connection:thread = 1:1的模型,随着连接数不断地扩大,线程膨胀的问题就会突显出来。
二、问题解决
那么如何避免线程膨胀的问题呢?很简单,我们只要稍微修改下上面的代码就可以了。
NioEventLoopGroup group = new NioEventLoopGroup();Bootstrap b = new Bootstrap();try {b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ChannelPipeline p = ch.pipeline();if (sslCtx != null) {p.addLast(sslCtx.newHandler(ch.alloc(), HOST, PORT));}//p.addLast(new LoggingHandler(LogLevel.INFO));p.addLast(new EchoClientHandler());}});for(Host HOST : Hosts){ChannelFuture f = b.connect(HOST, PORT).sync();}
在上面的代码中,我们使用同一个Bootstrap创建了多个连接,从而使连接共享了一个NioEventLoopGroup,避免了线程膨胀的问题。
问题就这样解决了吗?NO,还远远没有结束哦,那么问题又来了。
1、如果希望每个连接能够使用不同的Handler怎么办?
2、每个连接如何能够再次复用,避免重复创建channel?
为了能够创建异步操作的连接池我们需要实现如下的模型。
为了能够方便地建立一个异步操作的连接池,我们会使用到FixedChannelPool(不了解的同学麻烦Google一下吧,(⌒_⌒))
其伪代码如下(具体的代码实现结构还是留给读者自己思考吧):
Bootstrap b = new Bootstrap().channel(NioSocketChannel.class).group( new NioEventLoopGroup());//自定义的channelpoolhandler ChannelPoolHandler handler = new ChannelPoolHandler();//创建一个FixedChannelPool FixedChannelPool pool = new FixedChannelPool(bootstrap, handler);//从channelpool中获取连接或者创建新的连接,并添加listener pool.acquire.addlistener();
三、总结
通常情况下,我们并不需要使用Netty建立连接池,common pool可以满足我们的需求,但是有些业务场景(例如:返回结果时间不确定)需要使用这种异步的连接池,在正确的业务场景下选择正确的解决方案才是王道哦。
转载于:https://my.oschina.net/miwang/blog/849116
正确地利用Netty建立连接池相关推荐
- Ajax通讯异常12002,前端MVC框架[02] 发送AJAX请求及建立连接池
前端MVC框架[02] 发送AJAX请求及建立连接池 默认分类 2012-10-11 07:51:28 < ol start='100' class='dp-xml'> / 异步请求管理器 ...
- AsyncHttpClient源码分析-基于Netty的连接池实现
原文地址:asynchttpclient源码分析-基于Netty的连接池实现 最近项目重构,有了个机会更多接触一个有别于HttpAsyncClient的异步网络框架AsyncHttpClient,是个 ...
- weblogic oracle连接池配置文件,关于WebLogic 访问Oracle 数据库(建立连接池)问题...
我在使用WebLogic Server 控制台配置Oracle 数据库连接池,没有成功求助 各位大侠指点一二. 配置信息: URL:jdbc:oracle:thin:@TEST:1521:oral D ...
- 走进JavaWeb技术世界3:JDBC的进化与连接池技术
网络访问 随着 Oracle, Sybase, SQL Server ,DB2, Mysql 等人陆陆续续住进数据库村, 这里呈现出一片兴旺发达的景象, 无数的程序在村里忙忙碌碌, 读写数据库, ...
- SpringBoot使用Redis 数据访问(单点、集群、哨兵、连接池、Pipline、分布式框架Redisson、解决方案)
目录 Redis 文献资料 用Redis编程 Redis模块API 教程和常见问题解答 管理 嵌入式和物联网 故障排除 Redis集群 其他基于Redis的分布式系统 在SSD和永久性存储器上进行Re ...
- swoole mysql 并发_Swoole4 如何打造高并发的PHP7协程Mysql连接池?
一.数据库连接池基本概念 所谓的数据库连接池,一般指的就是程序和数据库保持一定数量的数据库连接不断开,并且各请求的连接可以相互复用,减少重复新建数据库连接的消耗和避免在高并发的情况下出现数据库max ...
- 连接池,数据库连接池
连接池 连接池是什么? 连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用. 连接池的优点 减少连接创建时间 简化的编程模式 受控的资源使用 注:连接池能够使性能最大化, ...
- 深入理解Spring Boot数据源与连接池原理
Create by yster@foxmail.com 2018-8-2 一:开始 在使用Spring Boot数据源之前,我们一般会导入相关依赖.其中数据源核心依赖就是spring‐boot‐s ...
- 数据库连接池了解和常用连接池对比
一..背景介绍 什么是连接池 1)先讲一下"池", 池(Pool)技术在一定程度上可以明显优化服务器应用程序的性能,提高程序执行效率和降低系统资源开销.这里所说的池是一种广义上的池 ...
最新文章
- IAR生产HEX文件
- [ZJOI2007]棋盘制作 报表统计 矩阵游戏 时态同步
- 【入门经典】在母版页中使用CSS
- android+版本升级的时候会清楚数据马,android主进程销毁了,线程会不会也销毁?...
- mysql 包含的那些文件
- springboot快速入门(一)——HelloWorld搭建
- python初级第三库(人工智能,web解析,人机交互)
- 某大型银行深化系统技术方案之八:核心层之异步流程控制机制
- SQL Server 2008支持将数据导出为 insert into 的脚本
- CAD绘图软件使用技巧总结及CAD快捷键大全
- android 图片置顶,Android布局图片置顶
- macOS 工具 - 查看PKG文件内容:SuspiciousPackage 使用方法
- 准确率、精确率、召回率、F值
- html5文本框里插图片文字,word应用教程:在文本框内插入图片
- 渲染吃显卡还是CPU,如何高效3D渲染?
- Final Cut Pro 学习笔记
- 单模/多模光纤能和单模/多模光模块混用吗?
- 到处走走-成都+峨眉山557
- Linux报错:-bash: 路径xx: No such file or directory解决方法
- 关于两个数相乘, 求其为多少进制
热门文章
- python实践项目(二)
- java21天打卡 day10-字符串2
- java高性能反射框架_终于有人把性能优化讲清楚了!阿里架构师推荐的Java性能权威指南可太强了...
- java 实现复制_在java中如何实现复制,粘贴,剪切
- php foreach 单箭头,PHP Foreach循环具有单个元素
- python构建huffman树_python:哈夫曼树,PythonHuffuman
- word中装订线位置_Word操作技巧:Word文档双面打印全攻略,解决打印难题
- lesson 4 communication pattern
- 跨区域报考计算机考试可以吗,考生注意!2020年医师资格机考跨题型不可以回看(附上机操作系统)...
- 三个优秀的PyTorch实现语义分割框架