搭載Dubbo+Zookeeper踩了這麼多坑,我終於決定寫下這篇!

語言: CN / TW / HK

大家好,我是melo,一名大二上軟體工程在讀生,經歷了一年的摸滾,現在已經在工作室裡邊準備開發後臺專案啦。

這篇文章我們不談資料結構了,來談談入門分散式踩過的坑。感覺到了分散式這一層,由於技術更新迭代很快,我們似乎很難接觸到第一手材料了(就連官方文件都沒有實時更新,很多不適用)。幾經摸索,看影片,翻文件,找部落格,終於把Dubbo+zookeeper的小demo給成功跑起來了,寫下這篇是因為裡邊有好多的坑,具體我都寫在程式碼的註釋裡邊了,希望可以幫到更多小夥伴,少踩一點坑,專心搞技術!

大型網際網路專案架構目標

衡量網站的效能指標:

響應時間 :指執行一個請求從開始到最後收到響應資料所花費的總體時間。

併發數 :指系統同時能處理的請求數量。

併發連線數 :指的是客戶端向伺服器發起請求,並建立了TCP連線。每秒鐘伺服器連線的總TCP數量

請求數 :也稱為QPS(Query Per Second) 指每秒多少請求.

併發使用者數 :單位時間內有多少使用者

吞吐量 :指單位時間內系統能處理的請求數量。

QPS :Query Per Second 每秒查詢數。

TPS :Transactions Per Second 每秒事務數。

•一個事務是指一個客戶機向伺服器傳送請求然後伺服器做出反應的過程。客戶機在傳送請求時開始計時,收到伺服器響應後結束計時,以此來計算使用的時間和完成的事務個數。

•一個頁面的一次訪問,只會形成一個TPS;但一次頁面請求,可能產生多次對伺服器的請求,就會有多個QPS

叢集和分散式

傳統

  • 叢集: 很多人幹同一件事情

很多臺伺服器,上邊負責同一個模組

  • 分散式 : 很多人幹不同的事情,合起來是一件大事情

很多臺伺服器,上邊負責不同的小模組,最後合成一個大模組

  • 叢集和分散式,往往是同時存在的

高可用性

  • 一個伺服器掛了,不會影響另一個伺服器,可以保證服務一直處於可用狀態

高伸縮性

  • 由於把各個模組儘量抽離開了,降低了彼此之前的耦合關係,所以比如要給E模組加多幾個,可用直接加不會影響其他模組

高可擴充套件性

  • 類似開閉原則,因為耦合度不高,所以擴充套件起來不是很難

架構演變

假設專案由 ABCD基礎模組組成 E是公共模組

單體架構

  • 一個伺服器上,放著一整個專案 ABCDE

垂直架構

  • 把專案拆成 獨立(互相沒有關聯) 的兩個模組 如 AB CD , 此時的E呢,因為兩個伺服器沒有關聯,所以E就不得不部署多次.即 ABE CDE 兩臺伺服器

缺點

  • 公共模組在每個伺服器上都需要用到

分散式架構

  • 垂直架構看起來已經是 不同伺服器幹不同的事情了, 不過還有一個公共模組E,在兩個伺服器中都出現過,我們要優化的話,可以 多加一臺伺服器 ,單獨放E

遠端呼叫E(RPC)

  • 用到 HTTP REST風格等(Dubbo都幫我們封裝好了)

缺點

  • E一但發生了改變,所有呼叫他的地方都需要去改變

SOA架構

沒有什麼是再多加一層解決不了的,加一箇中間商ESB

微服務架構(待深入)

Dubbo的架構

節點角色說明:

Provider 暴露服務的服務提供方

Container :服務執行容器

Consumer :呼叫遠端服務的服務消費方

Registry :服務註冊與發現的註冊中心

Monitor :統計服務的呼叫次數和呼叫時間的監控中心

快速入門

Zookeeper下載

官網: https://zookeeper.apache.org/releases.html

我選擇的是這個版本,帶有bin目錄的

Windows

  1. 直接解壓出來
  2. 將conf目錄下的zoo_sample.cfg複製一份,改名為zoo.cfg(因為預設配置檔案是這個名字)
  3. 然後退回安裝目錄,新建一個空的data 和 log

4 . 進入conf中修改zoo.cfg配置檔案,將dataDir=/tmp/zookeeper 修改成 zookeeper 安裝目錄所在的 data 資料夾,再新增一條新增資料日誌的配置(需要根據自己的安裝路徑修改)。

5 . 雙擊 bin目錄下的 zkServer.cmd 啟動程式:

6 . 控制檯顯示 bind to port 0.0.0.0/0.0.0.0:2181 ,表示服務端啟動成功!

7 . 雙擊同目錄下的zkCli.cmd 啟動客戶端

出現 Welcome to Zookeeper!,表示我們成功啟動客戶端。

注意

當需要一直啟動zookeeper時,這兩個cmd不能關掉不能關掉不能關掉!!!!!!!要保持執行

Linux

tar-zxvf (你下載的壓縮包名稱)

cd(你的安裝目錄)

cdconf/

cpzoo_sample.cfg zoo.cfg

vimzoo.cfg

此處需要按照上邊一樣修改,注意需要根據自己的安裝路徑修改 , 同樣也得建立data和log,修改埠等​

cd..

cdbin/

shzkServer.sh start

shzkCli.sh

  • 如果下載的版本不一樣,可能需要自行檢視一下幫助命令

詳細配置(SpringBoot)

多模組開發

此處其實用到了三個模組,一個是公共介面模組,一個是provider模組,一個是consumer模組

其中後兩個都共同去依賴公共模組

而provider又依賴consumer模組

想要完整原始碼的話可以評論區聯絡一下博主

特別注意

我們兩個模組都要去@import com.example.dubbo_interface.service.StuService;

  • 那這裡就意味著什麼,別的專案得能找到這個包啊,要怎麼把公共介面dubbo_interface裡邊的包暴露出來,可供別人呼叫呢,這裡是用到了maven的install命令,把dubbo_interface這一模組打包到公共倉庫去了,這樣別的專案就可以引用裡邊的內容了!

如果對maven這一塊還不太熟悉的話,具體可以參照這篇 maven(先給自己挖個坑,整理好了會發出來的)

以下一切配置都完成了之後,記得先開啟zookeeper!開啟zookeeper!開啟zookeeper!

provider提供服務端

yml檔案

dubbo:
  application:
    #配置應用的名稱(應用可以是提供者也可以是消費者)
    name: dubbo_service
  #協議中心
  protocol:
    #固定的, 是隻有provider才需要嗎?
    name: dubbo
    port: 20882
  #指定註冊中心的位置,127.0.0.1是ip地址,2181是埠號
  registry:
    address: zookeeper://127.0.0.1:2181
    ######這裡是關鍵,很多教程沒有配置,導致zookeeper連線不上
    timeout: 50000
  #要暴露的服務所在的包(配置掃包)
  #也可以在註解那裡掃包
#  scan:
#    base-packages: com.example.dubbo_service.service

#指定該專案模組啟動的埠,不可與其他專案埠重複
server:
  port: 8081

具體Service服務端

package com.example.dubbo_service.service;

import com.example.dubbo_interface.service.StuService;
import org.apache.dubbo.config.annotation.DubboService;

//暴露服務
@DubboService
public class StuServiceImpl implements StuService {

    @Override
    public String login() {
        return "111";
    }
}

引入Dubbo依賴和控制zookeeper的客戶端

這裡使用的是2.7.8版本,搭配2.5.5版本的Springboot

注意依賴介面模組

<!--依賴介面專案-->
<dependency>
   <groupId>com.example</groupId>
   <artifactId>dubbo_interface</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Dubbo Spring Boot Starter -->
		<dependency>
			<groupId>org.apache.dubbo</groupId>
			<artifactId>dubbo-spring-boot-starter</artifactId>
			<version>2.7.8</version>
		</dependency>
		<!--curator依賴-->
		<!--Curator提供了一套Java類庫, 可以更容易的使用ZooKeeper。 -->
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-recipes</artifactId>
			<version>5.1.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
			<version>5.1.0</version>
		</dependency>

啟動類

@EnableDubbo註解一般寫在啟動類上,預設會掃描當前註解所在類的包路徑下的所有 @Dubboservice 標註的元件,如果需要自定義掃描註冊的bean(服務實現),可以使用@DubboComponentScan或掃描屬性實現。另外,@EnableDubbo註解等效於在配置檔案中使用dubbo.scan.base-packages一步到位(開啟dubbo功能+掃描dubbo的服務實現bean)

package com.example.dubbo_service;

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

//開啟基於註解的Dubbo功能,同時掃描要暴露的服務端所在的位置
@EnableDubbo(scanBasePackages = "com.example.dubbo_service.service")
@SpringBootApplication
public class DubboServiceApplication {

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

}

consumer消費者端

注意,其不同於傳統的service,這裡為了能獨立啟動,也要設定成web專案那種(再借助Springboot啟動)

yml檔案

dubbo:
  application:
    #指定當前服務/應用的名字(同樣的服務名字相同,不要和別的服務同名)
    name: dubbo_controller
  ## consumer不需要這個通訊協議,因為consumer無需通過Dubbo來遠端呼叫
  #  protocol:
  #     name: dubbo
  ##    port: 20881
  #指定註冊中心的位置,127.0.0.1是ip地址,2181是埠號
  registry:
    address: zookeeper://127.0.0.1:2181
    ######這裡是關鍵,很多教程沒有配置,導致zookeeper連線不上
    timeout: 50000
  ##發現按照官網只配consumer的話,也還是連不到zookeeper的
  consumer:
    ##後來發現這裡就等效於DubboReference註解那裡的timeout設定
    timeout: 3000
  ##此處是用在暴露掃包的,consumer不需要暴露服務
#  scan:
#    base-packages: com.example.dubbo_service.service

#指定該專案模組啟動的埠,不可與其他專案埠重複
server:
  port: 8082

具體Controller消費者端

package com.example.dubbo_controller.controller;

import com.example.dubbo_interface.service.StuService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/stu")
public class StuController {

    /**
     * 遠端注入
     * 從zookeeper註冊中心獲取該service的訪問url
     * 進行遠端呼叫RPC
     * 將結果封裝成一個代理物件,給變數賦值
     */
    //沒timeout好像就出問題了??連不上??
    //也可以在yml裡邊的consumer的timeout進行配置
    @DubboReference/*(timeout = 5000)*/
    StuService stuService;

    @RequestMapping("/login")
    public String login(){
        return stuService.login();
    }
}

同上引入依賴

<!--依賴介面專案-->
<dependency>
   <groupId>com.example</groupId>
   <artifactId>dubbo_interface</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Dubbo Spring Boot Starter -->
		<dependency>
			<groupId>org.apache.dubbo</groupId>
			<artifactId>dubbo-spring-boot-starter</artifactId>
			<version>2.7.8</version>
		</dependency>
		<!--curator依賴-->
		<!--Curator提供了一套Java類庫, 可以更容易的使用ZooKeeper。 -->
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-recipes</artifactId>
			<version>5.1.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
			<version>5.1.0</version>
		</dependency>

啟動類

package com.example.dubbo_controller;

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

//開啟基於Dubbo的註解
@EnableDubbo
@SpringBootApplication
public class DubboControllerApplication {

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

公共介面

因為provider和consumer兩個模組都會需要用到這個介面,所以不如抽取出來作為公共的介面

package com.example.dubbo_interface.service;

//公共介面
public interface StuService {
    String login();
}

Dubbo-admin

人生建議: 直接用老版本的前後端未分離,直接可以一鍵啟動使用,埠預設在本機的7001

關於老版本的dubbo-admin我是直接用的尚矽谷教程裡邊的的尚矽谷的檔案裡邊應該會有,如果找不著的話也可以評論留言一下

修改application.properties

server.port

該專案要啟動的埠

registry.address

要監測的註冊中心的地址

啟動之前要先啟動zookeeper!!!(如何啟動參照上邊zookeeper安裝)

訪問localhost:埠號

預設使用者名稱和密碼都是root

最終效果

先開著zookeeper,如何啟動service模組,再啟動controller模組,最後啟動dubbo-admin專案

可以看到有一個服務數,兩個應用數,一個是提供者,一個是消費者

服務是我們的介面模組

提供者

消費者

訪問我們的介面

完整工程程式碼

  • 這裡三個模組的互相依賴關係pom檔案,基於個人專案名稱不同而有所不同,若對於 pom檔案和依賴關係 還有點迷惑的小夥伴們歡迎評論區微信交流

寫在最後

  • 分散式這一塊還是剛剛入門,原理方面希望也能多瞭解瞭解,希望接下來還能繼續堅持下去,多多補充這一塊的知識。關於Dubbo的一些高階特性,以及zookeeper的具體學習,過段時間再來補充!(flag瘋狂立起來了)

PPT來源

  • 黑馬Dubbo教程
  • dubbo-admin檔案來源: 尚矽谷