擼了快 3 年的 Laravel 了,儘量這周分享本人使用的多臺伺服器叢集部署方案

fivenull發表於2019-11-05

1、rsync+sersync自動同步差異化檔案
CentOS7 下使用 rsync+sersync 配置檔案自動同步
2、docker下安裝gogs
使用 Docker 部署版本控制工具 Gogs

大家看著圖個樂就行,這段純粹個人吐槽,可直接跳過
本人所在的公司,後端就我一個人,前端一名(原本2名,後來離職1名),設計兩名,策劃1名。17年進入這家公司,維護公司官網,最初就我一人,18年下半年逐漸增加到6人,隊伍也不算小了,本人負責整個後端架構和伺服器部署維護。
從15年出來工作到現在,陸陸續續也進過很多公司,最初的毛頭小子,技術小白,一步一步成長到現在,技術、經驗都有了很大的提升(自我感覺,請勿噴),從一開始的echo "hello world";,到現在的多語言版本hello world,只想說一句話,生命不息,程式碼不止!

最初的時候用的是tp3.23,幹外包,大家都懂,追求效率。幹了2年外包後,進入了一家本土稍微大一點論壇,主要做一些小專題,小專案和維護論壇,比之前外包難度稍高,還好有個老技術可以帶(幹外包的時候前期後端技術都跑了,就我一人,天天加班熬夜幹活學習,自己一個人閉門造車),瞭解了很多專案流程,包括寫程式碼需要注意的事項,程式碼安全、執行效率,redis佇列、應付併發等等。

之後跳槽就進入現在這家公司,主做維護,因為可以學到很多敲程式碼除外的東西,最初的時候可以跟著領導全國出差,感謝領導,學到了很多很多,為人處世等等。

框架選型

剛進來的時候是接手外包做的網站,因為部門戰略方向修改,所以整個專案相當於要推倒重來,因為外包用yii2做的,我不是很喜歡這個框架,citp又不合適,遂直接用laravel開擼,前期真的是碰了很多很多壁,一度想放棄,但是還是堅持了下來。

版本控制

最初程式碼使用ftp管理,後來跟換到svn,再到現在的git,自己docker環境下搭建的gogs。伺服器也從最初的1臺,到現在多臺,也部署了一臺負載均衡器,同步程式碼使用git提交觸發鉤子,然後rsync+sersync監聽檔案變化,自動同步差異化檔案,CDN隱藏伺服器真實域名。

API編寫

介面最初使用laravel + dingo API,到現在的golanggin重寫,爬蟲專案也從最初的phpguzzle包到目前的python重寫。最終,得到一個結論!就是 想要快速進步,就要靠大量專案餵養

  • 目前在的公司較為安逸,主做維護,所以有很多空餘時間。荒廢時間對於技術人員是最可怕的,我們公司是存在編制的,不犯什麼大錯誤基本可以幹一輩子了,擔憂技術停滯不前甚至倒退。
  • 公司在三線城市(房價漲幅世界第一,不想吐槽),城市的IT技術相較於北上廣深差距太大,自己又買不起房,學歷只是大專,自考的遠端教育本科又沒有含金量,只能不斷學習逼迫自身,靠技術去一線城市博得一席之地。
  • 學無止境,百度雲端儲存的內容估計這輩子都學不完了,從前端到後端到伺服器到人工智慧,內容太多了。經過長時間的思考,暫定以後端技術為主,前端不求精通,能做一些兼職即可,伺服器方面目前在研究docker+k8s,公司伺服器gogs就是搭建在docker環境下的。接下來深入研究golang,微服務方面。

這周看看能不能寫伺服器部署的一個分享出來,到時候請各位批評指正!

本文將從三個階段敘述,包含專案的架構、版本工具的選擇、程式碼部署、到安全

第一階段:剛接手專案

外包交付之前,是通過ftp的形式上傳檔案。
交付後到公司戰略方向調整後,因為公司業務較多,全國有20多個營業點,每個營業點都有一名前端設計,公司後端只有我一人。前端需要製作頁面,供外網訪問。

需要解決的問題:

  1. 專案需要重新設計,選擇框架?伺服器環境如何搭建?
  2. 程式碼安全問題,不希望全國的營業點直接訪問到專案原始碼,如何選型?
  3. 全國營業點中有技術較好的前端,如何給與部分網站修改許可權?
  4. 網站是站群系統,域名需要泛解析,laravel自帶的路由文件無法提供解決方案
  5. 後臺的選型,還有許可權等功能的開發

解決方案

  1. 因為發現了learnku社群(前身laravel-china.org),學習了釋出的教程,遂選擇了laravel。伺服器環境使用寶塔皮膚,定時備份網站和資料庫、設定阿里雲自動快照。
  2. 需要嚴格控制程式碼許可權,所以選擇了svn,建立不同角色,給目錄增加對應許可權。
  3. 借鑑blade模板和織夢的模板標籤,開發屬於laravel的自定義模板標籤。
  4. 改寫route路由,自己摸索泛解析匹配規則,輔以大量正則判斷,不斷試錯。
  5. 後臺模板使用ACE,手擼RBAC許可權管理,這個實現較為簡單,業務邏輯。

不足之處

  1. git比svn更好,但受限於技術,無法搭建。等自身實力達到後肯定要換掉。
  2. 對svn功能也不是很瞭解,區域經常上傳大檔案,導致專案愈發臃腫。
  3. 自寫的泛解析站群路由正則太多,檔案也較長,不利於後期維護和擴充套件。
  4. 後臺功能較少,篩選、統計等新功能開發效率較低。
  5. 沒有應付高併發的方案、也沒有應對網路惡意攻擊的解決手段。

伺服器使用CentOS,採用LNMP,直接用寶塔部署,手動安裝svn版本控制工具,通過鉤子自動同步程式碼,svn提交後,線上可以直接看到效果,php+svn就是這麼暴力,因為條件受限和技術受限,就沒有部署測試環境,所見即所得。

安全方面,laravel自身意見提供了一部分,包括csrf防SQL隱碼攻擊埠IP限制,使用阿里雲CDN隱藏伺服器真實IP等等,都是一些常見的。

第二階段

新專案的使用和內部專案迭代,還有個人經驗、技術的提升,此時產生了以下問題:

需要解決的問題:

  1. 不滿足於svn的侷限,需要選型新的工具。
  2. 新專案選型,需要用到佇列和定時任務。
  3. 伺服器訪問較大,需要購買多臺伺服器部署叢集。
  4. 後臺開發耗時較多(因為我們後臺功能很多),如何解決?

解決方案

  1. 在伺服器部署git私有管理器,實現版本控制,svngit同時存在。
  2. 學習laravel課程二,借鑑大佬程式碼和閱讀文件,實現佇列和定時任務。
  3. 購買阿里雲伺服器,和負載均衡,使用rsync+sersync監聽檔案變化,自動同步差異化檔案。
  4. 使用laravel-admin擴充套件包,快速生成後臺,加上自定義的介面,可以很輕鬆實現絕大部分業務功能。

不足之處

  1. 因為專案人員驟減,只限於辦公室的6個人,所以不需要對程式碼進行許可權控制,但總要限制,gitlab可以實現,可惜技術不足,無法滿足需求。
  2. 伺服器部署使用的寶塔皮膚,方便快捷(全部命令列太麻煩,效率也低),想全部容器化部署,使用k8s,這也是目前能想到的解決方案,受限於技術原因無法實現。下一步學習方向就在此。
  3. 網站後臺的UI,同事不滿意,但自建後臺,消耗的成本和時間會很大,目前只能這樣。

此間碰到過多起安全問題,網站執行受到大量的CC攻擊,期間最嚴重的一次,攻擊持續了4天,超過CDN負載,3天訪問次數達10億次以上,QPS峰值5W多,被阿里雲CDN拉入沙箱,整個業務完全終止外網訪問。

當時可以說人在公司呆了4天,基本天天熬夜到下半夜,受限於技術,通過iftop工具分析流量,只能採取最傻瓜的操作,就是伺服器防火牆封鎖IP,後因IP太多,直接封鎖IP段,但因為對方IP池太深,以失敗告終。

伺服器方面,opcache快取開啟,php調整程式數,nginx限流開啟,資料庫增加連線數,資料庫讀取增加快取,存入redis,但也只是杯水車薪。

通過不斷的查閱資料,給伺服器安裝了fail2ban,仍然沒有解決問題,為此阿里雲還專門和我建立了一個釘釘討論組,他們給的建議就是,花錢上高防伺服器,可惜的是因為價格太高,公司領導不允許。不過在不斷的分析IP來源中,發現了一個規律,就是流量來源90%以上都是國外的,因此和阿里雲技術溝通,看能否幫忙禁國外使用者訪問,答案是不能。

後來在其他部門同事的幫助下,我們更換了CDN服務提供商,使用百度雲CDN,軟磨硬泡,拜託百度雲技術幫忙封鎖國外IP,配合CDN限流和繼續封鎖IP段,正好在美國的領導通知我國外無法訪問網站,流量峰值不斷降低至正常狀態,此次危機才得以緩解,在次感謝百度雲CDN工作人員的幫助。

感謝@MIsakas提供的思路,可以在解析域名的時候把境外線路解析到虛假IP上,具體我還沒有試。

第三階段

因為部門方向再次變更,整個服務也需要大概,因為不斷閱讀社群優秀文章和教程,還有不斷的刷github,愈發發現之前程式碼寫的太垃圾,毅然決定重寫專案。

正好伺服器到期,公司也要更換阿里雲賬號,所以從購買伺服器開始,到網站部署,版本工具的選擇等等,算得上截止19年上半年學到的知識都用上了。

首先,伺服器安全層面,棄用密碼登入,採用ssh祕鑰,還有對應一系列的ssh配置,比如超時自動踢出登入,密碼隔斷自動修改等等,這些阿里雲都會提示,對照著修改就好。

因為公司後端就我一個人,所以我是允許root登入的,給埠設定ip限制就可以了。

伺服器

伺服器使用阿里雲負載均衡+雲ecs

環境搭建

環境搭建方面,為了省事,我仍然採用的寶塔皮膚,限制皮膚登入埠IP許可權。推薦大家linux安裝htop,友好性互動的程式檢視器,比top命令好用多了。

版本控制

程式碼版本控制,安裝docker,使用gogs進行版本控制。因公司業務是所見即所得的,所以不需要測試環境,線下修改直接push推送,觸發post-receive鉤子,自動同步線上程式碼。如果條件允許的話肯定要配置測試環境的,而且git分支也要嚴格控制許可權,master分支只允許核心人員推送,合併分支也是。修改bug可以使用dev分支,gogs的web介面也需要設定IP訪問許可權。

程式碼同步

程式碼同步方面,仍然使用rsync+sersync,目前受於技術限制,沒有發現其他更方便的同步方式

資料庫

資料庫用的mysql8+,多臺伺服器之間以內網通訊,設定獨立的賬號,分配許可權指定資料庫名。為了方便,管理員賬戶對外也指定了IP,資料庫對外埠也限制了IP。需要注意的是mysql8.0以上修改了密碼加密方式,連線不上的需要新建使用者或更換版本。

後臺開發

使用laravel-admin包,功能很強大,為作者點贊。絕大部分需求的功能都有,加上自定義的介面,可以滿足日常後臺開發的絕大部分需求。

快取服務

資料快取使用redis,一樣的需要限制IP訪問。需要注意的是,redis內網之間訪問,IP設定不是127.0.0.1,而是對應的內網IP。至於mysql的優化,社群一堆文章,我這裡不做贅述。

圖片等大檔案儲存

圖片等大檔案儲存到七牛雲或者阿里雲OSS,技術達到的話可以自行搭建圖片伺服器,記得使用https協議

使用cdn為網站加速

網站使用cdn加速,隱藏真實IP,否則一旦暴露,ddos攻擊小公司根本扛不住。

以上限制埠都可以通過linux防火牆進行設定。

如果併發壓力過高,記得開啟php的opcache,業務需要的話可以使用swoolePHP-FPM執行模式可以切換為動態,計算好php的連線數。

上線專案前可以用apacheab命令進行壓測,還可以使用第三方測試工具,比如JMeter等進行壓測,詳情見L06 Laravel 教程 - 電商進階 ( Laravel 5.8 )

使用supervisor託管佇列

佇列使用python編寫的supervisor進行管理,還可以使用Horizon佇列管理工具,記得控制好許可權

docker環境搭建gogsrsync+sersync,我會分兩篇文章,本週六寫好釋出。

API開發

API介面前期使用的是dingoAPI,後來使用golanggin框架重寫了,最近看laravel6.x自帶的Resource,覺得可以不用dingoAPI了。

至於為什麼使用golang,因為個人很喜歡go。我寫過pythonphp,都是解釋性語言,想換一門編譯型的,c++怕短時間入不了門,java又太重,所以選擇了go。這裡吐槽一下,php的陣列比go的map方便了N倍。
感謝@下水道里有隻貓,golang帶我入門,我是看了他的部落格原始碼才能下手重寫專案的。

建議

最近學習了laradock,發現是真的好用,docker-compose都配置好了,啟動的時候選擇對應映象,方便快捷,一件試部署。
擼了快 3 年的 Laravel 了,儘量這周分享本人使用的多臺伺服器叢集部署方案

不過有個坑,就是我習慣直接批量重啟容器,導致nginx容器連不上php容器

#我要執行2次,因為容器啟動順序衝突,還經常php容器連不上nginx
docker start $(docker ps -a | awk '{print $1}' | tail -n +2)

最好在laradock目錄下執行

# 例:docker-compose up -d nginx mysql redis workspace php-worker
docker-compose -d up 容器1 容器2 容器3 ...

至於後期的學習計劃,重心在容器化,docker+k8s,還有go的微服務方向。最近對數學起了興趣,準備明年買幾本高數書學習一下?。還有明年準備複習英語,這樣就可以參與社群的翻譯工作了。可惜自己基於ss協議搭建的梯子被封了,只能用電腦查閱文件了。

生命不息,程式碼不止

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章