DUBBO應用

1.現狀———解決方案

在大規模服務化之前,應用可能只是通過RMI或Hessian等工具,簡單的暴露和引用遠程服務,通過配置服務的URL地址進行調用,通過F5等硬件進行負載均衡。
(1) 當服務越來越多時,服務URL配置管理變得非常困難,F5硬件負載均衡器的單點壓力也越來越大。
此時需要一個服務註冊中心,動態的註冊和發現服務,使服務的位置透明。
並通過在消費方獲取服務提供方地址列表,實現軟負載均衡和Failover,降低對F5硬件負載均衡器的依賴,也能減少部分成本。

(2) 當進一步發展,服務間依賴關係變得錯蹤複雜,甚至分不清哪個應用要在哪個應用之前啓動,架構師都不能完整的描述?

(3) 接着,服務的調用量越來越大,服務的容量問題就暴露出來,這個服務需要多少機器支撐?什麼時候該加機器?
爲了解決這些問題,第一步,要將服務現在每天的調用量,響應時間,都統計出來,作爲容量規劃的參考指標。
其次,要可以動態調整權重,在線上,將某臺機器的權重一直加大,並在加大的過程中記錄響應時間的變化,直到響應時間到達閥值,記錄此時的訪問量,再以此訪問量乘以機器數反推總容量。

簡介

Dubbo是什麼
一個分佈式高性能RPC服務框架,SOA治理方案.

核心功能
A.遠程通訊
–多協議集成,提供對多種基於長連接的NIO框架抽象封裝
B.集羣容錯
–失敗自動切換,當出現失敗,重試其它服務器。(缺省)
C.自動發現
–基於註冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。
D.軟負載均衡
–可在內網替代F5等硬件負載均衡器,降低成本,減少單點

DUBBO架構展示

節點角色說明:
Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務註冊與發現的註冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
Container: 服務運行容器

調用關係說明
• 0. 服務容器負責啓動,加載,運行服務提供者。
• 1. 服務提供者在啓動時,向註冊中心註冊自己提供的服務。
• 2. 服務消費者在啓動時,向註冊中心訂閱自己所需的服務。
• 3. 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
• 4. 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
• 5. 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
這裏寫圖片描述

Dubbo模塊詳解:

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

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

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

協議支持Dubbo支持多種協議,如下所示:
Dubbo協議
Hessian協議
HTTP協議
RMI協議
WebService協議
Thrift協議
Memcached協議
Redis協議
在通信過程中,不同的服務等級一般對應着不同的服務質量,那麼選擇合適的協議便是一件非常重要的事情。你可以根據你應用的創建來選擇。例如,使用 RMI協議,一般會受到防火牆的限制,所以對於外部與內部進行通信的場景,就不要使用RMI協議,而是基於HTTP協議或者Hessian協議。

DUBBO配置

1.服務提供者暴露服務配置
Ref: 服務對象實現引用 interface: 服務接口名

2.服務消費者引用服務配置
Interface: 服務接口名 id: 服務引用BeanId

3.服務提供者協議配置
Name:協議名稱(默認是dubbo協議)hession,http.,webService,rmi

4.註冊中心配置
Port:dubbo協議缺省端口爲20880,rmi協議缺省端口爲1099,http和hessian協議缺省端口爲80
Host: 自動查找本機IP

5.監控中心配置
監控中心協議,如果爲protocol=”registry”,表示從註冊中心發現監控中心地址,否則直連監控中心否則直連監控中心服務器地址,address=”10.20.130.230:12080“

6.模塊信息配置
Name: 當前模塊名稱,用於註冊中心計算模塊間依賴關係

7.應用信息配置
Name:當前應用名稱,用於註冊中心計算應用間依賴關係,注意:消費者和提供者應用名不要一樣,此參數不是匹配條件, 你當前項目叫什麼名字就填什麼,和提供者消費者角色無關,比如:kylin應用調用了morgan應用的服務,則kylin項目配成 kylin,morgan項目配成morgan,可能kylin也提供其它服務給別人使用,但kylin項目永遠配成kylin,這樣註冊中心將顯示 kylin依賴於morgan

8.服務提供者默認值配置,說明:該標籤爲和標籤的默認設置。
Id: 協議BeanId,可以在中引用此ID
Protocol:協議名稱

9.服務消費者默認值配置, 該標籤爲標籤的缺省值設置

  1. 方法級配置, 該標籤爲或的子標籤,用於控制到方法級
    Name:方法名

  2. 方法參數配置, 該標籤爲的子標籤,用於方法參數的特徵描述



    Index: int值方法名
    Callback:布爾值參數是否爲callback接口,如果爲callback,服務提供方將生成反向代理,可以從服務提供方反向調用消費方,通常用於事件推送.

DUBBO依賴

<project>
  <dependencies>
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version> 2.4.9/version>
      </dependency>
   </dependencies>
</project>
    在阿里巴巴內部廣泛使用的GA版本爲:2.4.9

DUBBO簡單實例

服務接口:


import java.util.List;

import com.deppon.gis.common.pojo.User;

public interface UserService {

    public List<User> queryAll();
}

dubbo傳輸對象實體類(必須實現序列化接口)


import java.io.Serializable;

// 使用dubbo要求傳輸的對象必須實現序列化接口
public class User implements Serializable {

    private static final long serialVersionUID = -7341603933521593227L;

    private Long id;

    private String username;

    private String password;

    private Integer age;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password="
                + password + ", age=" + age + "]";
    }


}

服務提供方Spring核心配置文件以及代碼實現

<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.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方應用信息,用於計算依賴關係 -->
    <dubbo:application name="dubbo-provider" />

    <!-- 這裏使用的註冊中心是zookeeper -->
    <dubbo:registry address="zookeeper://10.230.13.74:2181"
        client="zkclient" />

    <!-- 用dubbo協議在20880端口暴露服務   port="20880"-->
    <dubbo:protocol name="dubbo"   port="20880"/>

    <!-- 將該接口暴露到dubbo中 -->
    <dubbo:service interface="com.deppon.gis.common.service.UserService"
        ref="userServiceImpl" />
     <!-- 服務提供方    interface:服務接口名  version:版本號(注意只有在版本號一致的情況下,纔可以完成消費端到提供端的調用)
     cluster:集羣容錯模式   retries:遠程服務調用重試次數,不包括第一次調用   timeout:服務方法調用超時時間 
     protocol:只調用指定協議的服務提供方     dubbo:method會繼承dubbo:service中配置的屬性   loadbalance:負載均衡策略-->
    <dubbo:service interface="com.deppon.gis.common.service.UserService"
         cluster="failover"  ref="userServiceImpl"  loadbalance="random">
         <!-- <dubbo:method name="queryAll" timeout="80" retries="2" loadbalance="leastactive" /> -->
    </dubbo:service>
    <!-- 將具體的實現類加入到Spring容器中 -->
    <bean id="userServiceImpl" class="com.deppon.gis.provider.service.impl.UserServiceImpl" />
    <!-- 監控中心配置 -->
    <dubbo:monitor protocol="registry"/>


</beans>

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import com.deppon.gis.common.pojo.User;
import com.deppon.gis.common.service.UserService;


public class UserServiceImpl implements UserService{

    public List<User> queryAll() {
        long x=0;
        List<User> users=new ArrayList<User>();
        try {
             InetAddress addr = null;
               try {
                  addr = InetAddress.getLocalHost();
               } catch (UnknownHostException e) {
                  e.printStackTrace();
               }
               String IP=addr.getHostAddress().toString();
            for (int i = 0; i < 20; i++) {
                x++;
                User user= new User();
                user.setAge(i);
                user.setId(x);
                user.setPassword("MIMA"+i);
                user.setUsername("用戶名"+IP+"--------線程名稱"+Thread.currentThread().getName());
                users.add(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return users;
    }

}

服務消費方spring核心配置文件以及代碼實現

<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.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方應用信息,用於計算依賴關係 -->
    <dubbo:application name="dubbo-consumer" />

    <!-- 這裏使用的註冊中心是zookeeper -->
    <dubbo:registry address="zookeeper://10.230.13.74:2181"
        client="zkclient" />

    <!-- 從註冊中心中查找服務 -->
    <dubbo:reference id="userService"
        interface="com.deppon.gis.common.service.UserService" >
         <!-- <dubbo:method name="queryAll" retries="2" /> -->
    </dubbo:reference>

    <!-- 監控中心配置 -->

    <dubbo:monitor protocol="registry"/>

    <bean id="conSumer" class="com.deppon.gis.consumer.ConSumer">
       <property name="userService" ref="userService"></property>
    </bean>
</beans>


import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogConfigurationException;
import org.apache.commons.logging.LogFactory;

import com.alibaba.fastjson.JSON;
import com.deppon.gis.common.pojo.User;
import com.deppon.gis.common.service.UserService;

public class ConSumer {
    private static  Log log=LogFactory.getLog(ConSumer.class);
    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void queryAll(){
        List<User> queryAll = userService.queryAll();
        if(queryAll==null &&queryAll.size()==0){
            log.info("info級別 獲取的數據爲0");
            System.out.println("獲取數據爲0----------------------------");
        }
        for (User user : queryAll) {
            if(user==null){
                log.error("error級別 獲取的數據爲空");
                System.out.println("獲取數據空----------------------------");
            }else{
            Object json = JSON.toJSON(user);
            System.out.println("阿里的fastjson,單獨解析json對象"+json);
            }
        }
    }


}

DUBBO實例運行
這裏寫圖片描述

Dubbo複雜配置

A.Dubbo服務集羣容錯配置
假設我們使用的是單機模式的Dubbo服務,如果在服務提供方(Provider)發佈服務以後,服務消費方(Consumer)發出一次調用請求,恰好 這次由於網絡問題調用失敗,那麼我們可以配置服務消費方重試策略,可能消費方第二次重試調用是成功的(重試策略只需要配置即可,重試過程是透明的);但 是,如果服務提供方發佈服務所在的節點發生故障,那麼消費方再怎麼重試調用都是失敗的,所以我們需要採用集羣容錯模式,這樣如果單個服務節點因故障無法提 供服務,還可以根據配置的集羣容錯模式,調用其他可用的服務節點,這就提高了服務的可用性。
Dubbo內置支持如下6種集羣模式:
Failover Cluster模式:
配置值爲failover。這種模式是Dubbo集羣容錯默認的模式選擇,調用失敗時,會自動切換,重新嘗試調用其他節點上可用的服務
**這裏寫圖片描述**
如果調用失敗一次,可以再次重試2次調用,服務級別調用超時時間爲100ms,調用方法queryRoomUserCount的超時時間爲80ms,允許重試2次,最壞情況調用花費時間160ms。
Failfast Cluster模式
配置值爲failfast。這種模式稱爲快速失敗模式,調用只執行一次,失敗則立即報錯。
Failsafe Cluster模式:
配置值爲failsafe。失敗安全模式,如果調用失敗, 則直接忽略失敗的調用,而是要記錄下失敗的調用到日誌文件,以便後續審計

Failback Cluster模式
配置值爲failback。失敗自動恢復,後臺記錄失敗請求,定時重發。通常用於消息通知操作

Forking Cluster模式
配置值爲forking。並行調用多個服務器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。

Broadcast Cluster模式
配置值爲broadcast。廣播調用所有提供者,逐個調用,任意一臺報錯則報錯(2.1.0開始支持)。通常用於通知所有提供者更新緩存或日誌等本地資源信息。

B.Dubbo服務負載均衡
Dubbo框架內置提供了4種負載均衡策略:
Random LoadBalance:隨機策略,配置值爲random。可以設置權重,有利於充分利用服務器的資源,高配的可以設置權重大一些,低配的可以稍微小一些(默認)
RoundRobin LoadBalance:輪詢策略,配置值爲roundrobin
LeastActive LoadBalance:配置值爲leastactive。根據請求調用的次數計數,處理請求更慢的節點會受到更少的請求
ConsistentHash LoadBalance: ” 一致性Hash,相同參數的請求總是發到同一提供者。
” 當某一臺提供者掛時,原本發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引起劇烈變動。

這裏寫圖片描述

此配置負載策略爲:隨機策略,dubbo:method配置負載策略爲輪訓策略,service默認策略爲隨機策略 methos如不定義隨機策略,默認繼承service負載策略

Dubbo管理控制檯,簡易控制中心的安裝

1. Dubbo管理控制平臺安裝
作用:Dubbo的管理控制檯,在實際的項目中非常的有用,尤其是在dubbo服務提供數量逐漸加大的情況下,通過Dubbo管理控制檯能夠很好的被我們所用,從而讓我們更好的使用Dubbo提供的服務.
操作步驟:
A.Dubbo.properties配置文件管理註冊中心連接以及管理控制平臺用戶名和密碼
dubbo.registry.address=zookeeper://10.230.13.74:2181配置Zookeeper註冊中心的地址和端口,這個屬性支持多個註冊中心的配置
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest以上兩個屬性是管理控制檯的用戶名密碼.
這裏寫圖片描述

B.啓動服務
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

2.Dubbo 簡易監控中心
dubbo-monitor作用:
Simple Monitor掛掉不會影響到Consumer和Provider之間的調用,所以用於生產環境不會有風險。

配置好了之後可以結合admin管理後臺使用,可以清晰的看到服務的訪問記錄、成功次數、失敗次數等…..

Simple Monitor採用磁盤存儲統計信息,請注意安裝機器的磁盤限制,如果要集羣,建議用mount共享磁盤。
charts目錄必須放在jetty.directory下,否則頁面上訪問不了

操作步驟
需要在服務端以及消費端dubbo核心配置文件中配置監控中心

服務端客戶端監控中心配置:
這裏寫圖片描述

啓動Dubbo-monitor監控中心
這裏寫圖片描述
因爲dubbo監控中心內嵌jetty服務器,啓動服務器,訪問ip+8080路徑
這裏寫圖片描述
這裏寫圖片描述

Dubbo管理SOA服務方案:

1.WebService
A.maven依賴

<dependencies>
        <!-- dubbo推薦版本2.4.9 阿里巴巴內部廣泛使用的GA版本-->
       <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.4.9</version>
            <exclusions>
                <exclusion>
                    <!-- 排除傳遞spring依賴 -->
                    <artifactId>spring</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
            </exclusions>
       </dependency>
      <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.1.39</version>
        </dependency>
        <dependency>
           <groupId>gis.deppon.com</groupId>
           <artifactId>dubbo-api</artifactId>
           <version>0.0.1-SNAPSHOT</version>
        </dependency>
         <dependency>
           <groupId>org.codehaus.jackson</groupId>
           <artifactId>jackson-mapper-asl</artifactId>
           <version>1.9.4</version>
     </dependency>
   <dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-simple</artifactId>
    <version>2.6.1</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>2.6.1</version>
</dependency>
  </dependencies>

B.服務端Web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">

    <display-name>dubbo</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo/dubbo-*.xml</param-value>
    </context-param>

    <!--Spring的ApplicationContext 載入 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

     <!--dubbo 服務根路徑-->
    <servlet>
        <servlet-name>dubbo</servlet-name>
        <servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dubbo</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
</web-app>

C.服務端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="dubbo-webservice-app" />

    <!-- 使用zookeeper註冊中心暴露服務地址 -->
    <dubbo:registry address="zookeeper://10.230.13.74:2181" />

    <!-- 用webservice協議在8080端口暴露服務,如server屬性定義servlet,則暴露端口號必須與所在服務的端口號保持一致 -->
    <dubbo:protocol name="webservice" port="8080" server="servlet" />
    <!-- 聲明需要暴露的服務接口 -->
    <dubbo:service interface="com.gis.webservice.service.DubboService"
        ref="dubboService" />

    <!-- 和本地bean一樣實現服務 -->
    <bean id="dubboService" class="com.gis.webservice.service.impl.DubboServiceImpl" />

</beans>

//接口
public interface DubboService {

    public String printWord(String word);
}
//實現類
import com.gis.webservice.service.DubboService;

public class DubboServiceImpl implements DubboService {

    public String printWord(String word) {

        return "DUBBO 集成webService  返回字符串";
    }

}

D.客戶端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="dubbo-webservice-consumer" />

    <!-- 使用zookeeper註冊中心暴露服務地址 -->
    <dubbo:registry address="zookeeper://10.230.13.74:2181" />

<!--URL屬性:服務端服務的訪問路徑,最後路徑則爲接口的全路徑 -->
   <dubbo:reference id="dubboService" interface="com.gis.webservice.service.DubboService"
    url="webservice://localhost:8080/services/com.gis.webservice.service.DubboService" />

    <bean id="consumerService" class="com.gis.consumer.service.impl.ConsumerServiceImpl">
        <property name="dubboService" ref="dubboService"></property>
    </bean>
</beans>

//代碼實現
import com.gis.consumer.service.ConsumerService;
import com.gis.webservice.service.DubboService;

public class ConsumerServiceImpl implements ConsumerService {

    private DubboService dubboService;

    public void setDubboService(DubboService dubboService) {
        this.dubboService = dubboService;
    }

    public void say() {
        String printWord = dubboService.printWord("123");
        System.out.println("WebService客戶端展示"+printWord);

    }


}

操作步驟:啓動服務端以及客戶端服務,輸入服務訪問路徑判斷webService服務是否搭建成功。如圖展示如出現以下內容即表示webService服務搭建成功
測試結果展示:
這裏寫圖片描述
這裏寫圖片描述

2.restfulWebService
簡介:Dubbox是Dubbo的一個擴展,功能展示:支持REST風格遠程調用(HTTP + JSON/XML); 支持基於Kryo和FST的Java高效序列化實現; 支持基於嵌入式Tomcat的HTTP remoting體系。
dubbo添加REST調用,其最主要到目的也是面向服務的提供端,即開發REST服務來提供給非dubbo的(異構)消費端。
A.服務端pom配置:
要引用2.8.4版本dubbo框架並且排除spring的依賴

 <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.8.4</version>
             <exclusions>
                <exclusion>
                <!--    排除傳遞spring依賴 -->
                    <artifactId>spring</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
            </exclusions>
        </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.15.0-GA</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty</artifactId>
            <version>3.7.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.2.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.1.39</version>
        </dependency>
        <dependency>
            <groupId>org.apache.bsf</groupId>
            <artifactId>bsf-api</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-simple</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.thrift</groupId>
            <artifactId>libthrift</artifactId>
            <version>0.8.0</version>
        </dependency>
        <dependency>
            <groupId>com.caucho</groupId>
            <artifactId>hessian</artifactId>
            <version>4.0.7</version>
        </dependency>
         <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency> 
        <!-- 要將 org.mortbay.jettyJAR包中的servlet-->
        <dependency>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>jetty</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.mortbay.jetty</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
            <version>6.1.26</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
             <version>1.2.16</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
           <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.0.0.GA</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.2.0.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
            <version>0.4</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-client</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-netty</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jdk-http</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jackson-provider</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxb-provider</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <!-- <dependency>   注意:此JAR包中也包含servlet類,如果使用要注意排除其中的servlet
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>8.0.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-logging-juli</artifactId>
            <version>8.0.11</version>
        </dependency> -->
        <!-- KRYO 高性能序列化庫 -->
        <dependency>
            <groupId>com.esotericsoftware.kryo</groupId>
            <artifactId>kryo</artifactId>
            <version>2.24.0</version>
        </dependency>
        <dependency>
            <groupId>de.javakaffee</groupId>
            <artifactId>kryo-serializers</artifactId>
            <version>0.26</version>
        </dependency>
        <dependency>
            <groupId>de.ruedigermoeller</groupId>
            <artifactId>fst</artifactId>
             <version>1.55</version>
      </dependency>

        <dependency>
            <groupId>com.deppon.gis</groupId>
            <artifactId>restapi</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- RESTFUL JAR包 -->
        <dependency>  
                <groupId>javax.ws.rs</groupId>  
                <artifactId>javax.ws.rs-api</artifactId>  
                <version>2.0</version>  
            </dependency>
         <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
   </dependencies>

B.服務端web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
<!-- dubbox 遠程調用的配置 -->
<!-- 如果你是用spring的ContextLoaderListener來加載spring,則必須保證BootstrapListener配置在ContextLoaderListener之前,否則dubbo初始化會出錯。 -->
   <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo/dubbo-*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>com.alibaba.dubbo.remoting.http.servlet.BootstrapListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
</web-app>

C.服務端spring核心配置以及代碼實現


<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.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!-- 開放dubbo協議,serialization表示序列化的方案  optimizer表示執行序列化的類-->
    <dubbo:protocol name="dubbo" serialization="kryo" optimizer="com.alibaba.dubbo.demo.SerializationOptimizerImpl"/>
    <dubbo:protocol name="dubbo" serialization="fst" optimizer="com.alibaba.dubbo.demo.SerializationOptimizerImpl"/>
    <dubbo:protocol name="dubbo" serialization="nativejava"/>
    <dubbo:protocol name="dubbo" serialization="hessian2"/>
    <dubbo:protocol name="dubbo" serialization="fastjson"/>
    <dubbo:protocol name="dubbo" serialization="dubbo"/>
    <!-- name:使用的協議  port:端口號   
     contextpath:所有rest服務對應的基礎路徑  
     server:如果爲servlet,那麼在web.xml中DispatcherServlet訪問路徑必須是 contextpath配置的訪問路徑
     extension:配置攔截器,多個攔截器類似於逗號分開
    -->
     <!-- 提供方應用信息,用於計算依賴關係   owner:該應用的負責人 -->
    <dubbo:application name="demo-provider" />
     <!-- 註冊中心地址 -->
    <dubbo:registry address="zookeeper://10.230.13.74:2181"/>
    <!-- 開啓dubbo註解掃描 -->
    <dubbo:annotation package="com.deppon.gis.service" />  
    <!--  name:使用的協議  
        port:端口號   
     contextpath:所有rest服務對應的基礎路徑  
     server:如果爲servlet,那麼在web.xml中DispatcherServlet訪問路徑必須是 contextpath配置的訪問路徑 
     extension:配置攔截器的實現類-->
     <!-- contextpath="services"  --><!-- server="servlet"  -->
    <dubbo:protocol name="rest"  port="9090"  contextpath="services" server="servlet" />
    <!-- extension="com.deppon.gis.filter.DubboxProviderFilter,
      com.deppon.gis.filter.DubboProvideCustomException,com.deppon.gis.filter.DubboConsumerFilter"extension 此屬性值爲自定義的dubbo攔截類需要實現ClientResponseFilter或者ContainerResponseFilter接口,可自行百度,此處不做演示 -->
   <!-- 聲明需要暴露的服務接口 -->
    <dubbo:service interface="com.deppon.gis.service.DubboProviderService" ref="dubboProviderServiceImpl"
      protocol="rest" validation="true"  timeout="2000" connections="100" />

    <bean id="dubboProviderServiceImpl" class="com.deppon.gis.provider.impl.DubboProviderServiceImpl" />

</beans>


import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
//接口上面不添加註解,保持接口的廣泛適用性,使用dubbo客戶端調用必須添加在接口上面
@Path("/restdemo")  //訪問路徑
public interface DubboProviderService {
      @GET  //請求方式
      @Path("/{param}")  //訪問路徑,並且請求參數加如正則校驗必須是數組
      @Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})  
      public String queryService(@PathParam("param") int name);
}

import com.deppon.gis.service.DubboProviderService;

public class DubboProviderServiceImpl implements DubboProviderService{

       //指定輸出JSON格式的數據。框架會自動將對象序列化爲JSON數據。application/json; charset=UTF-8,text/xml;charset=UTF-8
        public String queryService(int name) {
                return "客戶端使用restful風格調用服務端不使用servlet,返回字符串 name="+name ;
        }
}

A.非dubbo客戶端調用duboo-rest服務端
這裏寫圖片描述
B.dubbo客戶端調用dubbo服務端
服務端配置文件:
這裏寫圖片描述
客戶端配置文件:
這裏寫圖片描述
運行結果:
這裏寫圖片描述
C.dubbo客戶端調用非dubbo服務端
服務端配置文件:
這裏寫圖片描述
這裏寫圖片描述
接口:
這裏寫圖片描述
客戶端配置文件:
這裏寫圖片描述
實現:
這裏寫圖片描述

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