Dubbo使用入門

一、SOA和RPC介紹

1、SOA

隨着互聯網的發展,應用規模不斷擴大,應用之間的交互不可避免,這時將核心業務抽取出來,作爲獨立的服務,用於提高業務複用及整合,逐漸形成了分佈式服務架構。

當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實時管理集羣容量,提高集羣利用率。此時,用於提高機器利用率的資源調度和治理中心(SOA)[ Service Oriented Architecture]是關鍵。

2、RPC

RPC【Remote Procedure Call】是指遠程過程調用,是一種進程間通信方式,他是一種技術的思想,而不是規範。它允許程序調用另一個地址空間(通常是共享網絡的另一臺機器上)的過程或函數,而不用程序員顯式編碼這個遠程調用的細節。即程序員無論是調用本地的還是遠程的函數,本質上編寫的調用代碼基本相同。

RPC兩個核心模塊,通訊和序列化。
序列化要求傳輸的消息(參數和返回值)必須實現java.io.Serializable接口。

二、dubbo核心概念

1、簡介

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

官網:http://dubbo.apache.org/

2、基本概念

服務提供者(Provider):暴露服務的服務提供方,服務提供者在啓動時,向註冊中心註冊自己提供的服務。

服務消費者(Consumer): 調用遠程服務的服務消費方,服務消費者在啓動時,向註冊中心訂閱自己所需的服務,服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。

註冊中心(Registry):註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者

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

調用關係說明:

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

三、dubbo環境搭建

1、安裝zookeeper【linux】

1.1、安裝zookeeper

① 下載zookeeper

網址 https://archive.apache.org/dist/zookeeper/zookeeper-3.6.1/

② 解壓

③ 移動到指定位置

1.2、配置zookeeper

① 初始化zookeeper配置文件

拷貝/usr/local/zookeeper/conf/zoo_sample.cfg ,到同一個目錄下改個名字叫zoo.cfg

② 啓動zookeeper

2、安裝dubbo-admin管理控制檯【linux】

dubbo本身並不是一個服務軟件。它其實就是一個jar包能夠幫你的java程序連接到zookeeper,並利用zookeeper消費、提供服務。所以你不用在Linux上啓動什麼dubbo服務。

但是爲了讓用戶更好的管理監控衆多的dubbo服務,官方提供了一個可視化的監控程序,不過這個監控即使不裝也不影響使用。

2.1、下載dubbo-admin

git clone https://github.com/apache/dubbo-admin/tree/master

2.2、修改dubbo-admin配置

修改 src\main\resources\application.properties 指定zookeeper地址

2.3、打包dubbo-admin

mvn clean package -Dmaven.test.skip=true

2.4、運行dubbo-admin

java -jar dubbo-admin-0.0.1-SNAPSHOT.jar

在瀏覽器輸入地址: http://localhost:7001/

默認用戶名:root

默認密碼:root

四、dubbo-helloworld

1、提出需求

某個電商系統,訂單服務需要調用用戶服務獲取某個用戶的所有地址;

我們現在需要創建兩個服務模塊進行測試

[公式]

測試預期結果:

​ 訂單服務web模塊在A服務器,用戶服務模塊在B服務器,A可以遠程調用B的功能。

2、工程架構圖

3、創建模塊

3.1、gmall-interface:公共接口層(model,service,exception…)

① bean模型:

注意實現 java.io.Serializable 接口
public class UserAddress implements Serializable {
    private Integer id;
    private String userAddress;
    private String userId;
    private String consignee;
    private String phoneNum;
    private String isDefault;
}

② service接口:cn.edu.nju.gmall.service.UserService.getUserAddressList(String userId);

3.2、boot-user-service-provider:用戶模塊(對用戶接口的實現)

① pom.xml中導入gmall-interface依賴

        <dependency>
            <groupId>cn.edu.nju</groupId>
            <artifactId>gmall-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>

② 實現接口

public class UserServiceImpl implements UserService {
    public List<UserAddress> getUserAddressList(String userId) {
        UserAddress address1 = new UserAddress(1, "beijing", "1", "li", "888", "Y");
        UserAddress address2 = new UserAddress(2, "hangzhou", "1", "wang", "666", "N");
        return Arrays.asList(address1, address2);
    }
}

3.4、boot-order-service-consumer:訂單模塊(調用用戶模塊)

① pom.xml中導入gmall-interface依賴

<dependency>
            <groupId>cn.edu.nju</groupId>
            <artifactId>gmall-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>

② 調用接口

public class OrderServiceImpl implements OrderService {
    
    UserService userService;

    public List<UserAddress> initOrder(String userId) {
        System.out.println("userId = " + userId);
        return userService.getUserAddressList(userId);
    }
}

現在這樣是無法進行調用的。我們在boot-order-service-consumer引入了gmall-interface,但是interface的實現是boot-user-service-provider,我們並沒有引入,而且實際他可能還在別的服務器中。

4、使用dubbo改造

4.1、改造boot-user-service-provider作爲服務提供者

① 導入pom依賴

        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

② 編寫application.properties配置文件

dubbo.application.name=user-service-provider

dubbo.registry.address=127.0.0.1:2181
dubbo.registry.protocol=zookeeper

dubbo.protocol.name=dubbo
dubbo.protocol.port=20880

dubbo.monitor.protocol=registry

③ 添加註解

在接口實現類上添加註解

@Service    // com.alibaba.dubbo.config.annotation.Service,注意和spring的@Service區分
@Component  // 添加到Spring容器中
public class UserServiceImpl implements UserService {

在SpringBoot啓動類上添加註解

@EnableDubbo // 啓動dubbo服務
@SpringBootApplication
public class BootUserServiceProviderApplication {

4.2、改造boot-order-service-consumer作爲服務消費者

① 導入pom依賴

         <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

② 編寫application.properties配置文件

# 端口不要和tomcat衝突
server.port=8081

dubbo.application.name=order-service-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.monitor.protocol=registry

③ 添加註解

在使用接口時添加註解

@Service // 添加到Spring容器
public class OrderServiceImpl implements OrderService {

    @Reference // 使用dubbo提供的reference註解引用遠程服務
    UserService userService;

在SpringBoot啓動類上添加註解

@EnableDubbo // 啓動dubbo服務
@SpringBootApplication
public class BootUserServiceProviderApplication {

4.3、測試調用

寫一個controller用於測試

@Controller
public class OrderController {

    @Autowired
    OrderService orderService;

    @ResponseBody
    @RequestMapping("/initOrder")
    public List<UserAddress> initOrder(@RequestParam("uid") String userId) {
        return orderService.initOrder(userId);
    }
}

啓動boot-user-service-provider和boot-order-service-consumer,在dubbo-admin會看到相應服務和應用:

訪問boot-order-service-consumer的initOrder請求,會調用UserService獲取用戶地址

調用成功。說明我們order已經可以調用遠程的UserService了。

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