Composer 中國全量鏡像開源了,一起讓 PHP 社區(qū)更繁榮

image

先上鏈接:https://github.com/zencodex/composer-mirror

ZComposer 鏡像誕生于2017年3月份,至今已經(jīng)運(yùn)行2年多了,這不是一個(gè)多么有技術(shù)含量的東西,所以簡單聊一些開發(fā)和解決問題的思路,希望能對你有一點(diǎn)啟發(fā)。如果你覺得有些收獲,請點(diǎn)下鼠標(biāo),在 github 上給我1個(gè) star(支持下),謝謝。

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

  2. 穩(wěn)定性,因?yàn)椴婚g斷的采集數(shù)據(jù),上傳數(shù)據(jù),中間有一個(gè)環(huán)節(jié)出現(xiàn)差錯(cuò),就可以導(dǎo)致有問題,所以務(wù)必對采集完的包,通過 hash 值做完整性檢查。有時(shí)候第三方的API策略,或者CDN線路都可能導(dǎo)致出現(xiàn)問題。所以做鏡像最大的難點(diǎn),是穩(wěn)定性的保障。

  3. Webysther/packagist-mirror(官方推薦的鏡像開源) fork 自 hirak/packagist-crawler,但這些鏡像開源都沒有處理dist包,而dist包才是最大/最多的,最值得CDN處理的。ZComposer 開源是全量鏡像,包含了對 dist 部分的處理。dist 包還有個(gè) 65000上限子目錄數(shù) 的問題,1年的時(shí)間,包的數(shù)量都是成倍的增加。軟連接的方案是我原創(chuàng)出來的,或許隨著包的無限增加,還需要設(shè)計(jì)其他方案。

ZComposer 鏡像的安裝部署

推薦運(yùn)行主機(jī)配置:

  • [x] 內(nèi)存最好不低于4G
  • [x] 剩余磁盤空間不低于30G
$ apt install beanstalkd
$ cd composer-mirror
$ composer install

修改配置參數(shù)

通常根據(jù)自己部署的實(shí)際環(huán)境,修改參數(shù)。詳細(xì)配置說明詳見 config.default.php

cp config.default.php config.php,修改 config.php 中的如下參

    /**
     * distdir 用于存儲(chǔ) zip 包
     */
    'distdir' => __DIR__ . '/dist/',

    /**
     * 指向 mirrorUrl 對應(yīng)的 web 實(shí)際目錄
     */
    'cachedir' => __DIR__ . '/cache/',

    /**
     * packagistUrl:官方采集源
     */
    'packagistUrl' => 'https://packagist.org',

    /**
     * 鏡像包發(fā)布站點(diǎn), packages.json 入口根域名
     */
    'mirrorUrl' => 'https://packagist.laravel-china.org',

    /**
     * .json 中 dist 分發(fā) 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,默認(rèn) false
stdout_logfile_maxbytes = 10MB  ; stdout 日志文件大小,默認(rèn) 50MB
stdout_logfile_backups = 5      ; stdout 日志文件備份數(shù)
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,默認(rèn) false
stdout_logfile_maxbytes = 10MB  ; stdout 日志文件大小,默認(rèn) 50MB
stdout_logfile_backups = 5      ; stdout 日志文件備份數(shù)
stdout_logfile = /tmp/composer_daemon_stdout.log

crontab 定時(shí)任務(wù)

# sudo crontab -e
# 根據(jù)自己環(huán)境代碼的位置,替換 /home/zencodex/composer-mirror 
# getcomposer 是獲取最新的 composer,上傳到 CDN 云存儲(chǔ)

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

常用命令

# 執(zhí)行抓取任務(wù)
$ php ./bin/console app:crawler

# 后臺(tái)多進(jìn)程模型同步又拍云
$ php ./bin/console app:daemon

# 清理過期垃圾文件
$ php ./bin/console app:clear --expired=json

# 掃描并校驗(yàn)所有json和zip文件的hash256
$ php ./bin/console app:scan

For Developers

  • 沒有使用數(shù)據(jù)庫存儲(chǔ),完全是按目錄結(jié)構(gòu)存儲(chǔ)
  • 每個(gè)包的 dist/zip 文件存儲(chǔ)的是對應(yīng) github url的下載地址,因磁盤空間有限,不在本地存儲(chǔ),直接推送到云端
  • 清理過期文件,判斷是否有更新,是否過期的依據(jù)是文件的時(shí)間戳,所以不要手動(dòng)對文件做 touch,或引起時(shí)間戳變化的操作

如果使用非又拍云的其他平臺(tái),需要注意以下代碼,需要自行實(shí)現(xiàn)

  • ClientHandlerPlugin 需要 Flysystem 的對應(yīng) Adapter 有對應(yīng)接口,本例中只有 zencodex/flysystem-upyun 實(shí)現(xiàn)了,其他第三方包,可以參照樣例自行實(shí)現(xiàn)
  • Cloud::refreshRemoteFile,作用是刷新 CDN 緩存的文件,這個(gè)每日有調(diào)用頻率限制,所以只刷新 package.json 時(shí)使用
  • Cloud::refreshRemoteFile,如果使用非又拍云的平臺(tái),需要替換為自己平臺(tái)刷新代碼。或者參照 ZenCodex\Support\Flysystem\Adapter\UpyunAdapter 封裝 getClientHandler。
  • Cloud::prefetchDistFile 和 refreshRemoteFile 類似,調(diào)用的是云平臺(tái)特殊接口,無法統(tǒng)一封裝在 Flysystem,所以也通過 getClientHandler 處理

注意最大子目錄數(shù)的坑

代碼詳情見 src/Commands/PatchCommand.php

/*
|--------------------------------------------------------------------------
| linux ext4 支持的最大子目錄數(shù)有上限,大約 64000 ~ 65000,目前包的數(shù)量已經(jīng)超過上限
|--------------------------------------------------------------------------
|
| 有三種解決方法,前2種基本不現(xiàn)實(shí)。所以自己通過嘗試,找到了3 (軟連接不計(jì)數(shù)的方案)
|
|   1. 更換沒有子文件夾數(shù)量限制的文件系統(tǒng),比如 xfs 
|   2. 或者更改相關(guān)代碼,重新編譯 ext4 內(nèi)核
|   3. 切割大的文件夾,分散不同字母開頭的文件。在主文件夾里面使用軟連接,軟連接并不計(jì)數(shù)
|
*/

ZComposer 鏡像早期是 @Summer 提出的構(gòu)想,期間也得到了 @overtrue 和LC社區(qū)小伙伴們的大力支持,開源也是 Overtrue 提的建議,一并感謝大家們的鼓勵(lì)和支持。大俠們會(huì)在 2019 年 8 月 3 - 4 日,舉辦國內(nèi) 第一屆 Laravel Conf China 大會(huì),可謂華山論劍,高手云集的盛會(huì),趕緊通過官網(wǎng)報(bào)名吧:http://laravelconf.cn

文章首發(fā)于:https://learnku.com/articles/28887

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容