1.为什么很多程序员不用switch,分分析而是支源大量的if else?
2.DubboââHTTP åè®® + JSON-RPC
3.Dubbo 3.0.0 正式发布,新鲜出炉的源码中文教程快收藏
4.Dubbo 3.3.0-beta 版本正式发布
5.将Dubbo注册到Nacos,与DubboAdmin的分分析部署
为什么很多程序员不用switch,而是支源大量的if else?
探索了Dubbo源码中对ChannelEventRunnable的优化设计,发现了一段关于switch和if else的源码vue后台源码巧妙用法。在分析这段代码时,分分析我陷入了深思,支源试图理解其背后的源码原因。经过一番探索,分分析最终解开了这个谜团。支源
现代计算机CPU支持分支预测和指令流水线,源码这两个机制结合使用可以显著提升CPU的分分析执行效率。对于简单的支源if跳转指令,CPU能够较好地进行预测。源码然而,switch语句则涉及根据索引从地址数组中取地址并跳转,这使得CPU难以进行有效的预测。
在Dubbo的pythou源码实现中,观察到ChannelEventRunnable中的state常量超过.9%的情况下是ChannelState.RECEIVED。因此,通过将这个状态独立出来使用if语句进行判断,利用CPU的分支预测机制,可以进一步优化代码执行效率。
为了验证这一结论,通过实验对比了if和switch的执行效率。结果显示,独立的if语句在吞吐量方面明显优于switch。尽管从生成的字节码角度分析,switch的效率理论上高于if,但在实际测试中,if语句的性能优势更为显著。
通过对if和switch的执行过程进行对比分析,我们发现if语句的效率之所以优于switch,主要原因在于if的执行方式更符合CPU的分支预测机制。同时,通过实验数据支持了这一观点,etcpack源码证实了在热点分支的情况下,使用if语句可以带来更高的性能提升。
在探索分支预测机制时,我们还了解到指令流水线的概念,它通过将指令分解为多个步骤并行处理,以提高处理效率。分支预测器则利用历史信息预测指令跳转,提前执行相应路径的指令,以减少执行延迟。然而,分支预测也存在预测错误的风险,错误的预测可能导致流水线排空,从而影响性能。
在处理有序数组与非有序数组的问题上,同样涉及到分支预测的影响。排序后的数组使得每次循环的分支预测结果更倾向于正确,从而提高执行效率。而未排序的redsocks源码数组则可能导致预测错误,增加执行延迟。
综上所述,Dubbo源码中对ChannelEventRunnable的优化体现了对CPU分支预测和指令流水线的深入理解。通过调整代码结构,利用if语句独立处理热点分支,可以实现性能的显著提升。同时,探索了分支预测机制与指令流水线之间的关系,以及它们如何影响代码执行效率。在实际应用中,理解这些原理有助于优化代码性能,提升程序的执行速度。
DubboââHTTP åè®® + JSON-RPC
Protocol è¿æä¸ä¸ªå®ç°åæ¯æ¯ AbstractProxyProtocolï¼å¦ä¸å¾æ示ï¼
ä»å¾ä¸æ们å¯ä»¥çå°ï¼gRPCãHTTPãWebServiceãHessianãThrift çå议对åºç Protocol å®ç°ï¼é½æ¯ç»§æ¿èª AbstractProxyProtocol æ½è±¡ç±»ã
ç®åäºèç½çææ¯æ ç¾è±é½æ¾ï¼å¾å¤å ¬å¸ä¼ä½¿ç¨ Node.jsãPythonãRailsãGo çè¯è¨æ¥å¼å ä¸äº Web 端åºç¨ï¼åæ¶åæå¾å¤æå¡ä¼ä½¿ç¨ Java ææ¯æ å®ç°ï¼è¿å°±åºç°äºå¤§éçè·¨è¯è¨è°ç¨çéæ±ãDubbo ä½ä¸ºä¸ä¸ª RPC æ¡æ¶ï¼èªç¶ä¹å¸æè½å®ç°è¿ç§è·¨è¯è¨çè°ç¨ï¼ç®å Dubbo ä¸ä½¿ç¨âHTTP åè®® + JSON-RPCâçæ¹å¼æ¥è¾¾å°è¿ä¸ç®çï¼å ¶ä¸ HTTP åè®®å JSON é½æ¯å¤©ç¶è·¨è¯è¨çæ åï¼å¨åç§è¯è¨ä¸é½ææççç±»åºã
ä¸é¢å°±éç¹æ¥åæ Dubbo 对 HTTP åè®®çæ¯æãé¦å ï¼ä¼ä»ç» JSON-RPC çåºç¡ï¼å¹¶éè¿ä¸ä¸ªç¤ºä¾ï¼å¿«éå ¥é¨ï¼ç¶åä»ç» Dubbo ä¸ HttpProtocol çå ·ä½å®ç°ï¼ä¹å°±æ¯å¦ä½å° HTTP åè®®ä¸ JSON-RPC ç»å使ç¨ï¼å®ç°è·¨è¯è¨è°ç¨çææã
Dubbo ä¸æ¯æç HTTP åè®®å®é ä¸ä½¿ç¨çæ¯ JSON-RPC åè®®ã
JSON-RPC æ¯åºäº JSON çè·¨è¯è¨è¿ç¨è°ç¨åè®®ãDubbo ä¸ç dubbo-rpc-xmlãdubbo-rpc-webservice ç模åæ¯æç XML-RPCãWebService çåè®®ä¸ JSON-RPC ä¸æ ·ï¼é½æ¯åºäºææ¬çåè®®ï¼åªä¸è¿ JSON çæ ¼å¼æ¯ XMLãWebService çæ ¼å¼æ´å ç®æ´ãç´§åãä¸ Dubbo åè®®ãHessian åè®®çäºè¿å¶åè®®ç¸æ¯ï¼JSON-RPC æ´ä¾¿äºè°è¯åå®ç°ï¼å¯è§ JSON-RPC åè®®è¿æ¯ä¸æ¬¾é常ä¼ç§çè¿ç¨è°ç¨åè®®ã
å¨ Java ä½ç³»ä¸ï¼æå¾å¤æçç JSON-RPC æ¡æ¶ï¼ä¾å¦ jsonrpc4jãjpoxy çï¼å ¶ä¸ï¼jsonrpc4j æ¬èº«ä½ç§¯å°å·§ï¼ä½¿ç¨æ¹ä¾¿ï¼æ¢å¯ä»¥ç¬ç«ä½¿ç¨ï¼ä¹å¯ä»¥ä¸ Spring æ ç¼éåï¼é常éååºäº Spring ç项ç®ã
ä¸é¢å æ¥çç JSON-RPC åè®®ä¸è¯·æ±çåºæ¬æ ¼å¼ï¼
JSON-RPC请æ±ä¸å个å段çå«ä¹å¦ä¸ï¼
å¨ JSON-RPC çæå¡ç«¯æ¶å°è°ç¨è¯·æ±ä¹åï¼ä¼æ¥æ¾å°ç¸åºçæ¹æ³å¹¶è¿è¡è°ç¨ï¼ç¶åå°æ¹æ³çè¿åå¼æ´çæå¦ä¸æ ¼å¼ï¼è¿åç»å®¢æ·ç«¯ï¼
JSON-RPCååºä¸å个å段çå«ä¹å¦ä¸ï¼
Dubbo ä½¿ç¨ jsonrpc4j åºæ¥å®ç° JSON-RPC åè®®ï¼ä¸é¢ä½¿ç¨ jsonrpc4j ç¼åä¸ä¸ªç®åç JSON-RPC æå¡ç«¯ç¤ºä¾ç¨åºå客æ·ç«¯ç¤ºä¾ç¨åºï¼å¹¶éè¿è¿ä¸¤ä¸ªç¤ºä¾ç¨åºè¯´æ jsonrpc4j æåºæ¬ç使ç¨æ¹å¼ã
é¦å ï¼éè¦å建æå¡ç«¯å客æ·ç«¯é½éè¦ç domain 类以åæå¡æ¥å£ãå æ¥å建ä¸ä¸ª User ç±»ï¼ä½ä¸ºæåºç¡çæ°æ®å¯¹è±¡ï¼
æ¥ä¸æ¥å建ä¸ä¸ª UserService æ¥å£ä½ä¸ºæå¡æ¥å£ï¼å ¶ä¸å®ä¹äº 5 个æ¹æ³ï¼åå«ç¨æ¥å建 Userãæ¥è¯¢ User 以åç¸å ³ä¿¡æ¯ãå é¤ Userï¼
UserServiceImpl æ¯ UserService æ¥å£çå®ç°ç±»ï¼å ¶ä¸ä½¿ç¨ä¸ä¸ª ArrayList éå管ç User 对象ï¼å ·ä½å®ç°å¦ä¸ï¼
æ´ä¸ªç¨æ·ç®¡çä¸å¡çæ ¸å¿å¤§è´å¦æ¤ãä¸é¢æ们æ¥çæå¡ç«¯å¦ä½å° UserService ä¸ JSON-RPC å ³èèµ·æ¥ã
é¦å ï¼å建 RpcServlet ç±»ï¼å®æ¯ HttpServlet çåç±»ï¼å¹¶è¦çäº HttpServlet ç service() æ¹æ³ãæ们ç¥éï¼HttpServlet å¨æ¶å° GET å POST 请æ±çæ¶åï¼æç»ä¼è°ç¨å ¶ service() æ¹æ³è¿è¡å¤çï¼HttpServlet è¿ä¼å° HTTP 请æ±åååºå°è£ æ HttpServletRequest å HttpServletResponse ä¼ å ¥ service() æ¹æ³ä¹ä¸ãè¿éç RpcServlet å®ç°ä¹ä¸ä¼å建ä¸ä¸ª JsonRpcServerï¼å¹¶å¨ service() æ¹æ³ä¸å° HTTP 请æ±å§æç» JsonRpcServer è¿è¡å¤çï¼
æåï¼å建ä¸ä¸ª JsonRpcServer ä½ä¸ºæå¡ç«¯çå ¥å£ç±»ï¼å¨å ¶ main() æ¹æ³ä¸ä¼å¯å¨ Jetty ä½ä¸º Web 容å¨ï¼å ·ä½å®ç°å¦ä¸ï¼
è¿é使ç¨å°ç web.xml é ç½®æ件å¦ä¸ï¼
å®ææå¡ç«¯çç¼åä¹åï¼ä¸é¢å继ç»ç¼å JSON-RPC ç客æ·ç«¯ãå¨ JsonRpcClient ä¸ä¼å建 JsonRpcHttpClientï¼å¹¶éè¿ JsonRpcHttpClient 请æ±æå¡ç«¯ï¼
å¨ AbstractProxyProtocol ç export() æ¹æ³ä¸ï¼é¦å ä¼æ ¹æ® URL æ£æ¥ exporterMap ç¼åï¼å¦ææ¥è¯¢å¤±è´¥ï¼åä¼è°ç¨ ProxyFactory.getProxy() æ¹æ³å° Invoker å°è£ æä¸å¡æ¥å£ç代çç±»ï¼ç¶åéè¿åç±»å®ç°ç doExport() æ¹æ³å¯å¨åºå±ç ProxyProtocolServerï¼å¹¶åå§å serverMap éåãå ·ä½å®ç°å¦ä¸ï¼
å¨ HttpProtocol ç doExport() æ¹æ³ä¸ï¼ä¸åé¢ä»ç»ç DubboProtocol çå®ç°ç±»ä¼¼ï¼ä¹è¦å¯å¨ä¸ä¸ª RemotingServerã为äºéé åç§ HTTP æå¡å¨ï¼ä¾å¦ï¼TomcatãJetty çï¼Dubbo å¨ Transporter å±æ½è±¡åºäºä¸ä¸ª HttpServer çæ¥å£ã
dubbo-remoting-http 模åçå ¥å£æ¯ HttpBinder æ¥å£ï¼å®è¢« @SPI 注解修饰ï¼æ¯ä¸ä¸ªæ©å±æ¥å£ï¼æä¸ä¸ªæ©å±å®ç°ï¼é»è®¤ä½¿ç¨çæ¯ JettyHttpBinder å®ç°ï¼å¦ä¸å¾æ示ï¼
HttpBinder æ¥å£ä¸ç bind() æ¹æ³è¢« @Adaptive 注解修饰ï¼ä¼æ ¹æ® URL ç server åæ°éæ©ç¸åºç HttpBinder æ©å±å®ç°ï¼ä¸å HttpBinder å®ç°è¿åç¸åºç HttpServer å®ç°ãHttpServer ç继æ¿å ³ç³»å¦ä¸å¾æ示ï¼
è¿é以 JettyHttpServer 为ä¾ç®åä»ç» HttpServer çå®ç°ï¼å¨ JettyHttpServer ä¸ä¼åå§å Jetty Serverï¼å ¶ä¸ä¼é ç½® Jetty Server 使ç¨å°ç线ç¨æ± 以åå¤çè¯·æ± Handlerï¼
å¯ä»¥çå° JettyHttpServer æ¶å°çå ¨é¨è¯·æ±å°å§æç» DispatcherServlet è¿ä¸ª HttpServlet å®ç°ï¼è DispatcherServlet ç service() æ¹æ³ä¼æ请æ±å§æç»å¯¹åºæ¥ç«¯å£ç HttpHandler å¤çï¼
äºè§£äº Dubbo 对 HttpServer çæ½è±¡ä»¥å JettyHttpServer çæ ¸å¿ä¹åï¼åå° HttpProtocol ä¸ç doExport() æ¹æ³ç»§ç»åæã
å¨ HttpProtocol.doExport() æ¹æ³ä¸ä¼éè¿ HttpBinder å建åé¢ä»ç»ç HttpServer 对象ï¼å¹¶è®°å½å° serverMap ä¸ç¨æ¥æ¥æ¶ HTTP 请æ±ãè¿éåå§å HttpServer 以åå¤ç请æ±ç¨å°ç HttpHandler æ¯ HttpProtocol ä¸çå é¨ç±»ï¼å¨å ¶ä»ä½¿ç¨ HTTP åè®®ä½ä¸ºåºç¡ç RPC åè®®å®ç°ä¸ä¹æ类似ç HttpHandler å®ç°ç±»ï¼å¦ä¸å¾æ示ï¼
å¨ HttpProtocol.InternalHandler ä¸ç handle() å®ç°ä¸ï¼ä¼å°è¯·æ±å§æç» skeletonMap éåä¸è®°å½ç JsonRpcServer 对象è¿è¡å¤çï¼
skeletonMap éåä¸ç JsonRpcServer æ¯ä¸ HttpServer 对象ä¸åå¨ doExport() æ¹æ³ä¸åå§åçãæåï¼æ们æ¥ç HttpProtocol.doExport() æ¹æ³çå®ç°ï¼
ä»ç»å® HttpProtocol æ´é²æå¡çç¸å ³å®ç°ä¹åï¼ä¸é¢åæ¥ç HttpProtocol ä¸å¼ç¨æå¡ç¸å ³çæ¹æ³å®ç°ï¼å³ protocolBindinRefer() æ¹æ³å®ç°ã该æ¹æ³é¦å éè¿ doRefer() æ¹æ³å建ä¸å¡æ¥å£ç代çï¼è¿éä¼ä½¿ç¨å° jsonrpc4j åºä¸ç JsonProxyFactoryBean ä¸ Spring è¿è¡éæï¼å¨å ¶ afterPropertiesSet() æ¹æ³ä¸ä¼å建 JsonRpcHttpClient 对象ï¼
ä¸é¢æ¥ç doRefer() æ¹æ³çå ·ä½å®ç°ï¼
å¨ AbstractProxyProtocol.protocolBindingRefer() æ¹æ³ä¸ï¼ä¼éè¿ ProxyFactory.getInvoker() æ¹æ³å° doRefer() æ¹æ³è¿åç代ç对象转æ¢æ Invoker 对象ï¼å¹¶è®°å½å° Invokers éåä¸ï¼å ·ä½å®ç°å¦ä¸ï¼
æ¬æéç¹ä»ç»äºå¨ Dubbo ä¸å¦ä½éè¿âHTTP åè®® + JSON-RPCâçæ¹æ¡å®ç°è·¨è¯è¨è°ç¨ãé¦å ä»ç»äº JSON-RPC ä¸è¯·æ±åååºçåºæ¬æ ¼å¼ï¼ä»¥åå ¶å®ç°åº jsonrpc4j çåºæ¬ä½¿ç¨ï¼æ¥ä¸æ¥æ们è¿è¯¦ç»ä»ç»äº Dubbo ä¸ AbstractProxyProtocolãHttpProtocol çæ ¸å¿ç±»ï¼åæäº Dubbo ä¸âHTTP åè®® + JSON-RPCâæ¹æ¡çè½å°å®ç°ã
Dubbo 3.0.0 正式发布,新鲜出炉的中文教程快收藏
6月,Dubbo阵营迎来重大更新,正式发布了Dubbo 3.0.0版本。这份全新的中文教程新鲜出炉,不容错过。自助源码 对于Dubbo尚不清楚的朋友,这里先来科普一下:Dubbo是阿里巴巴推出的一款高性能、轻量级的Java服务框架,旨在简化分布式服务的开发和部署。 Dubbo的核心特性包括:高可用、高性能、分布式、可扩展、服务注册与发现、负载均衡等。它的发展历程也值得一提:年,Dubbo开源,标志着其诞生。
年,最后一个维护版本2.5.3发布后,项目一度沉寂。
年,Dubbo起死回生,官方重启维护,并得到重点支持。
年,Dubbo 3.0的开发正式启动,Dubbox项目分支合并,Spring Boot版本也相继发布。
年,Dubbo正式成为Apache顶级项目,适应云原生环境,强调服务的复用与云基础设施的对接。
Dubbo 3.0.0在保持与2.7.x兼容的同时,着重提升了易用性,拓展了超大规模微服务实践,以及与云原生基础设施的契合度。这份详细教程涵盖了8大模块,包括新功能介绍、概念架构解析、基本功能示例、升级与兼容性指南、多语言支持以及参考手册等,无论老用户还是新手都能从中获益。 深入理解Dubbo3的核心概念,可以参考“概念与架构”部分;想要直接体验新特性,可以参考“介绍与示例”;了解现有扩展和参考手册,可在“基本功能”和“参考手册”章节找到。教程详尽丰富,不容错过,快来领取吧!Dubbo 3.3.0-beta 版本正式发布
近日,Apache Dubbo社区宣布正式发布3.3分支的大版本3.3.0-beta.1。相较于3.2系列版本,3.3.0-beta版本引入了众多重量级功能升级。
3.3.0-beta.1版本带来的核心能力升级包括:Spring Boot Starters、Dubbo AOT静态化(GraalVM Native Image)、Triple协议升级、Rest协议升级、可观测性(Metrics & Tracing)、JDK 与协程支持等。
Spring Boot Starters组件可以简化Spring Boot用户的应用开发。例如,以Zookeeper注册中心为例,新版本的开发只需增加一个依赖即可。更多Starter组件包括dubbo-curator5-zookeeper-spring-boot-starter、dubbo-nacos-spring-boot-starter等。
Dubbo AOT静态化方案基于GraalVM Native Image实现,旨在提升Dubbo应用的启动与运行速度。Native的启动耗时降低了倍以上,内存损耗降低了3.5倍。
Triple协议是Dubbo3设计的基于HTTP的RPC通信协议规范,完全兼容gRPC协议,支持Request-Response、Streaming流式等通信模型,可同时运行在HTTP/1和HTTP/2之上。
Rest协议升级基于Dubbo的多协议发布能力,可以将RPC服务发布为标准的rest风格HTTP服务。可观测性方面,Metrics和Tracing的易用性得到大幅提升。
3.3.0-beta版本支持平滑升级到JDK 版本,并增加了Project Loom协程支持。Dubbo3规划的核心功能均已开发完成,将从3.3.0-beta.1版本开始进入长期稳定维护阶段。
将Dubbo注册到Nacos,与DubboAdmin的部署
本文介绍如何将 Dubbo 注册至 Nacos 并与 DubboAdmin 部署。
首先部署单机模式 Nacos,可以通过 IDEA 或 Maven 命令启动。配置鉴权确保安全。
Nacos 部署成功后,将 Dubbo 服务注册中心从 Zookeeper 迁移至 Nacos,修改 POM 文件引入依赖并调整 application.properties 配置。
接下来部署 Dubbo Admin 服务,切换分支后修改注册中心、端口号以及 Dubbo protocol 端口号。使用 Maven 命令打包后启动。
Dubbo Admin 提供多种功能,主要用于服务测试。启动后可访问 Web 管理端,探索其他功能。
注意生产环境中,确保无端口号冲突。 Dubbo Admin 默认账户密码为“root”。分享此内容,期待你的支持与指正。