談談上線變動

文章首發於公衆號 松花皮蛋的黑板報
做者就任於京東,在穩定性保障、敏捷開發、高級JAVA、微服務架構有深刻的理解
架構

爲何今天要討論這個話題呢?由於我最近上線時就犯了一個錯誤,想把這事和後來的覆盤分享給你們,事故的過程若是沒看懂能夠直接往下拉看覆盤。負載均衡

過程是這樣的:個人需求是在方法參數POJO類中新增一個可選參數,我將這個參數定義在POJO類的父類的最後一個。其中提供的是遠程調用RPC服務,因此須要打一個描述類的JAR包供調用方使用,這個JAR包包含服務接口和入參、出參實體。框架

聯調測試時使用的是1.1-SHAPSHOT版本,上線前我將版本號修改爲1.0-SHAPSHOT版本,而且將私服中1.0-SHAPSHOT快照包更新了,業務代碼沒作任何改動。快照包的意思是同一個版本每次更新時都從新生成一個附有時間戳的包,當你構建下載包時都會下載指定版本最新更新的包,好比能夠同時存在1.0-SHAPSHOT-2019101309和1.0-SHAPSHOT-2019080808版本。我當時上線後驗證是經過的,說明版本是向下兼容的,就是調用方使用的1.0-SHAPSHOT-201908080也能正常調用個人1.0-SHAPSHOT-2019101309版本的服務。過幾個小時後調用方使用了1.1-SHAPSHOT版本的包上線了,全量上線後,發現請求根本達到不了我這,由於在RPC框架中序列化異常了,此時調用方開始回滾,使用1.0最新的1.0-SHAPSHOT-2019101309開始構建上線,仍是出錯了。因而我比較着急也開始回滾,不過呢,我是將歷史構建的包發佈上線,也就是說使用的是1.0舊的1.0-SHAPSHOT-201908080包,固然毫無疑問仍是會調用出錯,此時才發現調用方回退時從新構建了,因而聯繫私服的同事將1.0最新的1.0-SHAPSHOT-2019101309刪除,隨後通知調用方從新構建上線,此時服務才恢復。運維

整個過程雙方都有不少操做缺陷,好比我上線的並非嚴格測試的包,甚至沒有通過雙方迴歸驗證。好比我處理線上問題的方法方式,我實際上是不須要回滾的。好比我告知了下游使用的版本號,可是下游仍是使用了測試的版本。再好比下游沒有進行灰度發佈驗證、異常後回退時從新構建了,等等。一個看似很簡單的上線卻失敗了,說明上線發版規範沒有徹底把握好。微服務

讀者可能以爲上線變動沒有值得深刻探討的地方,上線無非就是將要發佈的包經過必定的技術手段替換如今線上運行的包,或者將配置信息覆蓋更新,而後重啓服務,而且如今都是經過鼠標點點按鈕就能完成的事。可是呢,這其中有不少細節,稍微不注意就會像我同樣犯錯。接下來我將說說上線前、上線中、上線後、上線失敗須要注意的地方。性能

先來講說上線前,這個上線包含新增實例分組發佈、新增機器發佈、在原有機器上發佈。新增實例分組意味着你須要和舊分組仔細對比配置,包括日記級別配置。新增機器發佈意味着你的機器網段多是新的、你的調用外網服務權限多是沒有的、你的依賴系統庫多是沒有安裝的、你的IP可能不在白名單內,這些都是我在實際工做中碰到過的問題。測試

當上線條件和環境具有,包括前面說的機器配置,還包括上線時間,咱們就能夠提出上線申請了。原則上節假日(包括週末)前一天、重大促銷活動(好比產品發佈會)當天、流量高峯時間段都是不容許上線的。上線申請內容通常包括背景描述、操做對象、操做步驟、CHECKLIST、預期結果、回滾方案,還會包括自測狀況。任何操做都應該有明確的文字說明,拒絕模糊或僅在大腦中認爲可行的方案。同時你的操做變動還得周知產品、測試人員和其餘同事,不能只有你、代碼評審者、領導知道本次變動操做。避免當其餘服務受到牽連時,其餘人只能經過查看上線記錄或者翻查代碼提交記錄才知道應該找誰。若是你修改的是公共代碼或者協議,那更要提早周知了。spa

上線前檢查還有一個須要注意的地方,就是確保你構建出來的上線包包括了你合併的代碼塊,如今大部分的平臺構建出來的上線包,包名會附有最新提交到GIT代碼倉庫的COMMIT_ID,很是直觀明瞭。對象

當上線前檢查完成後,就能夠發佈部署了,通常將操做的服務實例按分組、機房分別分批部署,我這裏強調的是分組、分機房,強調的是並不只僅是以所有實例按多少比例部署,固然咱們一般按30%的比例進行分批部署。不過,若是你的比例恰好命中某個分組或者某個機房所有實例時,那就意味着這個分組、機房的服務在全量上線,就頗有可能出現無服務提供者的狀況,若是上線失敗,狀況就不是短暫性的了。blog

分批部署第一步通常是每一個機房選擇一臺進行發佈驗證,這樣有助於咱們及時地發現問題,避免影響擴散,甚至有些功能須要數據的積累才能驗證,因此有時也會分時間段部署,每間隔一個小時部署一小比例的服務實例。固然分批部署只是咱們規避線上風險的手段,不具有測試的目的,不能取代測試,也就是禁止將沒有進行測試的包部署到生產環境,那怕只是修改了RPC服務的JAR包版本號。

分批部署通常須要驗證原有功能是否有受到影響、業務監控是否有異常、服務實例是否正常啓動、流量是否正常到達、功能是否生效是否有缺陷、程序資源消耗是否正常、程序性能是否正常。我碰到過發佈平臺顯示上線成功,可是服務實例OOM崩潰了,若是此時貿然將此實例掛載到服務下,等待個人就是異常告警了。我還碰到過同事將新擴的機器部署後,卻忘記掛載流量的狀況,浪費了時間還浪費了機器資源,所幸原有機器成功抗住了流量。

說到這啊,我再補充一種狀況,部署時發現有臺機器連通性異常了,處在運維狀態,可能只是發包使用的端口受到影響而已,服務監聽的端口是沒有受到影響的,此時你須要將這臺機器流量摘掉,避免狀態正常後流量打到了錯誤的服務版本了。爲何要將這個事單獨拿出來講呢,實際上是想強調咱們要確認所有實例都更新爲新功能版本了,包括避免漏發實例。

上線變動是事故的高發場景,當真的發生問題時,咱們也不要慌張,先報備領導,而後第一時間止損和恢復服務。若是在發第一臺驗證的時候就出現異常了,最快的方式是修改Nginx配置將流量打到其餘正常機器上,若是你摘取流量或者中止實例,其實都是有非同步狀態的,由於用戶接入層的負載均衡心跳檢測多是有延遲的。若是全量發佈後發現異常,按照應急預案也沒法及時止損的話,只能選擇回滾服務,要避免形成二次影響。

實際上,當用戶碰到問題時極少會選擇反饋,沉默的是大多數,因此上線務必進行充分驗證和全方面的監控,不要乾等着用戶來反饋,當用戶來反饋時影響範圍可能很大了。那麼咱們就須要規範化工做過程和輸出,提升穩定性和質量。

好,本次的分享就到這,若是有幫助到你,歡迎點個在看或者分享給你的朋友們。

文章來源:www.liangsonghua.me

做者介紹:京東資深工程師-梁鬆華,在穩定性保障、敏捷開發、JAVA高級、微服務架構方面有深刻的理解

相關文章
相關標籤/搜索