欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Zookeeper 內(nèi)容的一些概念

系統(tǒng) 1680 0

?

閱讀指南——如何利用 Zookeeper 構(gòu)建上層應(yīng)用?

本文將帶你如何利用 Zookeeper 實(shí)現(xiàn)某些分布式應(yīng)用所必需的高級(jí)功能。所有功能均可以在客戶端按固定的模式實(shí)現(xiàn),不需要 Zookeeper 的特殊支持,也希望 Zookeeper 社區(qū)能將這些具有固定實(shí)現(xiàn)模式的功能集成到 Zookeeper 客戶端的程序庫中,可以簡(jiǎn)化 Zookeeper 的使用并且還能使某些功能的實(shí)現(xiàn)標(biāo)準(zhǔn)化。

即便 Zookeeper 本身使用異步通知( asynchronous ?notifications),但卻可以基于此構(gòu)建同步的( synchronous )一致性原語,如隊(duì)列和鎖。你將看到 Zookeeper 實(shí)現(xiàn)這些功能是完全可能的,因?yàn)?Zookeeper 提供了強(qiáng)制的全序更新,并對(duì)外提供了保序接口。?

注意下面的程序段試圖采取最佳的編程實(shí)踐,尤其是避免使用輪詢(polling),定時(shí)器(timers)和其他任何可能造成“羊群效應(yīng)(herd effect)”機(jī)制(“羊群效應(yīng)”一般會(huì)帶來網(wǎng)絡(luò)流量的突增,限制系統(tǒng)的可擴(kuò)展性)。

除了本文所列舉的功能,我們還可以想象出其他很多實(shí)用的功能,比如可撤銷的讀寫優(yōu)先鎖。本文提到的某些構(gòu)建方式——比如鎖,比較詳細(xì)的闡述了使用 Zookepper 的關(guān)鍵點(diǎn),其實(shí)你可以找到其他的例子,如事件處理和隊(duì)列,但是,本節(jié)中的例子只是模擬相關(guān)的功能,在具體實(shí)踐中需要考慮其他方面的因素。

開箱即用的應(yīng)用示例:命名服務(wù),配置管理,組關(guān)系管理

命名服務(wù)和配置管理是 Zookeeper 提供的最基本的應(yīng)用,這兩個(gè)功能可以直接用 Zookeeper 提供的 API 實(shí)現(xiàn)。

另外一個(gè)可以直接使用的功能是組關(guān)系管理,組在 Zookeeper 由一個(gè) Znode 表示,組中的某個(gè)成員可以用組節(jié)點(diǎn)下的臨時(shí)節(jié)點(diǎn)(Ephemeral Nodes)表示,當(dāng) Zookeeper 檢測(cè)到節(jié)點(diǎn)故障時(shí),節(jié)點(diǎn)成員中不正常的節(jié)點(diǎn)將會(huì)被自動(dòng)地移除。

屏障(Barriers)

分布式系統(tǒng)使用屏障( barriers )來阻塞某一節(jié)點(diǎn)集的任務(wù),直到滿足特定的條件該節(jié)點(diǎn)集的所有節(jié)點(diǎn)才能正常向前推進(jìn),就像屏障一樣,在當(dāng)條件不滿足時(shí),屏障阻塞了任務(wù)的執(zhí)行,只有當(dāng)條件滿足后屏障才會(huì)被拆除,各節(jié)點(diǎn)才能推進(jìn)自己正在執(zhí)行的任務(wù)。Zookeeper 中實(shí)現(xiàn)屏障時(shí)指定一個(gè)屏障節(jié)點(diǎn)(barrier node),如果屏障節(jié)點(diǎn)存在,屏障就會(huì)生效,下面是偽代碼:

  1. 客戶端在屏障節(jié)點(diǎn)上調(diào)用 ZooKeeper API?? exists(), watch 設(shè)置為 true .

  2. 如果? exists() ?返回 false,屏障消失,客戶端可以推進(jìn)的自己的工作。

  3. 否則,? exists() ?返回 true,客戶端等待屏障節(jié)點(diǎn)上監(jiān)聽事件的到來。

  4. 如果監(jiān)聽事件被觸發(fā),客戶端重新執(zhí)行? exists( ), ?再一次重復(fù)上述 1-3 步,直到屏障節(jié)點(diǎn)被移除。

?

(雙屏障)Double Barriers

雙屏障(Double barriers)使得所有客戶端在進(jìn)入和結(jié)束某一計(jì)算任務(wù)時(shí)都會(huì)得到同步。當(dāng)足夠的進(jìn)程processes(注:此處指節(jié)點(diǎn))加入到屏障時(shí),才啟動(dòng)任務(wù),然后當(dāng)任務(wù)完成時(shí),離開屏障區(qū),下面的代碼段示意如何使用 Zookeeper 創(chuàng)建屏障節(jié)點(diǎn)。

偽代碼中屏障節(jié)點(diǎn)用? b ?表示,每個(gè)客戶端進(jìn)程(節(jié)點(diǎn))?? p ?在進(jìn)入屏障節(jié)點(diǎn)時(shí)注冊(cè)事件,然后在離開時(shí)取消注冊(cè)事件。進(jìn)入屏障節(jié)點(diǎn)注冊(cè)事件的代碼如下表的? Enter 程序段所示, ?在繼續(xù)處理任務(wù)之前,它將等待客戶端? x ?進(jìn)程的注冊(cè)。(此處的? x ?由你針對(duì)自己的系統(tǒng)決定)

Enter Leave
  1. 創(chuàng)建名稱為? b +“/”+ p 的 Znode 節(jié)點(diǎn)

  2. 設(shè)置監(jiān)視: exists( b ?+ ‘‘/ready’’, true)

  3. 創(chuàng)建子節(jié)點(diǎn): create(? n , EPHEMERAL)

  4. L = getChildren(b, false)

  5. 如果L的孩子數(shù)目小于? x 的 , 則等待監(jiān)視事件

  6. 否則? create(b + ‘‘/ready’’, REGULAR)

  1. L = getChildren(b, false)

  2. 如果沒有任何子節(jié)點(diǎn),則退出。

  3. 如果? p ?是 L 中唯一節(jié)點(diǎn),則 delete(n) 并退出。

  4. 如果? p 是 L 中的序號(hào)最低的節(jié)點(diǎn),則等待 P 中的序號(hào)最高節(jié)點(diǎn)。

  5. 否則 依然存在,則? delete( n ) ?并繼續(xù)等待L中的最低節(jié)點(diǎn)。

  6. 跳轉(zhuǎn) 1

在進(jìn)入屏障時(shí),所有的進(jìn)程(節(jié)點(diǎn))監(jiān)視一個(gè)準(zhǔn)備好的節(jié)點(diǎn)(屏障節(jié)點(diǎn)),并創(chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn)作為屏障節(jié)點(diǎn)的孩子。除了最后進(jìn)入屏障的節(jié)點(diǎn)外,每個(gè)進(jìn)程(節(jié)點(diǎn))都等待屏障節(jié)點(diǎn),直到第 5 行的條件出現(xiàn)。該進(jìn)程(節(jié)點(diǎn))創(chuàng)建第 x 個(gè)節(jié)點(diǎn)——即最后的進(jìn)程(節(jié)點(diǎn)),它將會(huì)看到 x 個(gè)節(jié)點(diǎn),并喚醒其他進(jìn)程(節(jié)點(diǎn)),注意,所有的等待進(jìn)程(節(jié)點(diǎn))只是在退出的時(shí)候被喚醒,所以等待還是很高效的。

在退出屏障時(shí),你不能設(shè)置 諸如? ready ?的標(biāo)志,因?yàn)槟阍诘却M(jìn)程節(jié)點(diǎn)退出,通過使用臨時(shí)節(jié)點(diǎn),進(jìn)入屏障后失效的進(jìn)程節(jié)點(diǎn)并不會(huì)阻止其他運(yùn)行正確的節(jié)點(diǎn)完成任務(wù)。當(dāng)進(jìn)程節(jié)點(diǎn)準(zhǔn)備推出屏障區(qū)時(shí),它必須刪除它的進(jìn)程節(jié)點(diǎn),并等待其他進(jìn)程刪除各自的進(jìn)程節(jié)點(diǎn)。

當(dāng) b 沒有的進(jìn)程子節(jié)點(diǎn)時(shí),進(jìn)程(節(jié)點(diǎn))就會(huì)退出屏障區(qū)。然而,為了效率起見,你可以使用序號(hào)最低的進(jìn)程節(jié)點(diǎn)作為 ready 標(biāo)志。所有其他準(zhǔn)備退出屏障區(qū)的進(jìn)程(節(jié)點(diǎn))都監(jiān)視序號(hào)最低的將要退出進(jìn)程(節(jié)點(diǎn))消失,序號(hào)最低的進(jìn)程節(jié)點(diǎn)的擁有者則就等待其他任何一個(gè)節(jié)點(diǎn)的消失(選擇序號(hào)最高進(jìn)程節(jié)點(diǎn))。這意味著除了最后的一個(gè)進(jìn)程節(jié)點(diǎn)外,其他的每個(gè)進(jìn)程節(jié)點(diǎn)被刪除時(shí)只要喚醒一個(gè)進(jìn)程節(jié)點(diǎn)即可,當(dāng)它被刪除時(shí)就會(huì)喚醒其他的進(jìn)程節(jié)點(diǎn)。

隊(duì)列(Queues)

分布式隊(duì)列是通用的數(shù)據(jù)結(jié)構(gòu),為了在 Zookeeper 中實(shí)現(xiàn)分布式隊(duì)列,首先需要指定一個(gè) Znode 節(jié)點(diǎn)作為隊(duì)列節(jié)點(diǎn)(queue node), 各個(gè)分布式客戶端通過調(diào)用 create() 函數(shù)向隊(duì)列中放入數(shù)據(jù),調(diào)用create()時(shí)節(jié)點(diǎn)路徑名帶"queue-"結(jié)尾,并設(shè)置順序和臨時(shí)( sequence ?and ephemeral )節(jié)點(diǎn)標(biāo)志。 由于設(shè)置了節(jié)點(diǎn)的順序標(biāo)志,新的路徑名具有以下字符串模式:"_path-to-queue-node_/queue-X",X 是唯一自增號(hào)。需要從隊(duì)列中移除數(shù)據(jù)的客戶端首先調(diào)用? getChildren( ) ?函數(shù),同時(shí)在隊(duì)列節(jié)點(diǎn)(queue node)上將? watch ?設(shè)置為 true,并處理最小序號(hào)的節(jié)點(diǎn)(即從序號(hào)最小的節(jié)點(diǎn)中取數(shù)據(jù))。客戶端不需要再一次調(diào)用? getChildren( ), 隊(duì)列中的數(shù)據(jù)獲取完。如果隊(duì)列節(jié)點(diǎn)中沒有任何子節(jié)點(diǎn),讀取隊(duì)列的客戶端需要等待隊(duì)列的監(jiān)視事件通知。

Priority Queues

為了實(shí)現(xiàn)優(yōu)先隊(duì)列,你在普通隊(duì)列上只需要簡(jiǎn)單的改變兩處地方,首先,在某一元素被加入隊(duì)列時(shí),路徑名以 "queue-YY" 結(jié)尾,YY 表示優(yōu)先級(jí),YY越小優(yōu)先級(jí)越高,其次,從隊(duì)列中移除一個(gè)元素時(shí),客戶端需要使用最新的孩子節(jié)點(diǎn)列表,這意味著如果隊(duì)列節(jié)點(diǎn)上監(jiān)視通知被觸發(fā),客戶端需要讓先前獲取的孩子節(jié)點(diǎn)列表無效。

鎖(Locks)

完全分布式鎖是全局同步的,這意味著在任何時(shí)刻沒有兩個(gè)客戶端會(huì)同時(shí)認(rèn)為它們都擁有相同的鎖,使用 Zookeeper 可以實(shí)現(xiàn)分布式鎖,和優(yōu)先隊(duì)列一樣,我們需要首先定義一個(gè)鎖節(jié)點(diǎn)(lock node)。

需要獲得鎖的客戶端按照以下步驟來獲取鎖:

  1. 調(diào)用? create( ), 參數(shù) pathname 為 "_locknode_/lock-",并設(shè)置? sequence? 和? ephemeral ?標(biāo)志。

  2. 在所節(jié)點(diǎn)(lock node)上調(diào)用? getChildren( ) ?,不需要設(shè)置監(jiān)視標(biāo)志。 (為了避免“羊群效應(yīng)”).

  3. 如果在第 1 步中創(chuàng)建的節(jié)點(diǎn)的路徑具有最小的序號(hào)后綴,那么該客戶端就獲得了鎖。

  4. 客戶端調(diào)用? exists( ) ?,并在鎖目錄路徑中下一個(gè)最小序號(hào)的節(jié)點(diǎn)上設(shè)置監(jiān)視標(biāo)志。

  5. 如果? exists( ) ?返回 false,跳轉(zhuǎn)至第 2 步,否則,在跳轉(zhuǎn)至第 2 步之前等待前一部路徑上節(jié)點(diǎn)的通知消息。

解鎖協(xié)議非常簡(jiǎn)單:需要釋放鎖的客戶端只需要?jiǎng)h除在第 1 步中創(chuàng)建的節(jié)點(diǎn)即可。

注意事項(xiàng):

  • 一個(gè)節(jié)點(diǎn)的刪除只會(huì)導(dǎo)致一個(gè)客戶端被喚醒,因?yàn)槊總€(gè)節(jié)點(diǎn)只被一個(gè)客戶端監(jiān)視,這避免了羊群效應(yīng)。

  • 沒有輪詢和超時(shí)。

  • 根據(jù)你實(shí)現(xiàn)鎖的方式不同,不同的實(shí)現(xiàn)可能會(huì)帶來大量的鎖競(jìng)爭(zhēng),鎖中斷,調(diào)試鎖等等。

Shared Locks

在基本的鎖協(xié)議之上,你只需要做一些小的改變就可以實(shí)現(xiàn)共享鎖(shared locks):

獲取讀鎖: 獲取寫鎖:
  1. Call? create( ) ?to create a node with pathname " _locknode_/read-". This is the lock node use later in the protocol. Make sure to set both the? sequence ?and? ephemeral ?flags.

  2. Call? getChildren( ) ?on the lock node? without ?setting the? watch flag - this is important, as it avoids the herd effect.

  3. If there are no children with a pathname starting with " write-" and having a lower sequence number than the node created in step? 1 , the client has the lock and can exit the protocol.

  4. Otherwise, call? exists( ) , with? watch ?flag, set on the node in lock directory with pathname staring with " write-" having the next lowest sequence number.

  5. If? exists( ) ?returns? false , goto step? 2 .

  6. Otherwise, wait for a notification for the pathname from the previous step before going to step? 2

  1. Call? create( ) ?to create a node with pathname " _locknode_/write-". This is the lock node spoken of later in the protocol. Make sure to set both? sequence ?and? ephemeral ?flags.

  2. Call? getChildren( )? on the lock node? without ?setting the? watch ?flag - this is important, as it avoids the herd effect.

  3. If there are no children with a lower sequence number than the node created in step? 1 , the client has the lock and the client exits the protocol.

  4. Call? exists( ), ?with? watch ?flag set, on the node with the pathname that has the next lowest sequence number.

  5. If? exists( ) ?returns? false , goto step? 2 . Otherwise, wait for a notification for the pathname from the previous step before going to step? 2 .

Recoverable Shared Locks

對(duì)共享鎖做一些細(xì)小的改變,我們就可以使共享鎖變成可撤銷的共享鎖:

在第 1 步,在獲取讀者和寫者的鎖協(xié)議中,在調(diào)用? create( ) 后, 立即調(diào)用 getData( ) ,并設(shè)置監(jiān)視。如果客戶端稍后收到了它在第一步創(chuàng)建節(jié)點(diǎn)的通知,它會(huì)再一次在該節(jié)點(diǎn)上調(diào)用? getData( ) ,并設(shè)置監(jiān)視,查找 “unlock” 串。該信號(hào)會(huì)通知客戶端必須釋放鎖。這是因?yàn)椋罁?jù)共享鎖協(xié)議,你可以通過在鎖節(jié)點(diǎn)(lock node)上調(diào)用 setData()(將“unlock”寫入該節(jié)點(diǎn)) 請(qǐng)求擁有該鎖的客戶端放棄該鎖 。

注意該協(xié)議要求鎖的擁有者也同意釋放該鎖,該協(xié)定非常重要,尤其是鎖的擁有者需要在釋放該鎖前做一些處理。 當(dāng)然,你也可以通過約定“撤銷者可以在鎖的擁有者一段時(shí)間沒有刪除該鎖的情況下刪除該鎖節(jié)點(diǎn)”來實(shí)現(xiàn)可撤銷的共享鎖。

兩階段提交(Two-phased Commit)

兩階段提交協(xié)議可以讓分布式系統(tǒng)的所有客戶端決定究竟提交某一事務(wù)或還是終止該事務(wù)。

在 Zookeeper 中,你可以讓協(xié)調(diào)者(coordinator)創(chuàng)建事務(wù)節(jié)點(diǎn),比如,"/app/Tx",從而實(shí)現(xiàn)一個(gè)兩階段提交協(xié)議。 當(dāng)協(xié)調(diào)者(coordinator)創(chuàng)建了子節(jié)點(diǎn)時(shí),子節(jié)點(diǎn)內(nèi)容是未定義的,由于每個(gè)事務(wù)參與方都會(huì)從協(xié)調(diào)者接收事務(wù),參與方讀取每個(gè)子節(jié)點(diǎn)并設(shè)置監(jiān)視。然后每個(gè)參與方通過向與自身相關(guān)的 Znode 節(jié)點(diǎn)寫入數(shù)據(jù)來投票“提交(commit)”或“中止(abort)”事務(wù)。一旦寫入完成,其他的參與方會(huì)被通知到,當(dāng)所有的參與方都投完票后,協(xié)調(diào)者就可以決定究竟是“提交(commit)”或“中止(abort)”事務(wù)。注意,如果某些參與方投票“中止”,節(jié)點(diǎn)是可以決定提前“中止”事務(wù)的。

該實(shí)現(xiàn)方法有趣的地方在于協(xié)調(diào)者的唯一作用是決定參與方的組(the group of sites),創(chuàng)建 Zookeeper 節(jié)點(diǎn), 將事務(wù)傳播到相應(yīng)的參與方,實(shí)際上,Zookeeper 可以通過將消息寫入事務(wù)節(jié)點(diǎn)來傳播事務(wù)。

上述討論的方法存在兩個(gè)明顯的缺點(diǎn),一是消息的復(fù)雜性,復(fù)雜度為 O(n2),另外一個(gè)是僅通過臨時(shí)節(jié)點(diǎn)不能判斷某些參與方是否失效,為了利用臨時(shí)節(jié)點(diǎn)檢測(cè)參與方是否失效,必須參與方創(chuàng)建該節(jié)點(diǎn)。

為了解決第一個(gè)問題,你可以將系統(tǒng)設(shè)置成只有一個(gè)協(xié)調(diào)者可以收到事務(wù)節(jié)點(diǎn)狀態(tài)的變化,一旦協(xié)調(diào)者達(dá)成意見后通知其他參與方, 該方法可擴(kuò)展性較強(qiáng),但是速度很慢,因?yàn)樗械耐ㄐ哦贾赶騾f(xié)調(diào)者。

為了解決第二個(gè)問題,你可以讓參與方把事務(wù)傳播到參與方,并讓每個(gè)參與方創(chuàng)建自己的臨時(shí)節(jié)點(diǎn)。

Leader 選舉(Leader Election)

Zookeeper 實(shí)現(xiàn) Leader 選舉簡(jiǎn)單做法是在創(chuàng)建代表 “proposals” 客戶端的 Znode 節(jié)點(diǎn)時(shí)設(shè)置? SEQUENCE|EPHEMERAL ?標(biāo)志。基本想法是創(chuàng)建一個(gè)節(jié)點(diǎn),比如 "/election",然后在創(chuàng)建子節(jié)點(diǎn)時(shí)"/election/n_"設(shè)置標(biāo)志 SEQUENCE|EPHEMERAL. 當(dāng)設(shè)置順序節(jié)點(diǎn) SEQUENCE 標(biāo)志時(shí),Zookeeper 會(huì)在 "/election" 子節(jié)點(diǎn)的創(chuàng)建過程中自增子節(jié)點(diǎn)名稱后綴的序號(hào),最小后綴序號(hào)的 Znode 節(jié)點(diǎn)表示Leader。

然而,還沒完,監(jiān)視 Leader 失效也是非常重要的,當(dāng)前的 Leader 失效后需要一個(gè)新的客戶端起來接替舊的 Leader 的位置。一個(gè)簡(jiǎn)單的方式是讓所有的應(yīng)用進(jìn)程監(jiān)視當(dāng)前序號(hào)最小的 Znode 節(jié)點(diǎn), 并在當(dāng)前 序號(hào)最小的 Znode 節(jié)點(diǎn)失效是檢查他們是否為新的 Leader(注意當(dāng)前序號(hào)最小的節(jié)點(diǎn)可能會(huì)隨著 Leader 的消失而消失,他們可能是該Leader 節(jié)點(diǎn)的臨時(shí)子節(jié)點(diǎn)). 但是這會(huì)導(dǎo)致'羊群效應(yīng)(herd effect)":在當(dāng)前 Leader 失效后,其他所有的進(jìn)程(節(jié)點(diǎn))將會(huì)收到通知,并在 "/election" 節(jié)點(diǎn)上執(zhí)行 getChildren()來獲取"/election"節(jié)點(diǎn)的子節(jié)點(diǎn)列表,如果客戶端數(shù)目很大,它會(huì)使得Zookeeper服務(wù)器處理的操作次數(shù)急劇上升。為了避免羊群效應(yīng),客戶端只需要監(jiān)視 Znode 節(jié)點(diǎn)中的下一個(gè)節(jié)點(diǎn)就足夠。如果某個(gè)客戶端收到了它正在監(jiān)視的節(jié)點(diǎn)消失的通知,它將成為新的 Leader,因?yàn)榇藭r(shí)沒有其它的 Znode 節(jié)點(diǎn)的序號(hào)比它小。所以這就避免了羊群效應(yīng),并且客戶端也沒有必要監(jiān)視同一個(gè)最小的 Znode 節(jié)點(diǎn)。

以下是偽代碼:

假設(shè) ELECTION 成為Leader 選舉應(yīng)用的路徑,對(duì)于想要成為 Leader 的 Volunteer而言:

  1. 創(chuàng)建 Znode 節(jié)點(diǎn) z,路徑名稱為"ELECTION/n_"并設(shè)置 SEQUENCE 和 EPHEMERAL 標(biāo)志。

  2. 假設(shè) C 是"ELECTION"的子節(jié)點(diǎn)集合,? i 是 z 節(jié)點(diǎn)的序號(hào)。

  3. 監(jiān)視節(jié)點(diǎn) "ELECTION/n_j" 的改變,j 是滿足 j < i 最小的序號(hào),n_j 是 C 節(jié)點(diǎn)集合中的某個(gè)節(jié)點(diǎn)。

當(dāng)收到 Znode 節(jié)點(diǎn)刪除的通知時(shí):

  1. 假設(shè) C 是 “ELECTION” 新的子節(jié)點(diǎn)集合。

  2. 如果 z 是 C 中的最小節(jié)點(diǎn),則執(zhí)行 Leader 選舉流程。

  3. 否則,監(jiān)視節(jié)點(diǎn) "ELECTION/n_j" 的改變,j 是滿足 j < i 最小的序號(hào),n_j 是 C 節(jié)點(diǎn)集合中的某個(gè)節(jié)點(diǎn)。

注意,在子節(jié)點(diǎn)列表中沒有先遣節(jié)點(diǎn)的 Znode 并不意味著該節(jié)點(diǎn)的創(chuàng)建者知道它就是當(dāng)前的Leader,應(yīng)用程序可能需要考慮創(chuàng)建一個(gè)單獨(dú)的 Znode 來確認(rèn)該 Leader 已經(jīng)執(zhí)行了選舉流程。

Zookeeper 內(nèi)容的一些概念


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: avidolzvideo | 黄视频网站免费看 | 日韩成人av在线 | 狠狠狠操 | 香蕉久久久久久 | 欧美一区二区三区久久综合 | 一区二区三区四区国产 | 两性免费视频 | av播放在线 | 91精品亚洲 | 草樱av| 欧美全黄| 久久综合婷婷香五月 | 久久一区| 免费精品视频在线 | 四虎在线视频 | 午夜在线影院 | 国产在线精品一区 | 欧美特黄aaaaaa| 男女男精品视频免费观看 | 91久久青青草原免费 | 亚洲天堂久久精品 | 超碰97在线免费 | 欧美一区二区三区精品国产 | 一区二区三区在线电影 | 久久久久国产成人精品亚洲午夜 | 午夜影院操 | 午夜精品久久久久久久90蜜桃 | 成年免费视频网站入口 | 毛片免费看电影 | 欧美一区二区三区久久久 | 意大利av在线 | 日本免费黄色 | 黄色片免费看网站 | 国产熟妇另类久久久久XYZ | 亚洲三区在线观看 | 久久999| 精品国产九九 | 久久处女视频 | 91在线入口 | 国产极品久久 |