阿里巴巴dubbo使用教程(可直接應用於企業開發)

        本dubbo使用教程基於zookeeper-3.4.9搭建,包含服務提供者DubboProvider、和消費者DubboConsumer,可直接在Tomcat上運行。DubboProvider對外開放2個接口,DubboConsumer調用DubboProvider,並對外暴露HTTP服務。DubboProvider還提供了對數據庫的操作,基於SpringJDBC並加入了RowMapper通用類,這點在下文《SpringJDBC之RowMapper通用類》詳講。

        項目完整源碼見文末鏈接,下載即可用

        網上現有教程大多是直接照搬官網,用main函數啓動,未使用Tomcat啓動,直接應用於企業開發較爲困難。當然我也是參照官網,學習了前輩的經驗,哈哈。

        開發環境:Windows10、Eclipse、JDK8、Spring4.3.7、zookeeper-3.4.9。

1、服務提供者DubboProvider

先看下整體架構,摺疊部分爲基於SpringJDBC的數據庫操作,可暫不考慮。

1.1 定義接口IProviderService和接口IUserService

[java] view plain copy
  1. package com.zxiaofan.dubboProvidder.service;  
  2.   
  3. import com.zxiaofan.dubboProvidder.model.HelloBo;  
  4.   
  5. /** 
  6.  *  
  7.  * @author xiaofan 
  8.  */  
  9. public interface IProviderService {  
  10.     /** 
  11.      * 測試字符串傳輸. 
  12.      *  
  13.      * @param name 
  14.      * @return 
  15.      */  
  16.     String helloBoy(String name);  
  17.   
  18.     /** 
  19.      * 測試bean傳輸. 
  20.      *  
  21.      * @param bo 
  22.      * @return 
  23.      */  
  24.     HelloBo helloGirl(HelloBo bo);  
  25. }  
接口IUserService略過,詳見源碼。

1.2 接口IProviderService實現

[java] view plain copy
  1. package com.zxiaofan.dubboProvidder.service.impl;  
  2.   
  3. import org.springframework.beans.factory.annotation.Value;  
  4. import org.springframework.stereotype.Component;  
  5.   
  6. import com.zxiaofan.dubboProvidder.model.HelloBo;  
  7. import com.zxiaofan.dubboProvidder.service.IProviderService;  
  8.   
  9. /** 
  10.  *  
  11.  * @author xiaofan 
  12.  */  
  13. @Component("providerService")  
  14. public class ProviderServiceImpl implements IProviderService {  
  15.     @Value("${param.url}")  
  16.     private String url;  
  17.   
  18.     /** 
  19.      * {@inheritDoc}. 
  20.      */  
  21.     @Override  
  22.     public String helloBoy(String name) {  
  23.         String result = "hello " + name + ", This is dubboProvider[" + url + "]";  
  24.         System.out.println(result);  
  25.         return result;  
  26.     }  
  27.   
  28.     /** 
  29.      * {@inheritDoc}. 
  30.      */  
  31.     @Override  
  32.     public HelloBo helloGirl(HelloBo helloBo) {  
  33.         if (null == helloBo.getName()) {  
  34.             helloBo.setName("DefaultName");  
  35.         }  
  36.         helloBo.setUrl(helloBo.getName() + ":This is dubboProvider[csdn.zxiaofan.com]");  
  37.         return helloBo;  
  38.     }  
  39.   
  40. }  

1.3 dubbo-provider的相關參數配置

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.     http://www.springframework.org/schema/beans/spring-beans-4.3.xsd    
  6.     http://code.alibabatech.com/schema/dubbo    
  7.     http://code.alibabatech.com/schema/dubbo/dubbo.xsd">  
  8.   
  9.     <!-- 提供方應用信息,用於計算依賴關係 -->  
  10.     <dubbo:application name="${dubbo.applicationName}" />  
  11.   
  12.     <!-- 使用zookeeper廣播註冊中心暴露服務地址 -->  
  13.     <dubbo:registry protocol="${dubbo.registryProtocol}" address="${dubbo.registryAddress}" />  
  14.   
  15.     <!-- 用dubbo協議在20880端口暴露服務 -->  
  16.     <dubbo:protocol name="dubbo" port="${dubbo.port}" />  
  17.     <!-- <dubbo: protocol="registry"></dubbo:monitor> -->  
  18.   
  19.       
  20.     <!-- 和本地bean一樣實現服務 -->  
  21.     <bean id="providerService" class="com.zxiaofan.dubboProvidder.service.impl.ProviderServiceImpl" />  
  22.     <!-- 和本地bean一樣實現服務 -->  
  23.     <bean id="userService" class="com.zxiaofan.dubboProvidder.service.impl.UserServiceImpl" />      
  24.     <!-- 聲明需要暴露的服務接口 -->  
  25.     <dubbo:service interface="com.zxiaofan.dubboProvidder.service.IProviderService"  
  26.         ref="providerService"  retries="${dubbo.retries}" timeout="${dubbo.serverTimeout}"/>  
  27.     <!-- 聲明需要暴露的服務接口 -->  
  28.     <dubbo:service interface="com.zxiaofan.dubboProvidder.service.IUserService"  
  29.         ref="userService"  retries="${dubbo.retries}" timeout="${dubbo.serverTimeout}"/>  
  30. </beans>  
結合配置文件dubbo.properties來看
[plain] view plain copy
  1. # dubbo param  
  2. dubbo.applicationName=dubboProvider  
  3. dubbo.registryProtocol=zookeeper  
  4. dubbo.registryAddress=127.0.0.1:2181  
  5. dubbo.port=20880  
  6. #服務端超過serverTimeout未返回結果則拋500異常  
  7. dubbo.serverTimeout=120000  
  8. #客戶端超過clientTimeout未獲取到數據則拋500異常  
  9. dubbo.clientTimeout=120000  
  10. #dubbo調用失敗,默認重試2次  
  11. dubbo.retries=0  
    <bean id="providerService" class="com.zxiaofan.dubboProvidder.service.impl.ProviderServiceImpl" />聲明瞭對外暴露的接口;
    <dubbo:service interface="com.zxiaofan.dubboProvidder.service.IProviderService"
ref="providerService"  retries="${dubbo.retries}" timeout="${dubbo.serverTimeout}"/>聲明瞭接口的實現類以及重試次數、服務超時時間。

1.4 app-context.xml 以及 web.xml 相關配置

    app-context.xml指定包掃描路徑以及引入相關配置文件和dubbo-provider.xml。
[html] view plain copy
  1. <bean  
  2.         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  3.         <property name="locations">  
  4.             <list>  
  5.                 <value>/WEB-INF/config/param.properties</value>  
  6.                 <value>/WEB-INF/config/dubbo.properties</value>  
  7.                 <value>/WEB-INF/config/jdbc.properties</value>  
  8.             </list>  
  9.         </property>  
  10.         <property name="fileEncoding" value="UTF8"></property>  
  11.     </bean>  
  12.     <bean  
  13.         class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />  
  14.   
  15.     <!-- Aspect -->  
  16. <!-- <aop:aspectj-autoproxy proxy-target-class="true" />-->  
  17.     <context:component-scan base-package="com.zxiaofan"></context:component-scan>  
  18.     <import resource="classpath:com/zxiaofan/config/spring/dubbo-provider.xml"/>  
web.xml一定要引入app-context.xml以及設置監聽ContextLoaderListener。
[html] view plain copy
  1. <context-param>  
  2.         <param-name>contextConfigLocation</param-name>  
  3.         <param-value>  
  4.             classpath:/com/zxiaofan/config/spring/app-context.xml  
  5.          </param-value>  
  6.   </context-param>  
  7.    <!--初始化spring上下文 -->  
  8.     <listener>    
  9.       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    
  10.     </listener>  

2、消費者DubboConsumer

整體架構如下:


2.1 定義接口IConsumerService

[java] view plain copy
  1. package com.zxiaofan.dubboConsumer.service;  
  2.   
  3. /** 
  4.  *  
  5.  * @author zxiaofan 
  6.  */  
  7. public interface IConsumerService {  
  8.     String hi(String name);  
  9. }  

2.2 接口實現類ConsumerServiceImpl

[java] view plain copy
  1. package com.zxiaofan.dubboConsumer.service.impl;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.springframework.beans.factory.annotation.Value;  
  6. import org.springframework.stereotype.Component;  
  7.   
  8. import com.zxiaofan.dubboConsumer.service.IConsumerService;  
  9. import com.zxiaofan.dubboProvidder.model.HelloBo;  
  10. import com.zxiaofan.dubboProvidder.service.IProviderService;  
  11. import com.zxiaofan.dubboProvidder.service.IUserService;  
  12.   
  13. /** 
  14.  *  
  15.  * @author zxiaofan 
  16.  */  
  17. @Component("consumerService")  
  18. public class ConsumerServiceImpl implements IConsumerService {  
  19.     @Resource(name = "providerService")  
  20.     private IProviderService providerService;  
  21.   
  22.     @Resource(name = "userService")  
  23.     private IUserService userService;  
  24.   
  25.     @Value("${param.url}")  
  26.     private String url;  
  27.   
  28.     /** 
  29.      * {@inheritDoc}. 
  30.      */  
  31.     @Override  
  32.     public String hi(String name) {  
  33.         String result = null;  
  34.         if (null != name && name.startsWith("boy")) {  
  35.             System.out.println("Hi Boy!");  
  36.             result = providerService.helloBoy(name.replace("boy""~~~"));  
  37.         } else if (null != name && name.startsWith("select")) {  
  38.             System.out.println("hi select!");  
  39.             result = userService.selectByID(name.replace("select"""));  
  40.             return result;  
  41.         } else {  
  42.             HelloBo helloBo = new HelloBo();  
  43.             helloBo.setName(name);  
  44.             HelloBo helloBoResult = null;  
  45.             helloBoResult = providerService.helloGirl(helloBo);  
  46.             if (null != helloBoResult) {  
  47.                 result = helloBoResult.getUrl();  
  48.             }  
  49.         }  
  50.         result += "; This is dubboConsumer[" + url + "]";  
  51.         return result;  
  52.     }  
  53.   
  54. }  
總共有3個分支:
name.startsWith("boy"),跳轉helloBoy,其入參是單個字符串;
name.startsWith("select"),跳轉userService.selectByID,該接口調用服務提供者的IUserService接口,對數據庫進行查詢操作;
else:跳轉helloGirl接口,其入參是model。

2.3 dubbo-consumer的相關參數配置

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.     http://www.springframework.org/schema/beans/spring-beans-4.3.xsd    
  6.     http://code.alibabatech.com/schema/dubbo    
  7.     http://code.alibabatech.com/schema/dubbo/dubbo.xsd">  
  8.   
  9.       
  10.     <!-- 消費方應用名,用於計算依賴關係,不是匹配條件,不要與提供方一樣 -->  
  11.     <dubbo:application name="${dubbo.applicationName}"/>  
  12.   
  13.     <!-- 使用dubbo協議   註冊中心暴露服務地址 -->  
  14.     <dubbo:registry protocol="${dubbo.registryProtocol}"  address="${dubbo.registryAddress}"/>  
  15.   
  16.     <!-- 生成遠程服務代理,可以像使用本地bean一樣使用demoService -->  
  17.     <dubbo:reference id="providerService" interface="com.zxiaofan.dubboProvidder.service.IProviderService"  retries="${dubbo.retries}"  timeout="${dubbo.clientTimeout}"/>  
  18.     <dubbo:reference id="userService" interface="com.zxiaofan.dubboProvidder.service.IUserService"  retries="${dubbo.retries}"  timeout="${dubbo.clientTimeout}"/>  
  19. </beans>  
該配置文件配置了2個服務的調用關係:providerService(入參爲單字符串接口、入參爲model接口)、userService(基於SpringJDBC的數據庫服務)。

2.4 web.xml節選

[html] view plain copy
  1. <!--  <listener>  
  2.    <listener-class>  
  3.        org.springframework.web.util.Log4jConfigListener  
  4.      </listener-class>  
  5.  </listener> -->  
  6.   
  7.  <context-param>  
  8.     <param-name>contextConfigLocation</param-name>  
  9.     <param-value>  
  10.         classpath:/com/zxiaofan/config/spring/app-context.xml  
  11.      </param-value>  
  12.  </context-param>  
  13.    
  14.  <!--初始化spring上下文 -->  
  15. <listener>    
  16.      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    
  17. </listener>  
  18.   
  19. <!-- 必須有servlet -->  
  20.     <servlet>  
  21.     <servlet-name>HttpServer</servlet-name>  
  22.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  23.     <init-param>  
  24.         <param-name>contextConfigLocation</param-name>  
  25.         <param-value>  
  26.              classpath*:/com/zxiaofan/config/spring/httpServer-servlet.xml  
  27.            </param-value>  
  28.     </init-param>  
  29.     <load-on-startup>1</load-on-startup>  
  30. </servlet>   
  31. <servlet-mapping>  
  32.     <servlet-name>HttpServer</servlet-name>  
  33.     <url-pattern>/*</url-pattern>  
  34. </servlet-mapping>  
引入app-context.xml,監聽ContextLoaderListener,注意加上servlet,方便暴露HTTP服務。

3、註冊中心zookeeper

zookeeper可從官網下載,亦可從此處免費下載:http://download.csdn.net/detail/u010887744/9787895

4、 服務使用

4.1 啓動註冊中心

        Windows下雙擊zookeeper-3.4.9\bin下的zkServer.cmd即可直接啓動,linux下則啓動zkServer.sh即可。如果你是從官網下載的原生zookeeper,還得手動修改配置文件zoo_sample.cfg,複製一份命名爲zoo.cfg即可。啓動成功會看到如下畫面:


4.2、啓動DubboProvider

        啓動成功後,會在註冊中心看到註冊信息,包含了我們註冊的2個接口信息。注意不要被上面的Error:KeeperErrorCode = NodeExists for 誤導了,這是正常的,不用理會。

4.3、 啓動DubboConsumer

        建議新開一個Tomcat,專門用來啓動DubboConsumer,注意需要修改相關端口號哦,比如這裏修改HTTP端口爲8010,另外2個端口也要修改,避免衝突。
        測試第1個接口的第1個方法:單個字符串參數,HTTP服務地址:http://localhost:8010/DubboConsumer/api,參數csdn,結果如下,返回值包含了DubboConsumer、和DubboProvider添加的信息,證明服務是OK的。


測試第1個接口的第2個方法,dubboProvider的入參是model(dubboConsumer入參記得以boy開頭哦)。

        
        測試第2個接口的方法,dubboProvider的數據操作(dubboConsumer入參記得以select開頭哦,select後拼接數據庫中的id字段)。
Note:\dubbo\DubboProvider\test\com\zxiaofan\test\config\initDB.sql有建庫建表的SQL,可直接使用。


        最後放大招,項目源碼地址:https://github.com/zxiaofan/OpenSource_Study/tree/master/dubbo,項目OpenSource_Study下包含了本人各類開源軟件、框架學習的相關demo,包含Apache、Thrift、Guava、quartz等項目,持續學習ing。
        有任何問題,歡迎留言討論。
[javascript] view plain copy
  1. 歡迎個人轉載,但須在文章頁面明顯位置給出原文連接;  
  2. 未經作者同意必須保留此段聲明、不得隨意修改原文、不得用於商業用途,否則保留追究法律責任的權利。  
  3.   
  4. 【 CSDN 】:csdn.zxiaofan.com  
  5. 【GitHub】:github.zxiaofan.com  
  6.   
  7. 如有任何問題,歡迎留言。祝君好運!  
  8. Life is all about choices!   
  9. 將來的你一定會感激現在拼命的自己!  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章