當前位置: 妍妍網 > 碼農

Keepalived+Mysql實作高可用配置總結

2024-01-29碼農

關註上方 浩道Linux ,回復 資料 ,即可獲取海量 L inux Python 網路通訊、網路安全 等學習資料!

前言

大家好,這裏是 浩道Linux ,主要給大家分享 L inux P ython 網路通訊、網路安全等 相關的IT知識平台。

最近浩道的一位讀者咨詢我Keepalived+Mysql實作高可用相關的配置,他所用的環境是在Docker環境下進行的。而我為了尋找他相關問題,自己也在虛擬機器中搭建了一套環境進行驗證。原理都差不多,我這裏主要是跟大家捋一捋Keepalived這個知識點相關的一些概念總結,以及Keepalived配置過程中存在的一些坑。全文較長,但是實用性很高,大家感興趣,可以收藏,以便隨時檢視學習。

透過本文,大家將學習到以下相關知識內容:

1、什麽是高可用服務

2、Keepalived簡介

3、Keepalived常見套用場景

4、 Keepalived高可用故障切換原理介紹

5、 VRRP協定介紹

6、配置實作Keepalived監控Mysql

7、 Keepalived配置檔介紹

8、 Keepalived常見問題列舉

一、什麽是高可用服務

高可用服務 是指伺服器系統保持正常工作的能力和穩定性,即無論在何種條件下,伺服器都能夠始終保持正常執行,並且不會中斷或崩潰。高可用服務的目標是保證業務的連續性,提高使用者體驗,以及提升企業形象。

高可用服務的實作需要硬體和軟體兩個方面的支持。硬體方面,可以透過冗余設計來避免單點故障,例如雙電源、雙網卡、多RAID陣列等技術。軟體方面,可以使用負載均衡、熱備份、冷備份等技術。

此外,數據同步也是高可用服務的關鍵技術之一,透過將不同伺服器中的數據即時同步到其他伺服器上,可以保證數據的一致性和完整性。系統監控也是保證高可用服務的重要手段,可以即時監測系統的執行狀態和資源使用情況,及時發現異常情況並采取相應的措施。

為了提高伺服器的穩定性和可靠性,可以采取一些措施,例如對硬體進行冗余配置、合理規劃服務架構、及時備份和還原伺服器數據等。

二、Keepalived簡介

Keepalived(保持線上) 誕生的開始是為LVS負載均衡軟體設計的,用來管理並且監控LVS集群系統中各個服務節點的狀態。隨著後面新增加入可以實作高可用的VRRP功能。讓它除了能夠管理LVS負載均衡外,還可以作為其它服務(如Haproxy,Nginx,Mysql等)的高可用解決方案軟體。

Keepalived在基於VRRP協定實作的LVS服務高可用方案中,它透過檢測伺服器的狀態來避免單點故障的發生。一個LVS服務可能會有2台伺服器執行Keepalived,一台為主機伺服器(MASTER),一台為備份伺服器(BACKUP),但是對外表現為一個虛擬IP,主伺服器會發送特定的訊息給備份伺服器,當備份伺服器收不到這個訊息的時候,即主伺服器宕機的時候,備份伺服器就會接管虛擬IP,繼續提供服務,從而保證了高可用性。

Keepalived的作用是檢測伺服器的狀態,如果有一台web伺服器當機,或工作出現故障,Keepalived將檢測到,並將有故障的伺服器從系統中剝除, 同時使用其他伺服器代替該伺服器的工作,當伺服器工作正常後Keepalived自動將伺服器加入到伺服器群中。

(一)Keepalived行程

Keepalived啟動後會有三個行程,分別為:

1、父行程: 記憶體管理,對其它子行程管理

2、 子行程: VRRP子行程,實作vrrp協定

3、子行程: healthchecker子行程,實作健康檢查,檢測服務狀態;如果服務不可用,則通知vrrp子行程,發降級通告。

兩個子行程都被系統WatchDog看管,兩個子行程各自負責自己的事,healthchecker子行程負責檢查各自伺服器的健康程度,例如HTTP,如果healthchecker子行程檢查到MASTER上服務不可用了,就會通知本機上的VRRP子行程,讓他刪除通告,並且去掉虛擬IP,轉換為BACKUP狀態。

(二)Keepalived模組化設計

Keepalived采用模組化設計,主要包括下面五個模組:

1、core:核心模組,負責主行程的啟動和維護,全域配置檔的載入解析等;

2、check:檢查模組,負責healthchecker;

3、vrrp:vrrp模組,負責實作vrrp協定;

4、libipfwc:iptables庫,在LVS會用到;

5、libipvs:配置LVS會用到;

三、 Keepalived常見套用場景

(一)Web伺服器高可用: Keepalived可以與Web伺服器軟體如Nginx或HAProxy配合使用,以實作Web服務的高可用性。當Web伺服器出現故障時,Keepalived可以自動將請求切換到備用伺服器,從而保證服務的連續性和穩定性。

(二)資料庫服務高可用: 資料庫服務是非常重要的後端服務之一,Keepalived可以與資料庫軟體如MySQL配合使用,實作資料庫服務的高可用性。當主資料庫出現故障時,Keepalived可以自動將請求切換到備用資料庫,保證服務的連續性和穩定性。

(三)信件伺服器高可用: 信件伺服器是常見的後端服務之一,Keepalived可以與信件伺服器軟體如Postfix或Sendmail配合使用,實作信件服務的高可用性。當信件伺服器出現故障時,Keepalived可以自動將請求切換到備用伺服器,保證服務的連續性和穩定性。

(四)檔伺服器高可用: 檔伺服器是常見的後端服務之一,Keepalived可以與檔伺服器軟體如NFS配合使用,實作檔服務的高可用性。當檔伺服器出現故障時,Keepalived可以自動將請求切換到備用伺服器,保證服務的連續性和穩定性。

(五)雲服務平台的高可用: 在雲服務平台中,Keepalived可以與雲服務提供商的負載均衡器或其他高可用解決方案配合使用,實作雲服務的高可用性。這樣可以保證雲服務的連續性和穩定性,提高使用者的體驗和滿意度。

總之,Keepalived服務常見的套用場景主要涉及Web伺服器、資料庫、信件伺服器、檔伺服器以及雲服務平台等。這些場景都可以透過Keepalived來實作服務的高可用性和負載均衡,從而保證服務的連續性和穩定性。

四、 Keepalived高可用故障切換原理介紹

Keepalived高可用服務之間的故障切換原理是基於VRRP實作的,Keepalived服務正常時,主Master節點會不斷地向備節點發送心跳報文(組播形式),以此來告訴備節點自己還存活著。當主Master節點發生故障時,就無法發送心跳報文了,此時備節點也無法繼續檢測到來自主Master節點的心跳報文,於是呼叫自身來接管程式,接管主Master節點的IP資源及相關服務,以此來保證業務的連續性,一般接管速度可以小於1秒鐘。而當主Master節點恢復服務時,備節點又將會釋放主節點故障時自身接管的IP資源及相關服務,恢復到原來的備用節點模式。

五、 VRRP協定介紹

VRRP Virtual Router Redundancy Protoco l 的縮寫,中文名為 虛擬路由器冗余協定。

(一)VRRP出現背景

現實的區域網路中,通常采用配置一個預設閘道器的形式讓使用者存取外部網路,但是如果預設閘道器裝置發生故障,那麽所有使用者終端將無法存取外部網路,即出現單點故障了。

此時工程師們就想到了透過部署多個閘道器的方式來解決單點故障,但是多個閘道器之間是會存在沖突問題。因此就出現了VRRP協定。

VRRP的出現既能實作閘道器的備份,又能解決多個閘道器之間互相沖突的問題,從而提升網路的整體可靠性。

總之VRRP出現的目的就是為解決靜態路由單點故障問題的痛點,它能夠保證當個別節點路由器宕機時,整個網路還可以不間斷提供服務執行。

(二)VRRP工作原理

1、VRRP組網架構如下圖所示:

(1)如上圖,VRRP為每一個路由器組抽象出一台虛擬路由器(Virtual Router),這台虛擬路由器並非真實存在的物理裝置,而是由VRRP虛擬出來的邏輯裝置。如圖Router A和Router B組成一個虛擬路由器。一個VRRP組只會產生一台虛擬路由器,虛擬路由器擁有自己的IP地址以及MAC地址;

(2)虛擬路由器使用虛擬IP與外網互動通訊的(如圖中VIP),虛擬MAC與內網互動通訊(如圖中VMAC);

(3)所有裝置開始都是initialize狀態,當介面UP後,如果優先級(0-255)為255,則直接進入master狀態;如果小於255,則先進入backup狀態,待MasterDownInterval定時器超時後才進入master狀態。

獲得VIP的路由器為主路由器(Master狀態),其他路由器為備份路由器(Backup狀態);

(4)主路由器每隔 advertisement_intervl 秒(對應圖中配置項 advert_int),向組內其他路由器發送通告訊息(即心跳),告知本路由器的優先級等資訊;

(5)組播的方式發送心跳,組播地址為224.0.0.18;

(6)只有主路由器會響應針對虛擬IP地址的ARP請求,組內其他路由器會丟棄ARP請求。

(三)VRRP協定報文

1、VRRP報文結構如下:

2、VRRP協定欄位資訊

上述標紅的幾個欄位是關鍵欄位,都會出現在 keepalive 的配置檔中。

(1)Version VRRP協定版本號,RFC3768定義了版本2。

(2)Type: 該欄位指明了VRRP報文的型別,RFC3768只定義了一種VRRP報文,那就是VRRP通告報文,所以該欄位總是置為1,若收到的VRRP通告報文擁有非1的型別值,那麽會被丟棄。

(3)Virtual Rtr ID: 也就是我們上面介紹過的VRID,一個VRID唯一地標識了一個虛擬路由器,取值範圍是[1,255],所以一台路由器的介面可以同時執行最多255個VRRP例項,此欄位沒有缺省值,必須人為設定。

(4)Priority: 優先級,在一個虛擬路由器中用來選取Master路由器和Backup路由器,值越大表明優先級越高,此欄位共有8個bit,取值範圍[1,254],若沒有人為指定,缺省值是100。其中,VRRP協定會將IP地址擁有者路由器的該欄位永遠設定為255,若人為指定為其它值,也不會影響VRRP協定的預設行為,即IP地址擁有者路由器的該欄位總是255。另外,此欄位設定為0會出現在下面這種情形中,當Master路由器出現故障後,它會立刻發送一個Priority置0的VRRP通告報文,當Backup路由器收到此通告報文後,會等待Skew time時間,然後將自己切換為Master路由器,其中Skew time=(256-Backup路由器的優先級)/256,單位為秒,例如若Backup路由器的優先級為100,那麽Skew time=156/256=0.609秒,對於主路由器來說,Skew time並沒有實際意義,雖然cisco的路由器也會計算並顯示出來。

(5)Count IP Addrs(Addr Count) :VRRP通告報文中包含的IP地址數量,這個欄位其實就是為一個VRRP虛擬路由器所分配的IP地址的數量。

(6)Auth Type: 認證型別欄位,是一個8位元的無符號整數,一個虛擬路由器只能使用一種認證型別,如果Backup路由器收到的通告報文中認證型別欄位是未知的或和本地配置的不匹配,那麽它將丟棄該封包。目前支持3種認證方式:無認證,簡單字元,和MD5認證。

(7)Adver Int: 此欄位規定了Mater路由器向外發送VRRP通告報文的時間間隔,以秒為單位,取值範圍是[1,255],若沒有人工配置,缺省為1秒。

(8)Checksum: 整個VRRP報文的校驗和,計算過程中,將Checksum欄位置為0,計算完成後將結果填入此欄位。若希望進一步了解Checksum的計算,可以檢視RFC1071(CKSM)。

(9)IP Address: 此欄位存放VRRP虛擬路由器的虛擬IP地址,配置了幾個就封裝幾個。

(10)Authentication Data: RFC3768中規定,此欄位只是為了向RFC2338相容,在實際的封裝時,全置為0.,接收方也會忽略此欄位。

3、虛擬MAC地址

組成方式是00-00-5E-00-01-{VRID},前三個字節00-00-5E是IANA組織分配的,接下來的兩個字節00-01是為VRRP協定指定的,最後的VRID是虛擬路由器標識,取值範圍[1,255]。

4、虛擬路由器標識VRID

虛擬路由器標識,在同一個VRRP組內的路由器必須有相同的VRID。

六、 配置實作Keepalived監控Mysql

以下實驗主要是想透過Keepalived來監控Mysql服務,即透過監控Mysql埠或行程,如果監測到埠或行程不存在了,即認為Mysql服務已經掛死,此時透過關閉Keepalived服務,實作Keepalived切換到備伺服器,繼續提供高可用的Mysql服務。當然這裏僅僅是實作簡單的切換流程,具體細節還是靠大家自己去實驗摸索。

其中這裏透過在Keepalived配置檔中定義一個shell指令碼用來實作檢測如果 Mysql服務已經掛死,此時透過關閉Keepalived服務,實作Keepalived切換到備伺服器,繼續提供高可用的Mysql服務。

該指令碼路徑及內容如下所示:

[root@haodaolinux01 ~]# cat /opt/check_mysql.sh#!/bin/bash/database/mysql/bin/mysql -uroot -p123456 -e "show status" &>/dev/null if [ $? -ne 0 ] ;then systemctl stop keepalivedfi

當然,Mysql實際安裝路徑得結合你們自己實驗的環境來對應修改指令碼內容。以上僅是參考。

(一)實驗組網環境如下所示:

為了實驗順利進行,以上 兩台Centos7伺服器均關閉SELINUX及防火墻後進行

sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

(二)安裝Keepalived服務

以上兩台伺服器均安裝上 Kee pal ived服務

yum install -y keepalived

(三)修改Keepalived配置檔

執行步驟三完成keepalived安裝,預設情況下配置檔路徑為 /etc/keepalived/keepalived.conf

養成好習慣,修改前先備份配置檔。大家對配置檔不熟悉的話,可以先看後邊章節內容再回過頭來修改配置檔。

1、 haodaolinux01主機上修改配置檔

主要修改配置如下:

global_defs{router_idkeepalived-01script_userrootenable_script_security}vrrp_scriptcheck_mysql {script"/opt/check_mysql.sh"interval2}vrrp_instancehaodaolinux_01 {stateMASTERinterfaceens33virtual_router_id51priority100advert_int1authentication{auth_typePASSauth_pass1111}track_script{check_mysql}virtual_ipaddress{192.168.20.211/24dev ens33 label ens33:1}}

2、haodaolinux02主機上修改配置檔

主要修改配置如下:

global_defs { router_id keepalived-02 script_user root enable_script_security}vrrp_script check_mysql { script "/opt/check_mysql.sh" interval 2}vrrp_instance haodaolinux_02 { state BACKUP interface ens33 virtual_router_id 51 priority 50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } track_script { check_mysql } virtual_ipaddress { 192.168.20.211/24 dev ens33 label ens33:1 }}

(四)啟動Keepalived服務

在haodaolinux01和haodaolinux02主機上執行以下命令

systemctl start keepalived

(五)抓包測試驗證VRRP功能

我這裏的虛擬機器是采用NAT方式連線,所以可以在宿主機上進行抓包,可以看到主為192.168.20.231的主機透過組播宣告自己還存活,透過報文可以看到如配置檔中那樣攜帶對應資訊。

此時haodaolinux01是主節點,檢視VIP是在haodaolinux01上,透過檢視網卡介面資訊可以看到,如下圖所示:

(六)模擬故障發生

這裏透過在haodaolinux01手動停止mysql服務,觸發指令碼停止keepalived服務,抓包驗證haodaolinux02是否會接管,自動切過去

透過抓包看到,隨著haodaolinux01上的Mysql服務掛掉,一秒不到時間完成Keepalived切換。此時已由haodaolinux02發出組播報文。

haodaolinux02上檢視網路介面,VIP也已經漂移過來。

(七)模擬主節點故障恢復

現在在haodaolinux01上手動重新啟動Mysql及Keepalived,透過抓包檢視到報文,haodaolinux01會發出ARP廣播包重新整理ARP表,通知後端節點VIP已經漂移回haodaolinux01主機上,檢視haodaolinux01網路介面也驗證這個結論。

七、 Keepalived配置檔介紹

執行yum命令完成keepalived服務的安裝,預設情況下配置檔路徑為 /etc/keepalived/keepalived.conf

Keepalived配置檔可以分為三個部份內容:

全域配置(全域定義和靜態路由配置)

VRRP配置(VRRP同步組合、VRRP例項和VRRP指令碼)

LVS配置

以下針對 Keepalived配置檔相關部份內容做一個說明。

(一)全域配置(全域定義和靜態路由配置)

該配置主要用來設定Keepalived的故障通知機制和Router ID標識的。

如下面的配置內容所示:

! Configuration File for keepalivedglobal_defs { notification_email { [email protected] [email protected] [email protected] } notification_email_from [email protected] smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}

1、第一行是註釋部份,!開頭和#開頭一樣的效果,表示註釋;

2、第2行是空行;

3、第4到第8行是用來定義服務故障時報警的信箱地址。即當服務發生切換或節點有故障時,發信件進行報警。屬於可選配置項, notification_email指定在keepalived服務發生事件時,需要發送的Email地址,可以有多個,每一行定義一個地址;

4、第9行是指定發送信件的發送人,即發件人地址,也是可選的配置項;

5、第10行smtp_server用於指定發送信件的smtp伺服器,如果本機伺服器開啟了sendmail或postfix服務,就可以使用預設的配置實作信件發送,這個也是屬於可選配置項;

6、第11行smtp_connect_timeout表示連線smtp的超時時間,也是屬於可選配置項;

7、第12行是keepalived伺服器的路由標識(router_id),在一個區域網路內,這個router_id應該是唯一的;

8、第13行是 用於跳過檢查收到的VRRP通告中的所有地址。預設情況下,檢查收到的VRRP通告中的所有地址可能會比較耗時,如果通告與接收的上一個通告來自相同的master路由器,則不執行檢查,以跳過檢查,從而提高效率。

9、第14行表示該參數的目的是為了增加VRRP的安全性。在某些情況下,可能希望限制VRRP報文的傳播範圍,以防止未經授權的裝置或網路監聽這些報文。

10、第15行表示 當 vrrp_garp_interval 設定為 0 時,這意味著 GARP 請求不會被發送。這可能是出於安全考慮或特定的部署需求,例如在某些情況下,你可能不希望 VRRP 組中的裝置之間頻繁地交換 GARP 請求。

11、第16行表示當 vrrp_gna_interval 設定為 0 時,這意味著 GNA 請求不會被發送。這可能是出於安全考慮或特定的部署需求,例如在某些情況下,你可能不希望 VRRP 組中的裝置之間頻繁地交換 GNA 請求。

(二) VRRP配置(VRRP同步組合、VRRP例項和VRRP指令碼)

如下面的配置內容所示:

vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.200.16 192.168.200.17 192.168.200.18 }}

1、第一行表示定義一個vrrp_instance 例項,對應名字為VI_1,每個 VRRP 例項可以看作是 Keepalived 中的一個業務,用於實作路由器的高可用性。在Keepalived服務配置中,vrrp_instance 例項可以有多個存在。但是註意,存在於主節點中的vrrp_instance 例項,在備節點中也要對應存在,這樣才能在發生故障時實作切換接管;

2、第16行表示當前vrrp_instance例項的的角色狀態,並且當前角色配置為MASTER,這裏的狀態配置只能選擇MASTER和BACKUP兩種,字元寫成大寫狀態;

3、第3行表示定義對外提供服務的網路介面,如配置eth0,可以根據實際配置對應網路介面;

4、第4行virtual_router_id表示定義虛擬路由ID標識,這個標識最好定義成數位,並且在一個keepalived.conf配置檔中要唯一,同時MASTER和BACKUP角色中配置相同的例項時,virtual_router_id要求又是唯一的,以免出現腦裂問題;

5、第5行priority表示優先級,其後面跟一個數位,數位越大,表示該例項的優先級就越高。在同一個vrrp_instance例項中,MASTER的優先級配置要高於BACKUP;

6、第6行advert_int表示同步通知間隔,MASTER和BACKUP之間通訊檢查的時間間隔,單位為秒,預設配置1秒;

7、第7行大括弧中authentication 部份用於設定 VRRP 例項的認證型別和密碼。這是為了確保同一 VRRP 例項的主節點和備節點之間能夠進行正確的通訊和驗證。,包含auth_type和auth_pass,分別表示認證型別及認證密碼,認證型別通常有PASS,AH兩種,推薦用PASS,密碼采用明文方式;

8、第11行virtual_ipaddress大括弧中定義虛擬地址,可以定義多個虛擬地址,每一個地址占一行,配置時最好指定子網路遮罩、虛擬地址繫結的網路介面,不然子網路遮罩就是預設32位元,同時繫結的網路介面也是跟前面的interface參數配置保持一致。

(三) LVS配置

在Keepalived的配置檔中,LVS管理部份的配置主要用來實作負載均衡和服務的高可用性。

具體來說,Keepalived可以用來監控LVS排程器的狀態,並在發生故障時自動切換到備用排程器,以保證服務的高可用性。同時,Keepalived還可以管理LVS負載均衡軟體,透過讀取自身的配置檔,實作透過更底層的介面直接管理LVS的配置以及控制服務的啟動、停止等功能,使LVS的套用更加簡單方便。此外,Keepalived還具有對LVS下面節點進行健康檢查的功能,能夠自動將失效的節點伺服器從LVS的正常轉發佇列中清除出去,並將請求排程到別的正常節點伺服器上,從而保證終端使用者的存取不受影響。因此,Keepalived配置檔中LVS管理部份的配置主要用來實作負載均衡和服務的高可用性。

本文實驗沒有涉及到該部份內容,這裏不做說明了。

八、 Keepalived常見問題列舉

以下羅列一些在Keepalived使用過程中常見的一些問題,希望大家引起重視,能夠避坑!!!

(一)腦裂問題

1、什麽是腦裂問題

Keepalived使用過程中的腦裂問題是指在一個高可用(HA)集群中,當關聯著的兩個節點互相之間斷開通訊時,本來為一個整體的集群系統分裂為兩個獨立的節點。這時兩個節點會爭搶共享資源,結果會導致系統混亂和數據損壞。腦裂問題常見於有狀態服務(如MySQL)的HA集群,必須要嚴格防止腦裂的發生。

2、出現腦裂問題的原因有哪些

(1)心跳線故障,導致最終高可用伺服器之間無法正常通訊了;

(2)心跳網卡地址配置不正確,沖突等問題;

(3)心跳線之間的組網裝置發生故障,如交換機壞了;

(4)防火墻配置策略問題等導致裝置間的心跳通訊不正常了;

(二)主備切換問題

在正常情況下,只有主機擁有VIP,備機不擁有VIP。但是出現腦裂的時候,備機上會出現VIP,從而出現兩個結點同時擁有VIP的情況。

(三)防火墻問題

防火墻可能會阻斷主備機器之間的通訊,導致備機無法接收到主機的VRRP協定心跳包,從而出現腦裂問題。

(四)配置檔問題

Keepalived的配置檔中如果存在錯誤或不合理的配置,可能會導致Keepalived服務無法正常啟動或執行,從而影響LVS集群的正常工作。

(五)依賴服務問題

Keepalived作為LVS的高可用性解決方案軟體,需要依賴其他服務(例如:Nginx、Haproxy、MySQL等)的正常執行。如果這些服務出現問題,可能會導致Keepalived服務無法正常工作。

(六)針對以上問題解決方法

為了解決這些問題,需要仔細檢查Keepalived的配置檔,確保配置檔中的各項參數設定正確,同時需要檢查防火墻設定,確保主備機器之間的通訊不會被阻斷。此外,還需要對Keepalived服務進行監控和測試,確保其能夠正常地提供高可用性和負載均衡功能。

九、總結

Keepalived本身使用很廣泛,以上實驗僅僅帶大家入門,工作中具體使用,還需要大家自己去消化才能轉化為自己的知識技能。

更多精彩

關註公眾號 浩道Linux

浩道Linux ,專註於 Linux系統 的相關知識、 網路通訊 網路安全 Python相關 知識以及涵蓋IT行業相關技能的學習, 理論與實戰結合,真正讓你在學習工作中真正去用到所學。同時也會分享一些面試經驗,助你找到高薪offer,讓我們一起去學習,一起去進步,一起去漲薪!期待您的加入~~~ 關註回復「資料」可 免費獲取學習資料 (含有電子書籍、視訊等)。

喜歡的話,記得 點「贊」 「在看」