1. 引子
為什么突然想起來要學Dubbo呢秉继,原因有下:
之前有人問什么是SPI祈噪,以前學習嵌入式的時候,聽過硬件上有SPI總線協(xié)議尚辑,不知道Java世界也有一個SPI的概念辑鲤,全稱為:Service Provider Interface。在Dubbo的官網介紹開端就提到了SPI這個概念杠茬,為此就想通過Dubbo來多了解一下SPI月褥。
在學習Spring Cloud的時候,服務間訪問是通過REST風格的HTTP調用實現(xiàn)的澈蝙。但是很多書和文章提到在分布式架構中除了基于HTTP的REST調用外吓坚,還提到了RPC框架,即遠程過程調用來實現(xiàn)服務間調用灯荧。至于REST和RPC的區(qū)別是什么一直有點模糊礁击,直到在簡書上偶然翻到一篇文章,作者叫柳樹之逗载,那篇文章的地址是:http://www.reibang.com/p/2accc2840a1b哆窿。在簡書一堆無病呻吟的軟文中找到這種優(yōu)秀的作者也是比較稀少的。從文中得知厉斟,Dubbo就是基于RPC實現(xiàn)的挚躯。為此也產生了想深入學習Dubbo的念想。
2. 環(huán)境搭建
Dubbo官網文檔地址為:http://dubbo.apache.org/zh-cn/docs/source_code_guide/dubbo-spi.html擦秽。下面就先照著官網文檔內容進行環(huán)境搭建码荔。
2.1 zookeeper
dubbo的服務注冊依賴于zookeeper漩勤,在zookeeper官網下載包,分別執(zhí)行下面的命令缩搅。
-
解壓
> tar -zxvf zookeeper-3.4.10.tar.gz //解壓 > cd zookeeper-3.4.10/conf //切換到配置目錄下 > mv zoo_sample.cfg zoo.cfg //更改默認配置文件名稱 > vi zoo.cfg //編輯配置文件越败,自定義dataDir
-
啟動
> cd zookeeper-3.4.10/bin //切換到 bin目錄 > ./zkServer.sh start //啟動
-
客戶端連接
> cd zookeeper-3.4.10/bin //切換到 bin目錄 > ./zkCli.sh -server 127.0.0.1:2181
-
停止
> ./zkServer.sh stop //停止后,如果CLi沒有關閉硼瓣,將報錯
2.2 dubbo快速啟動
? dubbo官網已經提供了一個demo究飞,基于這個demo,我們可以快速創(chuàng)建出服務提供者和消費者堂鲤。這里直接從碼云上將dubbo代碼拉取下來:
git clone https://gitee.com/mirrors/dubbo.git
不使用官網寫的github亿傅,因為下載速度太慢了。
? 下載后可以看到這個一個整體的大目錄瘟栖,下面有以"dubbo-"開頭的各種包葵擎。其使用IDEA將dubbo/dubbo-demo/dubbo-demo-xml
這個目錄導入成一個maven工程。該maven工程中包含了名為dubbo-demo-xml-consumer
和名為dubbo-demo-xml-provider
的兩個模塊半哟。
2.2.1 公共模塊
在dubbo中坪蚁,服務提供者提供的方法要以接口的形式單獨打成一個jar包,然后分別被服務提供者和服務消費者引入镜沽。為此先新建一個只定義接口的maven工程:在dubbo-demo-xml這個大工程下敏晤,新建一個module,名為api缅茉。該模塊只定義一個接口:
package org.apache.dubbo.demo;
public interface DemoService {
String sayHello(String name);
}
然后嘴脾,pom.xml文件修改如下:
<groupId>com.dubbo.api</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
這樣,在根目錄下執(zhí)行mvn install
命令蔬墩,將應用api打包成一個jar包(target目錄下)译打。
生成jar包后,還要將這個jar包發(fā)布到本地的maven倉庫中拇颅,發(fā)布命令為:
mvn install:install-file -Dfile=/Users/yubuyun/Documents/workspace/dubbo/dubbo/dubbo-demo/dubbo-demo-xml/api/target/api-1.0-SNAPSHOT.jar -DgroupId=com.dubbo.api -DartifactId=api -Dversion=1.0.0 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true
這樣本地倉庫就有這個api-1.0-SNAPSHOT.jar了奏司。
2.2.2 服務提供者
添加依賴
首先修改pom.xml文件,將公共模塊這個jar包引入:
<dependency>
<groupId>com.dubbo.api</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
訪問接口實現(xiàn)
然后服務提供者應用中就可以直接實現(xiàn)DemoService這個接口了:
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();
}
}
這里服務提供者只是打印和返回了字符串樟插。
配置文件
dubbo官方的demo中在resources目錄下還提供了dubbo配置文件韵洋,名為dubbo-provider.xml
,內容如下:
<dubbo:application name="demo-provider"/>
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<dubbo:protocol name="dubbo"/>
<bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl"/>
<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService"/>
表示將當前應用起名為demo-provider
黄锤,注冊到本地的zookeeper搪缨,并且指定了接口實現(xiàn)類并注入到Spring容器中。
啟動服務提供者
main函數定義如下:
public class Application {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-provider.xml");
context.start();
System.in.read();
}
}
就是解析dubbo配置到容器中鸵熟,然后啟動副编。
2.2.3 服務消費者
添加依賴
首先修改pom.xml文件,將公共模塊這個jar包引入:
<dependency>
<groupId>com.dubbo.api</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
配置文件
dubbo官方的demo中在resources目錄下還提供了dubbo配置文件流强,名為dubbo-consumer.xml
痹届,內容如下:
<dubbo:application name="demo-consumer"/>
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<dubbo:reference id="demoService" check="false" interface="org.apache.dubbo.demo.DemoService" timeout="2000"/>
表示將當前應用起名為demo-consumer
呻待,注冊到本地的zookeeper,并且將通過demoService接口訪問其他應用队腐。
啟動服務消費者
啟動類定義如下:
public class Application {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml");
context.start();
DemoService demoService = context.getBean("demoService", DemoService.class);
String result = demoService.sayHello("hello");
System.out.println("consumer:"+result);
}
}
啟動過程中带污,服務消費者本身并沒有實現(xiàn)DemoService接口實現(xiàn),但是仍然可以直接調用該接口的訪問香到,這時直接就訪問到了服務提供者上。這就是RPC調用的優(yōu)點:像本地調用一樣進行遠程調用报破。
2.2.4 調試
首先啟動zookeeper悠就,然后啟動服務提供者,再啟動服務消費者充易,就會發(fā)現(xiàn)梗脾,服務提供者打印:
provider.DemoServiceImpl: Hello hello, request from consumer: /99.15.214.152:55576
服務消費者收到返回值后打禹镅ァ:
consumer:Hello hello, response from provider: 99.15.214.152:20880
這就說明兩個應用之間RPC調用成功了炸茧。
3. 其他
本文示例代碼的地址為:https://gitee.com/yubuyun/dubbo-study