ZComposer 映象誕生於2017年3月份,至今已經執行2年多了,這不是一個多麼有技術含量的東西,所以簡單聊一些開發和解決問題的思路,希望能對你有一點啟發。如果你覺得有些收穫,請點下滑鼠,在 github 上給我1個 star(支援下),謝謝。
-
安全性,不對原有的json,zip做修改,否則會引起 hash 變化,重新計算 hash 沒問題(之前第三方有這麼做的),這樣帶來的問題是,無法對包的安全性做校驗,假如有惡意黑映象,對資料做了修改,就無法判斷了。所以 ZComposer 的映象,所有的包都是和 packagist.org 官方一致的,可以比對 hash ,沒有任何修改。
-
穩定性,因為不間斷的採集資料,上傳資料,中間有一個環節出現差錯,就可以導致有問題,所以務必對採集完的包,透過 hash 值做完整性檢查。有時候第三方的API策略,或者CDN線路都可能導致出現問題。所以做映象最大的難點,是穩定性的保障。
-
Webysther/packagist-mirror(官方推薦的映象開源) fork 自 hirak/packagist-crawler,但這些映象開源都沒有處理dist包,而dist包才是最大/最多的,最值得CDN處理的。ZComposer 開源是全量映象,包含了對 dist 部分的處理。dist 包還有個 65000上限子目錄數 的問題,1年的時間,包的數量都是成倍的增加。軟連線的方案是我原創出來的,或許隨著包的無限增加,還需要設計其他方案。
ZComposer 映象的安裝部署
推薦執行主機配置:
- [x] 記憶體最好不低於4G
- [x] 剩餘磁碟空間不低於30G
$ apt install beanstalkd
$ cd composer-mirror
$ composer install
修改配置引數
通常根據自己部署的實際環境,修改引數。詳細配置說明詳見 config.default.php
cp config.default.php config.php
,修改 config.php 中的如下參
/**
* distdir 用於儲存 zip 包
*/
'distdir' => __DIR__ . '/dist/',
/**
* 指向 mirrorUrl 對應的 web 實際目錄
*/
'cachedir' => __DIR__ . '/cache/',
/**
* packagistUrl:官方採集源
*/
'packagistUrl' => 'https://packagist.org',
/**
* 映象包釋出站點, packages.json 入口根域名
*/
'mirrorUrl' => 'https://packagist.laravel-china.org',
/**
* .json 中 dist 分發 zip 包的CDN域名
*/
'distUrl' => 'https://dl.laravel-china.org/',
supervisor 配置
sudo vim /etc/supervisor/supervisord.conf
,新增如下配置資訊:
[program:crawler]
command=php ./bin/console app:crawler
directory=/home/zencodex/composer-mirror/ ;部署程式碼的位置,自行替換
autostart=true
autorestart=true
redirect_stderr = true ; 把 stderr 重定向到 stdout,預設 false
stdout_logfile_maxbytes = 10MB ; stdout 日誌檔案大小,預設 50MB
stdout_logfile_backups = 5 ; stdout 日誌檔案備份數
stdout_logfile = /tmp/composer_crawler_stdout.log
[program:composer_daemon]
command=php ./bin/console app:daemon
directory=/home/zencodex/composer-mirror/ ;部署程式碼的位置,自行替換
autostart=true
autorestart=true
redirect_stderr = true ; 把 stderr 重定向到 stdout,預設 false
stdout_logfile_maxbytes = 10MB ; stdout 日誌檔案大小,預設 50MB
stdout_logfile_backups = 5 ; stdout 日誌檔案備份數
stdout_logfile = /tmp/composer_daemon_stdout.log
crontab 定時任務
# sudo crontab -e
# 根據自己環境程式碼的位置,替換 /home/zencodex/composer-mirror
# getcomposer 是獲取最新的 composer,上傳到 CDN 雲端儲存
0 */2 * * * /usr/bin/php /home/zencodex/composer-mirror/bin/console app:clear --expired=json
0 1 * * * /usr/bin/php /home/zencodex/composer-mirror/getcomposer.php
常用命令
# 執行抓取任務
$ php ./bin/console app:crawler
# 後臺多程式模型同步又拍雲
$ php ./bin/console app:daemon
# 清理過期垃圾檔案
$ php ./bin/console app:clear --expired=json
# 掃描並校驗所有json和zip檔案的hash256
$ php ./bin/console app:scan
For Developers
- 沒有使用資料庫儲存,完全是按目錄結構儲存
- 每個包的 dist/zip 檔案儲存的是對應 github url的下載地址,因磁碟空間有限,不在本地儲存,直接推送到雲端
- 清理過期檔案,判斷是否有更新,是否過期的依據是檔案的時間戳,所以不要手動對檔案做 touch,或引起時間戳變化的操作
如果使用非又拍雲的其他平臺,需要注意以下程式碼,需要自行實現
- ClientHandlerPlugin 需要 Flysystem 的對應 Adapter 有對應介面,本例中只有 zencodex/flysystem-upyun 實現了,其他第三方包,可以參照樣例自行實現
- Cloud::refreshRemoteFile,作用是重新整理 CDN 快取的檔案,這個每日有呼叫頻率限制,所以只重新整理 package.json 時使用
- Cloud::refreshRemoteFile,如果使用非又拍雲的平臺,需要替換為自己平臺重新整理程式碼。或者參照
ZenCodex\Support\Flysystem\Adapter\UpyunAdapter
封裝 getClientHandler。 - Cloud::prefetchDistFile 和 refreshRemoteFile 類似,呼叫的是雲平臺特殊介面,無法統一封裝在 Flysystem,所以也透過 getClientHandler 處理
注意最大子目錄數的坑
程式碼詳情見 src/Commands/PatchCommand.php
/*
|--------------------------------------------------------------------------
| linux ext4 支援的最大子目錄數有上限,大約 64000 ~ 65000,目前包的數量已經超過上限
|--------------------------------------------------------------------------
|
| 有三種解決方法,前2種基本不現實。所以自己透過嘗試,找到了3 (軟連線不計數的方案)
|
| 1. 更換沒有子資料夾數量限制的檔案系統,比如 xfs
| 2. 或者更改相關程式碼,重新編譯 ext4 核心
| 3. 切割大的資料夾,分散不同字母開頭的檔案。在主資料夾裡面使用軟連線,軟連線並不計數
|
*/
ZComposer 映象早期是 @Summer 提出的構想,期間也得到了 @overtrue 和LC社群小夥伴們的大力支援,開源也是 Overtrue 提的建議,一併感謝大家們的鼓勵和支援。大俠們會在 2019 年 8 月 3 - 4 日,舉辦國內 第一屆 Laravel Conf China 大會,可謂華山論劍,高手雲集的盛會,趕緊透過官網報名吧:http://laravelconf.cn
本作品採用《CC 協議》,轉載必須註明作者和本文連結