当前位置: 首页 > 科技观察

纵览Dubbo大局,阅读源码前必须掌握这些!!

时间:2023-03-20 00:11:14 科技观察

作者个人研发在高并发场景下提供了一个简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。开源半年多以来,已成功为十几家中小企业提供精准定时调度解决方案,经受住了生产环境的考验。为了造福更多的童鞋,这里提供一个开源框架地址:https://github.com/sunshinelyz/mykit-delay由于我们要写一个深入分析Dubbo源码的系列话题,所以我们首先要做的是搭建一套Dubbo的源码环境,俗话说“工欲善其事,必先利其器”。不过,为了更好的理解Dubbo,我将本文分为三个部分:Dubbo中的核心作用、搭建Dubbo源码环境、Dubbo核心模块说明、运行Dubbo示例程序。说到做到,抓重点。注:本系列话题,我是基于Dubbo2.7.8版本分析源码的。Dubbo中的核心角色为了更好的说明Dubbo中的核心角色,这里直接引用一张Dubbo的依赖关系图。注:图片来自Dubbo官网。从Dubbo的依赖关系图可以看出,Dubbo主要由Registry、Provider、Consumer和Monitor四个部分组成。下面,我们分别对这四个部分进行简要介绍。登记处,登记中心。在Dubbo中,注册中心负责服务的注册和发现,主要是服务地址的注册和查找。值得一提的是,在Dubbo中,Provider和Consumer只在服务启动时与注册中心进行交互。之后,注册中心以长连接的形式感知到Provider的存在。如果Provider宕机或不可用,注册中心会立即推送相关事件通知Consumer。Provider,服务的提供者。Provider在启动时,会向注册中心注册自己的相关服务,主要是将自己的服务地址和相关配置信息封装成URL,添加到Zookeeper等服务中。Consumer,服务的消费者。当Consumer启动时,它会订阅注册中心来获取它关心的服务。主要是从Zookeeper等服务中获取Provider注册的URL,为Zookeeper等服务添加相应的监听器。Consumer在获取到Provider注册的URL后,会通过负载均衡算法从获取到的多个Provider中选择一个,与其建立连接,并发起RPC调用。如果Zookeeper等服务中注册的Provider发生变化,Consumer会通过注册中心添加的监听器获取最新的Provider信息。而且,Consumer会缓存Provider的信息。一旦Consumer和Provider建立连接,即使注册中心宕机或不可用,也不会影响Consumer和Provider之间的交互。Monitor:监控中心。主要用于统计Dubbo服务的调用次数和调用时间。在Dubbo的核心架构中,监控中心不是必须的,监控中心宕机或不可用不会影响Dubbo的整体服务。好了,Dubbo的核心角色介绍就到此为止了。更多信息可以参考Dubbo的官方文档。搭建Dubbo源码环境,我们可以使用如下命令下载github源码到本地。gitclonehttps://github.com/apache/dubbo.git接下来把Dubbo的源码切换到2.7.8gitcheckout-bdubbo-2.7.8dubbo-2.7.8使用Maven编译成mvncleaninstall-Dmaven.test.skip=trueIDEA项目,这里我使用IDEA来分析Dubbo源码。mvnidea:idea接下来我们就可以将Dubbo源码导入到IDEA中了。说了这么多,还有一种方式就是直接通过浏览器下载Dubbo2.7.8的源码到本地。在浏览器中打开链接:https://github.com/apache/dubbo/releases/tag/dubbo-2.7.8下载Dubbo源码。这里可以下载zip压缩包和tar.gz压缩包,下载到本地,解压,导入IDEA。导入完成后,我们看到的项目结构如下。下面简单介绍下Dubbo源码中的核心模块。Dubbo核心模块说明dubbo-common模块Dubbo的common模块提供了DubboSPI的实现、时间轮的实现、动态编译等常用功能。dubbo-remotingmoduleDubbo的远程通信模块,其中dubbo-remoting-api是整个模块的核心抽象,其他子模块基于其他开源框架实现dubbo-remoting-api。dubbo-rpc模块Dubbo的RPC模块依赖于dubbo-remoting模块。其中dubbo-remoting-api是整个dubbo-rpc模块的核心抽象,其他模块都是dubbo-remoting-api的实现。dubbo-registry模块是Dubbo中与registry交互的模块。其中dubbo-registry-api是整个dubbo-registry的核心抽象,其他模块是dubbo-registry-api的具体实现。dubbo-config模块是Dubbo中对外暴露配置的解析模块。其中dubbo-config-api子模块负责处理API方式使用Dubbo时的相关配置,dubbo-config-spring子模块负责处理与Spring集成时的相关配置方法.dubbo-metadatamoduleDubbo中的元数据模块。其中dubbo-metadata-api是对整个dubbo-metadata的抽象,其他模块都是dubbo-metadata-api的实现。dubbo-configcenter模块Dubbo的配置中心模块,提供多种服务发现方式和接入多种服务发现组件。dubbo-monitor模块Dubbo的监控模块主要用于统计服务调用次数、调用时间,实现调用链跟踪的服务。dubbo-cluster模块Dubbo的集群管理模块主要提供负载均衡、容错、路由等功能。运行Dubbo示例程序在Dubbo源码中,有一个示例程序模块dubbo-demo。在运行dubbo-demo模块中的示例之前,我们先在本地启动一个Zookeeper作为注册中心。注:小伙伴们可以自行去Apache官网下载Zookeeper。Dubbo示例程序结构Dubbo提供的示例程序整体结构如下。我们来看看dubbo-demo下的模块。dubbo-demo-interface:Dubbodemo定义的业务接口。dubbo-demo-xml:提供基于SpringXML的使用示例。dubbo-demo-annotation:提供基于Spring注解的使用示例。dubbo-demo-api:提供API方式使用Dubbo的示例。其中dubbo-demo-xml、dubbo-demo-annotation和dubbo-demo-api模块都依赖于dubbo-demo-interface模块。下面简单介绍一下dubbo-demo-interface模块和dubbo-demo-annotation模块的核心代码,并运行相关示例程序。小伙伴们可以自行分析运行dubbo-demo-xml和dubbo-demo-api中的示例程序,运行相关代码。(1)dubbo-demo-interface:定义业务接口。其中,DemoService接口的核心代码如下。packageorg.apache.dubbo.demo;importjava.util.concurrent.CompletableFuture;publicinterfaceDemoService{//同步调用StringsayHello(Stringname);//异步调用defaultCompletableFuturesayHelloAsync(Stringname){returnCompletableFuture.completedFuture(sayHello(name));}}(2)dubbo-demo-annotation:提供基于Spring注解的示例程序。Provider代码我们先来看dubbo-demo-annotation-provider模块,也就是服务提供者。其DemoServiceImpl的代码如下所示。@DubboServicepublicclassDemoServiceImplimplementsDemoService{privatestaticfinalLoggerlogger=LoggerFactory.getLogger(DemoServiceImpl.class);@OverridepublicStringsayHello(Stringname){logger.info("Hello"+name+",requestfromconsumer:"+RpcContext.getContext().getRemoteAddress());return"Hello"+name+",responsefromprovider:"+RpcContext.getContext().getLocalAddress();}@OverridepublicCompletableFuturesayHelloAsync(Stringname){returnnull;}}应用类的代码如下所示。publicclassApplication{publicstaticvoidmain(String[]args)throwsException{AnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext(ProviderConfiguration.class);context.start();System.in.read();}@Configuration@EnableDubbo(scanBasePackages="org.apache.dubbo.demo.provider")@PropertySource("classpath:/spring/dubbo-provider.properties")staticclassProviderConfiguration{@BeanpublicRegistryConfigregistryConfig(){RegistryConfigregistryConfig=newRegistryConfig();registryConfig.setAddress("zookeeper://127.0.0.1);2181"returnregistryConfig;}}}消费端代码接下来我们看一下dubbo-demo-annotation-consumer模块的代码,即服务消费端的示例代码。其中,DemoServiceComponent类的代码如下。@Component("demoServiceComponent")publicclassDemoServiceComponentimplementsDemoService{@DubboReferenceprivateDemoServicedemoService;@OverridepublicStringsayHello(Stringname){returndemoService.sayHello(name);}@OverridepublicCompletableFuturesayHelloAsync(Stringname){returnnull;}}应用类的代码如下所示。publicclassApplication{publicstaticvoidmain(String[]args){AnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext(ConsumerConfiguration.class);context.start();DemoServiceservice=context.getBean("demoServiceComponent",DemoServiceComponent.class);Stringhello=service.sayHello("world");System.out.println("result:"+hello);}@Configuration@EnableDubbo(scanBasePackages="org.apache.dubbo.demo.consumer.comp")@PropertySource("classpath:/spring/dubbo-consumer.properties")@ComponentScan(value={"org.apache.dubbo.demo.consumer.comp"})staticclassConsumerConfiguration{}}运行Dubbo示例程序我们先在本地启动Zookeeper,然后运行dubbo-demo-annotation-providermodule分别是dubbo-demo-annotation-consumer模块的Application类和Application类。此时IDEA的控制台会输出如下信息。result:Helloworld,responsefromprovider:192.168.0.5:20880Dubbo到此结束,我们介绍了Dubbo中的核心角色,如何搭建Dubbo源码环境,简要说明了Dubbo源码中的核心模块,并简要分析了Dubbo的Sample程序并运行示例程序。其中,在示例程序的引入和运行时,我们重点关注dubbo-demo-annotation示例模块,其他示例模块大家可以自行分析运行。在后续文章分析源码时,我们也主要采用调试Dubbo示例程序的方法。本文转载自微信公众号“冰河科技”,可通过以下二维码关注。转载本文请联系冰川科技公众号。