欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:架構(gòu) 微服務(wù)和kafka

柚子快報邀請碼778899分享:架構(gòu) 微服務(wù)和kafka

http://yzkb.51969.com/

一、微服務(wù)簡介

1.單體架構(gòu)

分布式--微服務(wù)--云原生

傳統(tǒng)架構(gòu)(單機(jī)系統(tǒng)),一個項目一個工程:比如商品、訂單、支付、庫存、登錄、注冊等等,統(tǒng)一部署,一個進(jìn)程

all in one的架構(gòu)方式,把所有的功能單元放在一個應(yīng)用里。然后把整個應(yīng)用部署到一臺服務(wù)器上。如果負(fù)載能力不行,將整個應(yīng)用進(jìn)行水平復(fù)制,進(jìn)行擴(kuò)展(擴(kuò)展是指模塊擴(kuò)展,不方便做開發(fā)測試),然后通過負(fù)載均衡實現(xiàn)訪問。

Java實現(xiàn):JSP、Servlet,打包成一個jar、war部署易于開發(fā)和測試:也十分方便部署;當(dāng)需要擴(kuò)展時,只需要將war復(fù)制多份,然后放到多個服務(wù)器上,再做個負(fù)載均衡就可以了。如果某個功能模塊出問題,有可能全站不可訪問,修改Bug后、某模塊功能修改或升級后,需要停掉整個服務(wù),重新整體重新打包、部署這個應(yīng)用war包,功能模塊相互之間耦合度高,相互影響,不適合當(dāng)今互聯(lián)網(wǎng)業(yè)務(wù)功能的快速迭代。特別是對于一個大型應(yīng)用,我們不可能吧所有內(nèi)容都放在一個應(yīng)用里面,我們?nèi)绾尉S護(hù)、如何分工合作都是問題。如果項目龐大,管理難度大

web應(yīng)用服務(wù)器:開源的tomcat、jetty、glassfish。商用的有weblogic、websphere、Jboss

2.微服務(wù)

Microservices Guide

每個模塊跑一個單獨(dú)應(yīng)用,微服務(wù)關(guān)注的業(yè)務(wù)邏輯(restful、API、http、grpc、tcp、http),

屬于SOA(Service Oriented Architecture)的子集

微服務(wù)化的核心就是將傳統(tǒng)的一站式應(yīng)用,根據(jù)業(yè)務(wù)拆分成一個一個的服務(wù),徹底去掉耦合,每一個微服務(wù)提供單個業(yè)務(wù)功能,一個服務(wù)只做一件事。每個服務(wù)都圍繞著具體業(yè)務(wù)進(jìn)行構(gòu)建,并且能夠被獨(dú)立地部署到生產(chǎn)環(huán)境、類生產(chǎn)環(huán)境等

從技術(shù)角度講就是一種小而獨(dú)立的處理過程,類似與進(jìn)程的概念,能夠自行單獨(dú)啟動或銷毀

微服務(wù)架構(gòu)(分布式系統(tǒng)),各個模塊/服務(wù),各自獨(dú)立出來,"讓專業(yè)的人干專業(yè)的事",獨(dú)立部署。分布式系統(tǒng)中,不同的服務(wù)可以使用各自獨(dú)立的數(shù)據(jù)庫。

服務(wù)之間采用輕量級的通信機(jī)制(通常是基于HTTP的RESTful API)。

微服務(wù)設(shè)計的思想改變了原有的企業(yè)研發(fā)團(tuán)隊組織架構(gòu)。傳統(tǒng)的研發(fā)組織架構(gòu)是水平架構(gòu),前端、后端、DBA、測試分別有自己對應(yīng)的團(tuán)隊,屬于水平團(tuán)隊組織架構(gòu)。而微服務(wù)的設(shè)計思想對團(tuán)隊的劃分有著一定的影響,使得團(tuán)隊組織架構(gòu)的劃分更傾向于垂直架構(gòu),比如用戶業(yè)務(wù)是一個團(tuán)隊來負(fù)責(zé),支付業(yè)務(wù)是一個團(tuán)隊來負(fù)責(zé)。但實際上在企業(yè)中并不會把團(tuán)隊組織架構(gòu)拆分得這么絕對,垂直架構(gòu)只是一種理想的架構(gòu)

微服務(wù)的實現(xiàn)框架有多種,不同的應(yīng)用架構(gòu),部署方式也有不同?

3.單體架構(gòu)和微服務(wù)比較

單體架構(gòu)的主要特征:

1.緊密耦合的組件:在單體架構(gòu)中,組件之間緊密耦合,這使得修改和擴(kuò)展應(yīng)用程序的各個部分而不影響整個系統(tǒng)變得更加困難。

2.單一代碼庫:應(yīng)用程序的所有部分都位于單一的代碼庫中,這對于開發(fā)和部署非常方便。

3.共享資源:組件共享相同的資源,如內(nèi)存和CPU,這可能導(dǎo)致性能瓶頸和爭用問題。

4.有限的可擴(kuò)展性:單體應(yīng)用程序在水平方向上進(jìn)行擴(kuò)展可能具有挑戰(zhàn)性,因為擴(kuò)展一個組件可能需要擴(kuò)展整個應(yīng)用程序。

5.復(fù)雜性:隨著應(yīng)用程序的增長,由于復(fù)雜性增加,維護(hù)和理解可能變得困難。

微服務(wù)架構(gòu)的主要特征:

1.松散耦合:微服務(wù)之間松散耦合,允許每個服務(wù)獨(dú)立開發(fā)、部署和擴(kuò)展,而不影響其他服務(wù)。

2.分布式系統(tǒng):微服務(wù)通過網(wǎng)絡(luò)通信,通常使用API,這需要仔細(xì)考慮網(wǎng)絡(luò)和通信模式。

3.獨(dú)立部署:服務(wù)可以獨(dú)立部署,實現(xiàn)持續(xù)交付和更快的發(fā)布周期。

4.專業(yè)化服務(wù):每個微服務(wù)專注于特定的業(yè)務(wù)功能,使代碼庫更易于管理和維護(hù)。

5.可擴(kuò)展性:微服務(wù)可以單獨(dú)擴(kuò)展,根據(jù)需求有效地分配資源。

6.多語言架構(gòu):不同的微服務(wù)可以使用最適合其需求的不同編程語言和技術(shù)進(jìn)行開發(fā)。?

4.微服務(wù)的優(yōu)缺點(diǎn)

微服務(wù)優(yōu)點(diǎn):

每個服務(wù)足夠內(nèi)聚,足夠小,代碼容易理解。這樣能聚焦一個簡單唯一的業(yè)務(wù)功能或業(yè)務(wù)需求。開發(fā)簡單、開發(fā)效率提高,一個服務(wù)可能就是專業(yè)的只干一件事,微服務(wù)能夠被小團(tuán)隊單獨(dú)開發(fā),這個小團(tuán)隊可以是2到5人的開發(fā)人員組成

微服務(wù)是松耦合的,是有功能意義的服務(wù),無論是在開發(fā)階段或部署階段都是獨(dú)立的。

微服務(wù)能使用不同的語言開發(fā),易于和第三方集成,微服務(wù)運(yùn)行容易且靈活的方式集成自動部署,通過持續(xù)集成工具,如:Jenkins、Hudson、Bamboo

微服務(wù)易于被一個開發(fā)人員理解、修改和維護(hù),這樣小團(tuán)隊能夠更關(guān)注自己的工作成果,無需通過合作才能體現(xiàn)價值

微服務(wù)允許你利用融合最新技術(shù)。微服務(wù)只是業(yè)務(wù)邏輯的代碼,不會和HTML/CSS或其他界面組件混合,即前后端分離

每個微服務(wù)都有自己的存儲能力,可以有自己的數(shù)據(jù)庫,也可以有統(tǒng)一數(shù)據(jù)庫

微服務(wù)缺點(diǎn):(耦合性低,通信比較復(fù)雜,通過url)

微服務(wù)把原有的一個項目拆分成多個獨(dú)立工程,增加了開發(fā)(編寫API)、測試、運(yùn)維(上線,需要會docker)、監(jiān)控等的復(fù)雜度

微服務(wù)架構(gòu)需要保證不同服務(wù)之間的數(shù)據(jù)一致性,引入了分布式事務(wù)和異步補(bǔ)償機(jī)制,為設(shè)計和開發(fā)帶來一定挑戰(zhàn)

開發(fā)人員和運(yùn)維需要處理分布式系統(tǒng)的復(fù)雜性,需要更強(qiáng)的技術(shù)能力

微服務(wù)適用于復(fù)雜的大系統(tǒng),對于小型應(yīng)用使用微服務(wù),進(jìn)行盲目的拆分只會增加其維護(hù)和開發(fā)成本

微服務(wù)技術(shù)棧

微服務(wù)治理:

注冊中心:將所有API、網(wǎng)關(guān)、Url,接口、端口所有調(diào)用的關(guān)系,放到注冊中心去,所有客戶端先訪問一個中間件發(fā)現(xiàn)中心,然后發(fā)現(xiàn)中心可以找到對應(yīng)的調(diào)用關(guān)系,然后客戶再次訪問就可以訪問到對應(yīng)的api節(jié)點(diǎn)

一旦微服務(wù)發(fā)生變更,會同步到注冊中心/目錄下

配置中心是一種統(tǒng)一管理各種應(yīng)用配置的基礎(chǔ)服務(wù)組件。12

配置中心的主要作用是將配置從應(yīng)用中抽取出來,進(jìn)行統(tǒng)一管理,從而優(yōu)雅地解決配置的動態(tài)變更、權(quán)限管理、持久化、運(yùn)維成本等問題。通過集中管理配置,配置中心將應(yīng)用的配置作為一個單獨(dú)的服務(wù)抽離出來,同時也需要解決新的問題,如版本管理(為了支持回滾)、權(quán)限管理等。在系統(tǒng)架構(gòu)中,配置中心是整個微服務(wù)基礎(chǔ)架構(gòu)體系中的一個組件,雖然其功能看似簡單,即配置的管理和存取,但它是整個微服務(wù)架構(gòu)中不可或缺的一環(huán)。

微服務(wù)網(wǎng)關(guān):做業(yè)務(wù)的擴(kuò)展,做OA系統(tǒng)(辦公、審計)

API網(wǎng)關(guān):將多個不同業(yè)務(wù)的API整合在一起,業(yè)務(wù)的擴(kuò)展、動態(tài)自制的管理反向代理、網(wǎng)關(guān)、負(fù)載均衡;API是入口,它還可以做限流(藍(lán)綠),流量控制、熔斷降級

微服務(wù)、分布式本質(zhì)是區(qū)域中心化

異步通信技術(shù):削峰、限流

把5個技術(shù)棧整合在一起,就會用到微服務(wù)框架

5.常見的微服務(wù)框架

Dubbo

阿里開源貢獻(xiàn)給了ASF,目前已經(jīng)是Apache的頂級項目,一款高性能的Java RPC服務(wù)框架,微服務(wù)生態(tài)體系中的一個重要組件

將單體程序分解成多個功能服務(wù)模塊,模塊間使用Dubbo框架提供的高性能RPC通信

內(nèi)部協(xié)調(diào)使用 Zookeeper,實現(xiàn)服務(wù)注冊、服務(wù)發(fā)現(xiàn)和服務(wù)治理

Spring cloud

一個完整的微服務(wù)解決方案,相當(dāng)于Dubbo的超集

微服務(wù)框架,將單體應(yīng)用拆分為粒度更小的單一功能服務(wù)

基于HTTP協(xié)議的REST(Representational State Transfer 表述性狀態(tài)轉(zhuǎn)移)風(fēng)格實現(xiàn)模塊間通信

二、ZooKeeper

1.zookeeper介紹(注冊中心、配置中心)

ZooKeeper 是一個開源的分布式協(xié)調(diào)服務(wù),ZooKeeper框架最初是在“Yahoo!"上構(gòu)建的,用于以簡單而穩(wěn)健的方式訪問他們的應(yīng)用程序。 后來,Apache ZooKeeper成為Hadoop,HBase和其他分布式框架使用的有組織服務(wù)的標(biāo)準(zhǔn)。 例如,Apache HBase使用ZooKeeper跟蹤分布式數(shù)據(jù)的狀態(tài)。ZooKeeper 的設(shè)計目標(biāo)是將那些復(fù)雜且容易出錯的分布式一致性服務(wù)封裝起來,構(gòu)成一個高效可靠的原語集,并以一系列簡單易用的接口提供給用戶使用。

ZooKeeper 是一個典型的分布式數(shù)據(jù)一致性解決方案,分布式應(yīng)用程序可以基于 ZooKeeper 實現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱、負(fù)載均衡、命名服務(wù)、分布式協(xié)調(diào)/通知、集群管理、Master 選舉、分布式鎖(為了保持一致性,API、URL、配置文件內(nèi)容保持一致)和分布式隊列等功能。

Zookeeper 一個最常用的使用場景就是用于擔(dān)任服務(wù)生產(chǎn)者和服務(wù)消費(fèi)者的注冊中心(提供發(fā)布訂閱服務(wù))。 服務(wù)生產(chǎn)者將自己提供的服務(wù)注冊到Zookeeper中心,服務(wù)的消費(fèi)者在進(jìn)行服務(wù)調(diào)用的時候先到Zookeeper中查找服務(wù),獲取到服務(wù)生產(chǎn)者的詳細(xì)信息之后,再去調(diào)用服務(wù)生產(chǎn)者的內(nèi)容與數(shù)據(jù)。如下圖所示,在 Dubbo架構(gòu)中 Zookeeper 就擔(dān)任了注冊中心這一角色。

2.zookeeper工作原理

ZooKeeper 是一個分布式服務(wù)框架,它主要是用來解決分布式應(yīng)用中經(jīng)常遇到的一些數(shù)據(jù)管理問題,如:命名服務(wù)、狀態(tài)同步、配置中心、集群管理等。

①:ZooKeeper 功能

命名服務(wù)

命名服務(wù)是分布式系統(tǒng)中比較常見的一類場景。命名服務(wù)是分布式系統(tǒng)最基本的公共服務(wù)之一。在分布式系統(tǒng)中,被命名的實體通??梢允羌褐械臋C(jī)器、提供的服務(wù)地址或遠(yuǎn)程對象等——這些我們都可以統(tǒng)稱它們?yōu)槊郑∟ame),其中較為常見的就是一些分布式服務(wù)框架(如RPC、RMI)中的服務(wù)地址列表,通過使用命名服務(wù),客戶端應(yīng)用能夠根據(jù)指定名字來獲取資源的實體、服務(wù)地址和提供者的信息等。

Zookeeper 數(shù)據(jù)模型(樹狀結(jié)構(gòu))

在 Zookeeper 中,節(jié)點(diǎn)分為兩類,第一類是指構(gòu)成Zookeeper集群的主機(jī),稱之為主機(jī)節(jié)點(diǎn);第二類則是指內(nèi)存中zookeeper數(shù)據(jù)模型中的數(shù)據(jù)單元,用來存儲各種數(shù)據(jù)內(nèi)容,稱之為數(shù)據(jù)節(jié)點(diǎn) ZNode。Zookeeper內(nèi)部維護(hù)了一個層次關(guān)系(樹狀結(jié)構(gòu))的數(shù)據(jù)模型,它的表現(xiàn)形式類似于Linux的文件系統(tǒng),甚至操作的種類都一致。

Zookeeper數(shù)據(jù)模型中有自己的根目錄(/),根目錄下有多個子目錄,每個子目錄后面有若干個文件,由斜杠(/)進(jìn)行分割的路徑,就是一個ZNode,每個 ZNode上都會保存自己的數(shù)據(jù)內(nèi)容和一系列屬性信息.(把狀態(tài),相關(guān)模塊都放在注冊中心)

狀態(tài)同步

每個節(jié)點(diǎn)除了存儲數(shù)據(jù)內(nèi)容和 node 節(jié)點(diǎn)狀態(tài)信息之外,還存儲了已經(jīng)注冊的APP 的狀態(tài)信息,當(dāng)有些節(jié)點(diǎn)或APP 不可用,就將當(dāng)前狀態(tài)同步給其他服務(wù)。

配置中心

現(xiàn)在我們大多數(shù)應(yīng)用都是采用的是分布式開發(fā)的應(yīng)用,搭建到不同的服務(wù)器上,我們的配置文件,同一個應(yīng)用程序的配置文件一樣,還有就是多個程序存在相同的配置,當(dāng)我們配置文件中有個配置屬性需要改變,我們需要改變每個程序的配置屬性,這樣會很麻煩的去修改配置,那么可用使用ZooKeeper 來實現(xiàn)配置中心, ZooKeeper 采用的是推拉相結(jié)合的方式:客戶端向服務(wù)端注冊自己需要關(guān)注的節(jié)點(diǎn),一旦該節(jié)點(diǎn)的數(shù)據(jù)發(fā)生變更,那么服務(wù)端就會向相應(yīng)的客戶端發(fā)送Watcher事件通知,客戶端接收到這個消息通知后,需要主動到服務(wù)端獲取最新的數(shù)據(jù)。

Apollo(阿波羅)是攜程框架部門研發(fā)的開源配置管理中心,此應(yīng)用比較流行

集群管理

所謂集群管理,包括集群監(jiān)控與集群控制兩大塊,前者側(cè)重對集群運(yùn)行時狀態(tài)的收集,后者則是對集群進(jìn)行操作與控制,在日常開發(fā)和運(yùn)維過程中,我們經(jīng)常會有類似于如下的需求:

希望知道當(dāng)前集群中究竟有多少機(jī)器在工作。

對集群中每臺機(jī)器的運(yùn)行時狀態(tài)進(jìn)行數(shù)據(jù)收集。對集群中機(jī)器進(jìn)行上下線操作。

ZooKeeper 具有以下兩大特性:

客戶端如果對ZooKeeper 的一個數(shù)據(jù)節(jié)點(diǎn)注冊 Watcher監(jiān)聽,那么當(dāng)該數(shù)據(jù)節(jié)點(diǎn)的內(nèi)容或是其子節(jié)點(diǎn)列表發(fā)生變更時,ZooKeeper服務(wù)器就會向已注冊訂閱的客戶端發(fā)送變更通知。對在ZooKeeper上創(chuàng)建的臨時節(jié)點(diǎn),一旦客戶端與服務(wù)器之間的會話失效,那么該臨時節(jié)點(diǎn)也就被自動清除。

Watcher(事件監(jiān)聽器)是 Zookeeper 中的一個很重要的特性。Zookeeper 允許用戶在指定節(jié)點(diǎn)上注冊一些 Watcher,并且在一些特定事件觸發(fā)的時候, ZooKeeper 服務(wù)端會將事件通知到感興趣的客戶端上去,該機(jī)制是 Zookeeper 實現(xiàn)分布式協(xié)調(diào)服務(wù)的重要特性。

ZooKeeper 服務(wù)流程

1. 生產(chǎn)者啟動

2. 生產(chǎn)者注冊至zookeeper

3. 消費(fèi)者啟動并訂閱頻道

4. zookeeper 通知消費(fèi)者事件

5. 消費(fèi)者調(diào)用生產(chǎn)者

6. 監(jiān)控中心負(fù)責(zé)統(tǒng)計和監(jiān)控服務(wù)狀態(tài)

3.zookeeper單機(jī)部署

官方文檔:https://zookeeper.apache.org/doc/r3.9.0/zookeeperStarted.html#sc_InstallingSingleMode

配置 Java 環(huán)境

官方依賴介紹? ZooKeeper: Because Coordinating Distributed Systems is a Zoo

案例: 安裝單機(jī) zookeeper

wget -P /usr/local/src https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/stable/apache-zookeeper3.9.0-bin.tar.gz

tar xf /usr/local/src/apache-zookeeper-3.9.0-bin.tar.gz -C /usr/local/? ---解壓包

ln -s /usr/local/apache-zookeeper-3.9.0-bin /usr/local/zookeeper? ---做軟鏈接

echo 'PATH=/usr/local/zookeeper/bin:$PATH' > /etc/profile.d/zookeeper.sh? ---做環(huán)境變量

. /etc/profile.d/zookeeper.sh? ?---運(yùn)行環(huán)境變量

cp /usr/local/zookeeper/conf/zoo_sample.cfg /usr/local/zookeeper/conf/zoo.cfg ---做數(shù)據(jù)目錄

?

tickTime=2000? #"滴答時間",用于配置Zookeeper中最小的時間單元長度,單位毫秒,是其它時間配置的基礎(chǔ)

initLimit=10?? #初始化時間,包含啟動和數(shù)據(jù)同步,其值是tickTime的倍數(shù)

syncLimit=5??? #正常工作,心跳監(jiān)測的時間間隔,其值是tickTime的倍數(shù)

dataDir=/tmp/zookeeper #配置Zookeeper服務(wù)存儲數(shù)據(jù)的目錄,基于安全,可以修改為dataDir=/usr/local/zookeeper/data

#dataLogdir=/usr/local/zookeeper/logs #可以指定日志路徑

clientPort=2181 #配置當(dāng)前Zookeeper服務(wù)對外暴露的端口,用戶客戶端和服務(wù)端建立連接會話

autopurge.snapRetainCount=3 #3.4.0中的新增功能:啟用后,ZooKeeper 自動清除功能,會將只保留此最新3個快照和相應(yīng)的事務(wù)日志,并分別保留在dataDir 和dataLogDir中,刪除其余部分,默認(rèn)值為3,最小值為3

autopurge.purgeInterval=24? #3.4.0及之后版本,ZK提供了自動清理日志和快照文件的功能,這個參數(shù)指定了清理頻率,單位是小時,需要配置一個1或更大的整數(shù),默認(rèn)是 0,表示不開啟自動清理功能

啟動 ZooKeeper

zkServer.sh start-foreground

zkServer.sh start

4.zookeeper集群部署

ZooKeeper集群用于解決單點(diǎn)和單機(jī)性能及數(shù)據(jù)高可用等問題

?

zookeeper集群基于Master/Slave的模型,處于主要地位(處理寫操作)的主機(jī)稱為Master節(jié)點(diǎn),處于次要地位(處理讀操作)的主機(jī)稱為 slave節(jié)點(diǎn),生產(chǎn)中讀取的方式一般是以異步復(fù)制方式來實現(xiàn)的。

對于n臺server,每個server都知道彼此的存在。只要有>n/2臺server節(jié)點(diǎn)可用,整個zookeeper系統(tǒng)保持可用。保證zookeep是基數(shù)節(jié)點(diǎn),不可以為偶數(shù)

因此zookeeper集群通常由奇數(shù)臺Server節(jié)點(diǎn)組成

當(dāng)進(jìn)行寫操作時,由leader完成,并且同步到其它follower節(jié)點(diǎn),當(dāng)在保證寫操作在所有節(jié)點(diǎn)的總數(shù)過半后,才會認(rèn)為寫操作成功

下圖表示讀的比例越高,性能越好

機(jī)器越多,寫性能就越差

集群角色?

?

領(lǐng)導(dǎo)者(Leader)??? 負(fù)責(zé)處理寫入請求的,事務(wù)請求的唯一調(diào)度和處理者,負(fù)責(zé)進(jìn)行投票發(fā)起和決議,更新系統(tǒng)狀態(tài)

跟隨者(Follower) ??接收客戶請求并向客戶端返回結(jié)果,在選Leader過程中參與投票

觀察者(Observer)?? 轉(zhuǎn)交客戶端寫請求給leader節(jié)點(diǎn),和同步leader狀態(tài)

? ? ? ? ? ? ? ? ? ? ? ? ? ?和Follower唯一區(qū)別就是不參與Leader投票,也不參與寫操作的"過半寫成功"策略

學(xué)習(xí)者(Learner)??? 和leader進(jìn)行狀態(tài)同步的節(jié)點(diǎn)統(tǒng)稱Learner,包括:Follower和Observer

客戶端(client) ?????請求發(fā)起方

選舉過程

節(jié)點(diǎn)角色狀態(tài):

LOOKING:尋找 Leader 狀態(tài),處于該狀態(tài)需要進(jìn)入選舉流程

LEADING:領(lǐng)導(dǎo)者狀態(tài),處于該狀態(tài)的節(jié)點(diǎn)說明是角色已經(jīng)是Leader

FOLLOWING:跟隨者狀態(tài),表示 Leader已經(jīng)選舉出來,當(dāng)前節(jié)點(diǎn)角色是follower

OBSERVER:觀察者狀態(tài),表明當(dāng)前節(jié)點(diǎn)角色是 observer

選舉 ID:

ZXID(zookeeper transaction id):每個改變 Zookeeper狀態(tài)的操作都會形成一個對應(yīng)的zxid。

ZXID最大的節(jié)點(diǎn)優(yōu)先選為Leader

myid:服務(wù)器的唯一標(biāo)識(SID),通過配置 myid 文件指定,集群中唯一,當(dāng)ZXID一樣時,myid大的節(jié)點(diǎn)優(yōu)先選為Leader

ZooKeeper 集群選舉過程:

當(dāng)集群中的 zookeeper 節(jié)點(diǎn)啟動以后,會根據(jù)配置文件中指定的 zookeeper節(jié)點(diǎn)地址進(jìn)行l(wèi)eader 選擇操作,過程如下:

每個zookeeper 都會發(fā)出投票,由于是第一次選舉leader,因此每個節(jié)點(diǎn)都會把自己當(dāng)做leader 角色進(jìn)行選舉,每個zookeeper 的投票中都會包含自己的myid和zxid,此時zookeeper 1 的投票為myid 為 1,初始zxid有一個初始值0x0,后期會隨著數(shù)據(jù)更新而自動變化,zookeeper2 的投票為myid 為2,初始zxid 為初始生成的值。每個節(jié)點(diǎn)接受并檢查對方的投票信息,比如投票時間、是否狀態(tài)為LOOKING狀態(tài)的投票。對比投票,優(yōu)先檢查zxid,如果zxid 不一樣則 zxid 大的為leader,如果zxid相同則繼續(xù)對比myid,myid 大的一方為 leader成為 Leader 的必要條件: Leader 要具有最高的zxid;當(dāng)集群的規(guī)模是 n 時,集群中大多數(shù)的機(jī)器(至少n/2+1)得到響應(yīng)并follower 選出的 Leader。

心跳機(jī)制:Leader 與 Follower 利用 PING 來感知對方的是否存活,當(dāng) Leader無法響應(yīng)PING 時,將重新發(fā)起 Leader 選舉。當(dāng) Leader 服務(wù)器出現(xiàn)網(wǎng)絡(luò)中斷、崩潰退出與重啟等異常情況時,ZAB(Zookeeper Atomic Broadcast) 協(xié)議就會進(jìn)入恢復(fù)模式并選舉產(chǎn)生新的Leader服務(wù)器。這個過程大致如下:

Leader Election(選舉階段):節(jié)點(diǎn)在一開始都處于選舉階段,只要有一個節(jié)點(diǎn)得到超半數(shù)節(jié)點(diǎn)的票數(shù),它就可以當(dāng)選準(zhǔn) leader。

Discovery(發(fā)現(xiàn)階段):在這個階段,followers 跟準(zhǔn) leader 進(jìn)行通信,同步 followers 最近接收的事務(wù)提議。

Synchronization(同步階段):同步階段主要是利用 leader 前一階段獲得的最新提議歷史,同步集群中所有的副本。同步完成之后 準(zhǔn) leader 才會成為真正的 leader。

Broadcast(廣播階段) :到了這個階段,Zookeeper 集群才能正式對外提供事務(wù)服務(wù),并且leader 可以進(jìn)行消息廣播。同時如果有新的節(jié)點(diǎn)加入,還需要對新節(jié)點(diǎn)進(jìn)行同步

ZAB 協(xié)議介紹

ZAB(ZooKeeper Atomic Broadcast 原子廣播) 協(xié)議是為分布式協(xié)調(diào)服務(wù) ZooKeeper 專門設(shè)計的一種支持崩潰恢復(fù)的原子廣播協(xié)議。 在 ZooKeeper 中,主要依賴 ZAB 協(xié)議來實現(xiàn)分布式數(shù)據(jù)一致性,基于該協(xié)議,ZooKeeper 實現(xiàn)了一種主備模式的系統(tǒng)架構(gòu)來保持集群中各個副本之間的數(shù)據(jù)一致性。

ZooKeeper 集群特性

整個集群中只要有超過集群數(shù)量一半的 zookeeper工作是正常的,那么整個集群對外就是可用的假如有 2 臺服務(wù)器做了一個 Zookeeper 集群,只要有任何一臺故障或宕機(jī),那么這個 ZooKeeper集群就不可用了,因為剩下的一臺沒有超過集群一半的數(shù)量,但是假如有三臺zookeeper 組成一個集群, 那么損壞一臺就還剩兩臺,大于 3臺的一半,所以損壞一臺還是可以正常運(yùn)行的,但是再損壞一臺就只剩一臺集群就不可用了。那么要是 4 臺組成一個zookeeper集群,損壞一臺集群肯定是正常的,那么損壞兩臺就還剩兩臺,那么2臺不大于集群數(shù)量的一半,所以 3 臺的 zookeeper 集群和 4 臺的 zookeeper集群損壞兩臺的結(jié)果都是集群不可用,以此類推 5 臺和 6 臺以及 7 臺和 8臺都是同理

另外偶數(shù)節(jié)點(diǎn)可以會造成"腦裂"現(xiàn)象,所以這也就是為什么集群一般都是奇數(shù)的原因。

ZooKeeper 集群部署

運(yùn)行腳本進(jìn)行安裝

配置文件和單機(jī)模式略微不同之處

?nc 訪問 ZooKeeper

ZooKeeper支持某些特定的四字命令字母與其的交互。它們大多是查詢命令,用來獲取 ZooKeeper服務(wù)的當(dāng)前狀態(tài)及相關(guān)信息。用戶在客戶端可以通過 netcat 或telnet向zookeeper發(fā)送下面命令

conf #輸出相關(guān)服務(wù)配置的詳細(xì)信息

cons #列出所有連接到服務(wù)器的客戶端的完全的連接/會話的詳細(xì)信息

envi #輸出關(guān)于服務(wù)環(huán)境的詳細(xì)信息

dump #列出未經(jīng)處理的會話和臨時節(jié)點(diǎn)

stat #查看哪個節(jié)點(diǎn)被選擇作為Follower或者Leader

ruok #測試是否啟動了該Server,若回復(fù)imok表示已經(jīng)啟動

mntr #輸出一些運(yùn)行時信息

reqs #列出未經(jīng)處理的請求

wchs #列出服務(wù)器watch的簡要信息

wchc #通過session列出服務(wù)器watch的詳細(xì)信息

wchp #通過路徑列出服務(wù)器watch的詳細(xì)信息

srvr #輸出服務(wù)的所有信息

srst #重置服務(wù)器統(tǒng)計信息

kill #關(guān)掉Server

isro #查看該服務(wù)的節(jié)點(diǎn)權(quán)限信息

將所有四字命令加入白名單

vim conf/zoo.cfg

4lw.commands.whitelist=*

echo stat | nc 127.0.0.1 2181

?

?

改完之后重啟服務(wù):systemctl restart zookeeper.service?

圖形化客戶端 ZooInspector

git clone GitHub - zzhang5/zooinspector: An improved zookeeper inspector?? 然后結(jié)合阿里云加速進(jìn)行mvn編譯即可使用

cd zooinspector/

mvn clean package -Dmaven.test.skip=true

chmod +x target/zooinspector-pkg/bin/zooinspector.sh

target/zooinspector-pkg/bin/zooinspector.sh

三、kafka

消息隊列歷史

2007 年的時候,Rabbit 技術(shù)公司基于Erlang語言開發(fā)了符合AMQP 規(guī)范RabbitMQ 1.0。

從最開始用在金融行業(yè)里面,現(xiàn)在MQ 已經(jīng)在世界各地的公司中遍地開花。國內(nèi)的絕大部分大廠都在用MQ,包括頭條,美團(tuán),滴滴,去哪兒,藝龍,淘寶也有用。

kafka的數(shù)據(jù)是存儲到zookeep中的/目錄下,kafka嫁接在zookeep上,kafka的消息是分片的,

MQ 定義

在分布式場景中,相對于大量的用戶請求來說,內(nèi)部的功能主機(jī)之間、功能模塊之間等,數(shù)據(jù)傳遞的數(shù)據(jù)量是無法想象的,因為一個用戶請求,會涉及到各種內(nèi)部的業(yè)務(wù)邏輯跳轉(zhuǎn)等操作。那么,在大量用戶的業(yè)務(wù)場景中,如何保證所有的內(nèi)部業(yè)務(wù)邏輯請求都處于穩(wěn)定而且快捷的數(shù)據(jù)傳遞呢? 消息隊列(Message Queue)技術(shù)可以滿足此需求

消息隊列(Message Queue,簡稱 MQ)是構(gòu)建分布式互聯(lián)網(wǎng)應(yīng)用的基礎(chǔ)設(shè)施,通過 MQ 實現(xiàn)的松耦合架構(gòu)設(shè)計可以提高系統(tǒng)可用性以及可擴(kuò)展性,是適用于現(xiàn)代應(yīng)用的最佳設(shè)計方案。

消息隊列是一種異步的服務(wù)間通信方式,適用于無服務(wù)器和微服務(wù)架構(gòu)。消息在被處理和刪除之前一直存儲在隊列上。每條消息僅可被一位用戶處理一次。消息隊列可被用于分離重量級處理、緩沖或批處理工作以及緩解高峰期工作負(fù)載。

MQ 使用場合

消息隊列作為高并發(fā)系統(tǒng)的核心組件之一,能夠幫助業(yè)務(wù)系統(tǒng)結(jié)構(gòu)提升開發(fā)效率和系統(tǒng)穩(wěn)定性

消息隊列主要有以下應(yīng)用場景

削峰填谷

諸如電商業(yè)務(wù)中的秒殺、搶紅包、企業(yè)開門紅等大型活動時皆會帶來較高的流量脈沖,或因沒做相應(yīng)的保護(hù)而導(dǎo)致系統(tǒng)超負(fù)荷甚至崩潰,或因限制太過導(dǎo)致請求大量失敗而影響用戶體驗,消息隊列可提供削峰填谷的服務(wù)來解決該問題。

異步解耦

交易系統(tǒng)作為淘寶等電商的最核心的系統(tǒng),每筆交易訂單數(shù)據(jù)的產(chǎn)生會引起幾百個下游業(yè)務(wù)系統(tǒng)的關(guān)注,包括物流、購物車、積分、流計算分析等等,整體業(yè)務(wù)系統(tǒng)龐大而且復(fù)雜,消息隊列可實現(xiàn)異步通信和應(yīng)用解耦,確保主站業(yè)務(wù)的連續(xù)性。

順序收發(fā)

細(xì)數(shù)日常中需要保證順序的應(yīng)用場景非常多,例如證券交易過程時間優(yōu)先原則,交易系統(tǒng)中的訂單創(chuàng)建、支付、退款等流程,航班中的旅客登機(jī)消息處理等等。與先進(jìn)先出FIFO(First In First Out)原理類似,消息隊列提供的順序消息即保證消息FIFO。

分布式事務(wù)一致性(zookeep)

交易系統(tǒng)、支付紅包等場景需要確保數(shù)據(jù)的最終一致性,大量引入消息隊列的分布式事務(wù),既可以實現(xiàn)系統(tǒng)之間的解耦,又可以保證最終的數(shù)據(jù)一致性。

大數(shù)據(jù)分析

數(shù)據(jù)在“流動”中產(chǎn)生價值,傳統(tǒng)數(shù)據(jù)分析大多是基于批量計算模型,而無法做到實時的數(shù)據(jù)分析,利用消息隊列與流式計算引擎相結(jié)合,可以很方便的實現(xiàn)業(yè)務(wù)數(shù)據(jù)的實時分析。

分布式緩存同步

電商的大促,各個分會場琳瑯滿目的商品需要實時感知價格變化,大量并發(fā)訪問數(shù)據(jù)庫導(dǎo)致會場頁面響應(yīng)時間長,集中式緩存因帶寬瓶頸,限制了商品變更的訪問流量,通過消息隊列構(gòu)建分布式緩存,實時通知商品數(shù)據(jù)的變化

蓄流壓測

線上有些鏈路不方便做壓力測試,可以通過堆積一定量消息再放開來壓測

消息隊列在測試環(huán)境做壓測,先不在生產(chǎn)環(huán)境上線

主流 MQ

目前主流的消息隊列軟件有 kafka、RabbitMQ、ActiveMQ、RocketMQ等,還有相對小眾的消息隊列軟件如ZeroMQ、Apache Qpid 等。

kafka不能做集群,但是可以基于zookeep做集群

Kafka 介紹

Kafka 被稱為下一代分布式消息系統(tǒng),由 Scala 和 Java編寫,是非營利性組織ASF(Apache Software Foundation)基金會中的一個開源項目,比如:HTTP Server、Tomcat、Hadoop、ActiveMQ等開源軟件都屬于 Apache基金會的開源軟件,類似的消息系統(tǒng)還有RabbitMQ、ActiveMQ、ZeroMQ。

Kafka用于構(gòu)建實時數(shù)據(jù)管道和流應(yīng)用程序。 它具有水平可伸縮性,容錯性,快速性,可在數(shù)千家組織中同時投入生產(chǎn)協(xié)同工作。

Kafka 特點(diǎn)和優(yōu)勢

特點(diǎn)

分布式: 多機(jī)實現(xiàn),不允許單機(jī)

分區(qū): 一個消息.可以拆分出多個,分別存儲在多個位置

多副本: 防止信息丟失,可以多來幾個備份

多訂閱者: 可以有很多應(yīng)用連接kafka,在kafka中沒有嚴(yán)格的說法,都叫訂閱者

Zookeeper: 早期版本的Kafka依賴于zookeeper, 2021年4月19日Kafka 2.8.0正式發(fā)布,此版本包括了很多重要改動,最主要的是kafka通過自我管理的仲裁來替代ZooKeeper,即Kafka將不再需要ZooKeeper!

優(yōu)勢

Kafka 通過 O(1)的磁盤數(shù)據(jù)結(jié)構(gòu)提供消息的持久化,這種結(jié)構(gòu)對于即使數(shù)以 TB 級別以上的消息存儲也能夠保持長時間的穩(wěn)定性能。

高吞吐量:即使是非常普通的硬件Kafka也可以支持每秒數(shù)百萬的消息。支持通過Kafka 服務(wù)器分區(qū)消息。

分布式: Kafka 基于分布式集群實現(xiàn)高可用的容錯機(jī)制,可以實現(xiàn)自動的故障轉(zhuǎn)移

順序保證:在大多數(shù)使用場景下,數(shù)據(jù)處理的順序都很重要。大部分消息隊列本來就是排序的,并且能保證數(shù)據(jù)會按照特定的順序來處理。 Kafka保證一個Partiton內(nèi)的消息的有序性(分區(qū)間數(shù)據(jù)是無序的,如果對數(shù)據(jù)的順序有要求,應(yīng)將在創(chuàng)建主題時將分區(qū)數(shù)partitions設(shè)置為1)

支持 Hadoop 并行數(shù)據(jù)加載

通常用于大數(shù)據(jù)場合,傳遞單條消息比較大,而Rabbitmq (支持單條小消息)消息主要是傳輸業(yè)務(wù)的指令數(shù)據(jù),單條數(shù)據(jù)較小,不適合集群化大規(guī)模的場景

Kafka 角色

Producer:Producer即生產(chǎn)者,消息的產(chǎn)生者,是消息的入口。負(fù)責(zé)發(fā)布消息到Kafka broker。

Consumer:消費(fèi)者,用于消費(fèi)消息,即處理消息

Consumer group: 每個consumer 屬于一個特定的consumer group(可為每個consumer 指定 group name,若不指定 group name 則屬于默認(rèn)的group),使用 consumer high level API 時,同一topic的一條消息只能被同一個consumer group 內(nèi)的一個consumer 消費(fèi),但多個consumer group 可同時消費(fèi)這一消息。

Broker:Broker是kafka實例,每個服務(wù)器上可以有一個或多個kafka的實例,假設(shè)每個broker對應(yīng)一臺服務(wù)器。每個kafka集群內(nèi)的broker都有一個不重復(fù)的編號,如: broker-0、broker-1等……

Topic :消息的主題,可以理解為消息的分類,相當(dāng)于Redis的Key和ES中的索引,kafka的數(shù)據(jù)就保存在topic。在每個broker上都可以創(chuàng)建多個topic。物理上不同 topic 的消息分開存儲在不同的文件夾,邏輯上一個 topic的消息雖然保存于一個或多個broker 上, 但用戶只需指定消息的topic即可生產(chǎn)或消費(fèi)數(shù)據(jù)而不必關(guān)心數(shù)據(jù)存于何處,topic 在邏輯上對record(記錄、日志)進(jìn)行分組保存,消費(fèi)者需要訂閱相應(yīng)的topic 才能消費(fèi)topic中的消息。

Replication: 同樣數(shù)據(jù)的副本,包括leader和follower的副本數(shù),基本于數(shù)據(jù)安全,建議至少2個,是Kafka的高可靠性的保障,和ES不同的,ES中的副本數(shù)不包括主分片數(shù)

Partition :是物理上的概念,每個topic 分割為一個或多個partition,即一個topic切分為多份.創(chuàng)建topic時可指定 parition 數(shù)量,partition的表現(xiàn)形式就是一個一個的文件夾,該文件夾下存儲該partition的數(shù)據(jù)和索引文件,分區(qū)的作用還可以實現(xiàn)負(fù)載均衡,提高kafka的吞吐量。同一個topic在不同的分區(qū)的數(shù)據(jù)是不重復(fù)的,一般Partition數(shù)不要超過節(jié)點(diǎn)數(shù)據(jù),注意同一個partition數(shù)據(jù)是有順序的,但不同的partition則是無序的。為了實現(xiàn)數(shù)據(jù)的高可用,比如將分區(qū) 0 的數(shù)據(jù)分散到不同的kafka 節(jié)點(diǎn),每一個分區(qū)都有一個 broker 作為 Leader 和一個 broker 作為Follower,類似于ES中的主分片和副本分片,

AR: Assigned Replicas,分區(qū)中的所有副本的統(tǒng)稱,AR= lSR+ OSR

lSR:ln Sync Replicas,所有與leader副本保持同步的副本 follower和leader本身組成的集合,是AR的子集

OSR:out-of-Sync Replied,所有與leader副本同步不能同步的 follower的集合,是AR的子集

分區(qū)的優(yōu)勢:

實現(xiàn)存儲空間的橫向擴(kuò)容,即將多個kafka服務(wù)器的空間結(jié)合利用提升性能,多服務(wù)器讀寫

實現(xiàn)高可用,分區(qū)leader 分布在不同的kafka 服務(wù)器,假設(shè)分區(qū)因子為 3, 分區(qū) 0 的leader為服務(wù)器A,則服務(wù)器 B 和服務(wù)器 C 為 A 的follower,而分區(qū) 1 的leader為服務(wù)器B,則服務(wù)器 A 和C 為服務(wù)器B 的follower,而分區(qū) 2 的leader 為C,則服務(wù)器A 和 B 為C 的follower。

假如設(shè)置一個wang的topic,它會生成多個目錄,在第一臺機(jī)器上有兩個目錄,一個存主本,一個存副本;第二個機(jī)器有兩個目錄,一個存主本,一個存副本;第三個機(jī)器有兩個目錄,都存副本。交叉是為了防止崩,這樣做可以保證數(shù)據(jù)的高可用

Kafka 寫入消息的流程

Kafka 部署

當(dāng)前版本 Kafka 依賴 Zookeeper 服務(wù),但以后將不再依賴

環(huán)境說明

#在三個節(jié)點(diǎn)提前部署zookeeper和kafka三個節(jié)點(diǎn)復(fù)用

node1:192.168.10.110

node2:192.168.10.110

node3:192.168.10.110

注意:生產(chǎn)中zookeeper和kafka一般是分開獨(dú)立部署的,kafka安裝前需要安裝java環(huán)境;確保三個節(jié)點(diǎn)的zookeeper啟動

Kafka 節(jié)點(diǎn)配置

配置文件說明

#配置文件 ./conf/server.properties內(nèi)容說明

############################# Server Basics###############################

# broker的id,值為整數(shù),且必須唯一,在一個集群中不能重復(fù)

broker.id=1

############################# Socket ServerSettings ######################

# kafka監(jiān)聽端口,默認(rèn)9092

listeners=PLAINTEXT://10.0.0.101:9092

# 處理網(wǎng)絡(luò)請求的線程數(shù)量,默認(rèn)為3個

num.network.threads=3

# 執(zhí)行磁盤IO操作的線程數(shù)量,默認(rèn)為8個

num.io.threads=8

# socket服務(wù)發(fā)送數(shù)據(jù)的緩沖區(qū)大小,默認(rèn)100KB

socket.send.buffer.bytes=102400

# socket服務(wù)接受數(shù)據(jù)的緩沖區(qū)大小,默認(rèn)100KB

socket.receive.buffer.bytes=102400

# socket服務(wù)所能接受的一個請求的最大大小,默認(rèn)為100M

socket.request.max.bytes=104857600

############################# Log Basics###################################

# kafka存儲消息數(shù)據(jù)的目錄

log.dirs=../data

# 每個topic默認(rèn)的partition

num.partitions=1

# 設(shè)置副本數(shù)量為3,當(dāng)Leader的Replication故障,會進(jìn)行故障自動轉(zhuǎn)移。

default.replication.factor=3

# 在啟動時恢復(fù)數(shù)據(jù)和關(guān)閉時刷新數(shù)據(jù)時每個數(shù)據(jù)目錄的線程數(shù)量

num.recovery.threads.per.data.dir=1

############################# Log FlushPolicy #############################

# 消息刷新到磁盤中的消息條數(shù)閾值

log.flush.interval.messages=10000

# 消息刷新到磁盤中的最大時間間隔,1s

log.flush.interval.ms=1000

############################# Log RetentionPolicy #########################

# 日志保留小時數(shù),超時會自動刪除,默認(rèn)為7天

log.retention.hours=168

# 日志保留大小,超出大小會自動刪除,默認(rèn)為1G

#log.retention.bytes=1073741824

# 日志分片策略,單個日志文件的大小最大為1G,超出后則創(chuàng)建一個新的日志文件

log.segment.bytes=1073741824

# 每隔多長時間檢測數(shù)據(jù)是否達(dá)到刪除條件,300s

log.retention.check.interval.ms=300000

############################# Zookeeper ####################################

# Zookeeper連接信息,如果是zookeeper集群,則以逗號隔開

zookeeper.connect=192.168.10.110:2181,192.168.10.120:2181,192.168.10.130:2181

# 連接zookeeper的超時時間,6s

zookeeper.connection.timeout.ms=6000

Kafka 讀寫數(shù)據(jù)?

kafka-topics.sh # 消息的管理命令

kafka-console-producer.sh?? #生產(chǎn)者的模擬命令

kafka-console-consumer.sh?? #消費(fèi)者的模擬命令

創(chuàng)建 Topic

創(chuàng)建名為 wang,partitions(分區(qū))為3,replication(每個分區(qū)的副本數(shù)/每個分區(qū)的分區(qū)因子)為 2 的topic(主題)

/usr/local/kafka/bin/kafka-topics.sh --create --topic wang --bootstrap-server 192.168.10.110:9092 --partitions 3 --replication-factor 2

#? 在各節(jié)點(diǎn)上觀察生成的相關(guān)數(shù)據(jù)

ls /usr/local/kafka/data/

#? 獲取所有 Topic

/usr/local/kafka/bin/kafka-topics.sh --list --bootstrap-server 192.168.10.110:9092

#? 驗證 Topic 詳情

/usr/local/kafka/bin/kafka-topics.sh --describe --bootstrapserver 192.168.10.110:9092 --topic wang

#? 生產(chǎn) Topic

/usr/local/kafka/bin/kafka-console-producer.sh --broker-list 192.168.10.110:9092,192.168.10.120:9092,192.168.10.130:9092 --topic wang

#? 消費(fèi) Topic

/usr/local/kafka/bin/kafka-console-consumer.sh --topic wang --bootstrap-server 192.168.10.110:9092 --from-beginning

#? 刪除 Topic

/usr/local/kafka/bin/kafka-topics.sh --delete --bootstrap-server 192.168.10.110:2181,192.168.10.120:2181,192.168.10.130:2181 --topic wang

?

創(chuàng)建消息

?在toplic中生產(chǎn)一下對應(yīng)的生產(chǎn)消息

?消費(fèi)消息

刪除wang這條消息

如何在應(yīng)用程序中關(guān)聯(lián)kafka

首先基于filebeat從應(yīng)用/web端將數(shù)據(jù)先收集進(jìn)來,然后將數(shù)據(jù)先放入kafka中,然后將其適當(dāng)?shù)姆制?,redis做緩存,kafka做消息,然后將基于logstash的INPUT模塊去關(guān)聯(lián)kafka,把kafka/redis中消息消費(fèi)出來,然后輸出值es中

柚子快報邀請碼778899分享:架構(gòu) 微服務(wù)和kafka

http://yzkb.51969.com/

推薦鏈接

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19540669.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄