應對節日高峯-Web架構實踐

今天要分享的主題是關於QQ會員活動運營平臺的架構實踐。首先做一個簡單的自我介紹,我叫徐漢彬,現在在騰訊的SNG增值產品部工作,主要負責QQ會員生活特權以及今天分享的AMS系統的研發建設。

今天我要分享的內容主要分爲三部分:

  • QQ增值業務在海量請求下的技術挑戰以及背景;
  • Web系統高併發場景的綜合優化策略;
  • 平臺高可用的建設實踐。

活動有很多特性,今天的主題主要關注點是在節假日高流量的推廣,例如五一是典型的節假日,各個業務都有他們的推廣需求,他們聚集在一起就會導致流量的突增。有的同學可能會有疑問:我看你PPT上放的幾個活動頁面都非常簡單,你今天講的這些AMS系統會不會沒有什麼技術含量?是的,如果我們的系統上只放這幾個活動頁面確實沒有什麼技術含量,但是如果把這幾個活動換成800+個,即我們的系統同時在線的活動有800+個呢?那麼它就是一個相對來說更具有挑戰性的場景。

我們這個系統叫做QQ會員活動運營平臺,在內部簡稱AMS,主要承載QQ增值運營業務的Web系統,它有兩點定位:

  • 滿足QQ增值活動業務需求的發展;
  • 保證平臺在海量用戶面前的高可用,也就是穩定性。

我們每天由用戶觸發的Web層CGI請求有3億-8億,同時在線的活動有800+個(每個月新上線的活動大概450+個,活動的在線週期通常是1個月,不斷有活動上線和下線,所以同時在線的是這個數目),我們這個系統背後涉及的存儲和Server超過100個,在典型節假日高峯期的請求量爲7w/s。

AMS系統涵蓋了很多運營業務,包括QQ、騰訊遊戲、個性化(表情)以及動漫閱讀等。舉一個例子:大家參加的2016年QQ春節紅包活動,就是除夕下午搶紅包,當時AMS系統就承載了紅包活動的遊戲禮包和閱讀禮包的發放,因此,春節過年我不能回家,在公司值班到第二天的凌晨3點,也就是大年初一的凌晨3點,所以做這個系統有時候也是不容易的。

Web系統高併發場景的綜合優化策略

關於Web系統高併發的綜合優化策略。我們先聚集到一個指標上——吞吐率。我們的吞吐量主要分爲三個方面:

  1. 請求延時:用戶請求CGI的響應耗時,舉個例子,假設我們的CGI平均耗時是是200毫秒,我想辦法把它優化到100毫秒,那麼相同的單位時間裏面系統的吞吐能力就提升了一倍;
  2. 單機性能:我們期望通過更少的CPU、內存和系統開銷支撐更高的併發數和處理更多的用戶請求;
  3. 規模:即機器越多,我能支撐的請求就越多,這裏面需要在整體系統架構上支持全面的平行擴容能力。

針對上述吞吐量的三個方面,我們對應提了以下解決方案:

一、降低CGI請求延時

天下武功唯快不破,跟快相對的就是慢,慢是一個怎樣的行爲?它的本質其實就是“等待”。假設我們MySQL在處理一個複雜的查詢,它比較慢沒有辦法響應給後端Server,這個過程中究竟發生了什麼事?我們從整個鏈路看,首先是瀏覽器端用戶發起了連接,它在等待服務器響應(對我們來說它在等待我們反向代理給它響應),反向代理在等待Web Server,Web Server在等待Server層,Server層在等待MySQL,當然這種鏈路真正在集羣系統裏遠不止這麼短,它很可能是一個更長的鏈路。整個鏈路所有的環節都在等待,它們等待的過程就需要付出系統的開銷和資源

有些同學可能會提出疑問,Server實現異步化不就行了嗎?其實在我們的後臺系統裏大部分Server都已經實現了異步化,我們是採用協程(微線程)來實現。實際上異步化的過程:程序在處理A任務,A任務遇到網絡I/O等待時程序迅速切到B任務,但A任務的現場必須得保留,那麼A任務所佔據的內存、數據、句柄連接和系統開銷資源都不能立刻釋放出來,都必須保留等到下次繼續使用,也就是機器的資源並沒有真正釋放出來,整條鏈路不管是同步等待還是異步它都沒有被釋放,所以我們可以下一個比較小的結論:等待的過程就是對資源佔據浪費的過程。

我們可以從三個方面進行優化:

  • 多級緩存和主動推送;
  • 既然我們知道等待是一個不好的過程,那麼我們需要合適的超時時間設置;
  • 非核心操作異步化,儘可能把CGI響應時間降低,把一條長的鏈路儘快釋放出來給其它請求使用。

接下來仔細講講這三方面:

第一,多級緩存和主動推送

緩存是一個好東西,緩存的本質是讓用戶離我們的數據端更近,例如瀏覽器本地的Cache、Server和Server之間內存Cache等等,Cache是非常經典的優化策略,被稱之爲萬金油,通常是哪裏不舒服就抹哪裏,而且效果還不錯。

但是,它在活動場景裏就比較不一樣了,比如一個新活動,在這個活動上線前所有人都沒有參加過這個活動,整個Cache鏈路從前端到後端沒有地方會有Cache,這裏面我們對新的活動進行大規模推廣會遇到一個問題:緩存穿透,我們的緩存策略是無法直接應對的。

那怎麼辦呢?我們採取的辦法是主動推送,以2016年春節搶紅包活動爲例,當時高峯高達十萬級每秒,對於十萬級每秒的頁面請求即使對CDN地理分佈式靜態文件服務都是有衝擊的,我們真正的做法,其實是提前幾天把這些靜態CSS、JS和圖片等資源推送到用戶手機終端,當用戶真正參加活動的時候就相當於有本地緩存,此時沒有產生網絡請求。

實現過程粗略概括大概是這樣:我們向離線包管理系統申請一個BID對應的需要推送的離線文件,然後把BID寫到URL的參數裏面去,我們手Q終端的WebView會攔截這個URL請求,發現有BID就會根據BID找到本地的離線文件,然後把它直接給WebView。通過這種方式避免了網絡請求,只有真正找不到的本地離線文件時纔會通過網絡請求CDN,我們利用這種方式解決靜態文件的流量衝擊問題。

那麼動態的文件呢?我們這樣做:在AMS系統早期我們Server裏數據保存在MySQL裏,MySQL在這種大流量併發衝擊下通常支撐力是不夠的,怎麼辦?我們通過數據同步的系統,不斷地把這些數據從MySQL(我們認爲比較弱的存儲)同步到內存級的Cache服務(實際上也是一個存儲)上去,包括還有另外一些能在前端直接展示的內容(比如一個活動的提示語)直接通過這個系統打包成靜態JSON文件,再把靜態JSON文件通過CDN分發出去,簡而言之:就是把支撐力弱的東西通過這種推送機制放到強的服務裏

可能從PPT上看,這裏還不夠形象,但是我們把這個蒙層一加後很多同學就看得非常直觀,這就是非常經典的Server層和MySQL層之間引進的內存的Cache的模式,只不過我們的內存Cache層的實現稍微複雜一點,有一個推送和同步數據的機制。

第二,超時時間設置

關於超時時間的合適設置,很多人認爲超時等待時間過長不好,所以乾脆直接設置短一點的超時時間。對於一般業務可以這樣做,但對活動運營系統比較不合適,因爲,活動運營系統是接入多方業務的系統。比如我們接入的業務組件超過800個,僅遊戲就接入了160多款遊戲,每一款遊戲都是一個獨立並且複雜的外部服務Server,每一個服務Server的性能和響應時間都是參差不齊的,我們對應的通信接口數以千計,這時候就很難通過一刀切的方式來設置這個超時時間。

超時時間如果設置太長會有什麼問題呢?假設有個服務流量比較大,如果你設置6秒並且該服務發生超時,就會發生一種情況:整個鏈路的系統資源在整整6秒的時候只處理了一個失敗請求,原本可以處理幾十個請求,但是現在整整6秒只處理一個失敗請求,並且這個失敗請求還會引起用戶的重試。

爲了避免這個問題應該怎麼做?我們的做法是:因材施教,快慢分離,例如我們設置天天酷跑平均響應時間爲100毫秒,那我設置爲1秒的超時時間就夠了;例如某款新遊戲平均需要700毫秒的響應時間,我們認爲把它設置爲5秒超時時間比較合理。我們通過這種方式動態的超時時間設置以及快慢分離的方法把它們隔離開來,最終使得整個系統的吞吐率不容易出現由於某個服務超時導致大量可控資源被佔據的場景出現。

第三、非核心操作異步化

非核心操作異步化,該優化方式比較常規,就不展開詳細的講述。簡而言之,就是將非核心操作直接提交到異步隊列中,不等待響應結果,目的是儘可能把CGI響應時間降低,把一條很長的鏈路儘快釋放出來給其它請求使用。

CGI延時優化成果

下圖是我們做到的優化成果,大家可以看到在我們的AMS系統主框架邏輯內部耗時在CGI層大概只需要35毫秒,這35毫秒我們大概處理了將近10個流程,包括登陸態校驗、活動配置讀取、Session等安全檢測的流程,當然可以看到平均的耗時還是需要100多毫秒,但是這100多毫秒主要耗時在於不可控的外部第三方,比如說我請求一個和我們合作的遊戲方的Server,它的耗時我們是不可控的,在可控的範圍我們通過CGI的延時優化把它優化到35毫秒。


二、提升Web服務單機性能

因爲我們是活動運營系統,考慮到活動運營系統的靈活多變的特點,它比較適合用PHP開發,因此業務邏輯實現主要採用了PHP編寫。然而,隨着AMS系統規模的逐步擴大,日請求規模從2012年的百萬級一直增長到現在的8億級別,WebServer和PHP的性能不足問題日益突出。

基礎軟件服務的升級,通常是一件吃力不討好的事情,因爲如果做得好,活動業務側不一定能感知得到,但是,如果升級搞出問題,則要承擔比較嚴重的後果。而且,AMS系統上很多都是營收活動,和金錢收入直接掛鉤,對這個系統做基礎升級,並不是一件輕鬆的事情,勇氣和安全風險可控的升級策略,缺一不可。

在WebServer的性能優化方面,我們考慮了三個方案。我們最終都沒有采納HHVM和Node升級安全,沒有采納的原因是基礎服務的升級是需要兼顧業務場景和投入產出比的考慮

首先是HHVM方案和NodeJS方案都是因爲遷移成本太高,前面提到我們的Server接入的服務非常多,我們PHP代碼有四十多萬行,比較多的業務PHP擴展和組件,這裏的兼容性遷移是大成本,並且,遷移風險也比較大;

PHP7+Apache2.4(Event)的升級方案是比較平滑的,因爲這個方案即可以兼容業務代碼,又可以比較可觀的提升單機性能和Web Server併發能力。

我們最終選擇的升級方案是:Apache2.0升級到2.4的Event模式PHP5.2升級到PHP7.0。有必要簡單介紹下我們以前使用的是老Apache的Prefork模式,這裏粗略地提下Prefork和Event的兩點區別:

MPM模式:Prefork是多進程模式,一個任務對接一個服務進程;Event則是多進程多線程模式,會啓數量比較少的進程,每個進程會有幾十個線程;Event是出一個線程來處理任務,線程通常比進程更輕量,這樣可以讓我們併發數更高;

長連接(keep-alive)問題:我們很多Web服務都會開啓HTTP長連接,用於減少HTTP連接的建立和斷開的系統開銷。長連接,通常在剛開始肯定會頻繁,但通訊完後它會被保持一段時間,保持期間Perfork模式的服務進程會被佔據,除了等什麼都不能做,直到長連接斷開爲止,這是一種系統資源的浪費;在Event模式下,它解決了這個問題,它用了專門的線程來保持這些長連接,當用戶真正觸發請求的時候,它再把請求給到後端的工作線程,工作線程處理完就把自己釋放出來避免被佔據,然後工作線程就可以繼續爲其他請求提供服務。

PHP7同比以前的版本區別主要是大的性能優化,對CPU和內存資源方面的佔用比以前更少。

在這個升級過程中有遇到什麼問題?

  • 首先我們的版本跨度比較大,Apache2.0升級到Apache2.4,PHP5.2升級到PHP7,我們真正的升級如果一步到位會比較危險,所以我們先升級到過渡版本,PHP方面我們先升級到PHP5.6(另外我們是去年實施升級的,當時PHP7的正式版還沒有發佈);
  • 除此之外我們還要解決語法兼容性、解決線程安全的問題(以前多進程是不需要考慮線程安全);
  • 有一些擴展要同步升級等等;
  • 比較系統的控制風險策略:逐步升級、灰度觀察、現網PHP7運維和監控工具支持等。

我們大概在2016年4月底的時候進行了單機灰度,5月初在單集羣全量發佈,在日請求億級的Web系統中,在國內屬於比較早升級到PHP7的。PHP7的AMS對比老AMS,從業務壓測結果來看大概有3倍的性能提升。從線上的CPU數據來看,我們實現了用更少的資源來支撐更高的併發、處理更多請求的目標。例如,以前一臺普通硬件配置的機器啓動500個進程,機器這時已經運作地比較滿,但我們現在已經可以啓到上千個線程。


三、關於規模——支持快速平行擴容

我們必須實現快速擴容與縮容。擴容這個行爲本身在我們公司有豐富的運維工具支持,機器的安裝、部署、啓動等各方面都是高度自動化完成的。但是,以前我們擴容是依然要花一天多的時間,爲什麼?還是因爲我們是活動運營系統,活動運營系統背後對接了很多外部發貨接口,這些發貨接口中有很多是比較敏感的發貨服務,例如發Q幣,還有發一些遊戲高價值的道具。

一般我們和敏感業務服務通信有包含兩步:加密簽名校驗和來源IP限制,每次擴容都需要新增IP,然後這些IP需要向各個敏感業務提出申請,讓對方的業務領導進行人工審批,加到來源IP限制的白名單中,才能生效。因此,我們大部分時間都花費在權限審批上,用一句話來總結問題就是:不是在審批中,就是在去往審批的路上。

我們的解決方案是通過搭建一箇中轉Proxy Server把通信的IP進行收攏,收攏爲中間的Proxy角色。我們內部再重新跟自己的Proxy實行簽名校驗和來源IP限制,只要我們的Proxy Server不進行擴容,我們就不需要重新申請IP權限審批。簡而言之,我們把一些外部的授權變爲內部授權,內部授權儘量做成自動授權,以及會把一些中間的驗證的過程儘可能做到自動化驗證。我們的擴容時間從原來的一天多縮小到1-2個小時,其中的關鍵點是大幅度減少人工依賴

第二個問題是機器持有成本的問題,活動運營業務因爲嚴重受到節假日效應的影響,是個流量上串下跳的典型業務。因此,如果我們部署機器太多,平時會利用率不足而導致機器低負載,運維團隊會挑戰我們的機器成本和預算,說我們佔據那麼多資源會浪費;如果部署的機器太少,我們在節假日又支撐不住,瞬間七八倍峯值的增長風險又很大。怎麼解決機器佔有的問題?雖然我們具備快速的擴容和縮容能力,但是在一般情況下,我們也不希望天天變更我們的現網環境,通常我們希望我們現網環境能做一個安靜的美男子,沒有什麼事大家別去隨便變更它。

於是,我們利用了運維團隊提供的Linux Container虛擬化技術,主要是共享CPU資源支持。例如,一臺24核的物理母機,上面分成8臺虛擬子機,虛擬子機上進行業務混合部署(不同業務各自佔據一臺子機),AMS也只佔據一子機器,平時非節假日我們具備高優先級使用1/8的CPU資源,但平時可能用不到,到節假日的時候1/8的CPU資源不夠,我們就把其它業務的空閒CPU資源拿過來用,就可以突破1/8的CPU的使用限制。實際上,這種CPU共享的技術方案,我感覺是爲活動運營類型系統量身訂做的策略。可能有同學說提出疑問,這樣會帶來後續擴展評估無法精準評估的問題,不過,我們配合前面講的快速擴容能力還是可以很好地應對的。

關於平臺高可用建設和實踐

既然是高可用,即不能隨便掛掉,AMS系統每日的CGI請求增長是比較快的,我們的項目創建於2012年,2012年時每日PV是百萬級的系統,之後每一年基本都是跨數量級的增長,一直到現在高峯的時候是8億多的流量,我們的可用性多次受到比較嚴峻的挑戰。

同樣是基於大流量Web系統下的高可用建設實踐,那我講述的又和其他講師的有什麼地方不一樣呢?主要有兩點:

首先我們面對的是活動運營業務場景下,活動在節假日流量峯值突增變化幅度是比較大;

我是AMS系統的初始開發人員,對這個高可用建設實踐有比較深刻的體會。最初只有兩個人的時候我就是它的開發人員,後來系統越變越大,我就慢慢地成爲了AMS的負責人。如果我們在系統上面發現一個年代就遠的坑,有非常大的可能就會追溯到我自己,這種感覺相當於,自己挖了一個坑自己跳下去,然後千辛萬苦爬起來。我就會想,當年的我究竟抱着怎樣一種喪心病狂、報復社會的心態挖下這麼深的坑,然後來坑害四年後的我呢?這些都會引起我強烈的反思,當年是在什麼場景下做出的這個設計?是因爲我太年輕?還是因爲沒有預料到未來的業務發展趨勢?這些追溯性的反思,促使我更深入的反省和思考系統上的設計和缺陷,同時,也加深了我對架構演變的認知水平。

我們把AMS早期的問題進行劃分,主要分三個方面的問題:

  • 存儲:主要是緩存穿透;
  • 架構:在架構早期流量規模比較小的時候不少寫死IP的行爲導致單點問題很明顯,即可能會出現這個點掛了,系統整體可用性都受到影響,還有局部影響全局的問題;
  • 協作:系統越來越大,參與的人越來越多,協作的成本也開始變得越來越高,如果來了一個新人修改了一個模塊,這個模塊可能涉及到了三個同學的相關模塊,他就需要和這三位同學都做確認,如果哪天確認漏了,最終發的版本可能就是有問題的。

我們總結上述各類問題爲天災和人禍天災包括網絡故障、機房停電、機器宕機、硬件故障;人禍方面包括異常發佈(例如某開發的代碼有問題影響了全局)、人工配置失誤和多人協作失誤。我們後來對這些問題進行了反思,它們之所以會比較頻繁地發生的關鍵原因就是單體架構(單片架構),即系統如果沒有做合適的拆分,導致所有的代碼或者服務糅合在一起,這會造成比較多問題。尤其是AMS系統是由小變大的,系統小的時候,通常就是一個單體。

於是,我們對系統架構進行合適的調整。Uinx哲學有一句話非常好

Do one thing and do it well

我只做一樣的東西並把它做好,對應的架構思想就是SOA微服務,微服務近幾年也被大家談論得比較多。

我們做的第一件事是L5名字服務,做到去中心化、無狀態和平行擴充,簡而言之,如果你要訪問一個Server,不管它是什麼都需要先向L5服務要對應服務的IP和端口,L5就從一組服務路由表裏按照一個分配算法隨機取一個給你,然後你再去請求它,如果成功了就要上報成功給它,失敗也上報失敗給它,這時候L5服務會計算出每一臺機器的延時和成功率情況,並且可以將失敗率高的機器踢掉,如果恢復正常就再加回來,從而,把偶然宕機或者機器異常的問題解決了。

但是這裏有些同學可能會有疑問:所有人都請求L5服務,L5服務會不會扛不住?確實,如果所有服務都去請求它,L5壓力會很大,所以L5的實際分爲兩層:

一層部署在本地Server的Client層,相當於本地路由表(服務器本地Server);

另一層是Server層,擴容的時候就往Server層添加機器IP,它就能從Server層下發到各個服務器的本地層。

另外我們把主要的存儲從MySQL慢慢遷移到CKV,CKV是我們公司內部研發的Key-Value分佈式存儲,可以理解爲類似的分佈式的Redis存儲。

下圖是AMS早期的系統架構圖,可以看出某些模塊有比較明顯的單體現象,後端服務數也不多。

架構經過多年演變之後如下圖,首先是CGI層,我們根據不同的功能、業務進行物理和業務上的拆分,拆分成一個個Web Server集羣,後端全部用L5的方式接入,讓它們無狀態且支持平行擴容,同時把一些Server從原來的大Server拆分成小的Server。當我們做完這一點以後,它們的耦合問題得到了相對來說比較好的優化。

回到前面的問題,天災怎麼避免?我們概括如下:

  • 網絡故障:建立合適的機器部署方案,例如把兩批機器跨網絡端部署,哪一天這邊被一鍋端或被挖斷了,另一邊邊還能用;
  • 機房停電:我們可以跨機房、跨IDC部署,我們的Web Server層就分別部署在5個機房上,哪天哪個機房停電了,對我們是沒有大的影響的;
  • 硬件故障:可以通過L5模式支持自動剔除和自動恢復;
  • 服務進程掛掉:通過Shell編寫的監控進程腳本把它重新拉起來。

做一個簡單的彙總,我通過路由和L5的模式,以及合適的機器部署情況做跨網絡、跨機房的部署,使得我整體的可用性能夠承受各種各樣的天災的襲擊。

我們聊一下人禍。首先是人工配置問題,配置可以說是業界的難題,爲什麼?因爲在我們公司、甚至說業界,很多大型的現網事故本身並不是由多麼高大上的Bug所導致,而是由配置文件引起,例如,配置多一個參數、少一個參數、改錯一個參數,進而導致很嚴重的問題。尤其我們一個月上線450多個活動,每個月對應上線的活動配置多達5000多份,怎麼杜絕參數錯誤的問題呢?

如下圖。假設這位運營同學提交了一份有問題的業務配置,首先我們會進行人工測試環節,如果人工測試無法發現,問題就會留落到現網。舉個實際的例子:我們庫存一共100個,但這個運營同學填寫200個,這個問題測試能發現嗎?不能,因爲只有發送到101的時候纔會出現異常。

對我們來說怎麼避免?我們的做法是在運營同學發佈前建立智能程序檢測的環節,回到前面的例子,庫存和配置數量不匹配,提交時我們直接把庫存兩邊拿過來對比一下,發現不匹配就直接提示,直到配置正確了之後再讓發佈通過。那麼我們的規則怎麼來?這幾十個規則就是活鮮鮮的多年血淚史(多麼痛的領悟),現網每出一單事故或者問題,我們就把事故拿出來分析、討論、抽象和總結,看能不能成爲檢測規則的一部分。解決人工配置難題,我認爲沒有說放之四海皆通的解決方案,更多是跟着業務亦步亦趨地共同發現和解決

關於可用性,能不能用一個比較收攏的例子對前面所講的事情進行概括呢?我們一起來討論一個場景,假設有一個新同事剛加入公司,他修改了一個模塊,這個模塊修改後可能有問題,有沒有辦法通過可用性和架構的建設來減輕或者避免這個問題?

也許有同學會質疑,人犯的錯誤難道還能干預和改變?

我們認爲是可以做一些工作的,我們分爲事前、事中和事後:

第一、事前

如果系統是單體架構,那麼裏面邏輯會很複雜,模塊與模塊之間的耦合會很重,如果不把裏面的代碼分離和隔離,耦合是天然的,就會有人寫出耦合的代碼。所以我們把單體架構經過合理拆分,我們把程序變得更簡單,協作更少,讓新人看到代碼更少,更簡單。首先從根源和架構上面儘可能避免新人犯錯。

其次,如果是單體架構,哪怕只是修改了一句簡單的輸出"hello world"的代碼,從測試完整的角度出發是需要把單體架構上所有的邏輯都回歸一次,這樣迴歸測試的成本是很高的。但如果拆分過的話,只需要迴歸一個具體的小模塊,小模塊的測試就可以比較輕鬆完成迴歸測試。

這樣可以做到三點:程序更簡單、更少協作、更容易測試,儘可能從源頭上面避免新人犯下錯誤。從軟件的長遠生命週期出發,人員總是會變換的,總會有新人加入和人員調整,所以必須考慮新同學加入的門檻成本問題。

另外一個是建立自動化測試,發佈之前跑一下自動化測試用例,建立灰度、觀察和全量模式,即使有問題我們也爭取儘可能早地發現它,如果事前擋不住了就到事中。

第二、事中

我們通過對服務的分離以及對架構的物理隔離。以前是一個單體,如果有人寫了一段代碼引起CPU100%,可能單體內所有的機器都受到影響,但如果是業務上物理隔離的,它隻影響到自己對應的業務或者功能模塊,我們通過這種架構隔離來縮小問題的影響範圍。

另外是建立多維度的監控能力,比如說前端CGI響應、L5、模塊之間的調用成功率、流量波動等監控,使得問題能夠更快更早地被我們發現。

總結一下:通過比較合適的架構設計和多維度監控能力,縮小問題的影響範圍,減少問題的影響時長。

三、事後

我們必須建立與發佈對應的回滾能力,不能想辦法再發一個新的版本去修復,而應該優先恢復現網系統正常,因此,發佈系統應該要具備一個按鈕,點一下讓它回滾到上一個正常的版本,也就是一鍵回滾能力;另外還需要有可追訴的日誌記錄,可以把受影響的用戶和相關的數據的統計出來,進行後續處理。

我今天的分享就到這裏,謝謝大家!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章