git-config配置多用户场景实践

gitgit是一个分布式版本控制软件,最初由林纳斯·托瓦兹创作,于2005年以GPL发布。最初目的是为更好地管理Linux内核开发而设计。应注意的是,这与GNU Interactive Tools(一个类似Norton Commander界面的文件管理器)有所不同。git最初的开发动力来自于BitKeeper和Monotone。git最初只是作为一个可以被其他前端(比如Cogito或Stgit)包装的后端而开发的,但后来git内核已经成熟到可以独立地用作版本控制。很多著名的软件都使用git进行版本控制,其中包括Linux内核、X.Org服务器和OLPC内核等项目的开发流程。更多相关介绍可以查看百科 git的基本使用主要是指一下基本操作: 安装ssh登入配置命令使用安装根据自己的系统进行选择安装方式,可以使用命令行安装,也可以使用安装包安装,git官方安装包地址 ssh登入配置安装完成之后,需要考虑和远程的仓库建立连接,就需要账号和密码,无论是github、gitlab等,都需要一个账户名,可以注册完成,然后设置: git config --global user.name "yourName"git config --global user.email "yourEmail"为了避免每次push代码都需要密码之类的,我们通过ssh来配置;执行: ssh-keygen一路enter即可,在~/.ssh/下会生成两个文件,复制其中的公钥: pbcopy < ~/.ssh/id_rsa.pub进入远程仓库的个人中心,https://github.com/settings/profile;会找到关于SSH and GPG keys,有一个New SSH key的按钮,点击后,可以黏贴上刚复制的公钥,然后Add SSH key即可; 可以pull和push代码测试是否成功。 git命令使用对于win10系统,推荐升级后使用好的官方新出的终端,Windows Terminal,需要当前最新的win10版本,用起来挺好的,可以再Microsoft的官方商城下载体验。对于mac或者linux用户,推荐配置 oh-my-zsh, 这个oh-my-zsh默认安装上了git plugin在~/.zshrc配置文件中,可以使用很多的简洁命令,git简写命令集合多用户配置git-config的官网巨长文档,开发人员经常遇到这样的问题,我们的公司仓库和个人仓库的用户名和邮箱配置是有区别的,为了能够很好地区分工程上传到不同的远程仓库,我们需要分别处理,保证在不同的工程使用不同的账户 按工程配置多用户按目录配置多用户按工程配置多用户目前git的配置变量可以放在三个地方: /etc/gitconfig 系统配置,对所有用户都生效。~/.gitconfig 用户配置,仅对当前用户生效。 git config --global user.name "yourName"git config --global user.email "yourEmail"projectRootPath/.git/config 项目根目录配置,仅对当前项目生效。对应:进入工程根目录执行 git config user.name "yourName"git config user.email "yourEmail"三层是从3-2-1的优先级处理的,这样我们可以对不同工程完成不同的配置,这个在工程数量多的时候简直不忍直视,所以需要寻找更好的方法。 按目录配置多用户在2017年,git新发布的版本2.13.0包含了一个新的功能includeIf配置,可以把匹配的路径使用对应的配置用户名和邮箱; 在~/目录下面存在三个配置文件, .gitconfig // 全局通用配置文件.gitconfig-self // 个人工程配置文件.gitconfig-work // 公司工程配置文件全局通用配置文件~/.gitconfig里面的内容是:主要是通过includeIf配置匹配不用的目录映射到不同配置文件上, [includeIf "gitdir:~/self-workspace/"] path = .gitconfig-self[includeIf "gitdir:~/workspace/"] path = .gitconfig-work个人工程配置文件~/.gitconfig-self: ...

July 10, 2019 · 1 min · jiezi

PHP的apc扩展导致引入文件错误

最近遇到一个非常奇怪的bug,在主机PHP代码版本回退的过程中,导致备机服务不可用。经过各种复现和文档查询,发现是PHP的apc扩展在和rsync同时使用时,会导致无法正确的处理缓存文件,最终影响服务。解决方案官方也有提供,加上一行配置:# php.ini[apc]apc.stat_ctime=1下面我们来说明下这个问题出现的机制。关键点:使用了PHP+apc扩展+rsync主从同步机制故障表现:引入时找不到文件平台服务上线更新后,访问平台服务时报错信息:Warning: include(Yii.php): failed to open stream: No such file or directory in /home/disk4/htdocs/oss_debug/protected/lib/Yii/framework/YiiBase.php on line 421Warning: include(): Failed opening ‘Yii.php’ for inclusion (include_path=’.:/home/work/lnmp/weblib/phplib:/home/work/lnmp/lib/php’) in /home/disk4/htdocs/oss_debug/protected/lib/Yii/framework/YiiBase.php on line 421Fatal error: Class ‘Yii’ not found in /home/disk4/htdocs/oss_debug/index.php on line 42这里的提示信息表明,问题出现在YiiBase.php文件中,在421行引入Yii.php时找不到该文件,而这里的include为相对路径,当前的引入路径为.:/home/work/lnmp/weblib/phplib:/home/work/lnmp/lib/php,多个引入路径以:分割,所以这里会在./,/home/work/lnmp/weblib/phplib,/home/work/lnmp/lib/php三个目录下查找该文件,分别检索了一下,发现确实均不存在该文件。但是在正常的服务下,却并不会查找该文件。具体为什么会去查找该文件,我猜测是先判断Yii类是否存在,不存在就去引入Yii.php,而Yii类在yii.php文件中有定义,因此猜测是没有正确引入yii.php导致。# yii.php<?phprequire(dirname(FILE).’/YiiBase.php’);class Yii extends YiiBase{}这个问题没有深究,因为最后发现故障跟这个点无关。复现一个小问题:改变目录后无法服务你只需要将你的服务目录换个名字即可复现,如你当前的服务目录是/home/work/lnmp/htdocs/oss/,你将它重名为/home/work/lnmp/htdocs/oss2,这个时候你就会发现服务受到了影响:# 访问 domain.com/oss2/index.phpWarning: file_get_contents(/home/work/lnmp/htdocs/oss/version): failed to open stream: No such file or directory in /home/work/lnmp/htdocs/oss/index.php on line 26Warning: require_once(/home/work/lnmp/htdocs/oss/protected/lib/Yii/framework/yii.php): failed to open stream: No such file or directory in /home/work/lnmp/htdocs/oss/index.php on line 38Fatal error: require_once(): Failed opening required ‘/home/work/lnmp/htdocs/oss6/protected/lib/Yii/framework/yii.php’ (include_path=’.:/home/work/lnmp/weblib/phplib:/home/work/lnmp/lib/php’) in /home/work/lnmp/htdocs/oss6/index.php on line 38可以看到当我们访问oss2目录时,程序却依然在尝试读取oss目录下的文件,这时文件自然不存在,因此报错。那么这是为什么呢?原因是我们使用了PHP的apc扩展。PHP的服务过程学习过计算机原理的同学,都了解语言分为编译型语言和解释型语言,由于语言是人来编写的,而机器无法直接执行,因此,在代码被执行前需要经历一个编译成机器可以识别的操作码的过程。编译型语言在执行前提前编译好,然后发布;解释型语言先发布,在执行时即时编译。因此我们常说编译型语言的性能好,主要就是快在这个地方。PHP属于解释型语言,常规的执行流程是:Nginx转发请求给PHP主进程主进程引入代码文件PHP解释器会先将代码切分为Token生成抽象语法树生成机器可以直接执行的操作码PHP虚拟机执行操作码如果文件有引入其他文件,循环执行上述2-6步骤执行完成,返回结果可以看到每次请求过来,都会对文件做一次编译和缓存,那么这样会非常影响效率,为了保证PHP的灵活性,同时提升效率,我们需要对编译好的操作码进行缓存。这就是apc扩展做的事情:判断文件是否有更新如果更新,重新编译并缓存否则,直接读取缓存的操作码apc扩展apc扩展文档Alternative PHP Cache (APC 可选 PHP 缓存) 是一个开放自由的 PHP opcode 缓存。它的目标是提供一个自由、 开放,和健全的框架,用于缓存、优化 PHP 中间代码。该扩展也提供了一些内置的方法,可以用于手动设置或清空缓存。清空缓存的方法:apc_clear_cache()。调用这个方法后可以解决因apc缓存过期文件导致的bug。另外,我们需要关注的几个配置项:apc.stat integer是否启用脚本更新检查。 改变这个指令值要非常小心。 默认值 On 表示APC在每次请求脚本时都检查脚本是否被更新, 如果被更新则自动重新编译和缓存编译后的内容。但这样做对性能有不利影响。 如果设为 Off 则表示不进行检查,从而使性能得到大幅提高。 但是为了使更新的内容生效,你必须重启Web服务器(译者注:如果采用cgi/fcgi类似的,需重启cgi/fcgi进程)。 生产服务器上脚本文件很少更改, 可以通过禁用本选项获得显著的性能提升。这个指令对于include/require的文件同样有效。但是需要注意的是, 如果你使用的是相对路径,APC就必须在每一次include/require时都进行检查以定位文件。 而使用绝对路径则可以跳过检查,所以鼓励你使用绝对路径进行include/require操作。apc.stat_ctime integer验证ctime(创建时间)可以避免SVN或者rsync带来的问题,确保自上次缓存统计inode没有改变。APC通常只检查mtime(修改时间)。apc.file_update_protection integer当你在一个运行中的服务器上修改文件时,你应当执行原子操作。 也就是先写进一个临时文件,然后将该文件重命名(mv)到最终的名字。 文本编辑器以及 cp, tar 等程序却并不是这样操作的,从而导致有可能缓冲了残缺的文件。 默认值 2 表示在访问文件时如果发现修改时间距离访问时间小于 2 秒则不做缓冲。 那个不幸的访问者可能得到残缺的内容,但是这种坏影响却不会通过缓存扩大化。 如果你能确保所有的更新操作都是原子操作,那么可以用 0 关闭此特性。 如果你的系统由于大量的IO操作导致更新缓慢,你就需要增大此值。可以看到,apc扩展可能会导致两个问题:rsync/svn配合使用时存在无法正确处理文件缓存的问题可能读到残缺文件,导致影响部分人的请求针对这两个问题,也分别提供了解决方案:# php.ini[apc]# 启动ctime检查stat_ctime=1# 默认值为2,变大这个值file_update_protection=5虽然文档中有说明,但还是有很多人会遇到这种问题,可以参考:stack overflow问题:Problems with APC on publish官方Issue:apc.include_once_override turn on issue在遇到这个问题时,除了上面的配置解决问题,还可以:PHP代码中执行apc_clear_cache()重启php-fpm进程另外,我们可以将apc扩展安装时包含的apc.php文件放到web服务目录下,就可以可视化的观察apc扩展的缓存情况。服务使用了rsync同步这次故障的一个关键因素是使用了rsync同步,我的服务架构是:导致这个问题的原因探究具体为什么在apc扩展跟rsync同时使用会产生这个bug,我没有看源码,不太了解,但我做了一些大胆的猜测,下面的内容不够清楚和正确,希望大家能给我更精确的指导:这里可以看出文件是怎么检查是否有更新的,而问题也就出现在这一部分,没有办法判断文件是否被更新,同时正确读取到缓存的文件。参考资料PHP手册 - APC运行时配置:https://www.php.net/manual/zh…stack overflow - Problems with APC on publish:https://stackoverflow.com/que…PHP官方issue - apc.include_once_override turn on issue:https://bugs.php.net/bug.php?…php可选缓存APC:https://www.cnblogs.com/hf805…关于上线系统的一些想法 (for php):http://bikong0411.github.io/2…如何刷新APC类加载器缓存?:http://cn.voidcc.com/question…rsync文件同步服务:https://xdays.me/rsync%E6%96%…APC’s Include Once Override breaks install:https://www.drupal.org/projec…《PHP 7底层设计和源码实现》 ...

April 12, 2019 · 1 min · jiezi