安全的代碼部署

安全的代碼部署

安全的代碼部署

安全,優雅的線上代碼部署。

非常非常重要卻又極其容易被忽視的問題:原子發佈


如果不能完全避免錯誤,那就努力把出錯的概率降到最低。

`switch` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '應用開關:1-開,0-關。應用升級、安裝、維護時需要暫時關閉,使其不能訪問,否則會出現意外(即使這樣也還是不能完全避免極端時候的併發問題,不過還是將故障降到最低概率了)',來自家校 s_app表

安全的實現服務部署的思考

上面這個問題可引申到怎麼實現安全,平滑的代碼部署的問題上去了。

要想實現安全的代碼遷移、熱替換、部署,光從應用層,用文件鎖,做開關的形式去做還是不行的,必須從內核的角度去做。

比如實現php服務的線上運行環境的代碼部署,如果直接替換文件可能會出現不可預料的問題,以及錯誤,所以做一個開關,暫停網站,但是已有的代碼還在內存中跑怎麼辦,那就做一個程序生命檢測的機制,只要程序有活著的,那就鎖文件,知道文件沒鎖了就說明整個系統停了,但是這樣還不夠,很難保證所有程序都遵循這個約定,活著時都去摸一摸這個問題。

那麼就要使出最後的絕招了,從內核去控制程序的生命,首先使用傳統的方式暫停所有程序,關閉隊列服務,關閉常駐程序,關閉訪問開關,此時也還不能夠確定是不是都停止了,那我們就等(正常的服務正在運行的可能此時還在內存中運行著呢),只要常駐和隊列服務關閉了,那麼內核一會也會停止的,只要從php內核那裡檢測到徹底沒有生命活動了,就表示當前沒有任何活動程序了,那麼此時就說明絕對安全了,此時就可以放心的開始部署工作了。

對於線上的服務部署,針對不同的平臺。業界肯定早已經有成熟的技術方案了,以後有時間在研究。

如果直接採用替換文件的方式,那麼是很危險的,可能會出現難以預料的錯誤,這在生產環境中是致命的,因為文件的替換可能不是原子性的同時都能夠替換(這是由PHP的運行機制決定的),這樣的話,如果舊文件引入新文件的,那麼邏輯可能就會出現難以預料的問題。所以安全的替換必須是原子性的,即要麼同時都替換,要麼都不替換,不能出現交叉的情況。

這種部署方式需要停服,對於一個線上的使用量很大的生產系統來說,停服代價太大了。

應該使用平穩的部署方案,比如A服務是舊服務,最新的提交時B服務,那麼開啟一個B服務,讓新的請求全部使用B服務,這樣就平滑過渡過來了,對原有的A服務完全沒有影響,兩者可以同時運行。等A服務逐漸沒有人訪問時,再停止就可以。


熱遷移

熱遷移,可以想象的例子,蜂巢遷移,想把A蜂巢的蜜蜂遷移到B蜂巢,但是當前A蜂巢已經在使用中了,要使得遷移過程中不影響採蜜的蜜蜂只能這樣,做個和A一樣性質的蜂巢B,將B放在A旁邊,關閉A的入口,只保留出口,這樣蜜蜂會慢慢到B蜂巢中去,而此時A蜂巢中還有工作的蜜蜂,所以不能直接關閉,但是我們關閉入口只保留出口,這樣A裡面的蜜蜂會逐漸減少,一段時間後完全沒有蜜蜂了,此時我們已經完成了熱遷移了,蜜蜂都轉移到B中了,現在可以放心的停用A了。

php + Laravel 實現部署自動化

Facebook 如何實現大規模快速發佈?

Facebook 是如何做大規模代碼部署的?

容器技術演化史

少年,是時候換種更優雅的方式部署你的php代碼了 - 碼王信息 - 博客園

一般如何將開發測試服務器上的代碼部署到生產環境? - 知乎

利用WebHook實現PHP自動部署Git代碼-蕭曄離

git pull 能實現原子性替換嗎?

Deployer 中文網 — PHP 代碼部署工具

在 2016 年做 PHP 開發是一種什麼樣的體驗?(一) - SegmentFault 思否

簡單輕鬆部署你的項目 - Deployer - PHP 那些事 - SegmentFault 思否

使用php部署工具deployer實現自動部署 - 二次元の技術宅

如何正確發佈PHP代碼 - CSDN博客

一個正確實現的發佈系統至少應該支持原子發佈。如果說每一個版本都表示一個獨立的狀態的話,那麼在發佈期間,任何一次請求只能在單一狀態下被執行。如此稱之為支持原子發佈;反之如果在發佈期間,一次請求跨越不同的狀態,那麼就不能稱之為原子發佈。我們不妨舉個例子來說明一下:假設一次請求需要 include 兩個 PHP 文件,分別是 a.php 和 b.php,當 include a.php 完成後,發佈代碼,接著 include b.php,如果處理不當的話,那麼就可能會導致舊版本的 a.php 和新版本的 b.php 同時存在於同一個請求之中,換句話說就是沒有實現原子發佈。(重要:非常非常重要卻又極其容易被忽視的問題)

PHP執行系統外部命令函數:exec()、passthru()、system()、shell_exec() - gaohj - 博客園


從nginx看 線上環境的熱部署和熱更新替換

【開源組件】深入淺出Nginx

思考1:Nginx如何做到熱部署?所謂熱部署,就是配置文件nginx.conf修改後,不需要stop Nginx,不需要中斷請求,就能讓配置文件生效!(nginx -s reload 重新加載/nginx -t檢查配置/nginx -s stop)通過上文我們已經知道worker進程負責處理具體的請求,那麼如果想達到熱部署的效果,可以想象:方案一:修改配置文件nginx.conf後,主進程master負責推送給worker進程更新配置信息,worker進程收到信息後,更新進程內部的線程信息。方案二:修改配置文件nginx.conf後,重新生成新的worker進程,當然會以新的配置進行處理,而且新的請求都必須交給新的worker進程,至於老worker進程,等把那些以前的請求處理完畢,kill掉即可。Nginx採用的就是方案二來達到熱部署的!

代碼部署規範 - 個人文章 - SegmentFault 思否


無服務器環境的安全部署

沒有服務器的網站怎麼安全部署呢(只能FTP上傳文件的那種虛擬主機),網站需要增加一個站點開關,能夠關閉入口(用戶訪問時就顯示網站關閉升級中,多多返利程序升級時就是這樣的,需要在後臺關閉站點),並保證沒有後臺程序在運行時(開關關閉後等一會,檢查沒有隊列等後臺任務),再上傳新文件覆蓋就可以,等新文件上傳完畢後在打開站點開關,這樣才能確保安全。否則直接上傳文件覆蓋就不滿足原子發佈。


分享到:


相關文章: