国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

淺談Mysql讀寫分離的坑以及應(yīng)對的方案 | 京東云技術(shù)團隊

這篇具有很好參考價值的文章主要介紹了淺談Mysql讀寫分離的坑以及應(yīng)對的方案 | 京東云技術(shù)團隊。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、主從架構(gòu)

為什么我們要進行讀寫分離?個人覺得還是業(yè)務(wù)發(fā)展到一定的規(guī)模,驅(qū)動技術(shù)架構(gòu)的改革,讀寫分離可以減輕單臺服務(wù)器的壓力,將讀請求和寫請求分流到不同的服務(wù)器,分攤單臺服務(wù)的負載,提高可用性,提高讀請求的性能。

淺談Mysql讀寫分離的坑以及應(yīng)對的方案 | 京東云技術(shù)團隊,數(shù)據(jù)庫,mysql,京東云,數(shù)據(jù)庫,主從復(fù)制,讀寫分離

上面這個圖是一個基礎(chǔ)的Mysql的主從架構(gòu),1主1備3從。這種架構(gòu)是客戶端主動做的負載均衡,數(shù)據(jù)庫的連接信息一般是放到客戶端的連接層,也就是說由客戶端來選擇數(shù)據(jù)庫進行讀寫

淺談Mysql讀寫分離的坑以及應(yīng)對的方案 | 京東云技術(shù)團隊,數(shù)據(jù)庫,mysql,京東云,數(shù)據(jù)庫,主從復(fù)制,讀寫分離

上圖是一個帶proxy的主從架構(gòu),客戶端只和proxy進行連接,由proxy根據(jù)請求類型和上下文決定請求的分發(fā)路由。

兩種架構(gòu)方案各有什么特點:

1.客戶端直連架構(gòu),由于少了一層proxy轉(zhuǎn)發(fā),所以查詢性能會比較好點兒,架構(gòu)簡單,遇到問題好排查。但是這種架構(gòu),由于要了解后端部署細節(jié),出現(xiàn)主備切換,庫遷移的時候客戶端都會感知到,并且需要調(diào)整庫連接信息

2.帶proxy的架構(gòu),對客戶端比較友好,客戶端不需要了解后端部署細節(jié),連接維護,后端信息維護都由proxy來完成。這樣的架構(gòu)對后端運維團隊要求比較高,而且proxy本身也要求高可用,所以整體架構(gòu)相對來說比較復(fù)雜

但是不論使用哪種架構(gòu),由于主從之間存在延遲,當一個事務(wù)更新完成后馬上發(fā)起讀請求,如果選擇讀從庫的話,很有可能讀到這個事務(wù)更新之前的狀態(tài),我們把這種讀請求叫做過期讀。出現(xiàn)主從延遲的情況有多種,有興趣的同學可以自己了解一下,雖然出現(xiàn)主從延遲我們同樣也有應(yīng)對策略,但是不能100%避免,這些不是我們本次討論的范圍,我們主要討論一下如果出現(xiàn)主從延遲,剛好我們的讀走的都是從庫,我們應(yīng)該怎么應(yīng)對?

首先我把應(yīng)對的策略總結(jié)一下:

  • 強制走主庫
  • sleep方案
  • 判斷主從無延遲
  • 等主庫位點
  • 等GTID方案

接下來基于上述的幾種方案,我們逐個討論一下怎么實現(xiàn)和有什么問題。

二、主從同步

在開始介紹主從延遲解決方案前先簡單的回顧一下主從的同步

淺談Mysql讀寫分離的坑以及應(yīng)對的方案 | 京東云技術(shù)團隊,數(shù)據(jù)庫,mysql,京東云,數(shù)據(jù)庫,主從復(fù)制,讀寫分離

上圖表示了一個update語句從節(jié)點A同步到節(jié)點B的完整過程

備庫B和主庫A維護了一個長連接,主庫A內(nèi)部有一個線程,專門用來服務(wù)備庫B的連接。一個事務(wù)日志同步的完整流程是:

1.在備庫 B 上通過 change master 命令,設(shè)置主庫 A 的 IP、端口、用戶名、密碼,以及要從哪個位置開始請求 binlog,這個位置包含文件名和日志偏移量。

2.在備庫 B 上執(zhí)行 start slave 命令,這時候備庫會啟動兩個線程,就是圖中的 io_thread 和 sql_thread。

3.其中 io_thread 負責與主庫建立連接。

4.主庫 A 校驗完用戶名、密碼后,開始按照備庫 B 傳過來的位置,從本地讀取 binlog,發(fā)給 B。備庫 B 拿到 binlog 后,寫到本地文件,稱為中轉(zhuǎn)日志(relay log)。

5.sql_thread 讀取中轉(zhuǎn)日志,解析出日志里的命令,并執(zhí)行。

上圖中紅色箭頭,如果用顏色深淺表示并發(fā)度的話,顏色越深并發(fā)度越高,所以主從延遲時間的長短取決于備庫同步線程執(zhí)行中轉(zhuǎn)日志(圖中的relay log)的快慢??偨Y(jié)一下可能出現(xiàn)主從延遲的原因:

1.主庫并發(fā)高,TPS大,備庫壓力大執(zhí)行日志慢

2.大事務(wù),一個事務(wù)在主庫執(zhí)行5s,那么同樣的到備庫也得執(zhí)行5s,比如一次性刪除大量的數(shù)據(jù),大表DDL等都是大事務(wù)

3.從庫的并行復(fù)制能力,Msyql5.6之前的版本是不支持并行復(fù)制的也就是上圖的模型。并行復(fù)制也比較復(fù)雜,就不在這兒贅述了,大家可以自行復(fù)習了解一下。

三、主從延遲解決方案

1.強制走主庫

這種方案就是要對我們的請求進行分類,通??梢詫⒄埱蠓殖蓛深悾?/p>

1.對于必須要拿到最新結(jié)果的請求,可以強制走主庫

2.對于可以讀到舊數(shù)據(jù)的請求,可以分配到從庫

這種方案是最簡單的方案,但是這種方案有一個缺點就是,對于所有的請求都不能是過期讀的請求,那么所有的壓力就又來到了主庫,就得放棄讀寫分離,放棄擴展性

2.sleep方案

sleep方案就是每次查詢從庫之前都先執(zhí)行一下:select sleep(1),類似這樣的命令,這種方式有兩個問題:

1.如果主從延遲大于1s,那么依然讀到的是過期狀態(tài)

2.如果這個請求可能0.5s就能在從庫拿到結(jié)果,仍然要等1s

這種方案看起來十分的不靠譜,不專業(yè),但是這種方案確實也有使用的場景。

之前在做項目的時候,有這樣么一種場景,就是我們先寫主庫,寫完后,發(fā)送一個MQ消息,然后消費方接到消息后,調(diào)用我們的查詢接口查數(shù)據(jù),當然我們也是讀寫分離的模式,就出現(xiàn)了查不到數(shù)據(jù)的情況,這個時候建議消費方對消息進行一個延遲消費,比如延遲30ms,然后問題就解決了,這種方式類似sleep方案,只不過把sleep放到了調(diào)用方

3.判斷主從無延遲方案

  1. 命令判斷

show slave status,這個命令是在從庫上執(zhí)行的,執(zhí)行的結(jié)果里面有個seconds_behind_master字段,這個字段表示主從延遲多少s,注意單位是秒。所以這種方案就是通過判斷當前這個值是否為0,如果為0則直接查詢獲取結(jié)果,如果不為0,則一直等待,直到主從延遲變?yōu)?

因為這個值是秒級的,但是我們的一些場景下是毫秒級的請求,所以通過這個方式判斷,不是特別精確

  1. 對比位點判斷主從無延遲

淺談Mysql讀寫分離的坑以及應(yīng)對的方案 | 京東云技術(shù)團隊,數(shù)據(jù)庫,mysql,京東云,數(shù)據(jù)庫,主從復(fù)制,讀寫分離

上圖是執(zhí)行一次show slave status 部分結(jié)果

  • Master_Log_File和Read_Master_Log_Pos表示讀到的主庫的最新的位點
  • Relay_Master_Log_File和Exec_Master_Log_Pos表示備庫執(zhí)行的最新的位點

如果Master_Log_File和Relay_Master_Log_File,Read_Master_Log_Pos和Exec_Master_Log_Pos這兩組值完全一致,表示主從之間是沒有延遲的

3)對比GTID判斷主從無延遲

  • Auto_Position:1表示這對主從之間啟用了GTID協(xié)議
  • Retrieved_Gtid_Set:表示從庫接收到的所有的GTID的集合
  • Executed_Gtid_Set:表示從庫執(zhí)行完成的所有的GTID集合

通過比較Retrieved_Gtid_Set和Executed_Gtid_Set集合是否一致,來確定主從是否存在延遲。

可見對比位點和對比GTID集合,比sleep要準確一點兒,在查詢之前都可以先判斷一下是否接收到的日志都執(zhí)行完成了,雖然準確度提升了,但是還達不到精確,為啥這么說呢?

先回顧一下binlog在一個事物下的狀態(tài)

1.主庫執(zhí)行完成,寫入binlog,反饋給客戶端

2.binlog被從主庫發(fā)送到備庫,備庫接收到日志

3.備庫執(zhí)行binlog

我們上面判斷主備無延遲方案,都是判斷備庫收到的日志都執(zhí)行過了,但是從binlog在主備之間的狀態(tài)分析,可以看出,還有一部分日志處于客戶端已經(jīng)收到提交確認,但是備庫還沒有收到日志的狀態(tài)

淺談Mysql讀寫分離的坑以及應(yīng)對的方案 | 京東云技術(shù)團隊,數(shù)據(jù)庫,mysql,京東云,數(shù)據(jù)庫,主從復(fù)制,讀寫分離

這個時候主庫執(zhí)行了3個事物,trx1,trx2,trx3,其中

  • trx1,trx2已經(jīng)傳到從庫,并且從庫已經(jīng)執(zhí)行完成
  • trx3主庫已經(jīng)執(zhí)行完成,并且已經(jīng)給客戶端回復(fù),但是還沒有傳給從庫

這個時候如果在從庫B執(zhí)行查詢,按照上面我們判斷位點的方式,這個時候主從是沒有延遲的,但是還查不到trx3,嚴格說就是出現(xiàn)了"過期讀"。那么這個問題有什么方法可以解決么?

要解決這個問題,可以引入半同步復(fù)制,也就是semi-sync repliacation(參考:https://dev.mysql.com/doc/refman/8.0/en/replication-semisync.html)。

可以通過

show variables like '%rpl_semi_sync_master_enabled%'
show variables like '%rpl_semi_sync_slave_enabled%'


這兩個命令來查看主從是否都開啟了半同步復(fù)制。

semi-sync做了這樣的設(shè)計:

1.事物提交的時候,主庫把binlog發(fā)給從庫

2.從庫接收到主庫發(fā)過來的binlog,給主庫一個ack確認,表示收到了

3.主庫收到這個ack確認后,才給客戶端返回一個事物完成的確認

也就是啟用了semi-sync,表示所有返回給客戶端已經(jīng)確認完成的事物,從庫都收到了binlog日志,這樣通過semi-sync配合判斷位點的方式,就可以確定在從庫上的查詢,避免了過期讀的出現(xiàn)。

但是semi-sync配合判斷位點的方式,只適用一主一備的情況,在一主多從的情況下,主庫只要收到一個從庫的ack確認,就給客戶端返回事物執(zhí)行完成的確認,這個時候在從庫上執(zhí)行查詢就有兩種情況

  • 如果查詢剛好是在給主庫響應(yīng)ack確認的從庫上,那么可以查詢到正確的數(shù)據(jù)
  • 但是如果請求落到其他的從庫上,他們可能還沒收到日志,所以依然可能存在過期讀

其實通過判斷同步位點或者GTID集合的方案,還存在一個潛在的問題,就是業(yè)務(wù)高峰期,主庫的位點或者GITD集合更新的非常快,那么兩個位點的判斷一直不相等,很可能出現(xiàn)從庫一直無法響應(yīng)查詢請求的情況。

上面的兩種方案在靠譜程度和精確性上都差了一點兒,接下來介紹兩種相對靠譜和精確一點兒的方案

4.等主庫位點

要理解等主庫位點,先介紹一條命令

select master_pos_wait(file, pos[, timeout]);

這條命令執(zhí)行的邏輯是:

1.首先是在從庫執(zhí)行的

2.參數(shù)file和pos是主庫的binlog文件名和執(zhí)行到的位置

3.timeout參數(shù)是非必須,設(shè)置為正整數(shù)N,表示這個函數(shù)最多等到N秒

這個命令執(zhí)行結(jié)果M可能存在的情況:

  • M>0表示從命令執(zhí)行開始,到應(yīng)用完file和pos表示的binlog位置,一共執(zhí)行了M個事務(wù)
  • 如果執(zhí)行期間,備庫的同步線程發(fā)生異常,則返回null
  • 如果等待超過N秒,返回-1
  • 如果剛開始執(zhí)行的時候,發(fā)現(xiàn)已經(jīng)執(zhí)行了過了這個pos,則返回0

當一個事務(wù)執(zhí)行完成后,我們要馬上發(fā)起一個查詢請求,可以通過下面的步驟實現(xiàn):

1.當一個事務(wù)執(zhí)行完成后,馬上執(zhí)行show master status,獲取主庫的File和Position

淺談Mysql讀寫分離的坑以及應(yīng)對的方案 | 京東云技術(shù)團隊,數(shù)據(jù)庫,mysql,京東云,數(shù)據(jù)庫,主從復(fù)制,讀寫分離

2.選擇一個從庫執(zhí)行查詢

3.在從庫上執(zhí)行 select master_pos_wait(File,Poistion,1)

4.如果返回的值>=0,則在這個從庫上執(zhí)行

5.否則回主庫查詢

這里我們假設(shè),這條查詢請求在從庫上最多等待1s,那么如果1s內(nèi)master_pos_wait返回一個大于等于0的數(shù),那么就能保證在這個從庫上能查到剛執(zhí)行完的事務(wù)的最新的數(shù)據(jù)。

上述的步驟5是這類方案的兜底方案,因為從庫的延遲時間不可控,不能無限等待,所以如果超時,就應(yīng)該放棄,到主庫查詢。

可能有同學會覺的,如果所有的延遲都超過1s,那么所有的壓力都到了主庫,確實是這樣的,但是按照我們設(shè)定的不允許出現(xiàn)過期讀,那么就只有兩種選擇,要么超時放棄,要么轉(zhuǎn)到主庫,具體選擇哪種,需要我們根據(jù)業(yè)務(wù)進行具體的分析。

5.等GTID方案

如果數(shù)據(jù)庫開啟的GTID模式,那么相應(yīng)的也有等GTID的方案

 select wait_for_executed_gtid_set(gtid_set, 1);


這條命令的邏輯是:

1.等待,直到這個庫執(zhí)行的事務(wù)中包含傳入的giid_set集合,返回0

2.超時返回1

在前面等待主庫位點的方案中,執(zhí)行完事務(wù)后,需要到主庫執(zhí)行show master status。從mysql5.7.6開始,允許事務(wù)執(zhí)行完成后,把這個事務(wù)執(zhí)行的GTID返回給客戶端,這樣等待GTIID的方案就減少了一次查詢。

這時等GTID方案的流程就變成這樣:

1.事務(wù)執(zhí)行完成后,從返回包解析獲取這個事務(wù)的GTID,記為gtid1

2.選定一個從庫執(zhí)行查詢

3.在從庫上執(zhí)行select wait_for_executed_gtid_set(gtid1,1)

4.如果返回0,則在這個從庫上執(zhí)行查詢

5.否則回到主庫查詢

和等待主庫位點方案一樣,最后的兜底方案都是轉(zhuǎn)到主庫查詢了,需要綜合業(yè)務(wù)考慮確定方案

上面的事物執(zhí)行完成后,從返回的包中解析GTID,mysql其實沒有提供對應(yīng)的命令,可以參考Mysql提供的api(https://dev.mysql.com/doc/c-api/8.0/en/mysql-session-track-get-first.html),在我們的客戶端可以調(diào)用這個函數(shù)獲取GTID

四、總結(jié)

以上簡單介紹了讀寫分離架構(gòu),和出現(xiàn)主從延遲后,如果我們用的讀寫分離的架構(gòu),那么我們應(yīng)該怎么處理這種情況,相信在日常我們的主從還是或多或少的存在延遲。上面介紹的幾種方案,有些方案看上去十分不靠譜,有些方案做了一些妥協(xié),但是都有實際的應(yīng)用場景,需要我們根據(jù)自身的業(yè)務(wù)情況,合理選擇對應(yīng)的方案。

但話說回來,導(dǎo)致過期讀的本質(zhì)還是一寫多讀導(dǎo)致的,在實際的應(yīng)用中,可能有別的不用等待就可以水平擴展的數(shù)據(jù)庫方案,但這往往都是通過犧牲寫性能獲得的,也就是需要我們在讀性能和寫性能之間做個權(quán)衡。

文中有不太嚴謹或者錯誤的地方還望大家多多指正。

作者:京東零售 尚有智

來源:京東云開發(fā)者社區(qū) 轉(zhuǎn)載請注明來源文章來源地址http://www.zghlxwxcb.cn/news/detail-694983.html

到了這里,關(guān)于淺談Mysql讀寫分離的坑以及應(yīng)對的方案 | 京東云技術(shù)團隊的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • mysql(六)讀寫分離

    mysql(六)讀寫分離

    目錄 前言 一、概述 二、配置JAVA環(huán)境及安裝阿米巴 三、配置阿米巴 ?四、測試 總結(jié) MySQL讀寫分離是一種常見的數(shù)據(jù)庫架構(gòu)設(shè)計模式,旨在提高系統(tǒng)的性能和可用性。它通過將讀操作和寫操作分離到不同的MySQL實例上來實現(xiàn)。 讀寫分離的原理是: 1. 主服務(wù)器(Master):負責處

    2024年02月15日
    瀏覽(26)
  • Mysql 主從復(fù)制、讀寫分離

    Mysql 主從復(fù)制、讀寫分離

    目錄 前言 一、主從復(fù)制原理 1.1 MySQL的復(fù)制類型 1.2?mysql主從復(fù)制的工作原理 1.3 MySQL主從復(fù)制延遲 1.4?MySQL四種同步方式 1.5 MySQL支持的復(fù)制類型 二、 MySQL應(yīng)用場景 三、主從復(fù)制實驗 3.1?MySQL主從服務(wù)器時間同步 3.1.1 安裝ntp、修改配置文件 3.1.2 兩臺SLAVE服務(wù)器配置 3.2 配置主從

    2024年02月16日
    瀏覽(23)
  • MySQL 中讀寫分離數(shù)據(jù)延遲

    MySQL 中讀寫分離數(shù)據(jù)延遲

    MySQL 中讀寫分離可能遇到的問題 前言 讀寫分離的架構(gòu) 基于客戶端實現(xiàn)讀寫分離 基于中間代理實現(xiàn)讀寫分離 MySQL 中如何保證主從數(shù)據(jù)一致 循環(huán)復(fù)制問題 主從同步延遲 主從同步延遲的原因 主從延遲如何處理 強制走主庫方案 Sleep 方案 判斷主從無延遲方案 配合semi-sync 等主庫

    2024年02月03日
    瀏覽(21)
  • MySQL主從復(fù)制與讀寫分離

    MySQL主從復(fù)制與讀寫分離

    STATEMENT∶基于語句的復(fù)制。在服務(wù)器上執(zhí)行sql語句,在從服務(wù)器上執(zhí)行同樣的語句,mysql默認采用基于語句的復(fù)制,執(zhí)行效率高。 ROW∶ 基于行的復(fù)制。把改變的內(nèi)容復(fù)制過去, 而不是把命令在從服務(wù)器上執(zhí)行一遍。 MIXED∶混合類型的復(fù)制。默認采用基于語句的復(fù)制,一旦發(fā)

    2024年02月05日
    瀏覽(21)
  • 項目實現(xiàn)讀寫分離操作(mysql)

    項目實現(xiàn)讀寫分離操作(mysql)

    Master(主庫)----(數(shù)據(jù)同步)— Slave(從庫) Mysql主從復(fù)制 mysql主從復(fù)制 介紹 mysql主從復(fù)制是一個異步的復(fù)制過程,底層是基于mysql數(shù)據(jù)庫自帶的 二進制日志 功能。就是一臺或多臺mysql數(shù)據(jù)庫(Slave,即從庫)從另一臺mysql數(shù)據(jù)庫(Master,即主庫)進行日志的復(fù)制然后再解析日

    2024年02月05日
    瀏覽(21)
  • Mysql-主從復(fù)制與讀寫分離

    Mysql-主從復(fù)制與讀寫分離

    1.在企業(yè)應(yīng)用中,成熟的業(yè)務(wù)通常數(shù)據(jù)量都比較大 2.單臺MySQL在安全性、 高可用性和高并發(fā)方面都無法滿足實際的需求 3.配置多臺主從數(shù)據(jù)庫服務(wù)器以實現(xiàn)讀寫分離 1.MySQL的復(fù)制類型 基于語句的復(fù)制(STATEMENT, MySQL默認類型) 基于行的復(fù)制(ROW) 混合類型的復(fù)制(MIXED) 2. MySQL主從復(fù)制

    2024年02月15日
    瀏覽(19)
  • 【MySQL 基于Amoeba讀寫分離】

    【MySQL 基于Amoeba讀寫分離】

    目錄 一、讀寫分離是什么? 二、常見的MySQL讀寫分離方案 1.基于程序代碼內(nèi)部實現(xiàn) 2.基于中間代理層實現(xiàn) 3.Amoeba 三、分離步驟 1.在主機Amoeba上安裝java環(huán)境 2.安裝并配置Amoeba 3.配置Amoeba讀寫分離,兩個Slave讀負載均衡 4.測試 4.1?在Client上進行訪問測試 4.2?通過代理訪問MySQL 四

    2024年02月15日
    瀏覽(17)
  • mycat實現(xiàn)mysql讀寫分離

    mycat實現(xiàn)mysql讀寫分離

    mycat集群+Haproxy+Keepalived+mysql1主2從 環(huán)境規(guī)劃 centos7.9 1主2從,讀寫分離 名稱 ip 端口 mysql-master 192.168.1.220 3306 mysql-slave1 192.168.1.221 3306 mysql-slave2 192.168.1.222 3306 mycat-1 192.168.1.221 8066 mycat-2 192.168.1.222 8066 haproxy-1 192.168.1.221 18066 haproxy-2 192.168.1.222 18066 keepalived-1 192.168.1.221 keepalived-2 1

    2024年01月19日
    瀏覽(19)
  • MySQL 主從復(fù)制與讀寫分離

    MySQL 主從復(fù)制與讀寫分離 1、什么是讀寫分離? 讀寫分離,基本的原理是讓主數(shù)據(jù)庫處理事務(wù)性增、改、刪操作(INSERT、UPDATE、DELETE),而從數(shù)據(jù)庫處理SELECT查詢操作。數(shù)據(jù)庫復(fù)制被用來把事務(wù)性操作導(dǎo)致的變更同步到集群中的從數(shù)據(jù)庫。 2、為什么要讀寫分離呢?讀快寫慢

    2024年02月06日
    瀏覽(25)
  • MySQL的讀寫分離的配置

    MySQL的讀寫分離的配置

    MySQL讀寫分離 就是創(chuàng)建不同的幾個數(shù)據(jù)庫來實現(xiàn)讀的時候是一個數(shù)據(jù)庫,寫的時候是另一個數(shù)據(jù)庫,提升系統(tǒng)的允許效率, 讀寫分離運用了MySQL的主從復(fù)制 主從復(fù)制的含義 :就是將主庫的數(shù)據(jù)同步到從庫的數(shù)據(jù),從而保證從庫的數(shù)據(jù)和主庫的數(shù)據(jù)保持一致。 主從復(fù)制的原理

    2024年02月22日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包