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

Cloud Foundry中基于Master/Slave機制的Service

系統 1631 0

Cloud Foundry作為業界最出色的PaaS平臺之一,給廣大的互聯網開發者和消費者提供出色的體驗。自Cloud Foundry開源以來,有關Cloud Foundry的研究越來越多,這也很好的支持著Cloud Foundry的生態系統。但是作為一個平臺,Cloud Foundry仍然會存在一些可靠性,擴展性方面的不足,這也吸引著眾多的Cloud Foundry愛好者對其進行更多更深入的研究。


本文主要講述Cloud Foundry中Service Gateway的運行機制,Service Gateway存在的單點故障問題,以及解決單點問題的Master/Slave Service Gateway機制。


1. Service Gateway運行機制

關于Cloud Foundry中Service Gateway的介紹,可以參考我之前的博文: Cloud Foundry Service Gateway 源碼分析

介紹該組件運行機制的時候,我希望使用Service Gateway的最常用的功能provision a service 和 bind a service 來簡要闡述,雖然不能代表所有的功能,但是這兩個功能可以讓我們對Service Gateway運行機制了解個大概。


1.1 Service Gateway的啟動

以上提及的博文中已經介紹得很多,關于啟動,需要強調的是fetch_handles的功能,即Service Gateway向Cloud Controller請求獲得service instance的信息,并存儲在內存中,后面會講到在provision a service 的時候會用到該內存中的信息;還有send_heartbeat的功能,即Service Gateway向Cloud Controller發送心跳信息,證明自己的存活狀態(另外Cloud Controller也會通過這個心跳信息來存儲該類型Service Gateway)。


1.2 provision a service

provision a service 的流程很簡單明了,主要實現創建一個服務實例,無非是Cloud Controller接收用戶請求,使用HTTP方式發送給Service Gateway,Service Gateway接收并處理請求后通過NATS向Service Node發送provision請求,Service Node接收到請求到provision完畢后,通過NATS將結果返回給Service Gateway,Service Gateway將結果備份一份以后,通過HTTP方式返回給Cloud Controller,最后Cloud Controller收到結果信息,將其持久化至數據庫,并對用戶做回應。這里需要注意的是:首先,關于provision出來的service instance的信息最終會被持久化到Cloud Controller的postgres數據庫中;然后,關于這些信息,Service Gateway會備份一份(存儲在內存中)。這兩點在后文中會顯得尤為重要。


1.3 bind a service

bind a service 主要是實現為一個應用綁定一個服務實例。流程與通信方式和provision a service 大同小異,不同的是,在Service Gateway在接收到Cloud Controller的時候,會從自己關于service的備份信息中找出來相應的service instance,然后給該instance發送請求。


2. Service Gateway的單點故障問題

在Cloud Foundry中,同種類型service的Service Gateway只有一個,因此在運行過程中,肯定會出現單點故障問題。一旦Service Gateway所在節點宕機,那么該Service Gateway變得不可用,所以關于該service的provision和bind等眾多請求都將得不到響應。需要注意的是,對于已經成功bind服務的應用來講,是不受影響的,因為app可以直接通過URL訪問Service Node,而不用經過Service Gateway。


由于目前的Cloud Foundry缺乏對于組件的狀態監控機制,所以Cloud Foundry對于Service Gateway的宕機不會采取任何措施,因此Cloud Foundry的管理員也不會被告知Service Gateway的故障,從而導致該類型service的不可用。當Cloud Foundry的用戶感受到該類型service不可用,并且向管理員反饋時,管理員才會去后臺去查看Service Gateway的狀態,發現狀態為關閉狀態,從而進行人為的啟動。在這一漫長的過程中,該類型的service均處于不可用狀態,大大影響Cloud Foundry的可用性。


在這樣的情況下,最理想的解決方案自然可以使得Cloud Foundry中關于某種類型的service可以具有多個Service Gateway ,如此一來,在一個Service Gateway宕機的時候,還可以有其他的Service Gateway繼續工作。通過以上的假設,在實際過程中,我曾經嘗試過兩種方案:Master/Slave Gateway 以及Multi Gateways。以下是兩個方案的簡述:

  1. Master/Salve Gateway : 該方案在執行過程中,只有一個Service Gateway接收到Cloud Controller的請求,并做處理;只有當一個Service Gateway宕機的時候,Cloud Controller才會將請求發給另一個請求。看到這里,肯定會有一些問題:那就是Cloud Controller如何獲知Gateway是否宕機的信息,另外Cloud Controller如何決策將請求發送給哪個gateway,還有一個Service Gateway已經provision完一個服務后宕機,則關于該服務的bind請求會發送至另一個Service Gateway,而這個Service Gateway不具有這個服務的任何信息,從而導致請求不能被執行。本文主要講述這種方案的設計與實現。
  2. Multi Gateways : multi 就是多個,另外有一種多個之間地位平等的概念,也就是說在Cloud Controller在接收到請求之后,分發給所有的該類型service的Service Gateway,從而使得當一個Service Gateway宕機之后,而其他的所有gateway仍能正常工作。當然,該方案也會存在難點:除了上一種方案中的部分困難之外,還有:由于請求為多個,一個Service Node接收到多個Service Gateway的請求后,該如何決策該請求是否執行過等。


3. 基于Master/Slave模式的Service Gateway

關于Master/Slave模式的Service Gateway框架如下圖:

Cloud Foundry中基于Master/Slave機制的Service Gateway——解決Service Gateway單點故障問題


3.1 兩個Service Gateway的注冊問題

由于該方案中有兩個同種類型的Service Gateway與Cloud Controller相連,則必須要解決的問題是:如何讓Cloud Controller認識這兩個Service Gateway。在這里,我們可以回憶在原先的Cloud Foundry中,Cloud Controller如何認識或者存儲一個Service Gateway:Cloud Controller接收Service Gateway的heartbeat信息的同時,在自己的postgres數據庫中存儲該Service Gateway的信息,也相當于完成Service Gateway的注冊。


解決方案

啟動同種類型service的兩個Service Gateway,他們分別向Cloud Controller發送heartbeat,由Cloud Controller接收這些請求,并決策哪一個是Master,哪一個是Slave ,從而存入數據庫。


具體實現

Cloud Controller的軟件框架是基于Rails編寫的,關于postgres數據庫的數據表都有一個model(MVC模式中的M),而修改數據表的模式則必須修改這個model文件,由于之前的模式會驗證service類型的唯一性,現在則必須將/cloudfoundry/cloud_controller/cloud_controller/app/models/service.rb中的驗證代碼validates_uniqueness_of :label 給注釋掉,這樣就有了向數據庫中添加相同類型service的可能性。另外我們還需要在該模式中加入一個屬性MasterOrSlave,這樣可以使得Cloud Controller決策Master/Slave后,將帶有Master/Slave標記的service記錄存入postgres數據庫。


以上操作只是從理論上,允許在數據庫中出現兩個相同label的service記錄,關于最終往數據庫中存兩條記錄還是需要Cloud Controller的controller來實現(MVC中的C)。在具體程序運行中,service_controller.rb文件中的create方法會接收來自Service Gateway的heartbeat信息,并做相應的注冊。為了實現Master/Slave模式,我們需要改進該方法,加入決策機制,實現Master/Slave的注冊。下圖是決策機制:

Cloud Foundry中基于Master/Slave機制的Service Gateway——解決Service Gateway單點故障問題


3.2 Cloud Controller決策使用Service Gateway的問題

解決了以上的注冊問題,Cloud Foundry還需要解決Cloud Controller如何選擇Service Gateway的問題。


解決方案:

Cloud Controller關于某一label的service 請求,首先找到該label的Master Service Gateway,如果該Service Gateway的active屬性為TRUE,則表示該Service Gateway存活狀態為存活,可以接收請求;若active屬性為FALSE,則表示該Service Gateway存活狀態為不存活,則找到該label的Slave Service Gateway,若Slave Service Gateway的active屬性為TRUE,則表示Slave Service Gateway可以接收請求,否則該類型的Master Slave Service Gateway都不可用,請求不會執行,用戶被告知Service Gateway不可用。決策流程如下圖:

Cloud Foundry中基于Master/Slave機制的Service Gateway——解決Service Gateway單點故障問題


3.3 Master/Slave Service Gateway之間服務信息的同步問題

在Cloud Foundry中Service Gateway的運行機制中,已經介紹了provision和bind的功能,在這兩個過程中,都涉及了一個內存空間(具體代碼為@prov_svcs),這個內存空間用來存放這個service類型的service信息。Service Gateway啟動的時候會通過fetch_handles方法獲取全部的信息,另外在每次經過這個Service Gateway的provision和bind等請求時,會有相應的信息更新。


那如果使用Master/Slave Service Gateway機制的話,為什么要考慮兩個Service Gateway之間@prov_svcs的同步信息呢?關于這個問題,可以推測:要保證Master/Slave Service Gateway的高可用性,那么在一個Service Gateway宕機的時候,另一個Service Gateway仍然可以工作,并接管之后的請求。但是,如果一個請求通過Master Service Gateway 成功provision 一個服務實例后,Master Service Gateway宕機了,那么關于這個服務實例的bind請求,肯定會通過Slave Service Gateway來完成,然而Slave Service Gateway不具有這個服務實例的任何信息,故bind失敗。毫無疑問,Master/Slave Service Gateway機制必須解決服務信息的同步問題,也就是在一個Service Gateway完成某一個請求,更新@prov_svcs后,必須將相同的更新告知另一個Service Gateway,完成信息的同步。


解決方案:

從Service Gateway的請求流程來看,關于service instance的信息在@prov_svcs中更新后,都會存儲到Cloud Controller的postgres數據庫中。為了做到Master/Slave Service Gateway的服務信息同步,最有效的方法就是一有信息被更新到Cloud Controller的postgres數據庫中,就馬上把這個更新信息發送給另一個Service Gateway。為了簡單起見,本文采取的同步方式是:Service Gateway以一個可以人為設定的頻率向Cloud Controller發送獲取服務信息的請求。這樣的話,從一定程度上說,可以保證兩個Service Gateway服務信息的同步。


具體實現 :

在上文的Service Gateway啟動的時候,已經講述過,Service Gateway會使用fetch_handles方法來獲取服務信息,具體代碼見asynchronous_service_gateway.rb:

      update_callback = Proc.new do |resp|
      @provisioner.update_handles(resp.handles)
      @handle_fetched = true
      event_machine.cancel_timer(@fetch_handle_timer)

      # TODO remove it when we finish the migration
      current_version = @version_aliases && @version_aliases[:current]
      if current_version
        @provisioner.update_version_info(current_version)
      else
        @logger.info("No current version alias is supplied, skip update version in CCDB.")
      end
    end

    @fetch_handle_timer = event_machine.add_periodic_timer(@handle_fetch_interval) { fetch_handles(&update_callback) }
    event_machine.next_tick { fetch_handles(&update_callback) }
  

從代碼中可以看到Service Gateway是首先是通過一個周期性的timer向Cloud Controller發送獲取請求,當收到Cloud Controller的響應之后,取消了這個timer。在Master/Slave Service Gateway 中為了不斷地發送fetch_handles請求,只需要將代碼event_machine.cancel_timer(@fetch_handle_timer)注釋掉即可。這樣的話,Service Gateway就會以周期@handle_fetch_interval發送fetch_handles請求。只要Cloud Controller關于service的信息有變動,Service Gateway就會在@handle_fetch_interval時間內獲知。在此基礎上,修改以上代碼只是實現周期性發送請求,而Service Gateway在接受周期性響應后,還需要在處理的時候作出相應的修改,具體代碼在provision.rb中,可以每次執行的時候都將@prov_svcs置空,然后再將所有的服務信息放入hash對象@prov_svcs。


關于該問題的解決,以上只是闡述了Service Gateway需要作的改動,這包括Service Gateway發送請求和接受請求,但是只有這些還是不夠的,對于通信的Server端,Cloud Controller也需要作一定的修改,主要是如何根據Service Gateway的請求,讀取postgres數據庫中所有的服務信息。代碼地址主要為cloudfoundry/cloud_controller/cloud_controller/app/controllers/service_controller.rb的list_handles方法。由于Cloud Controller都是通過Service Gateway的URL信息去尋找數據庫中數據表service_bindings和service_configs的關于該Service Gateway的所有service instance,而現在是Master/Slave Service Gateway機制,需要將兩個Service Gateway的服務信息全部信息找出,并返回給Service Gateway。比如:service instance A是由 Master Service Gateway來provision或者bind的,那么在service_configs或者service_bindings中是屬于Master Service Gateway的,因此Slave Service Gateway在獲取handles的時候,也需要將Master Service Gateway取出,并返回給Slave Service Gateway。其中的具體實現可以參考Rails中的model,在這里service_binding blongs_to :service_config,service_config belongs _to :service。


3.4 unprovison, bind和unbind等請求的部分修改

關于這部分的修改,以unprovision請求為例:


Cloud Controller在收到用戶關于某service instance的unprovision后,首先會從service_configs數據表中找出這個service instance,然后再取出Service Gateway的URL信息,并向這個URL發送unprovision請求。但是如果現在這個Service Gateway已經宕機的話,之前的機制將不能響應這個請求。如果要在Master/Slave Service Gateway機制中解決這個問題,只需要在每次執行unprovision請求的時候,不是去找service instance的Service Gateway信息,而是去尋找當前正在工作的Service Gateway 來完成unprovision工作。


關于bind和unbind操作,也是如此,在Cloud Controller向Service Gateway發送請求的時候,不是通過service instance來尋找Service Gateway,而是通過當前存活的Service Gateway來尋找。


4. 評價

以上關于Master/Slave Service Gateway設計與實現,已經闡述完畢,現在可以在評價這個機制。


首先從可用性入手,該機制很好的解決了之前Cloud Foundry中Service Gateway的單點故障問題,一旦Cloud Foundry中的一個Service Gateway宕機的話,該機制下,Cloud Foundry仍然可以使用另一個Service Gateway來完成工作。當然,當兩個Service Gateway都宕機的情況下,該機制也不能正常保證Service的工作,但是在兩個Service Gateway相同環境下,出現這種情況的概率要遠遠低于只有一個Service Gateway的時候。


Master/Slave Service Gateway機制最重要的部分主要是如何實現service信息的同步問題,本設計主要是通過周期性的發送獲取請求,來實現最終的同步。但是周期性的請求,其實不能嚴謹的保證consistency。如果關于一個service instance的porvision和bind操作在一個周期內需要完成,而在兩個請求之間的某個時刻,Master Service Gateway宕機的話,Slave Service Gateway也不可用。當這個周期非常粗粒度的時候,這樣的問題是不能容忍的,但是如果這個周期比較細粒度的話,問題能得到非常好的緩解,這樣的情況幾乎可以忽略不計。但是當周期性的請求粒度很細的話,勢必會造成Cloud Controller的通信的擁擠,這也是一個在請求很多,系統很大的時候不得不考慮的問題。


5. 總結

本文主要旨在解決原先Cloud Foundry中關于Service Gateway的單點故障問題。在簡要介紹Service Gateway的運行流程后,講述了Service Gateway可能存在的單點故障問題,并對于該問題提出了兩種解決方案。隨后,本文大篇幅介紹了其中一個解決方案Master/Slave Service Gateway機制,主要包括該方案的具體解決的問題和具體實現。最后,對于該機制進行了簡要的評價,主要著眼于可用性與對系統的性能影響。





轉載清注明出處。

這篇文檔更多出于我本人的理解,肯定在一些地方存在不足和錯誤。希望本文能夠對開始接觸Cloud Foundry中service的人有些幫助, 如果你對這方面感興趣,并有更好的想法和建議,也請聯系我。

我的郵箱:shlallen@zju.edu.cn

新浪微博: @蓮子弗如清





Cloud Foundry中基于Master/Slave機制的Service Gateway——解決Service Gateway單點故障問題


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 12306播播影院午夜 | 一级特黄视频 | 国产综合在线播放 | 午夜视频在线免费观看 | 日韩a无v码在线播放免费 | 91网站在线免费观看 | 黄色激情网站 | 夜夜夜操 | 欧美专区在线 | 欧美精品3atv一区二区三区 | 久久vs国产综合色大全 | 九九精品在线 | 久久久www成人免费精品 | 色宅男看片午夜大片免费看 | 精品一区二区三区视频 | 奇米亚洲| 日本va视频 | 九九精品久久 | 日本在线观看高清不卡免v 国产成人一区二区精品非洲 | 日本午夜免费无码片三汲大片 | 99在线观看精品 | 精品一区二区三区网站 | 一级片在线 | 欧美激情在线精品一区二区 | 小明台湾www永久视频 | 午夜久久久久久禁播电影 | 色开心婷婷 | 欧美疯狂xxxx乱大交视频 | 天天干天天舔天天操 | 亚洲欧美日韩精品久久亚洲区色播 | 婷婷综合色 | 国产精品视频在线播放 | 日本在线看 | 91亚洲精品丁香在线观看 | 国产精品一区二区免费 | 国产综合亚洲精品一区二 | 欧美第一页 | 日韩福利视频一区 | 久草干 | 日韩国产| 青青草人人 |