zookeeper 负载_ZooKeeper,策展人以及微服务负载平衡的工作方式
zookeeper 負(fù)載
Zookeeper如何確保每個(gè)工人都能從工作委托經(jīng)理那里愉快地完成工作。
Apache ZooKeeper是注冊,管理和發(fā)現(xiàn)在不同計(jì)算機(jī)上運(yùn)行的服務(wù)的工具。 當(dāng)我們必須處理具有許多節(jié)點(diǎn)的分布式系統(tǒng)時(shí),它是技術(shù)堆棧中必不可少的成員,這些節(jié)點(diǎn)需要知道其依賴關(guān)系從何處啟動(dòng)。
但是ZooKeeper的級別很低,即使標(biāo)準(zhǔn)用例也需要多行代碼。 這就是Apache Curator誕生的原因-一個(gè)比ZooKeeper更友好,更易于使用的包裝器庫。 使用Curator,我們可以用更少的代碼和更簡潔的方式交付更多內(nèi)容。
“ Guava對Java來說就像Curator對ZooKeeper一樣” – ZooKeeper提交者Patrick Hunt
使用ZooKeeper進(jìn)行負(fù)載均衡微服務(wù)
我們習(xí)慣于在應(yīng)用程序前面部署負(fù)載均衡器的情況。 它的作用是確保每個(gè)單個(gè)節(jié)點(diǎn)獲得或多或少相同的流量。
在微服務(wù)世界中,情況是相同的,但是與單片方法相比,我們具有顯著的優(yōu)勢:當(dāng)我們需要擴(kuò)展應(yīng)用程序時(shí),我們不必復(fù)制整個(gè)系統(tǒng)并將其部署在功能強(qiáng)大的服務(wù)器上即可平穩(wěn)運(yùn)行。 我們只能將精力集中在需要擴(kuò)展的小模塊上,因此擴(kuò)展成本要低得多(無論是在服務(wù)器成本還是在許多情況下準(zhǔn)備模塊部署所需的開發(fā)方面)。
但是隨著我們系統(tǒng)的發(fā)展,我們最終會得到許多可擴(kuò)展的模塊,每個(gè)模塊都需要單獨(dú)的負(fù)載平衡器。 這似乎很麻煩,因?yàn)榧词箾]有基礎(chǔ)設(shè)施,我們的基礎(chǔ)設(shè)施也非常復(fù)雜。 幸運(yùn)的是,如果我們將ZooKeeper用作服務(wù)編排和發(fā)現(xiàn)工具,則可以使用內(nèi)置的負(fù)載平衡功能,而不會在我們的微服務(wù)體系結(jié)構(gòu)中引入任何其他復(fù)雜性。
為了展示ZooKeeper中開箱即用的負(fù)載平衡工作方式,我們需要兩項(xiàng)服務(wù):將被多次部署的工作程序,以及將任務(wù)委派給已注冊工作程序的經(jīng)理。
簡單工人
讓我們從創(chuàng)建一個(gè)簡單的工作程序開始,該工作程序?qū)陕牻o定的端口并在被要求執(zhí)行其工作時(shí)返回一些結(jié)果。 為了實(shí)現(xiàn)這個(gè)微小的微服務(wù),我們將使用Groovy, Undertow輕量級servlet容器,當(dāng)然還要使用ZooKeeper和Curator。
我們的工作人員將由一個(gè)小類組成,該類具有主要方法,可完成三件事:
class Main {static final void main(String[] args) {// Step 1: Extract name and port number to launch worker// Step 2: Configure and start Rest server on given port// Step 3: Register worker in ZooKeeper} }為簡便起見,我將在此處省略步驟1和2,您可以在GitHub project上查看完整的源代碼。 我們的工作人員只有一個(gè)端點(diǎn)GET / work,該端點(diǎn)將返回一個(gè)帶有被調(diào)用工作人員名稱的響應(yīng):
@Path("/") class Main {@GET@Path("/work")public String work() {String response = "Work done by $workerName"println responsereturn response}}步驟3: ZooKeeper中的注冊工作人員是最有趣的地方,因此我將對其進(jìn)行詳細(xì)說明:
private static void registerInZookeeper(int port) {CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient("localhost:2181", new RetryNTimes(5, 1000))curatorFramework.start()ServiceInstance<Void> serviceInstance = ServiceInstance.builder().uriSpec(new UriSpec("{scheme}://{address}:{port}")).address('localhost').port(port).name("worker").build()ServiceDiscoveryBuilder.builder(Void).basePath("load-balancing-example").client(curatorFramework).thisInstance(serviceInstance).build().start() }- 第2-3行:我們創(chuàng)建并啟動(dòng)CuratorFramework客戶端,該客戶端包裝了我們要在ZooKeeper實(shí)例上執(zhí)行的所有操作。 為了簡單起見,我們將localhost與默認(rèn)端口一起使用(通常,它應(yīng)該是ZooKeeper的運(yùn)行實(shí)例的URL)
- 第4-9行創(chuàng)建了代表我們的工作人員的ServiceInstance。 我們傳遞了從其他微服務(wù)呼叫此工作人員所需的所有“聯(lián)系方式”
- 第11-16行在CuratorFramework客戶端代表的ZooKeeper中注冊我們的實(shí)例。
出發(fā)工人
現(xiàn)在,Worker已經(jīng)準(zhǔn)備就緒,因此我們可以創(chuàng)建胖子罐(使用Gradle fatJar任務(wù)),然后使用以下命令啟動(dòng)它:
java -jar simple-worker/build/libs/simple-worker-1.0-shadow.jar Worker_1 18005在啟動(dòng)worker之前,請記住您需要在默認(rèn)2181端口上運(yùn)行的ZooKeeper實(shí)例!
要檢查worker是否正在運(yùn)行,您應(yīng)該在http:// localhost:18005 / work上打開瀏覽器,并在其中看到“ Worker_1完成的工作”文本。 要驗(yàn)證工作人員是否已在ZooKeeper中正確注冊自己,請啟動(dòng)命令行客戶端:
cd/bin ./zkCli.sh然后執(zhí)行l(wèi)s命令,查看在/ load-balancing-example / worker路徑下注冊的一個(gè)節(jié)點(diǎn):
[zk: localhost:2181(CONNECTED) 1] ls /load-balancing-example/worker <enter> [f69545e8-8466-40c0-93e9-f493eb7496b4]簡單的經(jīng)理
現(xiàn)在,由于工作人員正在監(jiān)聽/ work的請求,因此我們可以創(chuàng)建簡單的經(jīng)理服務(wù)委托任務(wù)給其下屬。 主要方法看上去與簡單工作人員項(xiàng)目中的方法非常相似,主要區(qū)別在于我們沒有在ZooKeeper中注冊,我們僅創(chuàng)建角色(給驚喜)為我們提供工作人員實(shí)例的ServiceProvider 。 所以基本的工作流程是:
要?jiǎng)?chuàng)建ServiceProvider,我們必須創(chuàng)建CuratorFramework客戶端,連接到ZooKeeper,然后獲取具有給定名稱的服務(wù)的ServiceProvider,在本例中為worker :
CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient("localhost:2181", new RetryNTimes(5, 1000)) curatorFramework.start()ServiceDiscovery<Void> serviceDiscovery = ServiceDiscoveryBuilder.builder(Void).basePath("load-balancing-example").client(curatorFramework).build() serviceDiscovery.start()serviceProvider = serviceDiscovery.serviceProviderBuilder().serviceName("worker").build() serviceProvider.start()- 第1-2行,創(chuàng)建ZooKeeper客戶端,方法與簡單工作人員相同
- 第4-8行,創(chuàng)建ServiceDiscovery,它將能夠?yàn)槲覀兲峁┓?wù)提供商。
- 第10-11行。 創(chuàng)建并啟動(dòng)ServiceProvider,將用于獲取工作程序節(jié)點(diǎn)的工作實(shí)例。
最后,我們需要一個(gè)Rest端點(diǎn),經(jīng)理在該端點(diǎn)上等待任務(wù)委派:
@GET @Path("/delegate") public String delegate() {def instance = serviceProvider.getInstance()String address = instance.buildUriSpec()String response = (address + "/work").toURL().getText()println responsereturn response }起始經(jīng)理
Manager已準(zhǔn)備就緒,在fatJar任務(wù)完成后,我們可以使用以下命令啟動(dòng)它:
java -jar simple-manager/build/libs/simple-manager-1.0-shadow.jar 18000為了驗(yàn)證它是否正常工作,我們可以在瀏覽器中打開( http:// localhost:18000 / delegate )以查看消息“ Worker_1完成的工作”。
經(jīng)理對其員工一無所知。 他只知道服務(wù)是在ZooKeeper中的特定路徑下注冊的。 這很簡單,無論我們是在本地啟動(dòng)多個(gè)工作人員還是在不同國家的不同服務(wù)器上分散工作。
使用ZooKeeper開箱即用的負(fù)載平衡
想象一下這樣的情況:經(jīng)理從首席執(zhí)行官那里獲得了太多任務(wù),以至于他需要多個(gè)工人來委派工作。 在標(biāo)準(zhǔn)情況下,我們將被迫擴(kuò)大規(guī)模并在他們前面放置負(fù)載平衡器。 但是ZooKeeper無需任何其他工作即可為我們提供此功能。
讓我們添加更多在不同端口上偵聽的工作者:
java -jar simple-worker/build/libs/simple-worker-1.0-shadow.jar Worker_1 18005 &java -jar simple-worker/build/libs/simple-worker-1.0-shadow.jar Worker_2 18006 &java -jar simple-worker/build/libs/simple-worker-1.0-shadow.jar Worker_3 18007 &java -jar simple-worker/build/libs/simple-worker-1.0-shadow.jar Worker_4 18008 &訣竅是所有工作程序都在ZooKeeper中的同一路徑下注冊,因此當(dāng)我們在/ load-balancing-example / worker下列出節(jié)點(diǎn)時(shí),將看到四個(gè)實(shí)例:
[zk: localhost:2181(CONNECTED) 0] ls /load-balancing-example/worker <enter> [d5bc4eb9-8ebb-4b7c-813e-966a25fdd843, 13de9196-bfeb-4c1a-b632-b8b9969b9c0b, 85cd1387-2be8-4c08-977a-0798017379b1, 9e07bd1d-c615-430c-8dcb-bf228e9b56fc]這里最重要的是,要利用這四個(gè)新工作人員,經(jīng)理不需要對代碼進(jìn)行任何更改。 我們可以在流量增加時(shí)啟動(dòng)新的工作程序?qū)嵗?#xff0c;或者在無事可做時(shí)將其關(guān)閉。 Manager從這些操作中分離出來,它仍然調(diào)用ServiceProvider來獲取worker的實(shí)例并將工作傳遞給他。
所以現(xiàn)在當(dāng)我們打開http:// localhost:18000 / delegate并按幾次刷新時(shí),我們將看到:
Work done by Worker_1 Work done by Worker_2 Work done by Worker_3 Work done by Worker_4 Work done by Worker_1 Work done by Worker_2 Work done by Worker_3它是如何實(shí)現(xiàn)的? 默認(rèn)情況下,ServiceProvider使用Rounded-robin ProviderStrategy實(shí)現(xiàn),該實(shí)現(xiàn)旋轉(zhuǎn)給定路徑下可用的實(shí)例,從而使每個(gè)實(shí)例都有一些工作要做。 如果默認(rèn)機(jī)制不符合我們的需求,我們當(dāng)然可以實(shí)施自定義策略。
摘要
今天就這些。 如您所見,通過使用Apache ZooKeeper和Curator,我們可以在沒有需要部署,監(jiān)視和管理的單獨(dú)負(fù)載均衡器的情況下生存。 即使沒有微服務(wù)架構(gòu),基礎(chǔ)架構(gòu)也非常復(fù)雜。
翻譯自: https://www.javacodegeeks.com/2014/07/zookeeper-curator-and-how-microservices-load-balancing-works.html
zookeeper 負(fù)載
總結(jié)
以上是生活随笔為你收集整理的zookeeper 负载_ZooKeeper,策展人以及微服务负载平衡的工作方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信5.0安卓版下载安装(微信5.0安卓
- 下一篇: 高效的企业测试-集成测试(3/6)