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

单机百万连接调优和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线程

今日热点网易云音乐起诉腾讯音乐华为将会放弃部分低质量项目1网易云音乐起诉腾讯音乐不正当竞争,腾讯音乐回应4月27日消息,据网易云音乐公众号消息,网易云音乐宣布就腾讯音乐不正当竞争行为正式提起司法诉讼程序,起诉腾讯音乐通过非法盗播歌曲批量9999元起华为MateXs2核心配置一览4月28日晚,华为折叠旗舰及全场景新品发布会正式举行。ZOL正在为您带来此场发布会的最新快讯,请持续关注。在简单介绍完了华为MateXs2的配置之后,余承东宣布了该机的售价起售价9中国数字经济新趋势从数字化出海到出海数字化数字经济出海正呈现新的趋势。近日,亚马逊云科技发布中国企业上云出海趋势指出,中国与数字经济相关的出海正从数字化出海向出海数字化扩展。所谓数字化出海,也是第一波中国企业出海的主流,体北京率先允许自动驾驶车辆方向盘后无人今日北京率先放开自动驾驶主驾无人许可,成为国内首个开启乘用车无人化运营试点的城市,首批将投入14辆无人化车辆开展示范应用。百度小马智行成为首批获得先行区无人化示范应用道路测试通知书赵长鹏币安最新动向4月27日讯,币安创始人兼首席执行官赵长鹏周二在英国金融时报加密和数字资产峰会上表示,币安可能很快在欧洲G7国家建立一个受监管的实体。赵长鹏表示,币安已经有了一个标准的公司结构(这贝莱德推出首只区块链ETF贝莱德推出了首只专注于区块链的ETFTheiSharesBlockchainandTechETF(IBLC),旨在为围绕区块链技术不断增长的需求提供敞口,这也标志着这家全球最大的资TCL科技2021年营收净利均倍增新能源光伏及半导体材料成为新引擎本报记者矫月见习记者张军兵4月28日,TCL科技披露2021年年报,公司全年实现营业收入1635。4亿元,同比增长113。3实现净利润149。6亿元,同比增长195。3实现归属于上终究还是盼来了,华为Mate50定档7月见,首搭鸿蒙3。0售价不妥协对于华为的不公平遭遇,想必大家应该都有所了解。在芯片受限之后,华为手机不仅更新节奏变慢,数量也减少了。可这场持久战究竟要何时才能结束,还记得余承东曾表示过,华为将会在2023年王者广东重磅促消费政策来了!买新能源车每辆补贴1万元,燃油车也补5000元新能源汽车已经成为拉动消费的重要增长极,汽车产业聚集的广东省以补贴方式鼓励消费者购置新车。4月28日,广东省政府印发广东省进一步促进消费若干措施(下称措施),提出鼓励汽车消费推动家芯片供不应求,高通一季度赚疯了21世纪经济报道记者白杨北京报道4月28日,高通发布了2022财年第二财季(2022年第一季度)财报。报告期内,高通实现营收111。64亿美元,同比增长41净利润为29。34亿美元三大运营商5G新通话产品凑齐了,用户真的需要吗?4月26日,中国联通官方宣布和中国电信率先实现5G新通话互联互通。而就在半个月前,中国移动于4月12日发布了5G新通话产品。此外,今年1月25日,中国电信宣布5G消息正式商用。国内
阿里和腾讯背后的大股东是谁?京东小米的大老板又是谁?望周知在这几年以来,我们国家的市场当中有着相当大的变化,市场产业更为多元化,优秀企业的数量也是变得更加多了起来。例如像是我们大家熟知的互联网巨头企业阿里巴巴以及腾讯集团,电商产业当中的头都是华为合作!为什么媒体朋友大多看好赛力斯,而非阿维塔?近一个月以来,重庆汽车圈可以说异常热闹,重庆地产两大汽车集团,长安汽车和小康集团陆续发布了旗下的高端独立品牌,长安汽车的叫阿维塔,小康集团的叫AITO。关于这两个品牌,目前还都属于美国又拉黑大疆等8家中国公司,中芯国际恐遭更严厉制裁防走失,电梯直达安全岛报人刘亚东A来源新智元(IDAIera)新智元报道编辑桃子David新智元导读商汤之后,美国制裁再升级。外媒称,拜登政府周四将把大疆旷视等8家中国公司列入投资美国突然下黑手,国内AI巨头遭殃国内人工智能独角兽商汤科技,在上市前夕,突然遭美国制裁了!商汤科技延迟上市12月13日,商汤集团发布公告称,为保障公司有意投资者的利益并帮助他们考虑该等最新事态发展对其投资决定的潜马斯克称他将是美国纳税第一人!点赞中国车企聪明且勤奋的人太多,让人有一丝畏惧中国经济周刊经济网讯近日,马斯克和美国州参议员伊丽莎白沃伦在关于富豪交税问题发生争论。当地时间12月15日,马斯克称只需睁开眼睛2秒钟,就能知道我今年的纳税金额将超过历史上任何一个外媒称美国将制裁大疆,美军曾站出来激烈反对把它禁了我用啥?据环球网12月15日报道,英国媒体金融时报称,8家中国企业将被美国财政部列入制裁名单。而作为中国无人机产业的代表企业,大疆科技公司也在制裁名单之中。报道还称,除了美国商务部将会对8这两款电动车,搭载48V24Ah电池,续航100公里,禁摩城市也能上路对于一些禁摩城市地区的用户来说,在选择电动车时,除了会考虑车辆的性能外,还会考虑车辆能否上牌上路。而对此,不少电动车企业也都在开始加大对长续航新国标电动车的打造力度,下面就带大家来北京电信已实现五环内和城市副中心室外5G网络连续覆盖北京商报讯(记者石飞月)5G已经正式商用两周年,12月16日,北京商报记者获悉,北京电信不断加快5G基础设施建设的速度,实现了五环内和城市副中心室外5G网络连续覆盖,此外,大兴新机520km长续航电动SUV,充电快空间大的城市代步车,实拍威马W6520km长续航电动SUV,充电快空间大的城市代步车,实拍威马W6家用代步车这几年大家非常愿意选择SUV车型,看着结实安全有气势,而且空间上更能满足家庭需求,这也就是为什么近几年的对于V神的最新发文以太坊扩容的终局之战解析近日,V神发表了一篇关于以太坊扩容终局之战的文章取名Endgame,对于刚入圈的小白朋友们理解起来还是很吃力的,所以我们在这里做一个解析版。刚入圈的朋友你只需先记住以下两个中心思想Python中级精华模块和包模块和包概念模块每个独立的py文件包描述模块组织构成例如包package1init。pysubpackage1init。pytest。pytext。pysubpackage2ini