Composer 中國全量映象開源了,一起讓 PHP 社群更繁榮

扣丁禪師發表於2019-05-24

先上鍊接:https://github.com/zencodex/composer-mirro...

ZComposer 映象誕生於2017年3月份,至今已經執行2年多了,這不是一個多麼有技術含量的東西,所以簡單聊一些開發和解決問題的思路,希望能對你有一點啟發。如果你覺得有些收穫,請點下滑鼠,在 github 上給我1個 star(支援下),謝謝。

  1. 安全性,不對原有的json,zip做修改,否則會引起 hash 變化,重新計算 hash 沒問題(之前第三方有這麼做的),這樣帶來的問題是,無法對包的安全性做校驗,假如有惡意黑映象,對資料做了修改,就無法判斷了。所以 ZComposer 的映象,所有的包都是和 packagist.org 官方一致的,可以比對 hash ,沒有任何修改。

  2. 穩定性,因為不間斷的採集資料,上傳資料,中間有一個環節出現差錯,就可以導致有問題,所以務必對採集完的包,透過 hash 值做完整性檢查。有時候第三方的API策略,或者CDN線路都可能導致出現問題。所以做映象最大的難點,是穩定性的保障。

  3. 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 協議》,轉載必須註明作者和本文連結
尊道貴德 / 多行佈施

相關文章