基於spring及zookeeper的dubbo工程搭建

1、生產者搭建html

新建一個maven工程,勾選Create a simple projectjava

Packaging方式選擇jar包的方式。git

修改pom.xml文件:github

<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>
  <groupId>com.shaw</groupId>
  <artifactId>provider</artifactId>
  <version>1.0.0</version>
  
  <properties>  
      <spring.version>4.3.2.RELEASE</spring.version>  
  </properties>  

  <dependencies>  
      <dependency>  
          <groupId>com.alibaba</groupId>  
          <artifactId>dubbo</artifactId>  
          <version>2.5.3</version>  
          <exclusions>  
              <exclusion>  
                  <groupId>org.springframework</groupId>  
                  <artifactId>spring</artifactId>  
              </exclusion>  
          </exclusions>  
      </dependency>  
      <dependency>  
          <groupId>com.github.sgroschupf</groupId>  
          <artifactId>zkclient</artifactId>  
          <version>0.1</version>  
      </dependency>  
      
      <!-- spring相關 -->  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-core</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-beans</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-context</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-jdbc</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-web</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-webmvc</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-aop</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-tx</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-orm</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-context-support</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-test</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
      <dependency>  
          <groupId>org.springframework</groupId>  
          <artifactId>spring-jms</artifactId>  
          <version>${spring.version}</version>  
      </dependency>  
  </dependencies>  
</project>

按照如圖的方式,建立相關目錄文件web

ProviderService.javaspring

package com.shaw.service;

public interface ProviderService {
     public void sayHello();
}

ProviderServiceImpl.javaapache

package com.shaw.service.impl;

import com.shaw.service.ProviderService;

public class ProviderServiceImpl implements ProviderService{

    @Override
    public void sayHello() {
        System.out.println("Hello!I am Provider!");
    }

}

TestProviderService.java編程

package com.shaw.service;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestProviderService {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"application.xml"});
        context.start();
        System.out.println("生產者服務已經註冊成功!");
        try {
            System.in.read();//讓此程序一直跑,表示一直提供服務
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

application.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 ">   
    <!-- 具體的實現bean -->  
    <bean id="providerService" class="com.shaw.service.impl.ProviderServiceImpl" />  
    <!-- 提供方應用信息,用於計算依賴關係 -->  
    <dubbo:application name="provider"  />    
    <!-- 使用zookeeper註冊中心暴露服務地址 -->  
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />     
    <!-- 用dubbo協議在20880端口暴露服務 -->  
    <dubbo:protocol name="dubbo" port="29014" />  
    <!-- 聲明須要暴露的服務接口 -->  
    <dubbo:service interface="com.shaw.service.ProviderService" ref="providerService" />  
</beans> 

按照以下步驟測試生產者:tomcat

一、啓動zookeeper 

二、啓動tomcat  【一、2兩點的相關搭建能夠參考博主以前的博文《zookeeper環境及dubbo-admin管理平臺搭建》

三、右鍵TestProviderService類。

地址欄輸入:http://localhost:8080/dubbo-admin-2.5.4/ 帳戶密碼爲root/root。輸入服務名稱:com.shaw.service.ProviderService

至此,生產者搭建完成並提供服務了。

2、消費者搭建

按照搭建生產者的過程從新搭建一個consumer的工程:

工程目錄以下:

TestConsumerService.java

package com.shaw.consumer;

import java.io.IOException;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.shaw.service.ProviderService;

public class TestConsumerService {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"application.xml"});
        context.start();
        ProviderService testService = (ProviderService) context.getBean("testProviderService");
        testService.sayHello();
        try {
            System.in.read();
        } catch (IOException e) {       
            e.printStackTrace();
        }  
    }
}

application.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="consumer" />     
      <!-- 使用multicast廣播註冊中心暴露發現服務地址 -->  
    <dubbo:registry  protocol="zookeeper" address="zookeeper://127.0.0.1:2181" />       
      <!-- 生成遠程服務代理,能夠和本地bean同樣使用demoService -->  
    <dubbo:reference id="testProviderService" interface="com.shaw.service.ProviderService" />  
</beans> 

消費者測試:

繼續生產者的測試步驟不一樣的是最後在TestConsumerService類右鍵。

控制檯輸入了生產者打印出來的信息:

同時登陸:http://localhost:8080/dubbo-admin-2.5.4/ 也能夠查看相關消費者的服務信息如圖:

3、相關dubbo配置信息

3.1 dubbo經常使用配置

<dubbo:service/> 服務配置,用於暴露一個服務,定義服務的元信息,一個服務能夠用多個協議暴露,一個服務也能夠註冊到多個註冊中心。
  <dubbo:service ref="demoService" interface="com.unj.dubbotest.provider.DemoService" />
<dubbo:reference/> 引用服務配置,用於建立一個遠程服務代理,一個引用能夠指向多個註冊中心。   <dubbo:reference id="demoService" interface="com.unj.dubbotest.provider.DemoService" />
<dubbo:protocol/> 協議配置,用於配置提供服務的協議信息,協議由提供方指定,消費方被動接受。   <dubbo:protocol name="dubbo" port="20880" />
<dubbo:application/> 應用配置,用於配置當前應用信息,無論該應用是提供者仍是消費者。   <dubbo:application name="xixi_provider" />   <dubbo:application name="hehe_consumer" />
<dubbo:registry/> 註冊中心配置,用於配置鏈接註冊中心相關信息。
  <dubbo:registry address="zookeeper://127.0.0.1:2181" />

<dubbo:module/> 模塊配置,用於配置當前模塊信息,可選。 
<dubbo:monitor/> 監控中心配置,用於配置鏈接監控中心相關信息,可選。
<dubbo:provider/> 提供方的缺省值,當ProtocolConfig和ServiceConfig某屬性沒有配置時,採用此缺省值,可選。
<dubbo:consumer/> 消費方缺省配置,當ReferenceConfig某屬性沒有配置時,採用此缺省值,可選。
<dubbo:method/> 方法配置,用於ServiceConfig和ReferenceConfig指定方法級的配置信息。
<dubbo:argument/> 用於指定方法參數配置。

3.2 服務調用超時設置

 

 

上圖中以timeout爲例,顯示了配置的查找順序,其它retries, loadbalance, actives也相似。
方法級優先,接口級次之,全局配置再次之。
若是級別同樣,則消費方優先,提供方次之。 

其中,服務提供方配置,經過URL經由註冊中心傳遞給消費方。
建議由服務提供方設置超時,由於一個方法須要執行多長時間,服務提供方更清楚,若是一個消費方同時引用多個服務,就不須要關心每一個服務的超時設置。
理論上ReferenceConfig的非服務標識配置,在ConsumerConfig,ServiceConfig, ProviderConfig都可以缺省配置。

3.3 啓動時檢查 

Dubbo缺省會在啓動時檢查依賴的服務是否可用,不可用時會拋出異常,阻止Spring初始化完成,以便上線時,能及早發現問題,默認check=true。

若是你的Spring容器是懶加載的,或者經過API編程延遲引用服務,請關閉check,不然服務臨時不可用時,會拋出異常,拿到null引用,若是check=false,老是會返回引用,當服務恢復時,能自動連上。

能夠經過check="false"關閉檢查,好比,測試時,有些服務不關心,或者出現了循環依賴,必須有一方先啓動。 

1、關閉某個服務的啓動時檢查:(沒有提供者時報錯)
<dubbo:reference interface="com.foo.BarService" check="false" />
2、關閉全部服務的啓動時檢查:(沒有提供者時報錯) 寫在定義服務消費者一方
<dubbo:consumer check="false" /> 
3、關閉註冊中心啓動時檢查:(註冊訂閱失敗時報錯)
<dubbo:registry check="false" />

引用缺省是延遲初始化的,只有引用被注入到其它Bean,或被getBean()獲取,纔會初始化。

若是須要飢餓加載,即沒有人引用也當即生成動態代理,能夠配置: 

<dubbo:reference interface="com.foo.BarService" init="true" />

3.4 訂閱
一、問題
爲方便開發測試,常常會在線下共用一個全部服務可用的註冊中心,這時,若是一個正在開發中的服務提供者註冊,可能會影響消費者不能正常運行。 

二、解決方案

可讓服務提供者開發方,只訂閱服務(開發的服務可能依賴其它服務),而不註冊正在開發的服務,經過直連測試正在開發的服務。

禁用註冊配置:
<dubbo:registry address="10.20.153.10:9090" register="false" />
或者:
<dubbo:registry address="10.20.153.10:9090?register=false" />

3.5 回聲測試(測試服務是否可用)

回聲測試用於檢測服務是否可用,回聲測試按照正常請求流程執行,可以測試整個調用是否通暢,可用於監控。
全部服務自動實現EchoService接口,只需將任意服務引用強制轉型爲EchoService,便可使用。

<dubbo:reference id="memberService" interface="com.xxx.MemberService" /> 
MemberService memberService
= ctx.getBean("memberService"); // 遠程服務引用 EchoService echoService = (EchoService) memberService; // 強制轉型爲EchoService String status = echoService.$echo("OK"); // 回聲測試可用性 assert(status.equals("OK"))

3.6 延遲鏈接

延遲鏈接,用於減小長鏈接數,當有調用發起時,再建立長鏈接。
只對使用長鏈接的dubbo協議生效。 

<dubbo:protocol name="dubbo" lazy="true" />
3.7 令牌驗證
防止消費者繞過註冊中心訪問提供者,在註冊中心控制權限,以決定要不要下發令牌給消費者,註冊中心可靈活改變受權方式,而不需修改或升級提供者

1、全局設置開啓令牌驗證:
<!--隨機token令牌,使用UUID生成-->
<dubbo:provider interface="com.foo.BarService" token="true" /> 
<!--固定token令牌,至關於密碼-->
<dubbo:provider interface="com.foo.BarService" token="123456" />
2、服務級別設置開啓令牌驗證:
<!--隨機token令牌,使用UUID生成-->
<dubbo:service interface="com.foo.BarService" token="true" /> 
<!--固定token令牌,至關於密碼-->
<dubbo:service interface="com.foo.BarService" token="123456" /> 
3、協議級別設置開啓令牌驗證:
<!--隨機token令牌,使用UUID生成-->
<dubbo:protocol name="dubbo" token="true" /> 
<!--固定token令牌,至關於密碼-->
<dubbo:protocol name="dubbo" token="123456" />

3.8 日誌適配

缺省自動查找:log4j、slf4j、jcl、jdk 

能夠經過如下方式配置日誌輸出策略:dubbo:application logger="log4j"/> 

訪問日誌:
若是你想記錄每一次請求信息,可開啓訪問日誌,相似於apache的訪問日誌。此日誌量比較大,請注意磁盤容量。 

將訪問日誌輸出到當前應用的log4j日誌: 
<dubbo:protocol accesslog="true" />
將訪問日誌輸出到指定文件: 
<dubbo:protocol accesslog="http://10.20.160.198/wiki/display/dubbo/foo/bar.log" />

3.9 配置Dubbo緩存文件 

配置方法以下: 

<dubbo:registryfile=」${user.home}/output/dubbo.cache」 />
注意:
文件的路徑,應用能夠根據須要調整,保證這個文件不會在發佈過程當中被清除。若是有多個應用進程注意不要使用同一個文件,避免內容被覆蓋。 

這個文件會緩存:
註冊中心的列表
服務提供者列表 

有了這項配置後,當應用重啓過程當中,Dubbo註冊中心不可用時則應用會從這個緩存文件讀取服務提供者列表的信息,進一步保證應用可靠性。

 

本文代碼下載:dubbo-provider-consumer

相關文章
相關標籤/搜索