偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

線下環(huán)境為何不穩(wěn)定?怎么破

開發(fā) 開發(fā)工具
既然TiP一時(shí)半會(huì)兒還用不上、發(fā)揮不了很大的作用,那么接下去的問題就是:怎么辦?既然線下環(huán)境的不穩(wěn)定是必然的,那我們怎么用不太夸張的投入讓它盡量穩(wěn)定一點(diǎn)?

[[381478]]

 這篇文章想講兩件事:

  • 為什么線下環(huán)境[1]的不穩(wěn)定是必然的?
  • 我們怎么辦?怎么讓它盡量穩(wěn)定一點(diǎn)?

此外,還會(huì)談一談如何理解線下環(huán)境和線上環(huán)境的區(qū)別。

如果沒有時(shí)間讀完全文的話,這里是本文的主要觀點(diǎn):

1. 線下環(huán)境不穩(wěn)定是必然的,在沒有實(shí)現(xiàn)TiP之前,當(dāng)前我們能做的是盡量讓它穩(wěn)定一點(diǎn)。

2. 避免過多的籠統(tǒng)使用”環(huán)境問題“的說法。

3. 業(yè)務(wù)應(yīng)用線下環(huán)境的基礎(chǔ)設(shè)施必須按照生產(chǎn)環(huán)境標(biāo)準(zhǔn)運(yùn)維。一個(gè)實(shí)現(xiàn)手段就是直接使用生產(chǎn)環(huán)境的基礎(chǔ)設(shè)施。

4. stable層首先要把單應(yīng)用可用率提升上去。單應(yīng)用如果無法做到99.999%或100% 都是能調(diào)通的,鏈路的穩(wěn)定性就是緣木求魚、根本無從談起。

5. 減少dev環(huán)境的問題,主要有四個(gè)重點(diǎn):

  • 做好聯(lián)調(diào)集成前的自測;
  • 架構(gòu)上的投入(契約化、可測性);
  • 通過多環(huán)境、數(shù)據(jù)庫隔離等手段減少相互打擾;
  • 通過持續(xù)集成盡早暴露問題,降低問題的影響和修復(fù)成本。

6. IaC(Infrastructure-as-Code)是解題的一個(gè)關(guān)鍵點(diǎn)。

7. 線下環(huán)境是一個(gè)場景。要深刻理解線下環(huán)境和線上環(huán)境這兩個(gè)不同場景的差異。

以下是正文:

一 線下環(huán)境不穩(wěn)定的必然性

說起線下環(huán)境為什么不穩(wěn)定,經(jīng)常會(huì)聽到大家給出這些原因:

  • 為了成本,線下環(huán)境的機(jī)器不好,是過保機(jī);
  • 為了成本,線下環(huán)境的硬件資源是超賣的;
  • 工具配套不完善,線下環(huán)境的配置和生產(chǎn)環(huán)境沒保持同步;
  • 線下環(huán)境的監(jiān)控告警、自愈等沒有和生產(chǎn)環(huán)境對齊;
  • 投入不夠,不重視,對問題的響應(yīng)不及時(shí),流程機(jī)制等沒建立起來;
  • 測試活動(dòng)會(huì)產(chǎn)生臟數(shù)據(jù);

其實(shí)這些原因中大部分都不是本質(zhì)問題。換句話說,即便狠狠的砸錢、砸人、上KPI,即使機(jī)器不用過保機(jī)、硬件不超賣、工具建設(shè)好把配置監(jiān)控自愈等和生產(chǎn)環(huán)境保持對齊、問題響應(yīng)機(jī)制建立起來,線下環(huán)境也還是會(huì)不穩(wěn)定的。因?yàn)榫€下環(huán)境不穩(wěn)定的根源在于:

  • 線下環(huán)境里面有不穩(wěn)定的代碼
  • 線下環(huán)境不穩(wěn)定帶來的影響小

這兩個(gè)原因是相互有關(guān)系的:我們需要有一個(gè)地方運(yùn)行不穩(wěn)定的代碼,但我們怕不穩(wěn)定的代碼引起很大的問題,所以我們需要這個(gè)地方是低利害關(guān)系的(low-stakes);因?yàn)檫@個(gè)地方是低利害關(guān)系的,所以對它的問題我們必然是低優(yōu)先級處理的。

所以,線下環(huán)境必然是不穩(wěn)定的。

之所以Testing-in-Production(TiP)是一條出路,就是因?yàn)門iP把這兩個(gè)根源中的一個(gè)(即第二點(diǎn))給消除了:production不穩(wěn)定帶來的影響是很大的。但TiP注定是一條很漫長且艱難的道路,因?yàn)槲覀兣虏环€(wěn)定的代碼引起很大的問題。我們需要首先在技術(shù)上有充分的能力充分確保不穩(wěn)定的代碼也不會(huì)引起很大的問題。這是很有難度的,今天我們還沒有100%的信心做到能充分確保穩(wěn)定的代碼不會(huì)引起很大的問題。

既然TiP一時(shí)半會(huì)兒還用不上、發(fā)揮不了很大的作用,那么接下去的問題就是:怎么辦?既然線下環(huán)境的不穩(wěn)定是必然的,那我們怎么用不太夸張的投入讓它盡量穩(wěn)定一點(diǎn)?

對策還是要有的。否則,線下環(huán)境太不穩(wěn)定了,大家就都放棄了,不用了,直接跳過,直接把還不太穩(wěn)定的代碼部署到預(yù)發(fā)環(huán)境(pre-production)去了。把預(yù)發(fā)環(huán)境當(dāng)線下環(huán)境用,結(jié)果就是預(yù)發(fā)環(huán)境也被搞得像線下環(huán)境那樣不穩(wěn)定了。這樣再發(fā)展下去,預(yù)發(fā)環(huán)境越來越不穩(wěn)定了,我們還有地方可以去嗎?所以,還是要有一整套對策讓線下環(huán)境盡量穩(wěn)定一點(diǎn)。

二 怎么讓線下環(huán)境盡量穩(wěn)定一點(diǎn)

1 避免過多的籠統(tǒng)使用“環(huán)境問題”的說法

很多同學(xué)習(xí)慣用“環(huán)境問題”、“環(huán)境不穩(wěn)定”來指代線下環(huán)境里除了他自己的那個(gè)應(yīng)用之外的所有的問題:

  • 物理機(jī)和網(wǎng)絡(luò)的問題是“環(huán)境問題”
  • 中間件的問題是“環(huán)境問題”
  • 數(shù)據(jù)庫本身的問題是“環(huán)境問題”
  • 數(shù)據(jù)庫里的“臟”數(shù)據(jù)[2]是“環(huán)境問題”
  • 我的數(shù)據(jù)被別人的應(yīng)用消費(fèi)掉了是“環(huán)境問題”
  • 其他應(yīng)用的配置配錯(cuò)了是“環(huán)境問題”
  • 其他應(yīng)用重啟了導(dǎo)致我的調(diào)用失敗是“環(huán)境問題”
  • 其他應(yīng)用里的代碼bug也是“環(huán)境問題”
  • ...

“環(huán)境問題”這個(gè)說法太籠統(tǒng)了,過多的籠統(tǒng)使用這個(gè)說法是很有害的,因?yàn)樗鼤?huì)掩蓋很多真正的問題。其中的一些問題也是有可能造成生產(chǎn)環(huán)境的穩(wěn)定性和資金安全風(fēng)險(xiǎn)的。過多的籠統(tǒng)使用“環(huán)境問題”這個(gè)說法的另一個(gè)壞處是:會(huì)造成在大家的意識(shí)里“環(huán)境問題”是必然存在的、是無法避免的,導(dǎo)致大家一聽到“環(huán)境問題”第一反應(yīng)就是放棄,放棄排查、放棄抗?fàn)?、放棄探究、放棄改進(jìn)優(yōu)化。

要提升線下環(huán)境穩(wěn)定性,首先要正本清源,盡量避免籠統(tǒng)的使用“環(huán)境問題”這個(gè)說法。要盡量用具體一點(diǎn)的說法,比如,“網(wǎng)關(guān)配置問題”、“某某應(yīng)用啟動(dòng)超時(shí)”、“數(shù)據(jù)庫查詢超時(shí)“。這些表象/癥狀背后的原因有很多種可能,是需要我們?nèi)ヅ挪榍宄模荒?ldquo;刷墻”。所謂的“刷墻”的意思是:看到墻上有條裂縫,就找一桶乳膠漆刷一道,把裂縫遮蓋掉。“刷墻”的行為的一個(gè)例子:某個(gè)應(yīng)用啟動(dòng)失敗,就換臺(tái)服務(wù)器再試一試,成功了就繼續(xù)干下面的事情,不去探究之前啟動(dòng)失敗背后的原因了。

有些時(shí)候的確是項(xiàng)目時(shí)間太緊了,沒時(shí)間排查每一個(gè)問題??梢袁F(xiàn)實(shí)一點(diǎn),如果同樣的問題出現(xiàn)第二次或第三次(例如,同一個(gè)應(yīng)用、同一個(gè)項(xiàng)目分支,這周遇到兩三次啟動(dòng)失敗),就要追究一下了。

2 問題拆解

“環(huán)境問題”,歸根到底,無外乎來自于三個(gè)地方:

  • 基礎(chǔ)設(shè)施(中間件、數(shù)據(jù)庫、等等)的問題
  • stable環(huán)境的問題
  • dev環(huán)境的問題

這里要解釋一下什么是stable和dev。線下環(huán)境的結(jié)構(gòu)在螞蟻集團(tuán)和阿里集團(tuán)的做法一般是這樣的:

  • 基礎(chǔ)設(shè)施之上,首先有一個(gè)stable環(huán)境。
  • stable環(huán)境跑的是和生產(chǎn)環(huán)境的版本相同的代碼,每次生產(chǎn)環(huán)境發(fā)布后,stable也會(huì)同步更新。
  • dev環(huán)境就是項(xiàng)目環(huán)境,是SUT(System Under Test)。每個(gè)項(xiàng)目有自己的dev環(huán)境,部署的是這個(gè)項(xiàng)目的代碼,這個(gè)項(xiàng)目上的同學(xué)就在這個(gè)項(xiàng)目環(huán)境里做測試、聯(lián)調(diào)、集成。
  • dev環(huán)境不是一個(gè)全量的環(huán)境,它是“掛”在stable上的一個(gè)子集。某系統(tǒng)一共有一百個(gè)左右的應(yīng)用,它的stable環(huán)境是全量的,但dev環(huán)境只包含這個(gè)項(xiàng)目涉及的應(yīng)用,測試發(fā)起的流量里面包含一個(gè)標(biāo)簽,測試流量就會(huì)被某種路由機(jī)制(例如,在螞蟻用的是sofarouter)從stable環(huán)境的應(yīng)用路由到dev環(huán)境的應(yīng)用:

雖然這三趴對“環(huán)境問題”會(huì)因人而異,但都不可忽視。要提升線下環(huán)境穩(wěn)定性,必須對基礎(chǔ)設(shè)施、stable、dev這三趴三管齊下。

3 對策:基礎(chǔ)設(shè)施

基礎(chǔ)設(shè)施的穩(wěn)定是非常關(guān)鍵的一環(huán)。如果基礎(chǔ)設(shè)施不穩(wěn)定,就會(huì)出現(xiàn)“排查疲勞”:每次遇到一些奇怪的問題(啟動(dòng)超時(shí)、調(diào)不通、等等),如果排查下來10次有9次是基礎(chǔ)設(shè)施的問題,大家漸漸就不愿意排查了(因?yàn)椴皇谴a的問題),一些真正的代碼問題也會(huì)被漏過。

基礎(chǔ)設(shè)施層要遵循的原則是:(業(yè)務(wù)應(yīng)用的)線下環(huán)境的基礎(chǔ)設(shè)施必須按照生產(chǎn)標(biāo)準(zhǔn)運(yùn)維 。如果一個(gè)系統(tǒng)是運(yùn)行在公有云上的,那么這個(gè)原則就很容易實(shí)現(xiàn),因?yàn)榫€下環(huán)境也可以直接運(yùn)行在公有云上。但有些公司、有些系統(tǒng),是運(yùn)行在自建機(jī)房、私有云上的,那最好的做法是撤銷“線下機(jī)房”,直接把業(yè)務(wù)應(yīng)用的線下環(huán)境放在基礎(chǔ)設(shè)施的生產(chǎn)機(jī)房去跑(同時(shí)做好必要的訪問控制和業(yè)務(wù)數(shù)據(jù)隔離)。線下環(huán)境直接放在基礎(chǔ)設(shè)施的生產(chǎn)機(jī)房跑之后,基礎(chǔ)設(shè)施團(tuán)隊(duì)直接按照運(yùn)維其他生產(chǎn)機(jī)房那樣去運(yùn)維,中間件、數(shù)據(jù)庫、緩存、物理機(jī)、網(wǎng)絡(luò)、機(jī)房等所有的監(jiān)控告警、巡檢、發(fā)布和變更管控、應(yīng)急、自愈能力、容量管理、等等都能做到位,穩(wěn)定性可用率有明確的metrics和SLA。慢慢的,就能形成這樣的心智:例如,當(dāng)線下環(huán)境的某個(gè)業(yè)務(wù)應(yīng)用出現(xiàn)數(shù)據(jù)庫查詢timeout的時(shí)候,我們首先懷疑的是應(yīng)用自己的SQL查詢語句有問題,而不是懷疑數(shù)據(jù)庫有問題。

4 對策:stable環(huán)境

線下環(huán)境不穩(wěn)定性的時(shí)候,工程師的心智是:當(dāng)我在dev環(huán)境跑測試遇到錯(cuò)誤的時(shí)候,我的第一反應(yīng)是“一定是‘環(huán)境問題’”。也就是說,我的第一反應(yīng)是“別人的問題”,只有當(dāng)“別人的問題”都排出后我才會(huì)認(rèn)真的去看是不是我自己的問題(包括項(xiàng)目的問題)。

當(dāng)基礎(chǔ)設(shè)施層穩(wěn)定保障好以后,就能形成這樣的心智:當(dāng)某個(gè)應(yīng)用出現(xiàn)數(shù)據(jù)庫查詢timeout的時(shí)候,我們首先懷疑的是應(yīng)用(可能是stable的、可能是dev的)的SQL有問題,而不是懷疑數(shù)據(jù)庫有問題。

當(dāng)stable和基礎(chǔ)設(shè)施這兩趴的穩(wěn)定性都治理好以后,就能形成這樣的心智:當(dāng)我在dev環(huán)境跑測試遇到錯(cuò)誤的時(shí)候,我的第一反應(yīng)是“一定是我們的項(xiàng)目有問題”。其實(shí)今天在生產(chǎn)環(huán)境大家就是這樣的心智。一次變更、一次發(fā)布后,如果出現(xiàn)問題,做發(fā)布做變更的同學(xué)的第一反應(yīng)都是懷疑是不是這個(gè)變更/發(fā)布有問題,而不是懷疑是不是(生產(chǎn))環(huán)境本身不穩(wěn)定。做stable和基礎(chǔ)設(shè)施的穩(wěn)定性治理也要達(dá)成這樣的心智。

stable的穩(wěn)定性治理,最終就是在做一道證明題:拿出數(shù)據(jù)來,證明stable是穩(wěn)定的(所以,如果有問題,請先排查你的項(xiàng)目)。證明stable是穩(wěn)定的數(shù)據(jù)分兩類:

  • 單應(yīng)用
  • 鏈路

單應(yīng)用就是檢查應(yīng)用是否起來了、是否或者、RPC調(diào)用是否調(diào)通(不管業(yè)務(wù)結(jié)果是成功還是失敗,但至少RPC調(diào)用沒有system error)。它驗(yàn)證的是單個(gè)應(yīng)用是可用的,不管業(yè)務(wù)邏輯對不對,不管配置對不對,不管簽約綁卡能不能work,至少這個(gè)應(yīng)用、這個(gè)服務(wù)、這個(gè)微服務(wù)是up and running的。單應(yīng)用穩(wěn)定性必須達(dá)到100%,或者至少應(yīng)該是“五個(gè)9”。這個(gè)要求是合理的,因?yàn)閱螒?yīng)用的穩(wěn)定性是鏈路穩(wěn)定性的基礎(chǔ)。如果單應(yīng)用都沒有up and running,鏈路功能的可用和正確性就根本無從談起。

單應(yīng)用的穩(wěn)定性度量是很通用的,不需要理解業(yè)務(wù)場景就可以度量。我們需要做的事情就是:對目標(biāo)形成共識(shí),把度量跑起來,然后根據(jù)度量數(shù)據(jù)投入人力,一個(gè)個(gè)問題的排查解決,把穩(wěn)定性一點(diǎn)點(diǎn)提升上來;后續(xù)再出現(xiàn)問題,第一時(shí)間排查解決,讓穩(wěn)定性維持在很高的水平。

鏈路的穩(wěn)定性,說白了就是跑腳本、跑測試用例。頻率是分鐘級也可以,小時(shí)級也可以。驗(yàn)證鏈路的腳本是需要不斷的補(bǔ)充豐富的,當(dāng)發(fā)生了一個(gè)stable的問題但是驗(yàn)證腳本沒有發(fā)現(xiàn),就要把這個(gè)問題的場景補(bǔ)充到鏈路驗(yàn)證腳本(測試用例)里面去。也可以借用測試用例充分度的度量手段(例如,行覆蓋率、業(yè)務(wù)覆蓋率、等等),主動(dòng)的補(bǔ)充鏈路驗(yàn)證腳本。很多其他測試用例自動(dòng)生成的技術(shù)也可以用上來。

最后,達(dá)到的效果就是:用數(shù)據(jù)說話。用很有說服力的數(shù)據(jù)說話:stable的單應(yīng)用都是好的,鏈路也都是通的,這時(shí)候出現(xiàn)了問題,就應(yīng)該先懷疑是項(xiàng)目(dev環(huán)境)的問題。

順便說一句:stable能不能像基礎(chǔ)設(shè)施那樣也直接用生產(chǎn)環(huán)境呢?可以的,stable用生產(chǎn)就是Testing-in-Production了。螞蟻的影子鏈路壓測就是這種做法的一個(gè)例子。只不過如果要把這個(gè)做法推廣到更大面積的日常功能測試、支持更多鏈路和場景,復(fù)雜度和難度會(huì)比影子鏈路壓測更高。

5 對策:dev環(huán)境

嚴(yán)格來說,dev環(huán)境的問題不能算是“環(huán)境問題”,也不能算是“線下環(huán)境穩(wěn)定性問題”。因?yàn)閐ev環(huán)境就是被測對象(SUT),既然是還在寫代碼、聯(lián)調(diào)集成和測試,那我們的預(yù)期就是它是不穩(wěn)定的,是會(huì)有問題的。只不過實(shí)際工作中,dev環(huán)境本身的問題也構(gòu)成了大家對線下環(huán)境不穩(wěn)定的體感。

根據(jù)我們對一些項(xiàng)目進(jìn)行的具體數(shù)據(jù)分析來分類,在dev環(huán)境遇到的問題的幾個(gè)頭部類型是:

  • 自測沒做好。單應(yīng)用本身就有bug,而且這些bug是在單應(yīng)用的unit test和接口測試中是可以發(fā)現(xiàn)的,但是由于各種原因,單應(yīng)用的自測沒做好,這些bug留到了在dev環(huán)境中進(jìn)行聯(lián)調(diào)集成的時(shí)候才發(fā)現(xiàn)。
  • 架構(gòu)方面的原因。例如,接口契約問題。一個(gè)項(xiàng)目里,系分做好以后,上下游兩個(gè)應(yīng)用各自按照系分去編碼實(shí)現(xiàn),但由于系分做的不夠好,或者上下游對系分的理解有差異,兩個(gè)應(yīng)用到了dev環(huán)境放在一起一跑才發(fā)現(xiàn)跑不通。這類問題是無法通過自測來發(fā)現(xiàn)的(因?yàn)楸旧淼睦斫饩陀胁町?。另一個(gè)比較常見的架構(gòu)原因是可測性。
  • 干擾。同一個(gè)項(xiàng)目中幾個(gè)同學(xué)各自在做聯(lián)調(diào)集成時(shí)候的相互干擾,以及幾個(gè)項(xiàng)目之間的相互干擾。配置被別人改掉了,數(shù)據(jù)被別人改掉了,這些情況都很常見。

自測沒做好,解法就是要做好自測:

  • 單應(yīng)用的測試要達(dá)到一定的覆蓋率和有效性。例如,我之前團(tuán)隊(duì)的要求是A級系統(tǒng)的單應(yīng)用測試(unit test和接口測試)要達(dá)到90%以上的行覆蓋率、以及變更行的覆蓋率100%,用例的有效性也要達(dá)到90%。
  • 單應(yīng)用的測試要達(dá)到很好的穩(wěn)定性。根據(jù)過去在很多地方的時(shí)間和觀察,我建議的標(biāo)準(zhǔn)是”90%成功率“,這是在“能做得到的”和“夠好了”之間的一個(gè)比較好的平衡。比這個(gè)高,雖然更好,但難度太高,不適合大部分的團(tuán)隊(duì);比這個(gè)低,穩(wěn)定性就不夠了,就會(huì)感受到測試噪音帶來的各種問題。“90%成功率”是一個(gè)“甜蜜點(diǎn)”。“90%成功率”的意思是:一個(gè)單應(yīng)用的所有unit test和接口測試的整體通過率,跑一百遍,有至少90遍是100%通過的。
  • 單應(yīng)用的測試也要足夠快,一個(gè)單應(yīng)用的所有unit test和接口測試要能在10分鐘內(nèi)跑完。
  • 代碼門禁是必須的,是標(biāo)配。很多其他東西是可以根據(jù)具體團(tuán)隊(duì)的具體情況有不同的做法的,例如,大庫、主干開發(fā)。有些團(tuán)隊(duì)可以舉出一些合理的理由說“大庫模式不適合我”、“主干開發(fā)不適合我”。但我不相信哪個(gè)團(tuán)隊(duì)能舉出合理的理由說“代碼門禁不適合我”。

接口契約在軟件行業(yè)已經(jīng)有比較多的實(shí)踐了,例如OpenAPI、ProtoBuf、Pact等。應(yīng)用間的接口(包括RPC調(diào)用和消息),如果只是在一個(gè)文檔里面用中文或者英文來描述的,上下游之間就比較容易出現(xiàn)gap。也經(jīng)常出現(xiàn)接口改動(dòng)只是通過釘釘說了一下,連文檔都沒有更新。應(yīng)用間的接口應(yīng)該以某種DSL來規(guī)范的描述,并且在單應(yīng)用層面根據(jù)這個(gè)DSL描述進(jìn)行契約測試,這樣能大大減少兩個(gè)應(yīng)用到了dev環(huán)境放在一起一跑才發(fā)現(xiàn)跑不通的情況。

6 dev環(huán)境:隔離

上面講到,dev環(huán)境問題的第三個(gè)主要來源是相互干擾。既有同一個(gè)項(xiàng)目中幾個(gè)同學(xué)各自在做聯(lián)調(diào)集成時(shí)候的相互干擾,也有幾個(gè)項(xiàng)目之間的相互干擾。項(xiàng)目之間的相互干擾的根源是共享數(shù)據(jù)庫:

過去,stable環(huán)境以及多個(gè)項(xiàng)目的dev環(huán)境的代碼都是訪問同一個(gè)庫的,相互影響就是不可避免的。數(shù)據(jù)的邏輯隔離和物理隔離都可以解決多項(xiàng)目間的干擾:

  • 邏輯隔離:多個(gè)項(xiàng)目的dev環(huán)境仍然和stable一起共享同一套庫表,但是在表的數(shù)據(jù)層面增加一些標(biāo)識(shí)列,并且在應(yīng)用的代碼邏輯里面根據(jù)這種標(biāo)識(shí)來讀寫數(shù)據(jù)。
  • 物理隔離:每個(gè)dev環(huán)境分別有自己的庫或者表,各自的數(shù)據(jù)在庫或表的層面就是隔離的。相比邏輯隔離,物理隔離有兩個(gè)優(yōu)點(diǎn):1)對應(yīng)用代碼的入侵很小,需要的應(yīng)用改造工作量很小;2)不同的項(xiàng)目能夠有不同的數(shù)據(jù)庫表結(jié)構(gòu)。

除了數(shù)據(jù)庫,緩存、DRM等也需要進(jìn)行隔離,減少多個(gè)項(xiàng)目之間的相互干擾。做好隔離對提升穩(wěn)定性有很大的幫助。而且,數(shù)據(jù)庫和緩存等的隔離也能大大降低“臟”數(shù)據(jù)引起的問題。

7 dev環(huán)境:多環(huán)境

除了多個(gè)項(xiàng)目之間的干擾以外,同一個(gè)項(xiàng)目中幾個(gè)同學(xué)各自在做聯(lián)調(diào)集成時(shí)候,由于大家都在同一套dev環(huán)境(項(xiàng)目環(huán)境)上工作,也會(huì)出現(xiàn)相互干擾。

解決項(xiàng)目內(nèi)相互干擾的出路是多環(huán)境:

IaC(Infrastructure-as-Code)和GitOps是實(shí)現(xiàn)多環(huán)境能力的關(guān)鍵。有了GitOps能力(包括Configuration-as-Code和Database-as-Code),能反復(fù)快速創(chuàng)建出一套套新的項(xiàng)目環(huán)境,并且保證新創(chuàng)建的項(xiàng)目環(huán)境中的配置都是對的(IaC也能更好更有效的確保stable的配置、二方包版本、CE版本等和生產(chǎn)環(huán)境是一致的)。

8 dev環(huán)境:持續(xù)集成

單應(yīng)用的持續(xù)集成已經(jīng)是比較普遍了:在master分支和項(xiàng)目分支上,每次有代碼提交都會(huì)觸發(fā)一次單應(yīng)用的編譯構(gòu)建和測試(包括unit test和接口測試),或者以某個(gè)固定周期(例如每15分鐘或者每小時(shí))定時(shí)觸發(fā)一次,確保該應(yīng)用的編譯構(gòu)建和測試一直是好的。

多應(yīng)用的持續(xù)集成就是:在項(xiàng)目分支上,每次有代碼提交、或者每隔一定時(shí)間,把本項(xiàng)目各個(gè)應(yīng)用的項(xiàng)目分支最新代碼部署到dev環(huán)境上,并且跑一遍鏈路級別的用例,確保本項(xiàng)目的這些應(yīng)用的項(xiàng)目分支代碼還是好的。

在很多團(tuán)隊(duì),今天開發(fā)同學(xué)的很多受挫感和時(shí)間的浪費(fèi)都與缺乏項(xiàng)目級別的多應(yīng)用持續(xù)集成有關(guān),例如:

  • 小李跟我說收單支付已經(jīng)跑通了,讓我可以開始測結(jié)算了。但我今天到項(xiàng)目環(huán)境里一跑,發(fā)現(xiàn)收單有問題。我又去找小李,小李看了一下承認(rèn)是他的問題,他當(dāng)時(shí)只看了行業(yè)層的resultCode是Success,沒有check下游單據(jù)的狀態(tài)是否正確。
  • 我兩天前已經(jīng)把正向流程(例如:支付)跑通了,但今天我要調(diào)逆向流程(例如:退款)的時(shí)候發(fā)現(xiàn)項(xiàng)目環(huán)境里正向流程又不work了。逆向流程的調(diào)試被block了,我要先花時(shí)間排查正向流程的問題。
  • 項(xiàng)目環(huán)境里正向流程兩天前是work的,今天不work了,從兩天前到現(xiàn)在,這個(gè)中間正向流程是從什么時(shí)間開始不work的?兩天時(shí)間,如茫茫大海撈針啊。
  • 我是負(fù)責(zé)下游應(yīng)用的。上游的同學(xué)今天一次次來找我check數(shù)據(jù),每次他在項(xiàng)目環(huán)境里發(fā)起一筆新的調(diào)用,都要來找我讓我做數(shù)據(jù)check。這事兒我躲也躲不掉,因?yàn)樯嫌蔚耐瑢W(xué)不理解我的應(yīng)用的內(nèi)部實(shí)現(xiàn),要他們理解每個(gè)下游應(yīng)用的數(shù)據(jù)邏輯也不現(xiàn)實(shí)。
  • 我是負(fù)責(zé)上游行業(yè)層的,我在項(xiàng)目環(huán)境里每次發(fā)起一筆新的測試交易的時(shí)候,我都要挨個(gè)兒找下游各域的同學(xué)去做數(shù)據(jù)check,找人找的好辛苦啊。我也理解他們的難處,那么多項(xiàng)目,那么多項(xiàng)目環(huán)境,那么多人都去找他們做數(shù)據(jù)check。
  • 我是負(fù)責(zé)上游行業(yè)層的,下游的同學(xué)經(jīng)常來找我,讓我?guī)退麄儼l(fā)起一筆交易,因?yàn)樗麄兊膽?yīng)用改了代碼,他們先知道新的代碼work不work。后來我實(shí)在覺得這種要求太多了,寫了一個(gè)發(fā)起交易的小工具,讓他們自己去跑。但有些會(huì)自己去學(xué)著用這個(gè)小工具,有些還是會(huì)來找我。
  • 我是負(fù)責(zé)下游應(yīng)用的,我經(jīng)常要去找上游同學(xué)幫我發(fā)起一筆。他們被我騷擾的很煩,但我也沒辦法。他們雖然給了我一個(gè)小工具,但很難用,很多參數(shù)不知道怎么填。

做好了多應(yīng)用的持續(xù)集成,這些問題就都解決了:

  • 由于用例都自動(dòng)化了,發(fā)起交易和做check都不需要再求爺爺告奶奶的刷臉找人了。
  • 由于用例都自動(dòng)化了,發(fā)起一筆新的交易和驗(yàn)證各域的數(shù)據(jù)是否正確 都已經(jīng)都自動(dòng)化在用例的代碼里了,無論是上游還是下游的同學(xué),都只要跑這些用例就可以了,不需要了解小工具的參數(shù)怎么填,也不會(huì)因?yàn)槭杪┥賑heck了數(shù)據(jù)。
  • 由于用例都自動(dòng)化了,所以可以高頻的跑,可以每個(gè)小時(shí)都跑一次,或者可以每15分鐘就跑一次。這樣,一旦前兩天已經(jīng)跑通的功能被break了,我馬上就知道了。
  • 由于用例高頻的跑了,一旦前兩天已經(jīng)跑通的功能被break了,我馬上就知道了,而且問題排查也很容易聚焦。比如,如果這個(gè)功能一直到上午9:30還是好的,但是從9:45開始就開始失敗了,那我就可以聚焦看9:30-9:45這段時(shí)間前后總共幾十分鐘時(shí)間里發(fā)生了什么、誰提交了新代碼、誰改了數(shù)據(jù)或配置。

做好了多應(yīng)用的持續(xù)集成,其他的好處還有:

  • 由于用例高頻的跑了,一個(gè)用例一天要跑幾十次,就很容易暴露出用例本身或者應(yīng)用代碼的一些穩(wěn)定性問題。比如,有一個(gè)鏈路,從昨天到今天在本項(xiàng)目的多應(yīng)用持續(xù)集成里面跑了幾十次,其中有幾次失敗了。但從昨天到今天,這個(gè)鏈路沒有相關(guān)代碼和配置改動(dòng)。所以雖然失敗的比例小于10%,我還是要排查一下,排查結(jié)果發(fā)現(xiàn)了一個(gè)代碼的bug。如果放在過去,沒有這種多應(yīng)用的持續(xù)集成,一個(gè)鏈路跑了一次失敗了,第二次通過了,我很難判斷第一次失敗到底是“環(huán)境問題”,還是真的代碼有bug。
  • 由于用例在項(xiàng)目分支里高頻的跑了,我就有一個(gè)參考物。如果一個(gè)用例在項(xiàng)目分支里是一只穩(wěn)定pass的,但今天在我的個(gè)人分支代碼上失敗了,有了持續(xù)集成的結(jié)果作為參照物,我就很快能判斷出來這很有可能是我的個(gè)人分支的代碼有問題。

三 線下環(huán)境和線上環(huán)境的區(qū)別

線下環(huán)境和線上環(huán)境的區(qū)別是什么,不同的人有不同的回答。有的說線下的容量沒有線上大,有的說線下沒有真實(shí)用戶,有的說線下缺少生產(chǎn)的真實(shí)數(shù)據(jù),等等,各種答案都有。線下環(huán)境和線上環(huán)境還有一個(gè)很本質(zhì)的區(qū)別是:它們是兩個(gè)不同的場景。

線下環(huán)境是一個(gè)場景。

我們做業(yè)務(wù)架構(gòu),先要搞明白業(yè)務(wù)場景,然后才能正確的設(shè)計(jì)業(yè)務(wù)架構(gòu)和技術(shù)實(shí)現(xiàn)。數(shù)據(jù)的讀和寫是高頻的還是低頻的,數(shù)據(jù)塊是大而少的還是小而多的,讀取數(shù)據(jù)的時(shí)間段上有沒有明顯的峰谷,數(shù)據(jù)寫入后是否會(huì)修改(mutable vs. immutable)等等,這些都會(huì)影響我們的架構(gòu)和技術(shù)實(shí)現(xiàn)方案。

線下環(huán)境也是一個(gè)場景,一個(gè)和生產(chǎn)環(huán)境有不少差異的場景[3]:

1 基礎(chǔ)設(shè)施層面

中間件

一個(gè)配置值、一個(gè)開關(guān)值,在線上的改動(dòng)是低頻的,大部分情況下一天可能也就推個(gè)一兩次,但在線下可能每天會(huì)有幾十次、幾百次,因?yàn)橥扑鸵粋€(gè)配置一個(gè)開關(guān)可能是測試的一部分。這個(gè)差異就是場景的差異。

服務(wù)器

服務(wù)器重啟,在生產(chǎn)環(huán)境里是一個(gè)低頻事件,很多應(yīng)用只會(huì)在發(fā)布的時(shí)候重啟一次,兩次重啟間的間隔一般都是數(shù)天。但在線下環(huán)境,重啟的頻率可能會(huì)高很多。

數(shù)據(jù)庫

在生產(chǎn)環(huán)境,庫的創(chuàng)建和銷毀是一個(gè)低頻事件,但是在線下,如果搞了持續(xù)回歸和一鍵拉環(huán)境,線下環(huán)境數(shù)據(jù)庫就會(huì)有比生產(chǎn)高的多得多的庫創(chuàng)建銷毀操作。

數(shù)據(jù)丟失

生產(chǎn)環(huán)境,我們是不允許數(shù)據(jù)丟失的。所以,數(shù)據(jù)庫(例如螞蟻的OceanBase)和DBA團(tuán)隊(duì)花了大量的心血在數(shù)據(jù)丟失場景上。但在線下,數(shù)據(jù)丟失是完全可以接受的。這個(gè)差異,對數(shù)據(jù)層的架構(gòu)和技術(shù)實(shí)現(xiàn)意味著什么?例如,數(shù)據(jù)庫在生產(chǎn)環(huán)境是三副本、五副本的,在線下不能支持單副本,能不能很容易的在單服務(wù)器、單庫級別配置成單副本。

代碼版本

生產(chǎn)環(huán)境,一個(gè)系統(tǒng),最多同時(shí)會(huì)有幾個(gè)不同的代碼版本在運(yùn)行?線下環(huán)境呢?這個(gè)差異,意味著什么?

抖動(dòng)

“抖動(dòng)”是很難避免的,業(yè)務(wù)應(yīng)用一般都有一些專門的設(shè)計(jì)能夠容忍線上的基礎(chǔ)設(shè)施層的一些”抖動(dòng)“。因此,在生產(chǎn)環(huán)境場景里,基礎(chǔ)設(shè)施層面每天抖N次、每次抖10-20秒,不是一個(gè)太大的問題。但這樣的抖動(dòng)在線下環(huán)境就是個(gè)比較大的問題:每次抖動(dòng),都會(huì)造成測試用例的失敗。這并不是因?yàn)檫@些用例寫的不夠“健壯”,而是有很多時(shí)候測試用例就是不能有防抖邏輯的。例如,如果測試用例有某種retry邏輯,或者測試平臺(tái)會(huì)自動(dòng)重跑失敗的案例[4],那么就會(huì)miss掉一些偶發(fā)的的bug[5]。在線下環(huán)境里,我們寧可接受每周有一次30分鐘的outage(不可用),也不愿意接受每周幾十次的10-20秒抖動(dòng)。一次30分鐘的outage,大不了就直接忽略掉那段時(shí)間的所有測試結(jié)果。而每周幾十次的10-20秒抖動(dòng)意味著大量的測試噪音[6],意味著要么是大量的額外的排查成本,要么是漏過一些問題的可能。

2 業(yè)務(wù)應(yīng)用層面

業(yè)務(wù)數(shù)據(jù)

線下的數(shù)據(jù)模式和生產(chǎn)是不一樣的。由于執(zhí)行測試用例,線下的營銷系統(tǒng)里的當(dāng)前營銷活動(dòng)的數(shù)量可能比生產(chǎn)要高一個(gè)數(shù)量級。所以營銷應(yīng)用要在技術(shù)層面處理好線下這個(gè)場景,如果一個(gè)營銷應(yīng)用會(huì)在啟動(dòng)的時(shí)候就加載所有的當(dāng)前活動(dòng),可能就會(huì)在線下出現(xiàn)很長的啟動(dòng)時(shí)間。

數(shù)據(jù)的生命周期

我一直倡導(dǎo)的一個(gè)原則是“Test environment is ephemeral”,也就是說,線下環(huán)境的存在時(shí)間是很短的。存在時(shí)間短,要求create的成功率高、時(shí)間短,但對數(shù)據(jù)清理要求比較低。存在時(shí)間長的,就要求upgrade的成功率高,對create的要求很低,對數(shù)據(jù)完整性和測試數(shù)據(jù)清理的要求非常高。繼續(xù)推演下去,要做好測試數(shù)據(jù)清理,需要什么?基建層有什么技術(shù)方案?業(yè)務(wù)層需要做什么?業(yè)務(wù)層是否需要對數(shù)據(jù)進(jìn)行打標(biāo)?測試數(shù)據(jù)清理這件事,是放在業(yè)務(wù)層做(基建層提供原子能力),還是在基礎(chǔ)設(shè)施層做(業(yè)務(wù)層按照規(guī)范打標(biāo))?這就是一個(gè)架構(gòu)設(shè)計(jì)問題。這樣的問題,要有頂層設(shè)計(jì)、架構(gòu)設(shè)計(jì),要針對場景進(jìn)行設(shè)計(jì),不能有啥用啥、湊合將就。

業(yè)務(wù)流程

生產(chǎn)環(huán)境入駐一個(gè)商戶,會(huì)經(jīng)過一個(gè)人工審批流程,這個(gè)流程也許會(huì)走兩三天,有六七個(gè)審批步驟。這在線上是OK的,因?yàn)榫€上的商戶入駐是相對低頻且能夠接受較長的處理周期的。但在線下,由于要執(zhí)行自動(dòng)化的測試用例,而且要確保測試用例是“自包含”的,商戶的創(chuàng)建就會(huì)是高頻,而且必須快速處理的。所以在技術(shù)層面,針對線下環(huán)境的場景,要能夠“短路”掉審批流程(除非本身要測試的就是審批流程)。類似的流程還有網(wǎng)關(guān)的映射配置,線上的網(wǎng)關(guān)配置是低頻的,但線下的網(wǎng)關(guān)配置是高頻動(dòng)作,而且會(huì)反反復(fù)復(fù)。

3 其他

問題排查

線上環(huán)境是有比較清楚的基線的,比較容易把失敗的交易的鏈路數(shù)據(jù)和成功的交易的鏈路做比較。這個(gè)做法在線下環(huán)境同樣有效嗎?如果不是,為什么?是什么具體的線下環(huán)境的場景差異導(dǎo)致的?又比如說,對日志的需求,線上線下有差異嗎?

權(quán)限模型

線下數(shù)據(jù)庫的權(quán)限,如果讀和寫的權(quán)限是綁定的、申請權(quán)限就是同時(shí)申請了讀和寫,就會(huì)很難受。因?yàn)楣こ處煘榱烁玫淖鰡栴}排查,希望申請上下游應(yīng)用的數(shù)據(jù)庫讀權(quán)限,但他們只需要讀權(quán)限,不需要寫權(quán)限。如果讀寫權(quán)限是綁定的,即便他們只需要讀權(quán)限,也要經(jīng)過繁瑣的申請審批,因?yàn)樯婕傲藢憴?quán)限,寫權(quán)限如果缺乏管控,容易出現(xiàn)數(shù)據(jù)經(jīng)常被改亂掉的情況。讀寫權(quán)限申請的時(shí)候是綁定的,這在線上環(huán)境的場景下也許是OK的,因?yàn)樯a(chǎn)環(huán)境要跑DML本身是有工單流程的,不容易出現(xiàn)數(shù)據(jù)被改亂掉的情況。但讀寫權(quán)限綁定在線下就不合適了。從架構(gòu)和設(shè)計(jì)層面說,讀寫權(quán)限綁定是因?yàn)锳CL的模型本身沒有支持到那個(gè)顆粒度。

我們一直說,做技術(shù)的要理解業(yè)務(wù)。比如,做支付系統(tǒng)的,要深刻理解不同的支付場景的差異(比如,代扣、協(xié)議支付、收銀臺(tái)、…),才能有效的進(jìn)行架構(gòu)設(shè)計(jì)和技術(shù)風(fēng)險(xiǎn)保障。例如,代扣場景,沒有uid。這意味著什么?沒有uid,意味著灰度引流的做法會(huì)不一樣,精準(zhǔn)灰度的做法可能會(huì)不一樣,新建機(jī)房的切流方案也會(huì)不一樣。

線下環(huán)境也是類似的道理。線下環(huán)境也是一個(gè)場景。這個(gè)場景和生產(chǎn)是不同的場景。每一層(SaaS、PaaS、IaaS)都要深刻的理解不同場景的差異,才能有效的把不同場景都保障好。如果一個(gè)應(yīng)用、一個(gè)平臺(tái),它的設(shè)計(jì)和實(shí)現(xiàn)只考慮了X場景、沒有考慮Y場景,那么它在Y場景下就會(huì)遇到這樣那樣的不舒服,也會(huì)使得Y場景下的客戶不滿意。

充分理解“線下環(huán)境”這個(gè)場景,把這個(gè)場景納入到架構(gòu)和技術(shù)實(shí)現(xiàn)的考慮中,有助于讓線下環(huán)境盡量保持穩(wěn)定。

四 結(jié)語

總結(jié)一下上面所說的一些關(guān)鍵點(diǎn):

1. 線下環(huán)境不穩(wěn)定是必然的,在沒有實(shí)現(xiàn)TiP之前,當(dāng)前我們能做的是盡量讓它穩(wěn)定一點(diǎn)。

2. 避免過多的籠統(tǒng)使用“環(huán)境問題”的說法。

3. 業(yè)務(wù)應(yīng)用線下環(huán)境的基礎(chǔ)設(shè)施必須按照生產(chǎn)環(huán)境標(biāo)準(zhǔn)運(yùn)維。一個(gè)實(shí)現(xiàn)手段就是直接使用生產(chǎn)環(huán)境的基礎(chǔ)設(shè)施。

4. stable層首先要把單應(yīng)用可用率提升上去。單應(yīng)用如果無法做到99.999%或100%都是能調(diào)通的,鏈路的穩(wěn)定性就是緣木求魚、根本無從談起。

5. 減少dev環(huán)境的問題,主要有四個(gè)重點(diǎn):a)做好聯(lián)調(diào)集成前的自測;b)架構(gòu)上的投入(契約化、可測性);c)通過多環(huán)境、數(shù)據(jù)庫隔離等手段減少相互打擾;d)通過持續(xù)集成盡早暴露問題,降低問題的影響和修復(fù)成本。

6. IaC(Infrastructure-as-Code)是解題的一個(gè)關(guān)鍵點(diǎn)。

7. 線下環(huán)境是一個(gè)場景。要深刻理解線下環(huán)境和線上環(huán)境這兩個(gè)不同場景的差異。

Note

[1] 線下環(huán)境:這里主要講的是互聯(lián)網(wǎng)應(yīng)用的分布式系統(tǒng)的線下環(huán)境。也就是通常說的“服務(wù)端”的線下環(huán)境。這是阿里集團(tuán)和螞蟻集團(tuán)里面涉及技術(shù)人員最多的一類線下環(huán)境。

[2] 其實(shí),很多”臟“數(shù)據(jù)一點(diǎn)都不”臟“。很多時(shí)候,”臟“數(shù)據(jù)只不過是之前其他人測試和調(diào)試代碼留下的數(shù)據(jù),但這些數(shù)據(jù)的存在使得后面的執(zhí)行結(jié)果不符合我們的預(yù)期。例如,我要測試的是一個(gè)文件打批功能,這個(gè)功能會(huì)把數(shù)據(jù)庫里面尚未清算的支付都撈出來、寫到一個(gè)文件里。我創(chuàng)建了一筆未清算的支付,然后運(yùn)行打批,我預(yù)期結(jié)果是文件里面只有一條記錄,但打出來實(shí)際有兩條記錄,不符合我的預(yù)期。這種情況其實(shí)是我的預(yù)期有問題,是我的測試用例里面的assert寫的有問題,或者是我的測試用例的設(shè)計(jì)、我的測試架構(gòu)的設(shè)計(jì)有問題,也有可能是被測代碼的可測性(testability)有問題。

[3] 這些場景的差異,也許有人會(huì)把它們都?xì)w結(jié)為“可測性”。這樣說也不是沒有道理,因?yàn)闇y試就是線下環(huán)境最大的一個(gè)作用。但我們還是不建議把線下環(huán)境這個(gè)場景就直接說成“可測性”,因?yàn)?ldquo;可測性”是一種能力,能力是用來支撐場景的,這就好像“可監(jiān)控”是一種能力,“可監(jiān)控”這種能力是用來支撐線上環(huán)境這個(gè)場景的。

[4] 我們是堅(jiān)決反對測試平臺(tái)提供自動(dòng)重跑失敗用例能力的,因?yàn)樽詣?dòng)重跑對質(zhì)量是有害的。自動(dòng)重跑會(huì)掩蓋一些bug和設(shè)計(jì)不合理的地方,久而久之這些問題就會(huì)積累起來。

[5] 偶發(fā)bug也可以是很嚴(yán)重的bug。曾經(jīng)有過一個(gè)bug,這個(gè)bug會(huì)以1/16的幾率出現(xiàn)。最后排查發(fā)現(xiàn),原因是這段業(yè)務(wù)應(yīng)用代碼在處理GUID的時(shí)候代碼邏輯有問題(而GUID是16進(jìn)制編碼的)。當(dāng)時(shí)的test case只要rerun一下,大概率就會(huì)通過(有15/16的通過幾率)。

[6] 有噪音的測試,比沒有測試 還要糟糕。沒有測試,是零資產(chǎn)。有噪音的測試,是負(fù)資產(chǎn)。有噪音的測試,要額外搭進(jìn)去很多排查的時(shí)間,而且還會(huì)損害大家對測試的信心(類似“狼來了”)。

 

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2021-04-19 11:12:46

區(qū)塊鏈貨幣加密貨幣

2010-09-15 13:27:33

無線信號不穩(wěn)定

2021-04-23 22:42:11

加密貨幣礦工比特幣

2011-06-29 14:39:29

網(wǎng)站排名

2011-04-01 15:02:43

路由器鏈路

2010-09-14 13:17:11

無線網(wǎng)絡(luò)不穩(wěn)定

2011-10-25 09:47:59

服務(wù)器

2010-04-06 10:42:59

無線網(wǎng)絡(luò)不穩(wěn)定

2009-12-25 09:39:08

ADSL MODEM

2010-04-15 15:54:24

無線信號不穩(wěn)定

2022-01-26 00:25:30

比特幣黃金加密貨幣

2014-01-15 11:13:11

手機(jī)無線網(wǎng)不穩(wěn)定

2010-08-25 11:15:56

2018-06-07 10:18:01

服務(wù)器網(wǎng)站優(yōu)化

2018-07-17 09:09:44

AE項(xiàng)目

2021-10-10 12:41:01

Windows 11系統(tǒng)微軟

2021-05-17 11:22:28

比特幣數(shù)字貨幣金融

2017-09-06 12:00:08

無人咖啡店新零售友飲吧

2010-04-09 14:40:44

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號