Dubbo 入門-細說分散式與集群

来源:https://www.cnblogs.com/yangyuanhu/archive/2020/03/07/12439106.html
-Advertisement-
Play Games

什麼是Dubbo Dubbo是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向介面的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現。 什麼是RPC RPC全稱(Remote Procedure Call)遠程過程調用 過程指的是某個代碼片段的執行,遠程調用則意味著我 ...


什麼是Dubbo

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

什麼是RPC

RPC全稱(Remote Procedure Call)遠程過程調用

過程指的是某個代碼片段的執行,遠程調用則意味著我們可以在其他進程,甚至其他機器上去調用這段代碼,當然也能獲取到其執行後的返回值,按照這個定義,我們請求某個http地址得到相應數據其實也算一次RPC,但是這樣的方式太過麻煩,(數據要先打包成http請求格式,在調用相關的請求庫,拿到的結果也是文本格式的需要在進行轉換),執行效率,和開發效率相比RPC則低一些;

我們需要一種更簡單的方式來完成分散式開發中的RPC環節,這也是Dubbo的核心所在,有多簡單呢? 調用遠程伺服器上的某個服務時就像是調用本地的某個方法一樣簡單,就像下麵這樣

為什麼需要rpc

RPC是用來實現分散式構架的基石,分散式構架將同一個系統中的不同模塊拆分到不同的子系統中,而子系統又分佈在不同的伺服器上,這時就需要RPC在來完成子系統之間的相互訪問;

可以這麼說分散式少不了RPC,RPC也要在分散式系統中才能發揮其核心價值;

rpc的實現原理

毫無以為底層肯定是要通過socket來進行網路通訊的,但是如何能夠直接調用另一個機器上的方法呢?

服務消費方(client)調用以本地調用方式調用服務;

2)client stub接收到調用後負責將方法、參數等組裝成能夠進行網路傳輸的消息體;

3)client stub找到服務地址,並將消息發送到服務端;

4)server stub收到消息後進行解碼;

5)server stub根據解碼結果調用本地的服務;

6)本地服務執行並將結果返回給server stub;

7)server stub將返回結果打包成消息併發送至消費方;

8)client stub接收到消息,併進行解碼;

9)服務消費方得到最終結果。

當然傳遞的參數或返回值是某個Java對象時則還需要對其進行序列化與反序列化

分散式與集群

集群:

集群構架是將相同的處理邏輯進行複製(複製一份源代碼),創建出一組具備相同功能的服務集合,集群中每個服務都能夠獨立的完成用戶的請求,它們之間基本上不需要互相通訊,也就用不上RPC了;

分散式:

分散式指的是將一個系統拆分為多個獨立的子系統,部署在不同的機器上;

在處理任務時會將一個任務拆分成若幹子任務,分發給不同的子系統處理,每個子系統僅能處理一部分任務,通常一個完整的任務包含多個處理步驟,例如用戶要購買某個商品,需要先創建訂單,然後修改庫存,假設修改庫存的服務由另一個伺服器提供這時候RPC就閃亮登場了;

可以發現分散式與集群在底層構架上完全不同,所以要將一個原本集群的系統重構為分散式的話,則需要大量的修改,所以若系統後期存在高併發的需求,則可以在項目初期就採用分散式構架來搭建;

分散式是必要的嗎?

分散式的優缺點:

  • 可將原本串列的任務變為並行執行(沒有前後依賴),提高計算速度
  • 提高可用性,由於系統分佈在不同的計算節點上,其中某個節點失效不會對整個系統產生太大的影響
  • 各個子系統獨立運行,極大的降低了系統的耦合度,使得各個子系統的擴展性和可業務功能的維護性提高
  • 因為模塊化,所以系統模塊重用度更高(系統級別)
  • 技術開放,多樣化,完全可以使用其他語言,其他平臺來開發某個子系統
  • 更有效的利用硬體資源

缺點:

  • 因為需要走RPC,響應時間變長

  • 系統構架更加複雜,運維工作麻煩

  • 需要進行服務管理和調度
  • 測試和調試更複雜
  • 公共模塊無法復用(代碼級別)

需要強調的是:分散式和集群並不是只能二選一,在高併發下場景下還可以給壓力大的節點組建集群;
分散式與微服務:

分散式系統是多個處理機通過通信線路互聯而構成的鬆散耦合的系統,是一個更寬泛的概念;

微服務從結構上來看也屬於分散式,微服務強調的是將某個功能完完全全的獨立出來,徹底的解開耦合;

RPC和微服務才算是同一級別的東西,即實現分散式可以使用rpc也可以使用微服務;

系統構架演進:

image

SOA是解決海量併發訪問的終極解決方案,無論是採用RPC還是微服務

為什麼需要Dubbo:

引用官方原話:

在大規模服務化之前,應用可能只是通過 RMI 或 Hessian 等工具,簡單的暴露和引用遠程服務,通過配置服務的URL地址進行調用,通過 F5 等硬體進行負載均衡。

當服務越來越多時,服務 URL 配置管理變得非常困難,F5 硬體負載均衡器的單點壓力也越來越大。此時需要一個服務註冊中心,動態地註冊和發現服務,使服務的位置透明。並通過在消費方獲取服務提供方地址列表,實現軟負載均衡和 Failover,降低對 F5 硬體負載均衡器的依賴,也能減少部分成本。

當進一步發展,服務間依賴關係變得錯蹤複雜,甚至分不清哪個應用要在哪個應用之前啟動,架構師都不能完整的描述應用的架構關係。 這時,需要自動畫出應用間的依賴關係圖,以幫助架構師理清關係。

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

簡單的說,Dubbo不僅僅是實現了RPC,同時提供了整套分散式服務的管理方案; 包括

  • 服務註冊與發現

  • 負載均衡
  • 流量調度
  • 提供可視化的服務治理工具,和運維工具

構架及服務調用流程

dubbo-architucture
舉例

角色:

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

調用過程:

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

hello Dubbo

1.創建鋪Maven工程DubboDemo

2.在當前工程下創建provider模塊

3.為provider添加依賴

 <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.13</version>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.11</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.32.Final</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.8.0</version>
        </dependency>

4.dubbo發佈服務的單位是介面,所以我們需要創建一個服務介面,在消費端也需要同樣的介面來產生代理對象,為了抽取公共部分代碼,可以新建一個模塊然後讓提供方和消費方依賴這個項目從而找到需要的介面

在公共模塊中創建介面:

package com.yyh.service;

public interface HelloService {
    String helloMan(String name);
}

​ 在pom中和依賴剛纔新建的項目

<dependency>
  <groupId>org.example</groupId>
  <artifactId>hello_Interface</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

5.在provider中創建實現類

package com.yyh.service.impl;

import com.yyh.service.HelloService;

public class HelloServiceImpl implements HelloService {
    public String helloMan(String name) {
        return "hello: "+name;
    }
}

6.編寫提供方配置文件

<?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="hello-service">
      <dubbo:parameter key="qos.enable" value="true"/>
    </dubbo:application>
    <!--dubbo這個服務所要暴露的服務地址所對應的註冊中心-->
    <dubbo:registry address="N/A"/>
    <!--當前服務發佈所依賴的協議;webserovice、Thrift、Hessain、http-->
    <dubbo:protocol name="dubbo" port="20880"/>
    <!--服務發佈的配置,需要暴露的服務介面-->
    <dubbo:service interface="com.yyh.service.HelloService" ref="helloService"/>
    <!--Bean bean定義-->
    <bean id="helloService" class="com.yyh.service.impl.HelloServiceImpl"/>
</beans>

7.啟動服務

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class Runner {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:provider.xml");
        context.start();
        System.out.println("send anyket to exit");
        System.in.read();
    }
}

8.為了方便調試我們可以提供一個日誌配置在資源目錄下名為log4j.properties

log4j.rootLogger=info,console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout 
log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r]-[%p] %m%n

9.創建消費端模塊

在pom中引入同樣的依賴

10.創建配置文件consumer.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:application name="hello-consumer"/>
    <!--註冊中心        -->
    <dubbo:registry address="N/A"/>
    <!--創建一個代理對象到容器中    -->
    <dubbo:reference id="helloService" interface="com.yyh.service.HelloService"
                     url="dubbo://192.168.2.5:20880/com.yyh.service.HelloService"/>

</beans>

11.運行測試:

import com.yyh.service.HelloService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Runner {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:consumer.xml");
        HelloService helloService = (HelloService) context.getBean("helloService");
        String jerry = helloService.helloMan("jerry");
        System.out.println(jerry);
    }
}

若輸出hello jerry則表示調用服務成功了;


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 鷹眼插件 AMap.OverView 預設在地圖右下角顯示縮略圖 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>map</title> <script type="text/javascript" src= ...
  • 開始 今天和大家聊聊AOP:面向切麵編程思想。開始聊之前,先和大家一起從編程思想的發展說起。 編程思想的發展歷程: 1、POP編程 首先,大家應該都知道,什麼是POP編程吧,就是面向過程編程。關於這個編程思想就不做介紹了。 從思維上來講,面向過程更強調細節,忽視了整體性和邊界性。 典型代表是 C/C ...
  • 基礎準備: 8種基本數據類型包括4種整型,2種浮點型,1個字元型,1個布爾型 暫且稱呼為:(4211) 4種整型: byte short int long 2種浮點型:float double 1種字元型:char 1種布爾型:boolean 詳細分析: 基本數據類型和引用數據類型的區別: 基本數據 ...
  • 目的: 寂寞的夜晚總需要精神依托,用Python滋潤疲憊的身心!!! 效果: 實現類 1 from Common import Common 2 import requests 3 4 class Get_mn(Common): 5 """ 6 title:Python爬取成人網站圖片Demo 7 ...
  • 基於S2SH開發房屋租賃管理系統(前臺+後臺)開發環境: Windows操作系統開發工具:Myeclipse+Jdk+Tomcat+MYSQL資料庫運行效果圖 源碼及原文鏈接:https://javadao.xyz/forum.php?mod=viewthread&tid=102 ...
  • 基於S2SH開髮網上蛋糕店(甜品)購物商城系統(前臺+後臺) 開發環境: Windows操作系統開發工具:eclipse+Jdk1.8+Tomcat8+MySQL資料庫註意:請使用JDK1.8 Tomcat8版本運行運行效果圖 源碼及原文鏈接:https://javadao.xyz/forum.ph ...
  • 第一步:引入庫 import time import base64 import rsa import binascii import requests import re from PIL import Image import random from urllib.parse import qu ...
  • 前面知道NumPy是 Python 語言的一個擴展程式庫,支持大量的維度數組與矩陣運算,也針對數組運算提供大量的數學函數庫。numpy是基於c語言開發,所以這使得numpy的運行速度很快,高效率運行就是numpy的一大優勢。但numpy的特長並不是在於數據處理,而是在於能非常方便地實現科學計算,所以 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...