dubbo 框架

2.1 dubbo  

  Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、輕量級的開源 Java RPC 框架,它提
供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和html

發現。java

  Dubbo 是一個分佈式服務框架,致力於提供高性能和透明化的 RPC 遠程服務調用方案、 服
務治理方案。
官網:http://dubbo.apache.org/zh-cn/node

快速開始文檔地址:http://dubbo.apache.org/zh-cn/docs/user/quick-start.htmlweb

面向接口代理:調用接口的方法,在 A 服務器調用 B 服務器的方法,由 dubbo 實現對 B 的
調用,無需關心實現的細節,就像 MyBatis 訪問 Dao 的接口,能夠操做數據庫同樣。不用關
心 Dao 接口方法的實現。這樣開發是方便,舒服的。redis

 

2.2 基本架構

架構圖:算法

provider:提供者,供應商,提供程序spring

consumer:消費者數據庫

subscribe:訂閱apache

notify:通知服務器

invoke:調用,呼叫

  服務提供者( (Provider) ):暴露服務的服務提供方,服務提供者在啓動時,向註冊中心注
冊本身提供的服務。
  服務消費者( (Consumer ): 調用遠程服務的服務消費方,服務消費者在啓動時,向註冊
中心訂閱本身所需的服務,服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一
臺提供者進行調用,若是調用失敗,再選另外一臺調用。
  註冊中心( (Registry) ):註冊中心返回服務提供者地址列表給消費者,若是有變動,註冊
中心將基於長鏈接推送變動數據給消費者
  監控中心( (Monitor) ):服務消費者和提供者,在內存中累計調用次數和調用時間,定時
每分鐘發送一次統計數據到監控中心

 

調用關係說明:
⚫ 服務容器負責啓動,加載,運行服務提供者。
⚫ 服務提供者在啓動時,向註冊中心註冊本身提供的服務。
⚫ 服務消費者在啓動時,向註冊中心訂閱本身所需的服務。
⚫ 註冊中心返回服務提供者地址列表給消費者,若是有變動,註冊中心將基於長鏈接推送
變動數據給消費者。
⚫ 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如
果調用失敗,再選另外一臺調用。

⚫  服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數
據到監控中心。

 

2.3 dubbo  支持的協議

  支持多種協議:dubbo , hessian , rmi , http, webservice , thrift , memcached , redis。
dubbo 官方推薦使用 dubbo 協議。dubbo 協議默認端口 20880
使用 dubbo 協議,spring 配置文件加入:
<dubbo:protocol name="dubbo" port="20880" />

 

2.4  電商平臺需求

  某電商平臺系統需求,用戶瀏覽商品;選擇商品下訂單,訂單系統須要獲取用戶信息中
的送貨地址;向支付系統請求完成付款。

 

2.5直連方式 dubbo

  點對點的直連項目:消費者直接訪問服務提供者,沒有註冊中心。消費者必須指定服務
提供者的訪問地址(url)。
消費者直接經過 url 地址訪問固定的服務提供者。這個 url 地址是不變的。

 

2.5.1 實現目標

 

2.5.2 實現方式

以 JavaSE 爲例,服務提供者,服務消費者都是 JavaSE 項目

(1) 建立服務提供者: 訂單服務

A 、 建 新建 java project

項目名稱: link-orderservice-provider
設置 version 爲 1.0.0

B 、 maven pom.xml

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.3.16.RELEASE</version>
</dependency>
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.6.2</version>
</dependency>

 

在<build>中加入 plugin

<plugins>
    <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
        <source>1.8</source>
        <target>1.8</target>
        </configuration>
    </plugin>
</plugins>                

C 、  建立 訂單實體 類:Order

package com.bjpowernode.domain;

import java.io.Serializable;

public class Order implements Serializable {

    private String id;
    private String goodName;
    private float price;
    private  int amount;

    public String getId() {
        return id;
    }

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

    public String getGoodName() {
        return goodName;
    }

    public void setGoodName(String goodName) {
        this.goodName = goodName;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id='" + id + '\'' +
                ", goodName='" + goodName + '\'' +
                ", price=" + price +
                ", amount=" + amount +
                '}';
    }
}

D 、  新建 訂單 服務接口:OrderService

package com.bjpowernode.service;

import com.bjpowernode.domain.Order;

public interface OrderService {
    public Order createOrder(Integer userId,String goodName,float price,int amount);
}

E 、  新建接口的實現類:OrderServiceImpl

package com.bjpowernode.service.impl;

import com.bjpowernode.domain.Order;
import com.bjpowernode.service.OrderService;

import java.util.UUID;

public class OrderServiceImpl implements OrderService {
    public Order createOrder(Integer userId, String goodName, float price, int amount) {
        Order order=new Order();
        order.setAmount(amount);
        order.setGoodName(goodName);
        order.setId(UUID.randomUUID().toString().replace("-",""));
        order.setPrice(price);
        System.out.println("建立訂單"+order);
        return order;
    }
}

F 、 建 建立 dubbo 

orderservce-provider.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服務名稱-->
    <dubbo:application name="link-orderservice-provider"/>

    <!--聲明訪問dubbo服務的協議-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--聲明服務的接口暴露服務-->
    <dubbo:service interface="com.bjpowernode.service.OrderService"
                   ref="orderService" registry="N/A"/>

    <!--聲明接口的實現類對象-->
    <bean id="orderService" class="com.bjpowernode.service.impl.OrderServiceImpl"/>

</beans>

G 、  測試配置 文件

package com.bjpowernode;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class OrderProviderApplication {
    public static void main(String[] args) throws IOException {
        String config="orderservice-provider.xml";
        ApplicationContext context=new ClassPathXmlApplicationContext(config);
        //調用容器的啓動方法。
        ((ClassPathXmlApplicationContext) context).start();

        System.in.read();
    }
}

H 、 地 安裝本地 jar 到 到 maven 

  服務接口中的方法要給消費者使用,消費者項目須要知道接口名稱和接口中的方法名稱、參
數等。這些信息服務提供者才知道。須要把接口的 class 文件打包爲 jar .
  服務接口項目的類文件打包爲 jar, 安裝到 maven 倉庫,倉庫中的提供者 jar 能夠被消費者
使用。
使用 idea 的 maven 窗口執行 install

(2 )  建立服務消費者: 商品網站

A 、 建 新建 java project

項目名稱: link-main-web

B 、 maven pom.xml

<dependency>
    <groupId>com.bjpowernode</groupId>
    <artifactId>link-orderservice-provider</artifactId>
    <version>1.0.0</version>
</dependency>

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency>

<dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency>

<build>加入 maven 編譯插件

<plugins>
    <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>            

C 、  建立 購買商品 接口

package com.bjpowernode.service;

import com.bjpowernode.domain.Order;

public interface ShopService {
  //用戶id,商品名稱,價格,數量
public Order buyGoods(Integer userId,String goodName,float price,int amount); }

D 、  建立 購買接口和實現類

package com.bjpowernode.service.impl;

import com.bjpowernode.domain.Order;
import com.bjpowernode.service.OrderService;
import com.bjpowernode.service.ShopService;
import com.sun.org.apache.xpath.internal.operations.Or;

public class ShopServiceImpl implements ShopService {
  //使用遠程服務接口
private OrderService orderService; public void setOrderService(OrderService orderService) { this.orderService = orderService; } @Override public Order buyGoods(Integer userId, String goodName, float price, int amount) { System.out.println("buyGoods訪問服務提供的方法"); System.out.println("代理:"+orderService.getClass().getName());       
      
      //調用遠程方法,建立訂單 Order order
= orderService.createOrder(userId,goodName,price,amount); return order; } }

 

E 、 建立 dubbo 配置文件

shop-consume.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://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!--聲明dubbo的服務名稱
       name:dubbo的服務名稱,自定義的字符串,可使用項目的名稱。
           服務的名稱最好是惟一值,dubbo框架內部用來區分服務的。
   -->
    <dubbo:application name="link-main-web" />

    <!--聲明要使用的遠程接口(服務提供者)
      id:dubbo建立的接口的實現類對象的名稱(動態代理)
      interface:遠程的接口全限定名稱(服務提供者中的接口)
      registry:表示是否使用註冊中心, 不使用賦值爲"N/A"
      url:訪問服務提供者的地址,直連方式中,地址是固定的。
        http://localhost:8080/myweb
        dubbo://localhost:20880

   -->
    <dubbo:reference id="remoteOrderService" interface="com.bjpowernode.service.OrderService"
    registry="N/A" url="dubbo://localhost:20880">

    </dubbo:reference>

    <!--聲明自定義的業務對象-->
    <bean id="shopService" class="com.bjpowernode.service.impl.ShopServiceImpl">
        <property name="orderService" ref="remoteOrderService"></property>
    </bean>


</beans>

 

F 、 執行消費者

package com.bjpowernode;

import com.bjpowernode.domain.Order;
import com.bjpowernode.service.ShopService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ConsumeApplication {
    public static void main(String[] args) {
        String config = "main-consume.xml";
        ApplicationContext context = new ClassPathXmlApplicationContext(config);
        ShopService shopService = (ShopService) context.getBean("shopService");
        Order order = shopService.buyGoods(1, "thinkpad", 5999, 1);
        System.out.println(order);
    }
}

 

2.6 dubbo  服務化最佳實踐

2.6.1 分包

  建議將服務接口、服務模型、服務異常等均放在公共包中。

2.6.2  粒度

  服務接口儘量大粒度,每一個服務方法應表明一個功能,而不是某功能的一個步驟,否
則將面臨分佈式事務問題,Dubbo 暫未提供分佈式事務支持。
  服務接口建議以業務場景爲單位劃分,並對相近業務作抽象,防止接口數量爆炸。

不建議使用過於抽象的通用接口,如:Map query(Map),這樣的接口沒有明確語義,會
給後期維護帶來不便。

 

2.6.3 版本

每一個接口都應定義版本號,爲後續不兼容升級提供可能,如: <dubbo:service

interface="com.xxx.XxxService" version="1.0" />。
建議使用兩位版本號,要變動服務版本。先升級一半提供者爲新版本,再將消費者所有
升爲新版本,而後將剩下的一半提供者升爲新版本。

2.7  改造 dubbo 項目

  抽象分散在多個項目中的公共接口,實體類,異常,工具類到一個項目中,在其餘項目
如服務提供者,消費者共用公共的資源。

2.7.1 實現目標

用戶訪問電商網站瀏覽商品—選擇商品購買
用戶訪問電商網站—查看用戶信息(收件人地址)

 

 

 

 

 

2.8 dubbo  經常使用標籤

Dubbo 中經常使用標籤。分爲三個類別:公用標籤,服務提供者標籤,服務消費者標籤

2.8.1 公用標籤

<dubbo:application/><dubbo:registry/>

 

A、配置應用信息

<dubbo:application name=」服務的名稱」/>

B、 、 配置註冊中心

<dubbo:registry address=」ip:port」 protocol=」協議」/>

2.8.2 服務提供者標籤

配置暴露的服務

<dubbo:service interface=」服務接口名」 ref=」服務實現對象 bean」>

2.8.3 服務消費者

配置服務消費者引用遠程服務

<dubbo:reference id=」服務引用 bean 的 id」 interface=」服務接口名」/>
相關文章
相關標籤/搜索