Composer 中国全量镜像开源了,一起让 PHP 社区更繁荣

先上链接: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 协议》,转载必须注明作者和本文链接
YIN 流黑客,开源作品 uapp
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 33
Summer

希望有大公司可以维护多几个镜像,来分担点 LC 镜像 的维护压力。目前镜像虽然使用的是又拍云做 CDN 加速,但是还是使用的 Linode 服务器在做主机(在国外),有时候会不稳定。

对于维护者来讲,镜像是免费维护着的。一旦镜像出问题,可能项目上线部署一半,都是十万火急的事情。过去两年也真是很感谢 @扣丁禅师 ,所有的问题都很及时的解决了。

有多个镜像的话,一个服务不稳定了,我们切换另一个服务既可,也不用那么着急了。

如果你发现镜像,请前往此文章提交改进进行收录,以惠及更多用户 Wiki:Laravel 安装和开发环境:Composer 国内加速镜像

6年前 评论
Summer (作者) 6年前
CryptoPanda 6年前
江湖 6年前

阿里云 PHP Composer 全量镜像正式上线!https://mp.weixin.qq.com/s/Fk7aaFJRviV2Dng...

阿里云现在也搞了一个,是不是也是基于这个做的?

我们也在此向 Laravel China 开发者 Summer、禅师致敬:
毫无疑问,我们也是 Laravel China 的受益者,感谢你们对 PHP 社区的付出,也非常感谢 Summer 对我们的认可,阿里云会继续努力,一起让 PHP 社区变得更好!

文章最后提到了你们。

5年前 评论
Summer

希望有大公司可以维护多几个镜像,来分担点 LC 镜像 的维护压力。目前镜像虽然使用的是又拍云做 CDN 加速,但是还是使用的 Linode 服务器在做主机(在国外),有时候会不稳定。

对于维护者来讲,镜像是免费维护着的。一旦镜像出问题,可能项目上线部署一半,都是十万火急的事情。过去两年也真是很感谢 @扣丁禅师 ,所有的问题都很及时的解决了。

有多个镜像的话,一个服务不稳定了,我们切换另一个服务既可,也不用那么着急了。

如果你发现镜像,请前往此文章提交改进进行收录,以惠及更多用户 Wiki:Laravel 安装和开发环境:Composer 国内加速镜像

6年前 评论
Summer (作者) 6年前
CryptoPanda 6年前
江湖 6年前
Jennie

万分感谢

6年前 评论

给在座的各位打个电话

6年前 评论

感谢大神们的付出

6年前 评论
GoPPy

Nice!

6年前 评论

万分感谢各位的付出。

6年前 评论

一直在用这个镜像,感谢付出。

6年前 评论
Egfly

感谢

6年前 评论
Rytia

感谢 LC,继续努力

6年前 评论
农村闲散劳动力

感谢

6年前 评论

:blush: 好好看 好好学

6年前 评论

不知道 https://pkg.phpcomposer.com/ 的镜像跟 lc 的镜像有什么区别?以前一直用前者,后面前者有段时间有问题,就改用 lc,并一直用到现在。
另外,感谢提供镜像服务的人。

6年前 评论
Summer 6年前

感谢镜像 造福国内开发者

6年前 评论

做镜像太费钱,又没有收入

6年前 评论
扣丁禅师 (楼主) 6年前

也可以基于 https://learnku.com/laravel/t/16274 这来做镜像

6年前 评论

@wujingke 也感谢你早期的支持,最早期你也给了我很多参考意见,包括你的参考代码。感谢 :thumbsup:

6年前 评论
wujingke 6年前
Summer 6年前
CryptoPanda 6年前

赞一个👍

6年前 评论

:thumbsup:感谢 laravel 社区,禅师,站长,和很多为镜像付出的朋友们,无以回报,唯有买教程支持了

6年前 评论

问题反馈:

file

镜像好像从昨天早上开始一直没有进行同步更新,请问是怎么回事?因为需要更新自己包,镜像一直没有更新导致项目无法获取最新版本的包。

6年前 评论

@JimChen 正常 index.html 是不允许 CDN 缓存的,但不知道为啥莫名其妙被缓存了,所以仅是首页面缓存显示时间没动。

正常更新是没有影响的,你也可以通过 http://packagist.laravel-china.org/package... 查看时间,这个 json 时间是最准确的。我再给首页换个方式更新时间。感谢反馈

6年前 评论

阿里云 PHP Composer 全量镜像正式上线!https://mp.weixin.qq.com/s/Fk7aaFJRviV2Dng...

阿里云现在也搞了一个,是不是也是基于这个做的?

我们也在此向 Laravel China 开发者 Summer、禅师致敬:
毫无疑问,我们也是 Laravel China 的受益者,感谢你们对 PHP 社区的付出,也非常感谢 Summer 对我们的认可,阿里云会继续努力,一起让 PHP 社区变得更好!

文章最后提到了你们。

5年前 评论