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 协议》,转载必须注明作者和本文链接
不住念,无名无相
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 33
Summer

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

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

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

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

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

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

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

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

文章最后提到了你们。

4年前 评论
Summer

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

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

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

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

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

万分感谢

4年前 评论

万分感谢 :+1:

4年前 评论

给在座的各位打个电话

4年前 评论

感谢大神们的付出

4年前 评论
GoPPy

Nice!

4年前 评论

万分感谢各位的付出。

4年前 评论

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

4年前 评论
Egfly

感谢

4年前 评论
Rytia

感谢LC,继续努力

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

感谢

4年前 评论

:blush: 好好看 好好学

4年前 评论

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

4年前 评论
Summer 4年前

感谢镜像 造福国内开发者

4年前 评论

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

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

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

4年前 评论

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

4年前 评论
wujingke 4年前
Summer 4年前
CryptoPanda 4年前

赞一个👍

4年前 评论

赞一个 :+1:

4年前 评论

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

4年前 评论

问题反馈:

file

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

4年前 评论

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

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

4年前 评论

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

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

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

文章最后提到了你们。

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!