在上一篇《冰河開始對Dubbo下手了!》一文中,咱們重點介紹了爲什麼要學習Dubbo,並且仍是要深刻理解Dubbo的原理和核心源碼。既然是要寫深度解析Dubbo源碼的系列專題,咱們首先要作的就是搭建一套Dubbo的源碼環境,正所謂「工欲善其事,必先利其器」。可是,爲了更好的理解Dubbo,我將本文重點分紅三個部分:Dubbo中的核心角色、搭建Dubbo源碼環境、Dubbo核心模塊說明、運行Dubbo的示例程序 四個部分。說幹就幹,上重點。java
注:本系列專題,我是基於Dubbo 2.7.8版本進行源碼分析的。git
文章已收錄到:github
https://github.com/sunshinelyz/technology-binghe算法
https://gitee.com/binghe001/technology-binghespring
爲了更好的說明Dubbo中的核心角色,這裏,我就直接引用一張Dubbo的依賴關係圖。apache
注:圖片來自Dubbo官網。api
從Dubbo的依賴關係圖中,咱們能夠看出,Dubbo主要由四部分構成:Registry、Provider、Consumer和Monitor 。接下來,咱們就分別對這四部分進行簡單的介紹。瀏覽器
好了,對於Dubbo的核心角色咱們就介紹到這兒,更多的信息,小夥伴們能夠參見Dubbo的官方文檔。緩存
咱們可使用以下命令將github的源碼下載的本地。bash
git clone https://github.com/apache/dubbo.git
接下來,將Dubbo的源碼切換到2.7.8
git checkout -b dubbo-2.7.8 dubbo-2.7.8
使用Maven進行編譯
mvn clean install -Dmaven.test.skip=true
轉換成IDEA項目,這裏我使用的是IDEA分析Dubbo源碼。
mvn idea:idea
接下來,咱們就能夠將Dubbo源碼導入到IDEA了。
說了這麼多,其中還有一種方式就是經過瀏覽器直接下載Dubbo 2.7.8的源碼到本地。
在瀏覽器中打開連接:https://github.com/apache/dubbo/releases/tag/dubbo-2.7.8 下載Dubbo源碼。
這裏下載zip壓縮包和tar.gz壓縮包都可,下載到本地後解壓,將其導入到IDEA中便可。
導入完成後,咱們看到的項目結構以下所示。
接下來,咱們就對Dubbo源碼中的核心模塊進行簡單的介紹。
Dubbo的公共模塊,提供了Dubbo SPI的實現、時間輪的實現、動態編譯等通用的功能。
Dubbo的遠程通訊模塊,其中,dubbo-remoting-api是對整個模塊的核心抽象,其餘子模塊基於其餘開源框架對dubbo-remoting-api進行實現。
Dubbo的RPC模塊,依賴dubbo-remoting模塊。其中,dubbo-remoting-api是整個dubbo-rpc模塊的核心抽象,其餘模塊是對dubbo-remoting-api的實現。
Dubbo中與註冊中心交互的模塊。其中dubbo-registry-api是整個dubbo-registry的核心抽象,其餘模塊是對dubbo-registry-api的具體實現。
Dubbo中解析對外暴露的配置的模塊。其中,dubbo-config-api 子模塊負責處理以API 方式使用Dubbo時的相關配置,dubbo-config-spring 子模塊負責處理與 Spring 集成使用時的相關配置方式。
Dubbo中的元數據模塊。其中,dubbo-metadata-api是對整個dubbo-metadata的抽象,其餘模塊是對dubbo-metadata-api的實現。
Dubbo的配置中心模塊,其中,提供了多種服務發現的方式並接入了多種服務發現組件。
Dubbo 的監控模塊,主要用於統計服務調用次數、調用時間以及實現調用鏈跟蹤的服務。
Dubbo的集羣管理模塊,主要提供負載均衡、容錯、路由等功能。
在Dubbo源碼中,有一個示例程序模塊dubbo-demo,在運行dubbo-demo模塊中的示例前,咱們先在本地啓動一個Zookeeper做爲註冊中心。
注:小夥伴們能夠自行到Apache官網下載Zookeeper。
Dubbo提供的示例程序的整體結構以下所示。
咱們來看看dubbo-demo下有哪些模塊。
其中,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接口的核心代碼以下所示。
package org.apache.dubbo.demo; import java.util.concurrent.CompletableFuture; public interface DemoService { //同步調用 String sayHello(String name); //異步調用 default CompletableFuture<String> sayHelloAsync(String name) { return CompletableFuture.completedFuture(sayHello(name)); } }
(2)dubbo-demo-annotation:提供了基於Spring註解的示例程序。
Provider代碼
咱們先來看dubbo-demo-annotation-provider模塊,也就是服務的提供者。其DemoServiceImpl的代碼以下所示。
@DubboService public class DemoServiceImpl implements DemoService { private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class); @Override public String sayHello(String name) { logger.info("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress()); return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); } @Override public CompletableFuture<String> sayHelloAsync(String name) { return null; } }
Application類的代碼以下所示。
public class Application { public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class); context.start(); System.in.read(); } @Configuration @EnableDubbo(scanBasePackages = "org.apache.dubbo.demo.provider") @PropertySource("classpath:/spring/dubbo-provider.properties") static class ProviderConfiguration { @Bean public RegistryConfig registryConfig() { RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setAddress("zookeeper://127.0.0.1:2181"); return registryConfig; } } }
Consumer代碼
接下來,咱們來看看dubbo-demo-annotation-consumer模塊的代碼,也就是服務消費者的示例代碼。其中,DemoServiceComponent類的代碼以下所示。
@Component("demoServiceComponent") public class DemoServiceComponent implements DemoService { @DubboReference private DemoService demoService; @Override public String sayHello(String name) { return demoService.sayHello(name); } @Override public CompletableFuture<String> sayHelloAsync(String name) { return null; } }
Application類的代碼以下所示。
public class Application { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class); context.start(); DemoService service = context.getBean("demoServiceComponent", DemoServiceComponent.class); String hello = 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"}) static class ConsumerConfiguration { } }
咱們先在本地啓動Zookeeper,而後分別運行dubbo-demo-annotation-provider模塊的Application類和dubbo-demo-annotation-consumer模塊的Application類。
此時在IDEA的控制檯會輸出以下信息。
result :Hello world, response from provider: 192.168.0.5:20880
到這裏,咱們介紹了Dubbo中的核心角色,如何搭建Dubbo源碼環境,對Dubbo源碼中的核心模塊進行了簡單的說明,並簡單的分析了Dubbo的示例程序並運行了示例程序。其中,在介紹和運行示例程序時,咱們重點介紹了dubbo-demo-annotation示例模塊,小夥伴們可自行分析和運行其餘示例模塊。在後續的文章中分析源碼時,咱們也主要是經過debug Dubbo的示例程序的方式進行。
好了,今天就到這兒吧,我是冰河,你們有啥問題能夠在下方留言,也能夠加我微信:sun_shine_lyz,一塊兒交流技術,一塊兒進階,一塊兒牛逼~~