我所理解的服務化

講故事環節

我先講個故事python

好久好久之前(其實如今大部分網站都是這樣),咱們作一個網站,全部的功能代碼都會在一個代碼庫中,部署的時候 db 幾臺機器、nginx 幾臺機器、業務 server 幾臺機器。其中業務 server 的全部邏輯都是在一個進程中的,例如網站的登陸、用戶的評論、新建問題、某個活動等等。mysql

一塊兒看起來很美好。nginx

忽然有一天,老闆說咱們搞個紅包活動吧,微信紅包,上線後因爲中國人的薅羊毛心態,活動頁面 qps 瞬間暴增,致使網站的登陸邏輯 qps 也暴增,活動頁面壓垮的同時,全部其餘業務所有504,擴容時也是整個 server 一臺一臺的加。擴容後發現,其實 qps 大的頁面就只有這個活動也,容器上其餘頁面所有都是資源浪費。git

因此形成上面現象的問題有這麼幾個github

  • 降級邏輯,一個邊緣東西跪了不該該影響全站(除非是極爲核心邏輯、例如登陸)
  • 不能定點擴容

這時候就在想,若是登陸是一個服務,本身的業務也寫成一個服務,主站的其餘業務不動,登陸、活動、主站業務分機器部署,活動 qps 來的時候我只要擴展登陸和活動的容器就行了。並且這樣在活動的這個服務中能夠方便的接入登陸的降級。sql

什麼是降級

簡單的理解,降級就是指須要被降級的東西跪了的時候,業務不會5xx。apache

土辦法的作法就是加 try except,這樣就會有這麼一個問題,例以下面的代碼中,do_something 多是 mysql 的一次寫,其餘耗時操做的一次查,當 do_something 完全跪了的時候,若是用 try except,每一個 qps 來的時候,do_something 會依然執行,例如 mysql 跪了起不來,do_something 每次都會去鏈接 mysql,而後500。django

try:
        do_something()
    except Exception as ex:
        logging.error(ex, exc_info=1)

那麼咱們明知道這個地方跪了,爲何還要一直打他呢?降級時可不能夠在必定時間內返回一個默認值,不去真實的作 do_something,或者在接下來的必定次數的 qps 返回一個默認值?segmentfault

Hystrix的降級策略ruby

因此什麼是服務化

看看下面知乎的這個專欄好了

知乎服務化
知乎的一個回答
實施微服務,咱們須要哪些基礎框架? 這個撿着看

服務化的優勢和缺點

優勢

  • 根據服務擴容簡單
  • 降級容易作(就能夠評論跪了整個網站其餘功能還活着)
  • 上線時只上本身對應的服務便可,不影響其餘業務(數據相關還會影響)

缺點

  • 業務拆分定級,不然會服務爆炸(是個功能就寫個服務,後期服務巨多無比)
  • 數據一致性難以保持。當不用服務時,很是容易寫事務或者其餘邏輯保持數據一致性,服務化後難以作到這一點(回滾可能都是調用服務,依然可能失敗)
  • 沒必要要的服務間請求增多。不用服務時,不少東西查一次能夠用上下文的形式傳遞,服務化後服務內部可能須要本身從新查一遍。
  • 批量接口難以實現
  • 服務間解耦,通常採用消息系統(kafka),須要消息系統穩定
  • 非 rpc 層的單測是騙本身的,畢竟 rpc 調用的地方都會 mock

怎麼服務化

業務拆分是逃不掉的,服務化後還須要慢慢替換原有實現。

咱們重點說下技術手段

你能夠選擇 rest 或者 rpc,協議的話 HTTP 開銷比較大,業界如今彷佛比較主流的選擇是 thrift 協議,而後作一個 rpc。給出餓了麼實現的一套 python 版本 thriftpy

因此坑爹的點就在於,你拿到一套 thrift 的協議的時候,例如 thriftpy,他不像 django、ruby on rails之類的會有很是明確的代碼分層要求,若是內部不在強行定義規範,每一個開發寫出的服務都不同。

那麼當你服務有多個容器後,怎麼方便分組部署呢?首先你須要服務發現 consul, 例如咱們定義一個服務叫作用戶服務 member,他可能在物理機 A 3001端口,3002端口,物理機 B 3001端口起了3個 rpc server,consul 能夠註冊一個 member,物理機端口的事兒一樣註冊在裏面,業務方只要用 member 這個名字就行了,沒必要知道具體打的是哪一臺物理機的那個 server。

配套食用的可能還有 haproxy 作負載均衡的,我沒用過表示只知道這玩意兒。

你真的須要服務化麼

這個是很是須要思考的問題。若是你的網站 qps 很是低,搞毛幺蛾子。

相關文章
相關標籤/搜索