<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    SpringBoot系列之集成Dubbo示例教程

    共 10976字,需瀏覽 22分鐘

     ·

    2020-12-05 23:46

    走過路過不要錯(cuò)過

    點(diǎn)擊藍(lán)字關(guān)注我們


    一、分布式基本理論

    1.1、分布式基本定義

    《分布式系統(tǒng)原理與范型》定義:
    “分布式系統(tǒng)是若干獨(dú)立計(jì)算機(jī)的集合,這些計(jì)算機(jī)對(duì)于用戶來說就像單個(gè)相關(guān)系統(tǒng)”
    分布式系統(tǒng)(distributed system)是建立在網(wǎng)絡(luò)之上的軟件系統(tǒng)。

    1.2 架構(gòu)發(fā)展演變

    架構(gòu)的發(fā)展是由最初的單一應(yīng)用架構(gòu)構(gòu)建的,一般就是ORM框架方便數(shù)據(jù)庫操作。

    不過隨著系統(tǒng)越來越復(fù)雜,單一應(yīng)用架構(gòu)會(huì)變得難以維護(hù),所以架構(gòu)逐漸演變出了垂直應(yīng)用架構(gòu),所謂垂直應(yīng)用架構(gòu)其實(shí)就是安裝業(yè)務(wù)模板進(jìn)行拆分,比如可以安裝業(yè)務(wù)將一個(gè)電商系統(tǒng)分為訂單模塊,用戶信息管理模塊,商品管理模塊等等,這時(shí)候MVC框架就派上用場,MVC框架可以協(xié)助系統(tǒng)更好的按業(yè)務(wù)拆分,不過業(yè)務(wù)拆分后雖然是比單一應(yīng)用架構(gòu)更好維護(hù)了。

    不過隨著系統(tǒng)越來約復(fù)雜,發(fā)現(xiàn)很多共用的模塊很難復(fù)用起來,這時(shí)候分布式服務(wù)架構(gòu)登場了,分布式架構(gòu)是將一些核心業(yè)務(wù)抽取出來,作為獨(dú)立的服務(wù),逐漸形成穩(wěn)定的服務(wù)中心,當(dāng)應(yīng)用需要時(shí),就去服務(wù)中心調(diào)服務(wù)就可以,而實(shí)現(xiàn)這種服務(wù)注冊(cè)的肯定是RPC框架了。

    當(dāng)服務(wù)越來越多,容量的評(píng)估,小服務(wù)資源的浪費(fèi)等問題逐漸顯現(xiàn),此時(shí)需增加一個(gè)調(diào)度中心基于訪問壓力實(shí)時(shí)管理集群容量,提高集群利用率,這時(shí)候就需要流動(dòng)計(jì)算架構(gòu)(SOA)[ Service Oriented Architecture],用于提高機(jī)器利用率的資源調(diào)度,SOA是一個(gè)治理中心,綜上所述,到目前,軟件系統(tǒng)架構(gòu)演變經(jīng)歷了:單一應(yīng)用架構(gòu)->垂直應(yīng)用架構(gòu)->分布式應(yīng)用架構(gòu)->流動(dòng)計(jì)算架構(gòu),下面Dubbo官網(wǎng)的圖片可以很好的描述

    1.3、RPC簡介

    RPC概念
    RPC【Remote Procedure Call】是指遠(yuǎn)程過程調(diào)用,是一種進(jìn)程間通信方式,他是一種技術(shù)的思想,而不是規(guī)范。它允許程序調(diào)用另一個(gè)地址空間(通常是共享網(wǎng)絡(luò)的另一臺(tái)機(jī)器上)的過程或函數(shù),而不用程序員顯式編碼這個(gè)遠(yuǎn)程調(diào)用的細(xì)節(jié)。

    RPC核心模塊
    RPC有兩個(gè)核心模塊:通信和序列化

    二、Dubbo理論簡介

    Apache Dubbo (incubating) |?d?b??| 是一款高性能、輕量級(jí)的開源Java RPC框架,它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯(cuò)和負(fù)載均衡,以及服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)。

    官網(wǎng):
    http://dubbo.apache.org/


    Dubbo的服務(wù)治理:

    Dubbo原理圖片,圖片來自Dubbo官網(wǎng):

    Dubbo角色:

    • Provider:暴露服務(wù)的服務(wù)提供者

    • Container:服務(wù)運(yùn)行的容器

    • Consumer:調(diào)用遠(yuǎn)程服務(wù)的消費(fèi)者

    • Registry:服務(wù)注冊(cè)和發(fā)現(xiàn)的注冊(cè)中心

    • Minitor:統(tǒng)計(jì)服務(wù)調(diào)用次數(shù)和時(shí)間的監(jiān)控中心

    調(diào)用過程:

    下面根據(jù)我的理解說明一下

    • 0:服務(wù)器容器負(fù)責(zé)啟動(dòng)、加載、運(yùn)行服務(wù)提供者

    • 1:服務(wù)提供者在啟動(dòng)后就可以向注冊(cè)中心暴露服務(wù)

    • 2:服務(wù)消費(fèi)者在啟動(dòng)后就可以向注冊(cè)中心訂閱想要的服務(wù)

    • 3:注冊(cè)中心向服務(wù)消費(fèi)者返回服務(wù)調(diào)用列表

    • 4:服務(wù)消費(fèi)者基于軟負(fù)載均衡算法調(diào)用服務(wù)提供者的服務(wù),這個(gè)服務(wù)提供者有可能是一個(gè)服務(wù)提供者列表,調(diào)用那個(gè)服務(wù)提供者就是根據(jù)負(fù)載均衡來調(diào)用了

    • 5:服務(wù)提供者和服務(wù)消費(fèi)者定時(shí)將保存在內(nèi)存中的服務(wù)調(diào)用次數(shù)和服務(wù)調(diào)用時(shí)間推送給監(jiān)控中心

    三、Dubbo環(huán)境搭建

    3.1 Zookeeper搭建

    搭建Zookeeper,首先是搭建分布式架構(gòu)的注冊(cè)中心Zookeeper,當(dāng)然也可以用Redis等等來做服務(wù)注冊(cè)中心,不過本博客只介紹Zookeeper的,因?yàn)闆]有l(wèi)inux服務(wù)器,所以只介紹window版的搭建

    • 1、下載Zookeeper:
      網(wǎng)址?https://archive.apache.org/dist/zookeeper/zookeeper-3.4.13/

    • 2、解壓Zookeeper
      解壓Zookeeper之后,運(yùn)行bin目錄里的zkServer.cmd,發(fā)現(xiàn)報(bào)錯(cuò)了,提示找不到配置文件,所以需要繼續(xù)步驟3

    • 3、配置Zookeeper
      因?yàn)閆ookeeper的conf文件夾下面只提供zoo_sample.cfg文件,需要自己修改命名為zoo.cfg

    對(duì)于配置文件需要注意:

    dataDir=./ 臨時(shí)數(shù)據(jù)存儲(chǔ)的目錄(可寫相對(duì)路徑)

    clientPort=2181 zookeeper的端口號(hào)

    • 4、使用zkCli.cmd測試
      修改配置文件后,重新啟動(dòng)zkServer.cmd,啟動(dòng)bin目錄下面的zkCli.cmd,很顯然這是個(gè)客戶端程序,注意zkServer.cmd是服務(wù)端程序,必須啟動(dòng)

    ok,簡單在zkCli.cmd敲幾個(gè)命令測試一下:
    ls /:列出zookeeper根下保存的所有節(jié)點(diǎn)
    create –e /testNode 12345678:創(chuàng)建一個(gè)testNode節(jié)點(diǎn),值為12345678
    get /testNode:獲取/testNode節(jié)點(diǎn)的值

    3.2 Dubbo管理頁面搭建

    搭建了服務(wù)注冊(cè)中心后,就需要搭建Dubbo-admin了,最近看了一下,dubbo的Github項(xiàng)目已經(jīng)進(jìn)行了更新,管理平臺(tái)已經(jīng)做了比較大的改動(dòng),而我學(xué)習(xí)的時(shí)候,平臺(tái)是比較簡單的,所以本dubbo-admin搭建是以舊版master的為準(zhǔn),不過以學(xué)習(xí)為目的的,只需要知道具體原理和操作技巧就可以

    • 下載dubbo-admin
      去下載一下dubbo-admin,可以找主干master分支的,找到dubbo-admin,git clone到本地
      https://github.com/apache/incubator-dubbo-ops

    因?yàn)槲掖罱〞r(shí)候(ps:不是博客寫作時(shí)間),dubbo還沒做比較大改動(dòng),所以我以比較舊的版本為例子,現(xiàn)在新的具體參考dubbo官方的教程,本博客只是做記錄

    • 修改dubbo-admin

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

    • Maven package dubbo-admin

    mvn clean package -Dmaven.test.skip=true
    • 運(yùn)行dubbo-admin的jar

    maven打包之后,就去target里找到j(luò)ar,然后cmd運(yùn)行

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

    運(yùn)行成功之后,訪問:?http://127.0.0.1:7001,輸入默認(rèn)的賬號(hào)密碼root/root,登錄成功

    四、Dubbo服務(wù)注冊(cè)發(fā)現(xiàn)例子

    經(jīng)典例子(引用尚硅谷教程例子進(jìn)行改寫):

    4.1、業(yè)務(wù)場景

    某個(gè)電商系統(tǒng),訂單服務(wù)需要調(diào)用用戶服務(wù)獲取某個(gè)用戶的所有地址;
    我們現(xiàn)在 需要?jiǎng)?chuàng)建兩個(gè)服務(wù)模塊進(jìn)行測試

    模塊功能
    訂單服務(wù)模塊創(chuàng)建訂單等
    用戶服務(wù)模塊查詢用戶地址等
    • 測試預(yù)期結(jié)果:
      訂單服務(wù)web模塊在A服務(wù)器,用戶服務(wù)模塊在B服務(wù)器,A可以遠(yuǎn)程調(diào)用B的功能

    4.2、api工程創(chuàng)建

    創(chuàng)建工程:
    建議將服務(wù)接口,服務(wù)模型,服務(wù)異常等均放在 API 包中,因?yàn)榉?wù)模型及異常也是 API 的一部分,同時(shí),這樣做也符合分包原則:重用發(fā)布等價(jià)原則(REP),共同重用原則(CRP)。

    創(chuàng)建一個(gè)API工程,將實(shí)體類和接口都放在api工程

    maven新建一個(gè)shop-api-common工程:

    用戶地址DTO類:

    package com.test.dubbo.bean;
    import java.io.Serializable;
    public class UserAddress implements Serializable {

    private Integer id;
    private String userAddress; //用戶地址
    private String userId; //用戶id
    private String consignee; //收貨人
    private String phoneNum; //電話號(hào)碼
    private String isDefault; //是否為默認(rèn)地址 Y-是 N-否

    public UserAddress() {
    super();
    }

    public UserAddress(Integer id, String userAddress, String userId, String consignee, String phoneNum,
    String isDefault) {
    super();
    this.id = id;
    this.userAddress = userAddress;
    this.userId = userId;
    this.consignee = consignee;
    this.phoneNum = phoneNum;
    this.isDefault = isDefault;
    }

    public Integer getId() {
    return id;
    }
    public void setId(Integer id) {
    this.id = id;
    }
    public String getUserAddress() {
    return userAddress;
    }
    public void setUserAddress(String userAddress) {
    this.userAddress = userAddress;
    }
    public String getUserId() {
    return userId;
    }
    public void setUserId(String userId) {
    this.userId = userId;
    }
    public String getConsignee() {
    return consignee;
    }
    public void setConsignee(String consignee) {
    this.consignee = consignee;
    }
    public String getPhoneNum() {
    return phoneNum;
    }
    public void setPhoneNum(String phoneNum) {
    this.phoneNum = phoneNum;
    }
    public String getIsDefault() {
    return isDefault;
    }
    public void setIsDefault(String isDefault) {
    this.isDefault = isDefault;
    }
    }

    用戶信息服務(wù)接口:

    package com.test.dubbo.service;

    import java.util.List;

    import com.test.dubbo.bean.UserAddress;

    /**
    * 用戶服務(wù)
    */

    public interface UserService {

    /**
    * 按照用戶id返回所有的收貨地址
    * @param userId
    * @return
    */

    public List getUserAddressList(String userId);

    }

    訂單信息服務(wù)接口:


    package com.test.dubbo.service;

    import java.util.List;

    import com.test.dubbo.bean.UserAddress;

    public interface OrderService {

    /**
    * 初始化訂單
    * @param userId
    */

    public List initOrder(String userId);

    }


    ok,創(chuàng)建好api工程

    4.3、服務(wù)提供者工程

    要實(shí)現(xiàn)服務(wù)提供,配置文件主要需要配置如下:

    Dubbo提供者加載過程(Dubbo容器的啟動(dòng)):

    Spring加載xml配置之后暴露服務(wù)的過程:

    Exporter方法主要是打開socket的監(jiān)聽,接收客戶的請(qǐng)求

    ok,理解了上面的理論知識(shí)后,繼續(xù)創(chuàng)建一個(gè)user-service-provider工程:
    參考Dubbo官方例子


    2.2.1.RELEASE
    2.7.5
    2.12.0





    org.apache.dubbo
    dubbo-spring-boot-starter
    ${dubbo.version}





    org.apache.dubbo
    dubbo-dependencies-zookeeper
    ${dubbo.version}
    pom


    org.slf4j
    slf4j-log4j12




    我用的Springboot版本是2.2.1,dubbo starter版本是2.7.5,啟動(dòng)之后,發(fā)現(xiàn)報(bào)錯(cuò)

    Caused by: java.lang.: org.apache.curClassNotFoundExceptionator.framework.CuratorFrame

    找不到對(duì)應(yīng)的類,看起來是缺少jar了?通過網(wǎng)上資料搜索再加上如下配置即可:



    org.apache.curator
    curator-framework
    ${curator.version}




    org.apache.curator
    curator-recipes
    ${curator.version}

    curator是Zookeeper配置需要的
    maven配置好之后,就可以進(jìn)行dubbo配置:

    #server.port=7010

    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=20882

    dubbo.monitor.protocol=registry
    #dubbo.scan.base-packages=com.example.springboot.dubbo

    用戶服務(wù)類:

    package com.example.springboot.dubbo.service.impl;

    import com.example.spring.dubbo.bean.UserAddress;
    import com.example.spring.dubbo.service.UserService;
    import org.apache.dubbo.config.annotation.Service;
    import org.springframework.stereotype.Component;

    import java.util.Arrays;
    import java.util.List;


    @Service//暴露服務(wù)
    @Component
    public class UserServiceImpl implements UserService {

    @Override
    public List getUserAddressList(String userId) {

    UserAddress address1 = new UserAddress(1, "北京市昌平區(qū)", "1", "李老師", "010-56253825", "Y");
    UserAddress address2 = new UserAddress(2, "深圳市寶安區(qū)", "1", "王老師", "010-56253825", "N");

    return Arrays.asList(address1,address2);
    }

    }

    Springboot的啟動(dòng)類要加上@EnableDubbo注解:

    package com.example.springboot.dubbo;

    import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;

    /**
    *

    * Springboot啟動(dòng)類
    *

    *
    * @author nicky
    *

    * 修改記錄
    * 修改后版本: 修改人:修改日期: 2020年01月05日 修改內(nèi)容:
    *

    */

    @EnableDubbo(scanBasePackages="com.example.springboot.dubbo.service.impl")
    @SpringBootApplication
    public class UserServiceProviderApplication {

    public static void main(String[] args) {
    SpringApplication.run(UserServiceProviderApplication.class, args);
    }
    }

    啟動(dòng)Springboot類,然后在監(jiān)控平臺(tái)是可以看到服務(wù)注冊(cè)成功的


    查看服務(wù)接口的詳細(xì)信息:

    4.4、服務(wù)消費(fèi)者工程

    然后服務(wù)已經(jīng)注冊(cè)了,現(xiàn)在創(chuàng)建一個(gè)消費(fèi)者工程order-service-comsumer

    • maven加上配置

     
    2.2.1.RELEASE
    2.7.5
    2.12.0





    org.springframework.boot
    spring-boot-starter-web



    org.apache.dubbo
    dubbo-spring-boot-starter
    ${dubbo.version}





    org.apache.dubbo
    dubbo-dependencies-zookeeper
    ${dubbo.version}
    pom


    org.slf4j
    slf4j-log4j12







    org.apache.curator
    curator-framework
    ${curator.version}




    org.apache.curator
    curator-recipes
    ${curator.version}



    com.example.springboot
    shop-api-common
    0.0.1-SNAPSHOT




    • 消費(fèi)者配置文件:

    server.port=8081

    dubbo.application.name=order-service-consumer
    dubbo.registry.address=zookeeper://127.0.0.1:2181
    dubbo.monitor.protocol=registry
    • 訂單服務(wù)類:

    package com.example.springboot.dubbo.service.impl;

    import com.example.spring.dubbo.bean.UserAddress;
    import com.example.spring.dubbo.service.OrderService;
    import com.example.spring.dubbo.service.UserService;
    import org.apache.dubbo.config.annotation.Reference;
    import org.apache.dubbo.config.annotation.Service;

    import java.util.List;

    /**
    *

    * 訂單服務(wù)
    *

    *
    * @author nicky
    *

    * 修改記錄
    * 修改后版本: 修改人:修改日期: 2020年01月05日 修改內(nèi)容:
    *

    */

    @Service
    public class OrderServiceImpl implements OrderService{
    @Reference(loadbalance="random",timeout=1000) //dubbo直連
    UserService userService;

    @Override
    public List initOrder(String userId) {
    //1、查詢用戶的收貨地址
    List addressList = userService.getUserAddressList(userId);
    return addressList;
    }
    }

    • Springboot啟動(dòng)

    package com.example.springboot.dubbo;


    import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;

    /**
    *

    * Springboot啟動(dòng)類
    *

    *
    * @author nicky
    *

    * 修改記錄
    * 修改后版本: 修改人:修改日期: 2020年01月05日 修改內(nèi)容:
    *

    */

    @EnableDubbo(scanBasePackages="com.example.springboot.dubbo.service.impl")
    @SpringBootApplication
    public class OrderServiceProviderApplication {

    public static void main(String[] args) {
    SpringApplication.run(OrderServiceProviderApplication.class, args);
    }
    }

    寫一個(gè)Controller類進(jìn)行測試:

    package com.example.springboot.dubbo.controller;

    import com.example.spring.dubbo.bean.UserAddress;
    import com.example.spring.dubbo.service.OrderService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;

    import java.util.List;



    @Controller
    public class OrderController {

    @Autowired
    OrderService orderService;

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

    }

    在監(jiān)控平臺(tái)看,消費(fèi)者啟動(dòng)也是可以的





    往期精彩推薦



    騰訊、阿里、滴滴后臺(tái)面試題匯總總結(jié) — (含答案)

    面試:史上最全多線程面試題 !

    最新阿里內(nèi)推Java后端面試題

    JVM難學(xué)?那是因?yàn)槟銢]認(rèn)真看完這篇文章


    END


    關(guān)注作者微信公眾號(hào) —《JAVA爛豬皮》


    了解更多java后端架構(gòu)知識(shí)以及最新面試寶典


    你點(diǎn)的每個(gè)好看,我都認(rèn)真當(dāng)成了


    看完本文記得給作者點(diǎn)贊+在看哦~~~大家的支持,是作者源源不斷出文的動(dòng)力


    作者:SmileNicky

    出處:https://www.cnblogs.com/mzq123/p/12153889.html

    瀏覽 39
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評(píng)論
    圖片
    表情
    推薦
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    人人澡人人舔 | 久操伊人网 | 久热最新视频在线观看 | 天天干,夜夜操 | 蜜芽av在线播放 免费成人性爱网站 |