范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

单机百万连接调优和Netty应用级别调优

  单机百万连接调优
  准备两台Linux服务器,一个充当服务端,一个充当客户端。
  服务端操作系统:CentOS 7配置:4核8GIP:192.168.118.138
  客户端操作系统:CentOS 7配置:4核8GIP:192.168.118.139
  服务端和客户端均要配置java环境,基于jdk1.8。如何模拟百万连接#
  如果服务端只开一个端口,客户端连接的时候,端口号是有数量限制的(非root用户,从1024到65535,大约6w),所以服务端开启一个端口,客户端和服务端的连接最多6w个左右。
  为了模拟单机百万连接,我们在服务端开启多个端口,例如8000~8100,一共100个端口,客户端还是6w的连接,但是可以连接服务端的不同端口,所以就可以模拟服务端百万连接的情况。准备服务端程序#
  服务端程序的主要逻辑是:
  绑定8000端口一直到8099端口,一共100个端口,每2s钟统计一下连接数。
  channelActive触发的时候,连接+1, channelInactive触发的时候,连接-1。
  代码见:Server.java准备客户端程序#
  客户端程序的主要逻辑是:
  循环连接服务端的端口(从8000一直到8099)。
  代码见:Client.java
  准备好客户端和服务端的代码后,打包成Client.jar和Server.jar并上传到客户端和服务端的/data/app目录下。打包配置参考pom.xml
  服务端和客户端在/data/app下分别准备两个启动脚本,其中服务端准备的脚本为startServer.sh, 客户端准备的脚本为startClient.sh,内容如下:
  startServer.shjava -jar server.jar -Xms6.5g -Xmx6.5g -XX:NewSize=5.5g -XX:MaxNewSize=5.5g -XX:MaxDirectMemorySize=1g
  startClient.shjava -jar client.jar -Xms6.5g -Xmx6.5g -XX:NewSize=5.5g -XX:MaxNewSize=5.5g -XX:MaxDirectMemorySize=1g
  脚本文件见:startServer.sh 和 startClient.sh
  先启动服务端cd /data/app/   ./startServer.sh
  查看日志,待服务端把100个端口都绑定好以后。
  在启动客户端cd /data/app/  ./startClient.sh
  然后查看服务端日志,服务端在支撑了3942个端口号以后,报了如下错误:Caused by: java.io.IOException: Too many open files  at sun.nio.ch.FileDispatcherImpl.init(Native Method)  at sun.nio.ch.FileDispatcherImpl.(FileDispatcherImpl.java:35) 突破局部文件句柄限制#
  使用ulimit -n命令可以查看一个jvm进程最多可以打开的文件个数,这个是局部文件句柄限制,默认是1024,我们可以修改这个值vi /etc/security/limits.conf
  增加如下两行*               hard    nofile             1000000 *               soft    nofile             1000000
  以上配置表示每个进程可以打开的最大文件数是一百万。突破全局文件句柄限制#
  除了突破局部文件句柄数限制,还需要突破全局文件句柄数限制,修改如下配置文件vi /proc/sys/fs/file-max
  将这个数量修改为一百万echo 1000000 > /proc/sys/fs/file-max
  通过这种方式修改的配置在重启后失效,如果要使重启也生效,需要修改如下配置vi /etc/sysctl.conf
  在文件末尾加上fs.file-max=1000000
  服务端和客户端在调整完局部文件句柄限制和全局文件句柄限制后,再次启动服务端,待端口绑定完毕后,启动客户端。
  查看服务端日志,可以看到,服务端单机连接数已经达到百万级别。..... connections: 434703 connections: 438238 connections: 441195 connections: 444082 connections: 447596 ..... connections: 920435 connections: 920437 connections: 920439 connections: 920442 connections: 920443 connections: 920445 .....  Netty应用级别调优#场景#
  服务端接受到客户端的数据,进行一些相对耗时的操作(比如数据库查询,数据处理),然后把结果返回给客户端。模拟耗时操作#
  在服务端,模拟通过sleep方法来模拟耗时操作,规则如下:在90.0%情况下,处理时间为1ms在95.0%情况下,处理时间为10ms在99.0%情况下,处理时间为100ms在99.9%情况下,处理时间为1000ms
  代码如下protected Object getResult(ByteBuf data) {     int level = ThreadLocalRandom.current().nextInt(1, 1000);     int time;     if (level <= 900) {         time = 1;     } else if (level <= 950) {         time = 10;     } else if (level <= 990) {         time = 100;     } else {         time = 1000;     }     try {         Thread.sleep(time);     } catch (InterruptedException e) {     }     return data; } 客户端统计QPS和AVG逻辑#
  获取当前时间戳,客户端在和服务端建立连接后,会每隔1s给服务端发送数据,发送的数据就是当前的时间戳,服务端获取到这个时间戳以后,会把这个时间戳再次返回给客户端,所以客户端会拿到发送时候的时间戳,然后客户端用当前时间减去收到的时间戳,就是这个数据包的处理时间,记录下这个时间,然后统计数据包发送的次数,根据这两个变量,可以求出QPS和AVG,其中:
  QPS 等于 总的请求量 除以 持续到当前的时间
  AVG 等于 总的响应时间除以请求总数
  客户端源码参考:Client.java
  服务端源码参考:Server.java
  服务端在不做任何优化的情况下,关键代码如下... bootstrap.childHandler(new ChannelInitializer() {             @Override             protected void initChannel(SocketChannel ch) {                 ch.pipeline().addLast(new FixedLengthFrameDecoder(Long.BYTES));                 ch.pipeline().addLast(/*businessGroup,*/ ServerBusinessHandler.INSTANCE); //                ch.pipeline().addLast(ServerBusinessThreadPoolHandler.INSTANCE);             }         }); ... @ChannelHandler.Sharable public class ServerBusinessHandler extends SimpleChannelInboundHandler {     public static final ChannelHandler INSTANCE = new ServerBusinessHandler();       @Override     protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {         ByteBuf data = Unpooled.directBuffer();         data.writeBytes(msg);         Object result = getResult(data);         ctx.channel().writeAndFlush(result);     }      protected Object getResult(ByteBuf data) {         int level = ThreadLocalRandom.current().nextInt(1, 1000);         int time;         if (level <= 900) {             time = 1;         } else if (level <= 950) {             time = 10;         } else if (level <= 990) {             time = 100;         } else {             time = 1000;         }          try {             Thread.sleep(time);         } catch (InterruptedException e) {         }          return data;     }      @Override     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {         // ignore     } }
  运行服务端和客户端,查看客户端日志..... qps: 1466, avg response time: 35.68182 qps: 832, avg response time: 214.28384 qps: 932, avg response time: 352.59363 qps: 965, avg response time: 384.59448 qps: 957, avg response time: 403.33804 qps: 958, avg response time: 424.5246 qps: 966, avg response time: 433.35272 qps: 980, avg response time: 484.2116 qps: 986, avg response time: 478.5395 ..... 优化方案一:使用自定义线程池处理耗时逻辑#
  将服务端代码做如下调整bootstrap.childHandler(new ChannelInitializer() {             @Override             protected void initChannel(SocketChannel ch) {                 ch.pipeline().addLast(new FixedLengthFrameDecoder(Long.BYTES));                 //ch.pipeline().addLast(/*businessGroup,*/ ServerBusinessHandler.INSTANCE);                 ch.pipeline().addLast(ServerBusinessThreadPoolHandler.INSTANCE);             }         });
  其中ServerBusinessThreadPoolHandler中,使用了自定义的线程池来处理耗时的getResult方法。关键代码如下:private static ExecutorService threadPool = Executors.newFixedThreadPool(1000);     @Override     protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {         ByteBuf data = Unpooled.directBuffer();         data.writeBytes(msg);         threadPool.submit(() -> {             Object result = getResult(data);             ctx.channel().writeAndFlush(result);         });      }
  再次运行服务端和客户端,可以查看客户端日志,QPS和AVG指标都有明显的改善.... qps: 1033, avg response time: 17.690498 qps: 1018, avg response time: 17.133448 qps: 1013, avg response time: 15.563113 qps: 1010, avg response time: 15.415672 qps: 1009, avg response time: 16.049961 qps: 1008, avg response time: 16.179882 qps: 1007, avg response time: 16.120466 qps: 1006, avg response time: 15.822202 qps: 1006, avg response time: 15.987518 ....
  实际生产过程中,Executors.newFixedThreadPool(1000);中配置的数量需要通过压测来验证。优化方案二:使用Netty原生的线程池优化#
  我们可以通过Netty提供的线程池来处理耗时的Handler,这样的话,无需调整Handler的逻辑(对原有Handler无代码侵入),关键代码:bootstrap.childHandler(new ChannelInitializer() {             @Override             protected void initChannel(SocketChannel ch) {                 ch.pipeline().addLast(new FixedLengthFrameDecoder(Long.BYTES));                 // ch.pipeline().addLast(ServerBusinessHandler.INSTANCE);                 // 使用业务线程池方式                 // ch.pipeline().addLast(ServerBusinessThreadPoolHandler.INSTANCE);                 // 使用Netty自带线程池方式                 ch.pipeline().addLast(businessGroup,ServerBusinessHandler.INSTANCE);             }         });
  其中businessGroup是Netty自带的线程池EventLoopGroup businessGroup = new NioEventLoopGroup(1000);
  ServerBusinessHandler中的所有方法,都会在businessGroup中执行。
  再次启动服务端和客户端,查看客户端日志..... qps: 1027, avg response time: 23.833092 qps: 1017, avg response time: 20.98855 qps: 1014, avg response time: 18.220013 qps: 1012, avg response time: 17.447332 qps: 1010, avg response time: 16.502508 qps: 1010, avg response time: 15.692251 qps: 1009, avg response time: 15.968423 qps: 1008, avg response time: 15.888149 .....更多优化建议#
  参考Netty性能调优奇技淫巧还有其他的吗?
  1.如果QPS过高,数据传输过快的情况下,调用writeAndFlush可以考虑拆分成多次write,然后单次flush,也就是批量flush操作
  2.分配和释放内存尽量在reactor线程内部做,这样内存就都可以在reactor线程内部管理
  3.尽量使用堆外内存,尽量减少内存的copy操作,使用CompositeByteBuf可以将多个ByteBuf组合到一起读写
  4.外部线程连续调用eventLoop的异步调用方法的时候,可以考虑把这些操作封装成一个task,提交到eventLoop,这样就不用多次跨线程
  5.尽量调用ChannelHandlerContext.writeXXX()方法而不是channel.writeXXX()方法,前者可以减少pipeline的遍历
  6.如果一个ChannelHandler无数据共享,那么可以搞成单例模式,标注@Shareable,节省对象开销对象
  7.如果要做网络代理类似的功能,尽量复用eventLoop,可以避免跨reactor线程

加盟英超曼联,得到弗格森称赞,国足天才少年为何泯然众人提起中国足球,想必很多球迷都会恨铁不成钢。的确,最近几年中国足球的成绩实在不理想,而球员的能力相比十几年前也有不少下降。就连武磊加入西甲保级球队(现已降为西乙)都已经成为了中国球迷小米有品爆款返场,众筹收割3200416元,90后刚需如今人们的生活水平正在不断的提高,越来越注重健康和卫生问题。小到一双筷子,都需要注意它的使用和存放问题。现在的筷子主要有竹木铁塑不锈钢等各种材质。相比筷子材质的多样化,筷筒则多数是华为全新定义朋克养生,40热敷,三头按摩,编辑离不开身为当代年轻人,越来越崇尚一边作死一边自救的养生模式,什么熬夜敷面膜,啤酒加枸杞,可乐配党参,早已成为家常便饭。偶尔有了闲暇时光,小编还会和几个朋友相约去汗蒸,在药蒸房里挑战谁更抗易观天猫精灵销量超1500万阿里率先布局产业生态8月13日,市场分析机构易观发布智能音箱市场分析报告称,中国智能音箱市场增长迅猛,2019年市场规模预计将达到5990万台的规模。其中天猫精灵销量领先突破1500万与小米小爱音箱小数据时代,云计算加持,将推动装备制造业向智能一体化协同发展CiaoBello,我是老房。今天咱们来聊一聊关于传统装备制造业在技术飞速进步的当下,转型升级的发展方向。一智能制造产业的发展背景制造业是国民经济的主体,是现代工业的基石,新时代中5G来了,你玩抖音的姿势也应该改变了CiaoBello,我是老房。2019年6月6日,工信部向中国电信中国移动中国联通中国广电发放5G商用牌照,标志着中国正式进入了5G商用时代。关于5G,铺天盖地的宣传都在说将会改变解决关键痛点,跟着荣耀V30步入5G时代CiaoBella,我是老房。2019年6月6日,工信部向中国电信中国移动中国联通中国广电发放5G商用牌照,标志着中国正式进入了5G商用时代。关于5G,我们很多人更多的是停留在贸易小米系的海鸟品牌推出标签打印机,热敏打印无需耗材CiaoBella,我是老房。山下英子的断舍离相信很多人都看过,整洁的家居,有序的收纳,触手可及的便利,嗯,那句话怎么说的来着,令人怦然心动的整理魔法?精髓是,整齐划一的收纳盒,贴办公室也能做出好咖啡小米有品心想胶囊咖啡机Mini入手体验CiaoBella,我是老房。作为一个曾经在意大利待过几年的人,老房早已养成了喝咖啡的习惯,当年从意大利回国的时候也顺便带回来几个摩卡壶。摩卡壶在意大利其实就像咱们国人家的茶壶一样欢聚时刻随时分享富士小俏印二代珍贵照片立等可取CiaoBella,我是老房。祝大家新年快乐,平安健康。正如电子书再方便,也不如纸质书捧在手里读的那种完美体验。数码照片再便捷,也比不上相片拿在掌心的那种真实感。所以在这个信息技术圆润小巧音质好TFZCOCOQ1真无线蓝牙耳机CiaoBella,我是老房。被网友们戏称为田馥甄的TFZ耳机近期推出了一款主打轻便高颜值的入门级真无线蓝牙耳机COCOQ1,三百元左右的价位,也比较适合学生朋友们的采购预算。货架
大手笔!三菱化学拟投1。1亿欧元,扩大聚酯薄膜生产能力近期,三菱化学在其官网上宣布,将投资1。1亿欧元用来扩大其子公司三菱聚酯薄膜有限公司(MFE)位于德国威斯巴登的聚酯薄膜生产能力。此次新增生产线的设计产能为年产27000吨聚酯薄膜开学换机就要硬核宠粉海信阅读手机带你徜徉书香世界一转眼暑假就要结束了。随着开学季的到来,不少学生纷纷开始为自己准备学习用品,其中也包括智能手机这个日常使用频率最高的电子产品。然而,市面上的手机产品五花八门,作为学生到底应该怎么选用车开到转速红区到底伤不伤车呢最近有小伙伴问,车子不小心开到转速红区,会不会伤车?下面我们一起来了解下。转速红区转速表上一般标有数字010之间的一段区域,单位是千转分钟,如果指针指向6,也就是说现在发动机转速是车后的挡风玻璃为什么有很多横线关于汽车里的学问真是太多了,家里有车的朋友们,如果你们留心观察会发现一个问题,车辆后窗玻璃上会有一道道的横线,有的是红色,有的是白色,那么这个横线有什么作用呢?这些横线到底有什么作为什么LED大灯没有普及有啥缺点LED车灯是主流,未来更多的车型将配备LED车灯,甚至激光灯组。现在没有普及的原因只有一个成本问题。很多入门车型配备卤素灯,中高配则配备了LED灯组。很多国产车则是全系配备了LED星越S店内可试乘试驾售价13。57万元起星越S给你劲爽礼遇,8月31日前购车1焕新礼6000元置换补贴,2000元增购补贴,至高7000元置换补贴2金融礼至高金融贴息8000元3保养礼4。5年或12万公里免费保养4保值礼万兴PDF,一款很实用的办公软件,工作上的好帮手因为工作上经常需要处理大量PDF文档,我刚开始是下载了些办公软件来处理它们,但是每次使用这些软件都不大方便,不是缺少某项功能,就是处理起来需要耗费大量的时间。无可奈何,我便询问起了华为高端一体机最佳购买时机,华为MateStationX双十一来了现如今,随着5G时代的全面来袭,更多的智能产品走进了我们的生活。要说在智能领域中,最让国人倍感自豪的品牌,还要属华为。近年来,华为的每个举动都备受人们关注,研发的产品更是满满的创新小米平板5明日再次开售在上周举行的2021雷军年度演讲上,小米MIX4系列正式发布,同时,还带来了小米平板系列新成员小米平板5。8月16日,小米平板5系列迎来首销,根据小米公布的战报来看,小米平板5系列华为P50Pro屏幕全球第一超三星昨天,全球著名的权威评测机构DxOMark更新了华为P50Pro的屏幕测试,并且为其给出了93分的全球最高分,这是华为旗舰机的屏幕首次成为全球第一,超过了三星最强旗舰S21Ultr华为公布最新进展,鸿蒙OS再次加快进度了?鸿蒙OS的系统自从被上线,就一直被大家所关注着的!尤其是广大花粉,他们都想知道自己的华为手机,什么时候才能真正升级为鸿蒙系统。而就目前来看,华为进一步加快了鸿蒙OS的升级进度,已经