專家論壇

京東物流系統(tǒng)自動化運維平臺技術(shù)揭密

2018年01月29日來源:InfoQ

  簡單來理解,自動化運維就是要通過機器的方式來簡化整體的運維過程,特別是優(yōu)化重復類型的工作,以提高運維效率,減少因人工而引起的失誤操作。隨著運維管理的復雜度和難度增大,自動化運維也基本成為了運維平臺演進的必經(jīng)之路。但如何落地自動化運維平臺,不同的企業(yè)因為運維發(fā)展階段和業(yè)務體量的不同,都有不一樣的實現(xiàn)路徑。

  以京東為例,它的物流系統(tǒng)有很多分支機構(gòu), 比如倉庫、分撥中心、轉(zhuǎn)運中心等, 業(yè)務復雜的分支機構(gòu)可能會有自己的信息系統(tǒng), 這些信息系統(tǒng)往往分布式地部署到全國各地,那如何基于自動化運維平臺管理好這些分支機構(gòu)的服務器、 信息系統(tǒng), 降低因為地域分布造成的運維維護成本呢?京東資深架構(gòu)師趙玉開向 InfoQ 記者深入介紹了他們在自動化運維平臺方面的一些探索和實踐。另外,趙玉開也將會在 9 月 10 日舉行的 CNUTCon 全球運維技術(shù)大會 上分享相關(guān)話題,歡迎關(guān)注。

  InfoQ:可以先介紹下目前京東物流系統(tǒng)自動化運維平臺的一些基本情況嗎?

  趙玉開:京東物流系統(tǒng)自動化運維平臺從 2014 年開始啟動到現(xiàn)在已經(jīng)歷了三各階段,到目前管理了 MySQL、JMQ、 Redis 及自研應用等多種實例。

  眾所周知,京東業(yè)務發(fā)展迅猛,每周都需要開倉,數(shù)量多達十幾個。最初開倉過程特別冗長和復雜,開倉過程中涉及到研發(fā)人員部署系統(tǒng)、運營人員手動填寫多種申請、運維人員不僅要負責中間件安裝,還要負責整個流程中每個環(huán)節(jié)的進展確認及協(xié)調(diào),這直接導致了開倉慢,且涉及到的各部門都需要投入大量的人力成本。

  基于此,2014 年初我們啟動了一期自動化運維平臺研發(fā)的項目,2014 年 10 月項目一期上線時,已基本解決了開倉慢和人力成本的問題,也減少了開倉過程中運維同學的重復性工作內(nèi)容,制定標準化模板,解放了研發(fā)人員的重復性部署工作。運營人員可通過模板直接設(shè)置,將之前一些繁瑣的密碼、JMQ Token 等數(shù)據(jù)實現(xiàn)自動化配置,大大減少了流程耗費的時間。

  一期上線后,得到了流程中各環(huán)節(jié)涉及部門的贊賞,并在得到大家積極反饋后,迅速進入到二期項目。二期項目完成后,數(shù)據(jù)的初始化問題和研發(fā)日常批量部署問題也得到了解決,系統(tǒng)的自動化程度已可以滿足日常的工作需求。

  今年初,為接入更多物流作業(yè)單位,如分揀中心, 亞洲一號自動化物流中心等,我們開啟了三期項目,目前項目還在持續(xù)前行中。

  InfoQ:談談你們的自動化運維架構(gòu)?以及具體涉及到的技術(shù)棧?

  我們的自動化運維的核心組件是 SaltStack, 我們基于 SaltStack 做了很多自定義的模塊、Grains 和 Runner, 通過這些自定義的模塊、Grains 以及 Runner 來支撐我們的開倉、部署、數(shù)據(jù)同步等功能。

  如下圖是一個指令執(zhí)行過程圖, 分為兩個部分, 上面部分為部署在 IDC 的模塊, 下半部分則是部署在庫房機房的模塊。

  我們先逐個介紹部署在 IDC 部分的模塊:

  Web 使用 Java 技術(shù), 為用戶提供操作界面, 控制操作權(quán)限, 使用 Activiti 工作流引擎驅(qū)動各種流程, 下發(fā)開倉過程中的自動化運維指令。

  Salt-API-Proxy 是 Salt-API 的代理層, 通過 Nginx 實現(xiàn)了反向代理, 在 Nginx 的配置中對發(fā)送指令的服務器 IP 做了限制, 另外可以通過配置指向工作的 Salt-API 服務器。

  Salt-API 負責和 Salt-Master 交互發(fā)送 SaltStack 的 Runner 與 Module 的 API 指令, Runner 指令是運行在 Salt-Master 服務器上的, 可以讀取 master 配置, 也可以在一個 Runner 中協(xié)調(diào)執(zhí)行多個 Module 運行結(jié)果。

  Salt-Master 有兩個職責, 一是接受 salt-api 指令, runner 在本地執(zhí)行, module 下發(fā)指令到對應的 salt-minion, 另一職責是運維同學手動下發(fā)指令, 完成一些非常見的 minion 配置工作。

  RsyncServer 負責中間件安裝文件, 自研軟件的文件存儲和下發(fā), RsyncServer 的文件存儲是由 Salt-Master 發(fā)起的, Salt-Master 接受到 salt-api 的應用部署指令后, 會從部署指令中獲得部署包下載地址, 然后下載到指定部署包存儲目錄, 并做解壓操作; RsyncServer 的文件下發(fā)指令則是有 salt-minion 端的 Module 執(zhí)行觸發(fā)的

  倉庫部門和 IDC 之間通過 VPN 聯(lián)通, 每個倉庫的服務器上都安裝了 SaltStack 的 minion 端, minion 端是一個 Python 進程, 負責接收 Master 的 Module 指令, 并在本地執(zhí)行。另外 minion 端在執(zhí)行指令過程中需要將執(zhí)行過程中的輸出及時的輸出給用戶端, 讓用戶可以通過 Web 端查看執(zhí)行過程的情況, 即運維的可視化, 我們是通過 minion 端的可視化模塊, 將執(zhí)行過程輸出通過 HTTP POST 方式發(fā)送給 Web 端, Web 端將 POST 內(nèi)容存儲到任務執(zhí)行過程輸出表中, 前端通過輪詢方式讀取輸出表中的增量消息顯示給用戶端。

  我們采用的技術(shù)棧是 Java + Python。 前端界面展示、 工作流、權(quán)限控制、任務下發(fā)這些都是用的 Java 的 Spring MVC + MyBatis; 后端用的是 Python + Shell, Python 寫了大量的 SaltStack 自定義模塊。

  InfoQ:為什么當初要選擇 SaltStack 而沒有選擇 Ansible?

  不可否認 Ansible 也是一個非常好的自動化運維工具, 但是基于以下兩點我們最終選擇了 SaltStack。

  API 的易用性方面和 SaltStack 有差距, 我們的自動化運維系統(tǒng)一開始就有一個目標, 將開倉部署以及推廣版本這些功能開放給物流運營人員, 所以必須做好前端用戶體驗, 這需要好用的 API, SaltStack 恰好有。

  性能,標準 SSH 連接的時候比較耗時,ZeroMQ 傳輸?shù)乃俣葧旌芏唷?

  InfoQ:在應用部署自動化這塊,你們是怎么做的?

  應用部署大致分為這么幾個步驟: 打包、下發(fā)文件、更新配置、停止啟動實例、備份部署版本, 具體如下。

  我們使用的公司統(tǒng)一的打包系統(tǒng), 打包系統(tǒng)打好包, 部署任務審批通過,自動化運維系統(tǒng)就可以通過 API 獲得打包文件, 然后將部署包上傳到版本服務器, 并解壓縮,放到對應版本目錄下。

  通過 SaltStack 的 API 下發(fā)部署指令給部署目標服務器, 部署指令是一個 SaltStack 自定義模塊, 該模塊首先會執(zhí)行 rsync 指令從版本服務器上同步變更文件。

  文件下發(fā)之后更新配置, 通過 Web 接口請求自動化運維的 Web 端下發(fā)配置文件, 然后更新配置文件, 我們線上的配置文件是通過環(huán)境變量來配置的, 所以不管有多少個庫房, 都不需要更新配置文件, 只有在特殊需求是設(shè)置環(huán)境變量, 就可以依據(jù)當前作業(yè)單位的不同改變下發(fā)的配置文件的內(nèi)容。

  調(diào)用應用的 stop.sh 腳本停止當前實例, 再調(diào)用 start.sh 腳本啟動實例, 這里有一個約定, 不管是 Web 應用還是非 Web 應用必須在部署目錄有一個 bin 目錄下面有 start.sh 和 stop.sh 兩個文件。

  如果步驟 4 執(zhí)行成功, 那么將此版本的文件備份到當前服務器上, 以備回滾使用。

  InfoQ:自動化運維解決了你們哪些問題?沒有解決哪些問題?

  自動化運維解決了我們開倉周期長,人力成本高的問題, 提升了全國部署推廣的效率, 大大減少了運維同事的重復性工作, 把對成熟版本的推廣工作交給了運營人員, 減少了研發(fā)同事在推廣上線工作上的時間。

  現(xiàn)階段正在探索如何通過自動化運維技術(shù)快速排查問題, 另外就是我們未來會有一些自動化的物流作業(yè)單位,如何用自動化運維平臺管理好這些自動化的設(shè)備和設(shè)備軟件也是我們在探索的。

  InfoQ:自動化運維平臺上線了這么長時間,有做過復盤嗎?有哪些經(jīng)驗可以分享給讀者?未來有什么計劃?

  做過一些復盤, 每一期開發(fā)結(jié)束下一迭代開始的時候都會做復盤, 對現(xiàn)有問題進行總結(jié), 同時收集下一步的需求。 目前看最深刻的體會是做自動化運維系統(tǒng)一定要做好元數(shù)據(jù)的管理,元數(shù)據(jù)要管理好服務器信息屬性、 應用信息、應用配置、實例管理以及作業(yè)單位, 這些元數(shù)據(jù)要在一開始就做好, 能自動化收集的要自動化收集, 動態(tài)的參數(shù)一定要動態(tài)控制, 比如 Redis、MySQL 都有主從關(guān)系, 元數(shù)據(jù)中要存儲這個主從關(guān)系, 但是不能寫死, 必須有機制來更新主從關(guān)系, 否則 Redis 哨兵程序更新了 Redis 主從關(guān)系, 或者 MySQL DBA 因為某些原因切換了 MySQL 的主從, 自動化運維系統(tǒng)的元數(shù)據(jù)沒有做對應更新,再執(zhí)行指令時就會出問題, 甚至發(fā)生事故。

  未來計劃有兩個方面:

  繼續(xù)通過自動化運維系統(tǒng)來提升運維效率、 降低研發(fā)對應用運維的投入。

  做自動化物流作業(yè)系統(tǒng)的自動化運維, 管好其中的設(shè)備和軟件服務。

  InfoQ:在 CNUTCon 全球運維技術(shù)大會 上,你將會為讀者分享哪些技術(shù)點?

  這次大會我會給大家介紹下京東物流自動化運維平臺的技術(shù)架構(gòu), 并詳細介紹自動化開倉、批量部署的技術(shù)細節(jié)。