Dubbo分布式服務框架入門使用和跟事務共同使用時提供者(Provider)沒能發布到注冊中心解決方案


一、Dubbo入門寫個demo

概念:

Provider
暴露服務方稱之為“服務提供者”。
Consumer
調用 遠程服務方稱之為“服務消費者”。
Registry
服務注冊與發現的中心目錄服務稱之為“服務注冊中心”。
Monitor
統計服務的調用次數和調用時間的日志服務稱之為“服務監控中心”。

想了解更為深層的概念推薦詳細解說楊老師:

  https://www.cnblogs.com/yjmyzz/p/dubbox-demo.html

服務定義
服務是圍繞服務提供方和服務消費方的,服務提供方實現服務,而服務消費方調用服務。

服務注冊
對於服務提供方,它需要發布服務,而且由於應用系統的復雜性,服務的數量、類型也不斷膨脹;對於服務消費方,它最關心如何獲取到它所需要的服務,而面對復雜的應用系統,需要管理大量的服務調用。而且,對於服務提供方和服務消費方來說,他們還有可能兼具這兩種角色,即既需要提供服務,有需要消費服務。
通過將服務統一管理起來,可以有效地優化內部應用對服務發布/使用的流程和管理。服務注冊中心可以通過特定協議來完成服務對外的統一。Dubbo提供的注冊中心有如下幾種類型可供選擇:

  • Multicast注冊中心
  • Zookeeper注冊中心
  • Redis注冊中心
  • Simple注冊中心

服務監控
無論是服務提供方,還是服務消費方,他們都需要對服務調用的實際狀態進行有效的監控,從而改進服務質量。

 

以下皆是個人理解,如若有錯誤,還望指出,謝謝!

   dubbo就是個服務框架,如果沒有分布式的需求,其實是不需要用的,只有在分布式的時候,才有dubbo這樣的分布式服務框架的需求,並且本質上是個服務調用的東東,說白了就是個遠程服務調用的分布式框架(告別Web Service模式中的WSdl,以服務者與消費者的方式在dubbo上注冊)

下面就來說說入門使用dubbo,本文使用的注冊中心是Zookeeper注冊中心,在Linux系統下,開發工具是Intellij Idea,使用springboot微服務框架

  准備工作:下載注冊中心Zookeeper,下載地址 http://www.apache.org/dyn/closer.cgi/zookeeper/ 

第一步:

  啟動注冊中心Zookeeper

  windows下

    直接找到文件apach-zookeeper-3.4.5\bin,目錄下的zkServer.cmd雙擊啟動

  linux下

    同樣找到文件目錄 ,本人的是在 /usr/java/zookeeper/bin       使用 ./zkServer.sh start啟動 ,啟動需要一定時間,所以可以反復查看運行狀態,輸入 ./zkServer.sh status

第二步:

  訪問Dubbo

  widows下

    直接訪問http://localhost:8080即可

  linux下

    關閉防火牆 service iptables stop

    啟動注冊中心

    啟動Tomcat,找到安裝目錄輸入./startup.sh

    訪問http://裝有注冊中心的linux系統IP:8080

    

  到這里已經可以查看登陸到Zookeeper注冊中心:

    1,首先可以先查看下tomcate貓的啟動狀態 ,輸入  http://當前啟動注冊中心的機器ip地址:8080                                    ( tomcat默認8080端口)

    2,輸入  http://當前啟動注冊中心的機器ip地址:8080/dubbo-admin/  進入到注冊中心

    3,注冊中心會提示你輸入密碼 默認賬號是root,密碼是root,登陸成功后進入以下界面

    

 

    4,登陸注冊中心后,什么都沒有,下面就開始寫代碼

    4.1 服務提供者

        4.1.1在pom.xml中加入依賴

      <dubbo.version>2.5.3</dubbo.version>                                
         <zookeeper.version>3.4.7</zookeeper.version>                        
         <zkclient.version>0.1</zkclient.version>                        
                                
       <!-- dubbo相關 -->                                
            <dependency>                    
                <groupId>com.alibaba</groupId>                
                <artifactId>dubbo</artifactId>                
                <version>${dubbo.version}</version>                
            </dependency>                    
            <dependency>                    
                <groupId>org.apache.zookeeper</groupId>                
                <artifactId>zookeeper</artifactId>                
                <version>${zookeeper.version}</version>                
            </dependency>                    
            <dependency>                    
                <groupId>com.github.sgroschupf</groupId>                
                <artifactId>zkclient</artifactId>                
                <version>${zkclient.version}</version>                
       </dependency>                    

 

     4.1.2  

       邏輯代碼還是像平時一樣,該怎么寫就怎么寫,但要注意:

          服務提供者必須把Interface接口寫成一個包,並且暴露出來

         在本項目中再去實現service的接口,並且注入的@service必須為 alibaba下提供的service,但是這有弊端,就是不能跟事務@Transactional共同使用,具體解釋看文章結尾,

         例如:

           import com.alibaba.dubbo.config.annotation.Service;//引入的包是albaba提供的bean
           @Service
              public class StudentService implements StudentService{
              //實現本項目下接口包的方法
           }

 

     4.1.3  向注冊中心中給提供者的注冊下

      如果你使用是springboot微服務框架

      在application.properties總配置文件中加入 注冊

#注冊到zookeeper 中服務的名字
spring.dubbo.application.name=lwh_provider
#注冊中心的地址,ip為啟動了zookeeper的linux服務器的ip,2181是注冊中心的默認端口
spring.dubbo.registry.address=zookeeper://192.168.25.129:2181
#使用dubbo協議
spring.dubbo.protocol.name=dubbo
#dubbo服務在哪個端口暴露
spring.dubbo.protocol.port=20880
#去哪里掃描dubbo的服務組件,這是你service接口的實現類的包名,也就是上面提到的為什么把接口暴露出來
spring.dubbo.scan=com.lwh.service.impl

       如果你使用是spring,那就再spring配置中加入 注冊

<?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-admin 或 dubbo-monitor 會顯示這個名字,方便辨識-->
    <dubbo:application name="demotest-provider" owner="programmer" organization="dubbox"/>
    <!--使用 zookeeper 注冊中心暴露服務,注意要先開啟 zookeeper-->
    <dubbo:registry address="zookeeper://localhost:2181"/>
    <!-- 用dubbo協議在20880端口暴露服務 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!--使用 dubbo 協議實現定義好的 api.PermissionService 接口-->
    <dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" protocol="dubbo" />
    <!--具體實現該接口的 bean-->
    <bean id="demoService" class="com.alibaba.dubbo.demo.impl.DemoServiceImpl"/>
</beans>

 

    5 服務消費者

     5.1 跟提供者一樣,加入依賴

     5.2 代碼依舊跟以前一樣寫

      但是注意的是寫action時:你使用的service接口中的方法是提供者暴露出來的那個接口,所以,注入不能是@Autowired按類型注入了

      而是使用 alibaba提供的@Reference注入,例如:

1 import com.alibaba.dubbo.config.annotation.Reference;
2 
3 @Controller
4 public class StudentAction {
5     @Reference
6     private StudentService studentService;
7 
8 
9 }

     5.3 向注冊中心中給消費者的注冊下

      如果你使用是springboot微服務框架

      在application.properties總配置文件中加入 注冊

#消費者 在注冊中心注冊的名字
spring.dubbo.application.name=lwh_Consumer
#注冊中心的地址
spring.dubbo.registry.address=zookeeper://192.168.25.129:2181
#去哪里掃描消費者
spring.dubbo.scan=com.lwh.action

         如果你使用是spring,那就再spring配置中加入 注冊

<?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="demotest-consumer" owner="programmer" organization="dubbox"/>
    <!--向 zookeeper 訂閱 provider 的地址,由 zookeeper 定時推送-->
    <dubbo:registry address="zookeeper://localhost:2181"/>
    <!--使用 dubbo 協議調用定義好的 api.PermissionService 接口-->
    <dubbo:reference id="permissionService" interface="com.alibaba.dubbo.demo.DemoService"/>
</beans>

 

 

 然后讓兩個項目跑起來后,再去登陸注冊中心會發現自己發布的已經注冊到注冊中心去了

提供者

 

消費者

 

 到此為止,dubbo的入門就結束了,實際中有多提供者多消費者情況,比這要復雜的多,當然只有這樣才能體現dubbo的特性。

 

二、下面來說說關於Dubbo使用alibaba下的@Service注入發布Dubbo服務時,同時使用了@Transactional注解加入事務后Dubbo服務不能發布的問題,

也就是說不能同時使用@com.alibaba.dubbo.config.annotation.Service和@Transactional

  原因:因為當你使用事務后,spring bean中事務是使用事務代理的,簡單說就是執行者不是本體,而是代理類,那么,問題來了,這個時候Dubbo的AnnotationBean掃描類執行掃描代碼時,就獲取不到對應的注解,自然而然就發布不服務了

  解決方案

     經過網絡上再三尋找方法,發現有四種解決方案,但是個人覺得可執行的只有兩種:

     方法一(個人認為實用型):

      使用了@Transactional注解加入事務后,就不要使用@com.alibaba.dubbo.config.annotation.Service提供的@Service注解了,使用spring提供的@Service,然后自己寫個xml文件去配置Dubbo的服務

dubbo.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.2.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!-- 配置包掃描器 -->
<context:component-scan base-package="com.lwh"/>
<!-- 使用dubbo發布服務 -->
<!-- 提供方應用信息,用於計算依賴關系 -->
<dubbo:application name="dubbo_p" />
<dubbo:registry protocol="zookeeper"
address="192.168.25.129:2181" />
<!-- 用dubbo協議在20880端口暴露服務 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 聲明需要暴露的服務接口 -->
<dubbo:service interface="com.lwh.provider.service.UserService" ref="UserServiceImpl" timeout="600000"/>
</beans>

    方法二(反正我試了沒用)

                 接着使用alibaba提供的dubbo@Service發布dubbo服務,但是不使用spring提供的@Transactioncal注解加入的事務,使用自己配置的方式去加入事務,這里就不提供代碼了

    方法三(簡直瘋了,居然改源碼)

       修改Dubbo的源碼,也就是讓注解的事務代理,強制去讓他自己處理

    

 

        

 

 

 

 

 

 以上是個人所理解,技術有限,如若有錯誤,希望能夠提出交流,謝謝!

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM