中文字幕一区二区人妻电影,亚洲av无码一区二区乱子伦as ,亚洲精品无码永久在线观看,亚洲成aⅴ人片久青草影院按摩,亚洲黑人巨大videos

微服務(wù)的宏觀問題

發(fā)布于:2020-12-24 16:14:26

0

79

0

分布式系統(tǒng) 微服務(wù)

在短短20年的時間里,軟件工程已經(jīng)從設(shè)計具有單一數(shù)據(jù)庫和集中式狀態(tài)的整體式架構(gòu)轉(zhuǎn)變?yōu)槲⒎?wù),在微服務(wù)中,所有內(nèi)容都分布在多個容器,服務(wù)器,數(shù)據(jù)中心甚至大洲上。 分發(fā)事物解決了擴(kuò)展問題,但引入了一個全新的問題世界,其中許多問題以前是由整體解決的。

在本文中,我將簡要介紹網(wǎng)絡(luò)應(yīng)用程序的歷史,討論如何達(dá)到這一點。 之后,我們將討論Temporal的狀態(tài)執(zhí)行模型及其如何解決面向服務(wù)的體系結(jié)構(gòu)(SOA)引入的問題。 全面披露我是Temporal產(chǎn)品的負(fù)責(zé)人,所以我可能會有偏見,但我認(rèn)為這種方法是未來。

簡短的歷史課

二十年前,開發(fā)人員幾乎總是構(gòu)建單片應(yīng)用程序。 該模型簡單,一致,并且類似于您在本地環(huán)境中進(jìn)行編程的經(jīng)驗。

巨石本質(zhì)上依賴于單個數(shù)據(jù)庫,這意味著所有狀態(tài)都是集中的。 整體可以在一次交易中更改其任何狀態(tài),這意味著它會產(chǎn)生二進(jìn)制結(jié)果,無論它是否起作用。 不一致的空間為零。 因此,整體式為開發(fā)人員提供了很好的經(jīng)驗,因為這意味著沒有失敗的交易導(dǎo)致狀態(tài)不一致的機(jī)會。 反過來,這意味著開發(fā)人員不必不斷編寫代碼來猜測事物的狀態(tài)。

長期以來,整體式設(shè)計才有意義。 沒有大量的連接用戶,這意味著軟件的規(guī)模要求很小。 即使是最大的軟件巨頭,其經(jīng)營規(guī)模如今看來也很小。 像亞馬遜和谷歌這樣的少數(shù)公司正在“規(guī)模”經(jīng)營,但是它們是罕見的例外,而不是常規(guī)。

人們喜歡軟件

在過去的20年中,對軟件的需求不會停止增長。如今,預(yù)計應(yīng)用程序?qū)牡谝惶扉_始服務(wù)于全球市場。 TwitterFacebook等公司已經(jīng)實現(xiàn)了24/7全天候在線賭注。軟件不再只是幕后的力量,它已成為最終用戶體驗本身。現(xiàn)在期望每個公司都有軟件產(chǎn)品。可靠性和可用性不再是功能,而是必要條件。

不幸的是,當(dāng)規(guī)模和可用性成為需求時,整體式裝置便開始崩潰。開發(fā)人員和企業(yè)需要尋找方法來跟上全球快速增長和苛刻的用戶期望。他們開始尋找可減輕他們所遇到的可伸縮性問題的替代體系結(jié)構(gòu)。

他們找到的答案是微服務(wù)(很好的面向服務(wù)的體系結(jié)構(gòu))。最初,微服務(wù)似乎很棒,因為它們使應(yīng)用程序可以分解為相對獨立的單元,這些單元可以獨立擴(kuò)展。而且由于每個微服務(wù)都保持其自己的狀態(tài),這意味著您的應(yīng)用程序不再局限于一臺計算機(jī)上適合的狀態(tài)!開發(fā)人員最終可以構(gòu)建滿足日益連接的世界的規(guī)模需求的應(yīng)用程序。微服務(wù)還為團(tuán)隊和公司帶來了靈活性,因為它們?yōu)榻M織架構(gòu)提供了明確的責(zé)任線和分離線。

沒有免費的午餐

盡管微服務(wù)解決了從根本上阻礙軟件增長的可伸縮性和可用性問題,但并非一切都很好。開發(fā)人員開始意識到微服務(wù)具有一些嚴(yán)重的缺陷。

對于整體而言,通常只有一個數(shù)據(jù)庫實例和一臺應(yīng)用程序服務(wù)器。而且由于無法分解整體,因此只有兩個實際的縮放選項。第一種選擇是垂直擴(kuò)展,這意味著升級硬件以增加吞吐量/容量。垂直擴(kuò)展可以提高效率,但成本高昂,而且如果您的應(yīng)用程序需求不斷增長,那么絕對不是永久解決方案。如果垂直擴(kuò)展足夠,最終將耗盡硬件以進(jìn)行升級。第二種選擇是水平縮放,在整體式的情況下,這意味著僅創(chuàng)建其自身的副本,以便每個副本都可服務(wù)于一組特定的用戶/請求等。水平縮放式的整體式會導(dǎo)致資源利用不足,并且在足夠高的比例下,普通不會工作。微服務(wù)不是這種情況,微服務(wù)的價值來自擁有多種“類型”的數(shù)據(jù)庫,隊列和其他可獨立擴(kuò)展和操作的服務(wù)器的能力。但是人們轉(zhuǎn)向微服務(wù)時注意到的第一個問題是,他們突然開始對許多不同類型的服務(wù)器和數(shù)據(jù)庫負(fù)責(zé)。長期以來,微服務(wù)的這一方面一直沒有得到解決,開發(fā)人員和運營商不得不自己解決。解決微服務(wù)隨附的基礎(chǔ)架構(gòu)管理問題非常困難,這使應(yīng)用程序充其量是不可靠的。

需求是改變的最終工具。隨著微服務(wù)的采用迅速增加,開發(fā)人員變得越來越有動力來解決其潛在的基礎(chǔ)結(jié)構(gòu)問題。慢慢地但可以肯定的是,解決方案開始出現(xiàn),而Docker,KubernetesAWS Lambda等技術(shù)則填補了空白。這些技術(shù)中的每一種都大大減輕了運行微服務(wù)基礎(chǔ)架構(gòu)的負(fù)擔(dān)。開發(fā)人員不必編寫用于處理容器和資源的自定義代碼,而可以依靠工具來為它們完成工作?,F(xiàn)在,到2020年,我們終于達(dá)到了一個點,即基礎(chǔ)架構(gòu)的可用性不會破壞應(yīng)用程序的可靠性。做得好!

當(dāng)然,我們還沒有進(jìn)入完美穩(wěn)定軟件的烏托邦?;A(chǔ)架構(gòu)不再是應(yīng)用程序不可靠的根源;應(yīng)用程序代碼是。

微服務(wù)的另一個問題

使用整體,開發(fā)人員可以編寫以二進(jìn)制方式進(jìn)行狀態(tài)更改的代碼。事情發(fā)生了或沒有發(fā)生。借助微服務(wù),世界狀況分布在不同的服務(wù)器上?,F(xiàn)在,更改應(yīng)用程序狀態(tài)需要同時更新不同的數(shù)據(jù)庫。這引入了一種可能性,即一個數(shù)據(jù)庫將成功更新,而其他數(shù)據(jù)庫可能已關(guān)閉,從而使您陷入不一致的中間狀態(tài)。但是,由于服務(wù)是橫向可伸縮性的唯一解決方案,因此開發(fā)人員別無選擇。

在服務(wù)之間分配狀態(tài)的根本問題是,對外部服務(wù)的每次調(diào)用都是可用性骰子。開發(fā)人員當(dāng)然可以選擇忽略代碼中的問題,并假定他們調(diào)用的每個外部依賴關(guān)系將始終成功。但是,如果忽略它,則意味著這些下游依賴項之一可能會在沒有警告的情況下關(guān)閉應(yīng)用程序。結(jié)果,開發(fā)人員被迫改編他們現(xiàn)有的整體時代代碼,以添加檢查以檢查操作是否在事務(wù)中間失敗的檢查。在下面的代碼中,開發(fā)人員必須不斷從即席myDB存儲中檢索最后記錄的狀態(tài),以避免潛在的競爭情況。不幸的是,即使采用這種實施方式,仍然存在競賽條件。如果在不更新myDB的情況下更改了帳戶狀態(tài),則存在不一致的余地。

public void transferWithoutTemporal(
  String fromId, 
  String toId, 
  String referenceId, 
  double amount,) {
  boolean withdrawDonePreviously = myDB.getWithdrawState(referenceId);
  if (!withdrawDonePreviously) {
      account.withdraw(fromAccountId, referenceId, amount);      
      myDB.setWithdrawn(referenceId);
  }
  boolean depositDonePreviously = myDB.getDepositState(referenceId);
  if (!depositDonePreviously) {
      account.deposit(toAccountId, referenceId, amount);                
      myDB.setDeposited(referenceId);
  }}

不幸的是,編寫無錯誤的代碼是不可能的,并且通常,代碼越復(fù)雜,發(fā)生錯誤的可能性就越大。 如您所料,處理“中間”的代碼不僅復(fù)雜,而且令人費解。 某些可靠性總比沒有強(qiáng)。因此,開發(fā)人員被迫編寫此固有的錯誤代碼來維持最終用戶的體驗。 這不僅耗費了開發(fā)人員的時間和精力,而且使雇主付出了很多錢。 盡管微服務(wù)非常適合擴(kuò)展,但它們卻以開發(fā)人員的樂趣和生產(chǎn)力以及應(yīng)用程序的可靠性為代價。

數(shù)以百萬計的開發(fā)人員每天都在浪費時間來重新發(fā)明一種最創(chuàng)新的輪子,即可靠性樣板代碼。 當(dāng)前使用微服務(wù)的方法根本不能反映現(xiàn)代應(yīng)用程序?qū)煽啃院涂缮炜s性的要求。

因此,現(xiàn)在是我們向您介紹我們的解決方案的部分。需要說明的是,Stack Overflow并不認(rèn)可這一點。而且我們還沒有說它是完美的。我們想分享我們的想法,并聽聽您的想法。有什么比Stack更好的地方獲得改進(jìn)代碼反饋的呢?

直到今天,還沒有一種解決方案使開發(fā)人員能夠使用微服務(wù)而不會遇到我上面提到的這些問題。您可以測試和模擬故障狀態(tài),編寫代碼以預(yù)測故障,但是這些問題仍然會發(fā)生。我們相信Temporal解決了這個問題。 Temporal是一個開源(麻省理工學(xué)院,沒有惡作?。┑模袪顟B(tài)的,微服務(wù)編排運行時。

Temporal具有兩個主要組件:由您選擇的數(shù)據(jù)庫提供支持的有狀態(tài)后端層,以及受支持的語言之一的客戶端框架。應(yīng)用程序是使用客戶端框架和簡單的舊代碼構(gòu)建的,該代碼在代碼運行時自動將狀態(tài)更改保持在后端。您可以自由使用在構(gòu)建任何其他應(yīng)用程序時將依賴的依賴項,庫和構(gòu)建鏈。需要明確的是,后端本身是高度分布式的,因此這不是J2EE 2.0的情況。實際上,后端的分布式性質(zhì)正是實現(xiàn)幾乎無限水平縮放的原因。 Temporal旨在為應(yīng)用程序?qū)犹峁┮恢滦?,簡單性和可靠性,就?/span>DockerKubernetes和無服務(wù)器對基礎(chǔ)架構(gòu)所做的那樣。

Temporal為編排微服務(wù)提供了許多高度可靠的機(jī)制,但是最重要的是狀態(tài)保存。狀態(tài)保存是一種臨時功能,它使用事件源自動將正在運行的應(yīng)用程序中的所有有狀態(tài)更改持久化。就是說,如果運行您的Temporal工作流程功能的計算機(jī)崩潰了,該代碼將自動在另一臺計算機(jī)上恢復(fù),就像從未發(fā)生崩潰一樣。這甚至包括局部變量,線程和其他特定于應(yīng)用程序的狀態(tài)。比喻,了解此功能的工作原理的最佳方法是。作為當(dāng)今的開發(fā)人員,您很可能依賴版本控制SVN(它是OG Git)來跟蹤對代碼所做的更改。關(guān)于SVN的事情是,它不會在您進(jìn)行每次更改后就對應(yīng)用程序的全面狀態(tài)進(jìn)行快照。 SVN的工作方式是僅存儲新文件,然后引用現(xiàn)有文件,從而避免重復(fù)它們。對于運行應(yīng)用程序的有狀態(tài)歷史記錄,Temporal類似于SVN(再次大致類推)。只要您的代碼修改了應(yīng)用程序狀態(tài),Temporal就會以容錯的方式自動存儲所做的更改(而不是結(jié)果)。這意味著Temporal不僅可以還原崩潰的應(yīng)用程序,還可以將它們回滾,分叉等等。結(jié)果是,開發(fā)人員不再需要在基礎(chǔ)服務(wù)器可能發(fā)生故障的前提下構(gòu)建應(yīng)用程序。

作為開發(fā)人員,此功能就像從鍵入每個字母后手動保存(ctrl-s)文檔到使用Google文檔在云中自動保存一樣。不僅僅是您不再手動保存文件,而且不再有與該文檔關(guān)聯(lián)的機(jī)器。狀態(tài)保存意味著開發(fā)人員編寫的微服務(wù)最初所編寫的繁瑣的樣板代碼要少得多。這也意味著不再需要臨時基礎(chǔ)結(jié)構(gòu)(如獨立隊列,緩存和數(shù)據(jù)庫)。這樣可以減少操作負(fù)擔(dān)和添加新功能的開銷。這也使新員工的入職變得更加容易,因為他們不再需要增加混亂且特定于域的狀態(tài)管理代碼。

狀態(tài)保存也以另一種形式出現(xiàn):“耐用計時器”。耐用計時器是開發(fā)人員通過Workflow.sleep命令利用的容錯機(jī)制。通常,Workflow.sleep函數(shù)與語言本機(jī)sleep命令完全一樣。但是,有了Workflow.sleep,無論多長時間,您都可以安全地睡眠任何時間。有許多Temporal用戶,其工作流程休眠了數(shù)周甚至數(shù)年。為此,Temporal服務(wù)在基礎(chǔ)數(shù)據(jù)存儲區(qū)中保留持久性計時器,并跟蹤何時需要恢復(fù)相應(yīng)的代碼。同樣,即使底層服務(wù)器崩潰(或您只是將其關(guān)閉),當(dāng)打算觸發(fā)計時器時,代碼也會在可用的計算機(jī)上恢復(fù)。睡眠工作流不會消耗資源,因此您可以擁有數(shù)百萬個睡眠工作流,而開銷卻可以忽略不計。這看起來似乎非常抽象,所以這里是一個有效的臨時代碼示例:

public class SubscriptionWorkflowImpl implements SubscriptionWorkflow {
  private final SubscriptionActivities activities =
      Workflow.newActivityStub(SubscriptionActivities.class);
  public void execute(String customerId) {
    activities.onboardToFreeTrial(customerId);
    try {
      Workflow.sleep(Duration.ofDays(180));
      activities.upgradeFromTrialToPaid(customerId);
      while (true) {
        Workflow.sleep(Duration.ofDays(30));
        activities.chargeMonthlyFee(customerId);
      }
    } catch (CancellationException e) {
      activities.processSubscriptionCancellation(customerId);
    }
  }
}

除了保留狀態(tài)外,Temporal還提供了一套用于構(gòu)建可靠應(yīng)用程序的機(jī)制?;顒庸δ苁菑墓ぷ髁髦姓{(diào)用的,但是活動中運行的代碼不是有狀態(tài)的。盡管它們不是有狀態(tài)的,但活動具有自動重試,超時和心跳的功能?;顒訉τ诜庋b可能失敗的代碼非常有用。例如,假設(shè)您的應(yīng)用程序依賴于通常不可用的銀行的API。對于傳統(tǒng)的應(yīng)用程序,您將需要使用大量try / catch語句,重試邏輯和超時來包裝調(diào)用bank API的所有代碼。但是,如果您在活動中調(diào)用銀行API,那么所有這些東西都是開箱即用的,這意味著如果調(diào)用失敗,則將自動重試該活動。重試非常好,但是有時不可靠的服務(wù)是您擁有的服務(wù),因此您希望避免DDoSing。因此,活動調(diào)用還支持超時,該超時由持久計時器支持。這意味著您可以在重試嘗試之間讓活動等待數(shù)小時,數(shù)天或數(shù)周。這對于需要成功但無需擔(dān)心代碼執(zhí)行速度如何的代碼特別有用。

Temporal的另一個強(qiáng)大方面是它對正在運行的應(yīng)用程序提供的可見性。 可見性API提供了類似于SQL的界面,可從任何工作流程(正在運行或以其他方式)查詢元數(shù)據(jù)。 也可以直接在工作流程中定義和更新自定義元數(shù)據(jù)值。 可見性API非常適合Temporal操作員和開發(fā)人員,尤其是在開發(fā)過程中進(jìn)行調(diào)試時。 可見性甚至支持將批處理操作應(yīng)用于查詢結(jié)果。 例如,您可以向與您的創(chuàng)建時間查詢>昨天匹配的所有工作流發(fā)送終止信號。 Temporal還支持同步獲取功能,該功能使開發(fā)人員可以在運行的實例中獲取本地工作流變量的值。 這有點像您的IDE中的調(diào)試器適用于生產(chǎn)應(yīng)用。 例如,可以在以下代碼的運行實例中獲得greeting的值:

public static class GreetingWorkflowImpl implements GreetingWorkflow {  
  private String greeting;   
   @Override
    public void createGreeting(String name) {
      greeting = "Hello " + name + "!";
      Workflow.sleep(Duration.ofSeconds(2));
      greeting = "Bye " + name + "!";
    }    @Override
    public String queryGreeting() {      
       return greeting;
    }
  }

結(jié)論

微服務(wù)很棒,但是開發(fā)人員和企業(yè)為使用微服務(wù)付出的代價是生產(chǎn)力和可靠性。 Temporal旨在通過提供一種為開發(fā)人員支付微服務(wù)稅的環(huán)境來解決此問題。 狀態(tài)保留,自動重試失敗的呼叫以及開箱即用的可見性只是Temporal提供的使開發(fā)微服務(wù)合理化的一些基本要素。