天天看點

為什麼會出現微服務和分布式?

0x01 寫在前面的話

這幾年來,随着中國網際網路的不斷發展,各種新型技術和架構層出不窮。作為一名Java 軟體開發工程師,在外企的這兩年來,也許日子過得太過于安逸,導緻不知外面世界已發生了怎樣翻天覆地的變化。如今走出來,看到外面的世界,才發現自己的技術已經落後了好多。

而近些年來,越來越多的線上線下教育訓練機構也不斷造就了越來越多的程式員,這就導緻我們程式員這個行業所受到的壓力和挑戰也越來越大。但是我們應該都明白,一味地恐懼于壓力是沒有什麼用的,我們能做的唯有通過不斷學習,改變自己,增強自己的專業本領,才能在競争之中不被打倒,才能達到我們不被淘汰甚至加薪的願望。是以在接下來的日子裡,我會與大家一起共同學習了解新型技術和架構。

0x02 微服務和分布式

衆所周知,微服務和分布式在如今的碼農界,火熱到幾乎無人不知,無人不曉的地步。但是你有沒有好奇過為什麼它會突然出現并變得這麼火熱呢?

為什麼會出現微服務和分布式?

其實在最開始學習微服務和分布式的時候,我對這個問題也一直百思不得其解,是以也導緻我學習起來感覺很吃力,直到後來才偶然發現這個問題從架構的角度去思考這個問題,便豁然開朗了,學習起來也輕松了很多。

想要弄清楚這個問題,我們就不得不了解下企業級架構的演變。

在碼農界,企業應用使用的架構最開始是這樣的:

1. 企業架構設計之原始版

為什麼會出現微服務和分布式?

特點:

  • 單節點
  • 幾乎無容災
  • 負載能力低
  • 維護簡單
  • 問題???

應用程式中任意一個子產品一旦出現問題,整個應用的所有功能就全部停止服務了。

為了改善這種架構存在的問題,人們最開始想到的辦法是通過建立

伺服器叢集

類似這個樣子:

為什麼會出現微服務和分布式?

這樣我們有了多個

備用伺服器

,一旦一個伺服器壞掉,我們隻需要切換下另外一個伺服器便可以繼續提供服務。

架構繼續演進,人們慢慢發現浏覽器的請求一般包括html/css/js 和API請求資料庫資料,通路量小還好說,但是一旦通路量大了,服務端就會感到壓力很大,為了減輕負載的壓力,人們思考,将html/css/js 的請求和API的請求進行分離,設計了一個叫做Nginx 的伺服器來專門處理html/css/js 的請求。

這便是企業架構之動靜分離版

2. 企業架構設計之動靜分離版

為什麼會出現微服務和分布式?

這種特點:

  • Nginx 通路靜态資源
  • Nginx負載均衡
  • 應用分離
  • 依賴架構
  • 存在安全性低問題
  • 存在Session持久化問題

    問題:???

上面我們可以看出,動靜分離架構存在Session 持久化問題,那麼問題來了

1什麼是session 持久化?

web伺服器通常将那些暫時不活動但未逾時的HttpSession對象轉移到檔案系統或資料庫中儲存,伺服器要使用他們時再将他們從檔案系統或資料庫中裝載入記憶體,這種技術稱為Session的持久化。

2.為什麼session 需要持久化?

Session是存儲在伺服器端的,用戶端通路了某個能開啟會話功能的資源, web伺服器就會建立一個與該用戶端對應的HttpSession對象,每個HttpSession對象都要站用一定的記憶體空間。如果在某一時間段内通路站點的使用者很多,web伺服器記憶體中就會積累大量的HttpSession對象,消耗大量的伺服器記憶體,即使使用者已經離開或者關閉了浏覽器,web伺服器仍要保留與之對應的HttpSession對象,在他們逾時之前,一直占用web伺服器記憶體資源。

我們考慮下這種情況,某使用者登陸我們的網站,與我們的伺服器建立了一個session 連接配接,由于伺服器更新或者更新,伺服器不得不重新開機下,session 突然失效,使用者需不需要重新登陸? 再比如使用者重複“打開通路我們的網站然後再關閉浏覽器“這個操作,在時間較短的情況下,session 會重複建立,那麼是不是也會對伺服器的性能造成影響。

檢視詳情

于是程式員們設計了Memcached, Redis 等緩存資料庫來解決這個問題,這就是企業架構之緩存版。

3.企業架構之緩存版

為什麼會出現微服務和分布式?
  • 大量使用緩存
  • Nginx 接受Https
  • Session持久化
  • 存在一緻性問題
  • 存在緩存失效問題

    這種架構,使用了Redis、Memcached 高速緩存,一般支援key-value 形式的查詢,相當于傳統資料庫來說,它的性能非常好,它可以達到每秒六萬以上的查詢量。

引用高速緩存來提升服務的性能,高速緩存的使用分為三種情況,

  • 第一種情況 基于請求的查詢,當Http請求過來之後,應用先去查詢高速緩存是否存在結果,如果沒有結果,應用再去資料庫中查詢出來傳回給使用者并寫入到高速緩存中。
  • 第二種情況 基于查詢結果的緩存,當請求過來後,在查詢資料庫之前,先根據條件查詢高速緩存,如果查詢到結果,再封裝傳回給使用者,如果查詢不到,就從資料庫中查詢出來并寫入到緩存裡,再傳回給使用者。
  • 第三種情況 利用高速緩存來做session會話持久,在上一版動靜分離版中,由于部署了 多台機器,由于一台機器不能通路另外一台機器的

    session,是以将session公共存儲到高速緩存中,然後http請求過來之後,根據session的id從高速緩存中查詢對應的結果。相當于把session持久化在高速緩存中。

由于緩存版中大量使用了高速緩存,資料庫和高速緩存之間沒有同步機制,如果在查詢高速緩存的時候,資料庫中有更新,但是沒有及時更新到高速緩存中,那麼使用者查詢到的結果還是之前的結果。就會存在一緻性的問題。

這時雖然在一定程度上很大改進了, 但這種單體架構仍然存在一些痛點:

痛點一:項目過于臃腫

當大大小小的功能子產品都集中在同一個項目中的時候,整個項目必然變得十分臃腫,讓開發者難以維護。

痛點二:資源無法隔離

各個子產品依賴于同樣的資料庫,記憶體資源,一旦某個子產品功能使用不當,這個系統整體崩潰。

痛點三:無法靈活擴充

打個比方,假設我們有一個電商項目,有訂單子產品,支付子產品,使用者子產品,聊天子產品,一旦支付子產品出現問題,其他子產品都沒有任何問題的情況下,由于這是一個整體web應用,我們部署伺服器叢集的時候,就不得不把訂單子產品,支付子產品,使用者子產品,聊天子產品全部都部署上。

為什麼會出現微服務和分布式?

然而我們實際想要的隻是多部署幾個備用的比較重要容易出錯的支付子產品。

随着服務化的興起,越來越多企業将大型程式按照功能和業務拆分開來,分離成很多個小應用來提供服務,這就是分布式服務版。

4.企業架構之分布式服務

為什麼會出現微服務和分布式?

特點

  • 小型機虛拟化
  • 請求處理與業務分離
  • 應用服務化
  • 同步異步拆分
  • 資料庫讀寫分離
  • 運維難度大大增加

    分布式服務在保證功能不變的前提下,将應用拆分為前端web應用和背景服務。背景服務根據業務不同拆分為若幹個子應用,這些若幹個子應用共同提供服務,web應用調用這些服務和使用者打交道。此時,web應用就不會包括太多底層的功能。不同的服務封裝起來,組成一個業務邏輯。

web應用怎麼才能調用到另外一台機器上的服務呢?此時就需要使用我們的分布式服務架構,或者企業服務總線等技術來将其他機器提供的服務通過遠端調用來通路這些服務。

做的比較完善的分布式服務架構,比如Dubbo都可以提供服務路由,負載均衡,調用統計,等一些功能,更友善管理整個叢集上的服務。同時,拆分之後,應用的數量會增加很多,每個應用的負載相應地就會沒有之前那麼多。這時候我們需要對之前用來部署web應用的小型機進行虛拟化,簡單來講,就是在小型機上安裝若幹個虛拟機,将應用部署在虛拟機之中,或者部署在雲伺服器中。

這個版本還有個特性就是大量使用了第三方的中間件,比如,消息中間件ActiveMQ,排程中間件 tbschedule,以及叢集管理監控的平台

.使用消息中間件可以将大量的異步操作發送到消息中間件中,背景服務均勻地消費這些消息,避免了通路時的峰值對于整個資料庫壓力的影響。同時,拆分了異步的操作能夠提升服務的吞吐量,避免大量的耗時操作影響使用者。

同時,還增加了資料庫的讀寫分離,配置多個讀庫來和主庫同步,将所有的查詢都映射到讀庫上,避免了資料庫寫入時對資料讀取造成影響。

設定讀庫還有個好處,在主庫挂了情況下,進行讀寫切換,瞬間将讀庫切換成主庫。使得正常的業務不受影響。

但是由于伺服器的增多,第三方中間件的部署,以及資料庫主從等,比之前多了很多需要監控的機器,對于伺服器的部署必須能自動化運作,而且必須能實時監控,異常發生時能及時通知,對于運維增加了難度。

分布式服務版的瓶頸在于如果出現高并發的時候,對某些應用的壓力會非常大,而某台虛拟機的負載 就會非常高,有可能導緻整個的小型機都會受到影響。為了更好地負載壓力和配置設定伺服器的資源,于是便出現了彈性計算。

5. 企業架構之彈性計算

為什麼會出現微服務和分布式?

首先用引用一個概念,就是容器級别的虛拟化。簡單來說不需要部署配置設定多個虛拟機,而是采用docker 這種容器級的虛拟化系統,将應用部署到docker容器之中。容器級别的虛拟化可以了解為就像web應用部署到tomcat之中一樣。使用容器級别的虛拟化,能夠使得伺服器的資源可以實時配置設定。

假設一個場景,在監控到web應用的壓力負載增加到百分之七十以上的時候,使用腳本能夠新增一系列的docker容器,再将應用啟動起來。 這些操作能在秒級的情況下,瞬間增加了許多伺服器的資源,來滿足負載。當負載下降的時候,就停止應用,将docker容器也停止,能夠節省伺服器的資源來給其他服務使用。

這個版本增加了基于Hadoop的日志收集平台,在應用産生應用日志之後,使用日志收集平台,将日志寫入Hadoop叢集,不用再擔心日志在docker容器之中,停止之後日志丢失。同時,能夠對日志做查詢。

同樣,Hadoop在處理離線資源的時候,一般是在晚上,這個時候的應用負載都很低,可以控出很多伺服器的資源,我們在處理Hadoop任務之前,可以用docker新增很多節點,再來計算。

同時,還有一個好處就是能夠快速複制節點,在某部分機房有問題的時候,能夠快速在另外一個機房複制出大量應用,高效解決了,異地容災的問題。

這個版本的資料庫使用,和之前也不再一樣,應用不再直接和資料庫打交道而是使用了資料庫中間件。例如淘寶的TDDL,對于開發來說,不需要在配置中配置讀寫分離,而是隻是配置和中間件的連接配接。用資料庫中間件來路由表,包括單表被水準拆分之後,使用資料庫中間件來做集合,或者路由到具體的表中。

将資料庫的管理,和應用的開發人員隔離開來,更加簡化了應用對資料庫操作。開發人員不再擔心,随着資料量的增加,對資料庫的壓力,同時,中間件還能配置将資料庫中的資料同步到Hadoop叢集之中,再配置一些離線任務。

使用Hadoop來計算,計算的結果儲存在Hadoop之中。再用中間件去讀取Hadoop的計算結果,再寫入到資料庫。使用中間件,來對資料庫的資料源進行處理,生成更高效的資料來節省資料庫的資源。

原文連結