概念
RPC(Remote Procedure Call Protocol):遠程過程調用:
兩臺服務器A、B,分別部署不同的應用a,b。當A服務器想要調用B服務器上應用b提供的函數或方法的時候,由於不在一個內存空間,不能直接調用,需要通過網絡來表達調用的語義傳達調用的數據。
說白了,就是你在你的機器上寫了一個程序,我這邊是無法直接調用的,這個時候就出現了一個遠程服務調用的概念。
目錄結構
依賴管理
pom.xml 依賴配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-stuty01-start</artifactId>
<groupId>yh</groupId>
<version>1.0-SNAPSHOT</version>
<properties>
<!--指定jdk版本-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<!--add maven release 防止idea每次都默認以1.5版本編譯的maven設置(Target bytecode version)-->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<encoding>UTF-8</encoding>
<!--依賴版本設置-->
<spring.version>4.3.7.RELEASE</spring.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--spring 基本依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<!--dubbo依賴-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
</dependency>
<!-- zookeeper註冊中心客戶端依賴-->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
</dependencies>
</project>
服務接口
在新建包com.yh.dubbo下創建服務接口,該接口是服務提供者和消費者同時能看到的。
package com.yh.dubbo;
/**
* @Description: service 接口,提供者和消費者都能看到。實現由提供者來完成。
* @Author: 張穎輝(yh)
* @Date: 2018/7/24 17:08
* @param:
* @return:
* @Version: 1.0
*/
public interface IDemoService {
public String sayHello(String name);
}
服務實現
新建提供者包:com.yh.dubbo.provider 下創建服務實現類
package com.yh.dubbo.provider;
import com.yh.dubbo.IDemoService;
/**
* @Description: Description
* @Author: 張穎輝(yh)
* @CreateDate: 2018/7/17 10:21
* @UpdateUser: 張穎輝(yh)
* @UpdateDate: 2018/7/17 10:21
* @UpdateRemark: The modified content
* @Version: 1.0
*/
public class DemoServiceImpl implements IDemoService {
@Override
public String sayHello(String name) {
return "Hello,"+name;
}
}
提供者配置
基於spring的服務提供者配置spring-provider.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方應用信息,用於計算依賴關係 -->
<dubbo:application name="start-provider"/>
<!-- 使用multicast廣播註冊中心暴露服務地址 -->
<!--<dubbo:registry address="multicast://224.5.6.7:1234"/>-->
<!-- 使用 zookeeper 作爲註冊中心 註冊服務-->
<dubbo:registry address="zookeeper://192.168.5.100:2181"/>
<!-- 用dubbo協議在20880端口暴露服務 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- 聲明需要暴露的服務接口 -->
<dubbo:service interface="com.yh.dubbo.IDemoService" ref="demoService"/>
<!-- 和本地bean一樣實現服務 -->
<bean id="demoService" class="com.yh.dubbo.provider.DemoServiceImpl"/>
</beans>
從配置中可以看出註冊中心使用的zookeeper這也是官方推薦使用的註冊中心,如果爲了快速入門,沒有安裝zookeeper,那麼可以換爲多播/組播來替代zk作爲註冊中心,最後會講怎麼來使用多播/組播來做註冊中心。
提供者啓動類
服務提供者加載spring-provider.xml配置文件的啓動入口
package com.yh.dubbo.provider;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
* @Description: Description
* @Author: 張穎輝(yh)
* @CreateDate: 2018/7/17 10:37
* @UpdateUser: 張穎輝(yh)
* @UpdateDate: 2018/7/17 10:37
* @UpdateRemark: The modified content
* @Version: 1.0
*/
public class ProviderStart {
public static void main(String[] args) throws IOException {
// ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
// new String[]{"http://10.20.160.198/wiki/display/dubbo/provider.xml"});
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[]{"spring-provider.xml"});
context.start();
System.in.read();
}
}
消費者配置
服務消費者配置spring-consumer.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方應用信息,用於計算依賴關係 -->
<dubbo:application name="start-consumer"/>
<!-- 使用multicast廣播註冊中心暴露發現服務地址 -->
<!--<dubbo:registry address="multicast://224.5.6.7:1234"/>-->
<!-- 使用 zookeeper 作爲註冊中心 發現服務-->
<dubbo:registry address="zookeeper://192.168.5.100:2181"/>
<!-- 生成遠程服務代理,可以和本地bean一樣使用demoService -->
<dubbo:reference id="demoService" interface="com.yh.dubbo.IDemoService"/>
</beans>
在上面的配置中我們看到,和服務相關的只引用了服務的接口,並沒有使用服務的實現類。最後我們要通過dubbo來展現出RPC的效果。
消費者啓動類
服務消費者加載配置文件spring-consumer.xml,啓動spring容器後並調用服務
package com.yh.dubbo.consumer;
import com.yh.dubbo.IDemoService;
import com.yh.dubbo.provider.DemoServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Scanner;
/**
* @Description: 消費者啓動,並調用服務
* @Author: 張穎輝(yh)
* @CreateDate: 2018/7/17 10:37
* @UpdateUser: 張穎輝(yh)
* @UpdateDate: 2018/7/17 10:37
* @UpdateRemark: The modified content
* @Version: 1.0
*/
public class ConsumerStart {
public static void main(String[] args) {
// ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
// new String[]{"http://10.20.160.198/wiki/display/dubbo/consumer.xml"});
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[]{"spring-consumer.xml"});
context.start();
IDemoService demoService=(IDemoService)context.getBean("demoService");
System.out.println(demoService.sayHello("yh"));
while (true){
Scanner scanner=new Scanner(System.in);
System.out.println(demoService.sayHello(scanner.next()));
}
}
}
運行效果
分別啓動服務提供者和消費者,就是上面的代碼中的兩個main函數。
會在消費者的控制檯看到:
這說明消費者端可以正確的調用提供者對service接口的實現,並返回了期望的結果。
之後再控制檯手動輸入文字,回車
手動輸入的內容也正確的被處理和返回。
到此我們簡單的實現了dubbo的使用了,上面的啓動我們是靠着兩個main函數啓動的,實際上我們只要按照上面配置。在項目的spring容器啓動的時候dubbo也會隨之啓動,並且消費者這邊會自動將服務的實現類對象裝載到spring容器中,和平常一樣使用去注入service即可。
使用 multicast(多播/註冊)作爲註冊中心
將上文中的兩個spring配置文件的<dubbo:registry>配置中多播的部分解除註釋,把zookeeper部分的註釋掉。
注意:zookeeper需要使用你自己安裝的IP地址和端口號,但是多播/組播中配置的IP端口不需要任何改動。
重複上面的啓動過程就好了,沒錯就是這麼簡單:放開multicast配置這行的註釋——給zookeeper這行加上註釋——啓動!
錯誤參考:
如果使用multicast報錯[DUBBO] Ignore empty notify urls for subscribe url的解決辦法。