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

高并发服务优化篇从RPC预热转发看服务端性能调优

  本篇带大家来看下RPC的一些高级特性和其背后的原因。(还是以开源的dubbo和sofa为例来说明)。  Part1RPC为了性能做了哪些努力1.1Provider分组和直连
  路由寻址,负载均衡是很好,可以保证流量均匀从而保护服务节点稳定。
  但是,我们有的时候其实不希望我们的请求乱跑,最好能打到指定的机器上。比如联调和测试的时候,直连功能就显得很重要了。
  只有经历过多方合作联调时请求到处乱跑的痛,才知道分组和直连的功能对开发是多么的友好。  //以sofa为例 @Extension(value = "directUrl", order = -20000) @AutoActive(consumerSide = true) public class DirectUrlRouter extends Router {   //... }
  我们可以看到直连路由策略的order属性,被赋予了一个极小的值,变成了优先级最高的路由策略,所以只要配置的直连列表,则会优先走配置中的列表地址。
  摘自:www.sofastack.tech  1.2异步调用
  Future异步调用
  异步调用对服务性能和并发的支持起到很大的作用。
  一般异步调用有Futurn和callback等方式,这里我们说下Future的原理:
  调用下游之后,先返回一个Future,上游通过Future.get()方法对结果进行获取,如果结果未返回则会让出CPU资源进入等待,直到结果到达或超时后触发回调方法才被唤醒。由于篇幅问题,Future的核心逻辑的相关注释就不放了,之前的消息消费顺序保障的文章中也有叙述,有兴趣的同学可以看下~  1.3本地优先、远程优先
  很多时候,我们会遇到消费端和服务端可能都是自己的情况。这个时候,在常规的路由寻址之外,又提供给我们一种调用的可能性,就是直接调用当前服务器上的程序,这样做的好处比较明显,省去了网络传输等时间损耗,效率更高。  List localProviderInfo = new ArrayList(); // 解析IP,看是否和本地一致 for (ProviderInfo providerInfo : providerInfos) {      if (localhost.equals(providerInfo.getHost())) {         localProviderInfo.add(providerInfo);     } } // 命中本机的服务端 if (CommonUtils.isNotEmpty(localProviderInfo)) {      return super.doSelect(invocation, localProviderInfo); } else {    // 没有命中本机上的服务端    return super.doSelect(invocation, providerInfos); }
  当然,也需要看业务和内部服务路由的实际情况,比如在阿里的单元化部署下,需要根据用户ID路由到对应的zone进行处理,如果还是优先本机,那就可能在操作数据库的时候涉及到跨zone调用,比走远程rpc更加耗时。因此这种情况下就需要禁用本机优先策略。  1.4延迟暴露
  很多时候,我们的服务需要依赖一些其他内容才可以正常提供服务,比如缓存预热、线程池预热等等,所以,在服务真正就绪之后再注册到配置中心是很有必要的。  //服务注册之前,先延迟 public void export() {     // 根据配置延迟加载     if (providerConfig.getDelay() > 0) {          Thread thread = factory.newThread(new Runnable() {          @Override          public void run() {              try {                   Thread.sleep(providerConfig.getDelay());              } catch (Throwable ignore) {               }               //真正的服务注册逻辑               doExport();          }       });       thread.start();    } else {        doExport();    } } 1.5粘滞连接
  问:   我们需要每次都进行路由寻址和负载均衡来确定服务地址么?
  答:   大部分情况是有利的,不过有些特殊的场景,更希望多次请求连接到同一台服务器。
  比如,有状态的服务(很多带数据功能的服务都是有状态的,比如很久之前的带登陆session的Tomcat服务、存储集群服务等),其实希望每次请求都连接到相同的服务器。
  这就用到了粘滞连接功能。  protected ProviderInfo select(...)throws SofaRpcException {     // 判断isSticky 粘滞连接配置     if (consumerConfig.isSticky()) {         //如果最后一次使用的provider不为空,则使用         if (lastProviderInfo != null) {             ProviderInfo providerInfo = lastProviderInfo;                     //获取对应连接             ClientTransport lastTransport = connectionHolder.getAvailableClientTransport(providerInfo);             if (lastTransport != null && lastTransport.isAvailable()) {                checkAlias(providerInfo, message);                return providerInfo;             }         }     }     ... } 1.6预热转发
  前面扯了那么多,其实,这个才是我们今天想说的重点。
  预热转发是针对服务节点的负载均衡来说的。因为在服务刚启动的时候,如果请求过多可能会影响机器性能和正常业务,如果将处于预热期的机器的请求转发到集群内其它机器,过了预热期之后再恢复正常,则可以保证服务节点的性能和服务整体的可用性。
  那么这个功能是怎么实现的呢?--带权重的随机负载均衡。
  摘自sofastack:权重随机的原理   //累加总权重totalWeight,代码忽略…    //在总权重内随机得到一个值  int offset = random.nextInt(totalWeight);    //确定随机值落在哪个片断上  for (int i = 0; i < size; i++) {      offset -= getWeight(providerInfos.get(i));      if (offset < 0) {         providerInfo = providerInfos.get(i);         break;      } }
  配置示例:  core_proxy_url=weightStarting:0.2,during:60,weightStarted:0.2,address:x.x.x.x,uniqueId:core_unique
  如上,预热权重20%,预热持续时长60s。这样,按照上述计算方式,权重小的服务节点被选到的几率就相对小,以此达到权重随机的效果。
  那么,为什么刚发布的服务需要预热呢?预热可以起到什么作用呢?  Part2什么是JIT优化
  都说C++快,Java慢,都是高级语言,是什么导致了运行速度的差别呢?
  这个涉及到了两种执行方式:  解释执行   和  编译执行  。
  相对于C++直接将代码编译成机器码运行的方式,Java为了实现跨平台、高度抽象等特性,增加了虚拟机层来实现Java代码到机器码的转换,Java程序先是被编译成符合虚拟机规范的.class字节码逐条将字节码翻译成机器码然后执行,所以,速度上就慢一些。
  虽然,JVM的加入,给Java的运行速度增加了不少损耗,但是好处也很多,除了跨平台,还为我们实现了诸如内存管理、垃圾回收等容器级通用功能,让研发人员可以更加聚焦业务。
  不过,Java也是要面子的,我允许自己慢,但我不允许自己慢那么多!
  怎么办呢?遵循二八原则,是不是可以找寻程序当中的贡献了大部分调用量的核心代码,把这部分编译成机器码,提升其速度,不就把整体的速度提上去了么,JVM也是这么做的~
  所以,JVM兼容了解释执行和编译执行两种方式,也就是我们常说的  即时编译  。
  前面的问题到这里其实就可以回答了。为什么需要预热转发呢?是为了用小流量对程序进行预热,目的是为了让核心代码进行及时编译,提高峰值运行速率,提升服务响应~
  下面让我们详细看下JIT。  2.1即时编译器
  为了权衡编译时间和执行效率,JVM设置了多种即时编译器:  C1(Client 编译器):基于字节码完成部分优化,如方法内联、常量传递,相对于C2,速度快,但性能稍差。  C2(Server 编译器):耗时较长的全局优化,如无用代码消除、重排序、循环展开、公共子表达式替代、常量传播等等。  Graal(新的JIT编译器):侧重于性能和语言操作性。在一些负载上提供比传统编译器更好的峰值性能;用 Graal 执行的语言可以互相调用,可以使用来自其他语言的库。  2.2JIT优化触发条件
  前面我们说过,JVM其实是希望找到承担更多调用请求的代码块进行优化,那,怎么来确认哪些代码是优化目标呢?--  热点探测
  基于采样的热点探测 :
  周期采样,检测各线程栈顶方法,经常出现的方法即为热点方法。好处是简单高效,缺点是不精确,容易受线程运行状态的影响。
  基于计数的热点探测 :
  (包括方法调用计数器和回边计数器)每个方法建立计数器,用来统计调用次数。如果该方法执行次数超过阈值,则该方法被认定为热点方法。好处是足够精确。缺点是空间损耗大,且实现较难。
  另外,可以通过如XX:CompileThreshold等参数来修改阈值,不过,没有绝对把握,还是不要动为好。  Part3JIT指导代码优化3.1方法内联
  为什么我们在刚写代码的时候,总是被建议不要写很大的方法体?方法内联的JIT优化策略就是其中一个重要的原因。(还有GC友好等原因)
  JVM内的每一次方法调用,都是栈帧在内存中出栈入栈的过程,方法多了性能损耗自然大,所以要进行方法内联,即把方法执行逻辑直接复制到调用方内部,避免方法调用。
  但是,方法内联是有方法大小限制的,超过了一定大小的方法,没法做内联优化。所以,平常应该注意,尽量避免写很大很冗长的方法。
  让我们来举个栗子实际感受一下~
  两种书写风格的大数相加
  如上图所示,两个字符串型整数相加,都能实现功能,前一种写法,把中间过程全都拆开,罗列在的方法内,整个方法虽然理解起来稍微方便些,但整体显得冗长;第二种方法,把各个条件都囊括在了for循环条件内,三行代码完成整体操作。
  如果要去评价,我觉得大部分人都会说第二种写的好,但是,第二种的好难道真的局限于优雅么?  //添加JVM启动参数,用于打印代码执行过程中的编译详情 //-XX:+PrintCompilation String num1 = "12345"; String num2 = "23456"; //循环15000次,因为1.8分层编译下,各层阈值不一样,我们取最大阈值 for (int i=0;i<15001;i++) {     rejectionLB1.stringAdd(num1, num2);     //rejectionLB1.stringAdd2(num1, num2);  }
  执行15000次写法1
  (图中编译层次这一列中,3代表C1编译,4代表C2编译)
  我们看到,随着代码的执行次数的增加,一些方法,进行了C1编译,如我们的主方法  stringAdd  ,而少数方法,从C1编译提升到了C2编译,如AbstractStringBuilder::append方法。
  执行15000次写法2
  我们看到了什么,  stringAdd2   居然在进行到运行后期执行了C2编译,而且很明显,方法二的C2编译的方法,比方法一要多不少。所以,平常写代码该注意些什么,是不是显而易见了… 3.2其他优化
  方法内联虽然只是一种简单优化,但是,是后续其他优化的基石。
  而JVM的分层优化涉及的点非常多 [1] :
  局部优化 :关注局部数据流分析,数组越界检查消除;寄存器优化,优化跳转、循环、异常处理等;代码简化,如公共表达式提取等等等。
  控制流优化 :专注于代码重排序、循环缩减、循环展开、异常定位优化等等等。
  全局优化 :主要关注冗余消除,如方法调用、锁;逃逸分析;GC和内存分配优化等等等。 Part4总结
  本篇从RPC的预热转发功能,引出了其背后的理论依据--JIT优化。阐述了JIT的基本概念,并用一个实例说明了代码编写风格对JIT优化的实际影响。
  JIT相关的优化实现起来非常难,不过其原理和作用对我们普通研发也不是特别难理解,学习JIT优化的目的,在于了解JVM底层的运行逻辑和实现,让我们可以更加信任托管,聚焦业务逻辑,同时在编写代码时,尽量用JVM友好的方式进行,从而达到更好看、更高效的目的。
  来源:https://mp.weixin.qq.com/s/pktzfRuXc3PEb172zw4qNQ

王者荣耀S26段位继承突变,段位越高越难受,赛季战令奖励爆料眼看12月份即将就要结束了!2022年也将至,新赛季也即将到来,并且是全新赛年,毕竟是新的一年嘛!那新赛季就是王者的第26个赛季了,不得不说,王者已经陪伴玩家们度过了26个赛季,2王者荣耀XYG创奇迹,张大仙以前没有搭理我们,这次41拿下DYGXYG创造奇迹,张大仙以前没有队伍搭理我们,这次直接41拿下DYG。作为王者荣耀的玩家,我想很多人都会关注KPL的比赛,毕竟看看职业选手打比赛,是跟我们平时玩路人局是不一样的,而最S12或将出现三支超人气全华班?Uzi复出,Bin的去向已定前言目前各个赛区的转会期也都进入尾声了,而很多战队也都纷纷公布了新赛季的最终阵容,相信很多小伙伴们也都知道了吧?不过LPL赛区目前都还未官宣,所以各个战队的最终阵容也引起了大家的关PGC周决GEN出色发挥斩获第三周周冠,12支总决赛队伍出炉PGC结束了第三周最后一天的周决比赛日,最终GEN保持出色的发挥以3鸡119分的绝对优势拿到了第三周周冠,排名第二的NAVI拿到了88分,而NHGEX都是拿到了相应不错的分数来到了张大仙直言以前没有队伍搭理我们,这次直接41拿下比赛对于XYG这支队伍来说,他们在当初刚刚来带KPL的时候,很对观众都不看好这支队伍,甚至很多人认为这就是张大仙获取热度的一种手段。但是随着赛季的进行,观众们也是逐渐发现XYG是真的很DOTA2PIT联赛开幕在即,8支参赛队伍盘点(下)接着此前盘点的PIT参赛队伍,接下来我们再来看看secret的情况。这支队伍目前再度组建了一套极具压迫性的全明星阵容,NISHA以及sumail将担任这支队伍的12号位,tapzo大学生选手眼中的电竞赛事这是他们的兄弟情和社交空间12月份的第一个周末,注定会给马浩诚和他的小伙伴们留下珍贵的记忆作为西安欧亚学院代表队,他们携手拿下了2021和平精英高校赛总冠军。快乐不只属于这些站上赛场的年轻人,当比赛所在地广ag超玩会被淘汰后,月光首次解说kpl赛事,比分被全网认可季后赛已经结束了第一周的比赛,两支战队AG超玩会和MTG被淘汰出局!季后赛第二周,没有胜者组的比赛,但是却有四场败者组的赛事!败者组第二轮有两场比赛,这两场比赛结束之后,将会有两支大家小时候都玩过哪些游戏呢今天见吧里有个写童年时游戏的文章,于是触贴生情,也想写个关于童年各种游戏的文章,以下就以我从学前班至大学的经历为主线叙述游戏,不过有的年代太久远,我描述的可能不太准确,有知道的可以劫杯赛事开启,国内参赛队伍竞争激烈!主播战队彰显强大实力自从网易上线全新角色扮演类游戏永劫无间之后,再一次有了与鹅厂进行争锋的实力。熟悉这款游戏的网友应该都知道,永劫无间凭借独特的游戏剧情以及超高的游戏画质一经上线便火爆全网,与此同时这NH成PCL最后牌面,GEX刷新观众认知,证明自己不逊色于S级战队如果你也喜欢看绝地求生的比赛,那么肯定知道,在11月19日12月19日期间,PGC全球总决赛正在火热进行中。而HY也会对这个比赛进行全程直播,给观众们带来这场不容错过的视觉盛宴。为
YM再夺LDL冠军!上单晴天被称为小PDD,玩家这波是完美复刻在刚刚结束的LDL比赛中,PDD创办的YM战队力压敌人,成功拿下了2021LDL春季赛的冠军。虽然这不是YM第一次获得LDL的冠军,但这次夺冠对于YM来说还是有很大意义。毕竟他们的LOL陷入英雄改名风波!7大英雄称号被改,艾克成了时间奇才?作为当下人气最高的游戏之一,LOL公测至今已经有11年之久,对于很多小伙伴来说这就是他们的青春。在这么多年的时间里,许多英雄的诞生也成为了大家美好的回忆,基本上每一位玩家都有自己的Khan是去养老的,MSI揭幕战C9遭DK虐泉,上路差距不忍直视经过一段时间的等待后,我们终于迎来了MSI的比赛。在本次MSI的揭幕战中,世界冠军DK迎战北美新王C9引起了许多玩家的期待。由于两支队伍实力都很强,不少玩家认为这恐怕将是小组赛最有JKL刚传出恋情就出事了?绯闻女友被官方点名私藏标本涉嫌违法近段时间MSI的举办引起了很多玩家热议,特别是在RNG势如破竹拿下三连胜后,不少玩家认为只有DK才有资格和RNG一战,只要这两支队伍不提前相遇,那么最终的冠军大概率将在他们之间产生李炫君还是不够努力,EDG阿布炮轰圣枪哥被反驳那打野呢?虽然EDG在这个赛季没能成功夺冠,但这支刚刚重建的队伍却受到了很多期待,不少粉丝都认为EDG在夏季赛可以获得更好的成绩。不过就在近日,EDG的经理阿布在直播中点名批评队员却引起了许LOL更新对决机制!鳄鱼开大全程红怒,狗头Q技能变成范围AOE?大家应该都知道,在LOL这款游戏中除了不同阵营之间拥有敌对关系之外,许多英雄之间还有对决机制,像赛娜和锤石之间就拥有这个机制,击杀对方可以获得额外属性。而螳螂和狮子狗之间的对决机制RNG赢了比赛却败了人品?不遮耐克标被爆破,官博我真的没办法相信大家都还记得,前段时间因为新疆棉花事件导致国际大品牌耐克遭到抵制,就连LPL都加入到了抵制耐克的队伍中,不仅在各种海报上见不到耐克标志,就连队员在现场穿的衣服都遮挡了标志。不过LOL蒙多重做完成!新技能被质疑缝合怪,使用大招还会爆衣?对于LOL这款游戏来说,能够这么多年始终保持游戏的热度,除了不断推出新英雄之外,官方还会对老英雄进行重做,这样的举动也带给很多玩家新鲜感。经过长时间的等待后,蒙多医生这位老牌英雄终RNG双杀DK,小虎如来神掌打出含金量,笑笑谢谢你,原神目前虽然RNG已经提前锁定了晋级下一轮的资格,但由于小组赛会按照排名来安排比赛,因此对于RNG来说光是晋级下一轮还不够,他们需要保住小组第一的位置才能获得更大的优势。因此最后的两场EDG又在卖情怀?圈内人爆料厂长夏季赛上场,玩家Viper难顶了目前LPL夏季赛转会期已经结束,各大战队为了获得世界赛的名额或多或少都对阵容进行了改变。不过对于春季赛表现出色的队伍来说,有几支队伍保持了原班人马,并没有对阵容进行太多调整。其中ETES泄露转会期内幕,PDD旗下大将或将取代369,小龙堡加入LGD?目前MSI正在如火如荼地进行着,不少玩家都期待最后的冠军产生。不过这段期间除了MSI之外,各大赛区也都进入到转会期,许多队伍都在为夏季赛做准备。虽然LPL的转会期已经开启,但由于M