dubbo學習——基礎環境搭建過程及要點記錄

網上關於dubbo的資料其實已經不少了,尤其是還有一個比較全面的官方文檔教程。
但是正所謂知易行難,很多事不動動手,就總不知道里邊的一些細節。
雖然早就想學一下dubbo,但是奈何需要學的東西太多,於是就以“工作爲主導”的出發點,先學了其他技術。
這次,也是基於上邊的出發點,我們某個項目需要重構成dubbo的項目,於是便正好從dubbo基礎環境搭建開始學一下,並寫一篇筆記備忘。
這篇筆記大概會包含如下一些內容:
1、搭建過程記錄
2、遇到的問題和解決辦法記錄,這一點會在搭建過程記錄的同時進行說明,不另外指出

整個過程基本如下:

zookeeper註冊中心

註冊中心的理解

由於之前學習過springcloud微服務,所以對於zookeeper註冊中心的理解,我覺得還是比較容易的。具體的理解可以參考當時寫的springcloud的註冊中心那篇文章: http://blog.csdn.net/tuzongxun/article/details/72650100
比較明顯的不同是,這裏的zookeeper需要下載安裝一個zookeeper軟件。

zookeeper安裝

我在安裝的時候主要是參考了“小寶鴿”的博客,他寫的很是詳細,所以我覺得沒有必要在重複造輪子,只需要記住在哪裏可以查到參考資料。他關於zookeeper安裝的博客地址如下:
http://blog.csdn.net/u013142781/article/details/50395650

dubbo管理平臺

由於管理平臺與業務邏輯本身沒有關係,所以我沒有深入瞭解,也是直接參考“小寶鴿”的博客:
http://blog.csdn.net/u013142781/article/details/50396621

dubbo服務者

創建項目

根據目前的主流,我這裏是在eclipse中創建了一個maven管理的web項目。

基礎依賴

項目基礎依賴主要參考dubbo官方指導文檔的說明http://dubbo.io/books/dubbo-user-book/dependencies.html
按照這個文檔上所說,需要包含如下一些依賴組件,分別是:
dubbo.jar
spring.jar
log4j.jar
commons-logging.jar
javassist.jar
netty.jar
在實際導入的時候會發現,dubbo.jar已經依賴了spring.jar和netty.jar,這個版本也是根據導入的dubbo.jar的版本來定的。
爲了避免衝突,也爲了使用自己想要的版本的spring和netty,於是在導入dubbo.jar時需要把這兩個先進行排除配置,之後的pom.xml中依賴包的配置基本如下:

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.15</version>
</dependency>
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>org.jboss.netty</groupId>
    <artifactId>netty</artifactId>
    <version>3.2.5.Final</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.5.3</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.jboss.netty</groupId>
            <artifactId>netty</artifactId>
        </exclusion>
    </exclusions>
</dependency>

spring配置

dubbo本身就整合了spring,因此spring的配置是必不可少的,這裏也是使用最簡單的配置,文件頭就先省略:

<context:property-placeholder location="classpath:config.properties" />
<import resource="spring-dubbo-provider.xml" />

config.properties配置

配置dubbo服務,需要指定zookeeper註冊中心的地址,以及使用dubbo暴露服務的端口等,這些配置配在config.properties文件中:

dubbo.zookepper.address=127.0.0.1:2181
dubbo.provider.port=29880

dubbo配置

要把我們的項目作爲一個服務註冊到zookeeper註冊中心,就需要進行相應的配置,配置如下:

<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="dubboServerDemo-pro"/>
    <!-- 註冊中心配置,file值爲application name加實例名 -->
    <dubbo:registry protocol="zookeeper" address="${dubbo.zookepper.address}" file="dubboServerDemo-pro-1.cache"/>
    <!-- 用dubbo協議在20880端口暴露服務,dubbo訪問日誌輸出到應用日誌 -->
    <dubbo:protocol name="dubbo" port="${dubbo.provider.port}" accesslog="true"/>
    <!-- 聲明需要暴露的服務接口  超時時間90分鐘,超時不重試-->
    <dubbo:service interface="dubboServerTest.DubboServerService" ref="dubboServiceTest" cluster="failfast" timeout="5400000" />
    <!-- 和本地bean一樣實現服務 -->
    <bean id="dubboServiceTest" class="dubboServerTest.DubboServerServiceImpl" /> 
</beans>

dubbo具體服務接口和實現

dubbo的具體服務接口和實現就是很普通的java接口和類,如下:

package dubboServerTest;
public interface DubboServerService {
    public void sayHello();
}
package dubboServerTest;
public class DubboServerServiceImpl implements DubboServerService {
    @Override
    public void sayHello() {
        System.out.println("dubbo測試");
    }
}

web.xml配置

spring.xml文件需要被加載,可以用java代碼加載,也可以用其他方式,我這裏就選擇使用web.xml的配置來加載,web.xml配置如下:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

問題說明

按理說,照上邊的做法程序應該是可以運行,並且可以再管理平臺中顯示出服務者的,但是實際上我啓動後卻拋出瞭如下異常:

java.lang.NoClassDefFoundError: org/I0Itec/zkclient/exception/ZkNoNodeException

原因是少了zookeeper的依賴包,需要在pom.xml中補上如下的依賴配置:

<dependency> 
    <groupId>com.101tec</groupId> 
    <artifactId>zkclient</artifactId>
    <version>0.10</version>
</dependency>

消費者

項目搭建

消費者的項目搭建其實和服務者差不多,區別在於dubbo的配置略有區別,消費者的配置大致如下:

<!-- 消費方應用名,用於計算依賴關係,不是匹配條件,不要與提供方一樣 -->
<dubbo:application name="consumer-of-helloworld-app"  />
<!-- 使用multicast廣播註冊中心暴露發現服務地址 -->
<dubbo:registry address="${dubbo.zookepper.address}" />
<!-- 生成遠程服務代理,可以和本地bean一樣使用demoService -->
<dubbo:reference id="demoService" interface="dubboServerTest.DubboServerService" />

同樣的,這裏的也需要指定註冊中心的地址,也是配置在config.properties中:

dubbo.zookepper.address=zookeeper://127.0.0.1:2181

需要注意的是,這裏配置的zookeeper註冊中心地址的寫法,和服務中心配置的寫法也略有不同。

接口聲明

消費端,需要一個和服務端一樣的接口,但是不用實現這個接口。這裏的做法實際上和webservice接口比較類似,像cxf、xfire、hessian都差不多。

服務調用

在消費端可以直接調用上邊聲明的接口的抽象方法,而實際上運行的就是服務端的具體實現,調用處的代碼如下:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import dubboServerTest1.DubboServerService;
public class MyController {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "classpath:spring.xml");
        DubboServerService dubboServerService = (DubboServerService) applicationContext
                .getBean("demoService");
        dubboServerService.sayHello();
    }
}

問題說明

消費者這裏相對比較簡單,但是除了說對於zookeeper註冊中心地址的配置處有細節需要注意外,對於接口的聲明也需要特別注意。
爲了驗證是否和webservice一樣的,消費端接口包括包名在內都必須和服務端一樣,我在聲明接口時特意使用了不一樣的包名,使得實際的類內容以及在dubbo配置文件中的配置如下:

package dubboServerTest1;
public interface DubboServerService {
    public void sayHello();
}
<dubbo:reference id="demoService" interface="dubboServerTest1.DubboServerService" />

然後運行main方法的時候,就會拋出如下異常:

Caused by: java.lang.IllegalStateException: Failed to check the status of the service dubboServerTest1.DubboServerService. No provider available for the service

由此也就證明,消費端的接口聲明,包括包名在內,都必須和服務端一模一樣。針對這個問題,有一種推薦的做法,就是把這個接口類打包,讓服務端和消費端公用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章