系列笔记:
Modern PHP 笔记(一):语言特性
Modern PHP 笔记(二):良好实践
Modern PHP 笔记(三):部署测试和调优
第六章:主机
可选:
- 共享服务器
- 虚拟私有服务器VPS
- 专用服务器
- PaaS
第七章:配置
目标:安装Web服务器,以便接收HTTP请求;设置并管理一组PHP进程,处理PHP请求,
进程可以与web服务器通信。
设置服务器
一般选择nginx。因为apache为每个PHP请求派生一个子进程,比较耗资源。
然后作者展示了一个登陆VPS的例子:需要ssh登陆、创建非根用户管理web服务器,不要使用root
SSH密钥对认证
因为使用密码登陆有漏洞,尽量使用SSH密钥对认证。
SSH密钥对登录流程如下:
使用SSH密钥对认证方式登录远程设备时,远程设备随机创建一个消息,使用公钥加密,然后把密
文发给本地设备,本地设备收到密文后使用私钥解密,然后把解密后的消息发给远程服务器。远程
服务器验证解密后的消息之后,再赋予你访问服务器的权限。
适合在一台电脑中登录远程,多台不适合。
// 生成私钥、公钥文件 ~/.ssh/id_rsa 和 ~/.ssh/id_rsa.pub
ssh-keygen
// 复制公钥到服务器
scp ~/.ssh/id_rsa.pub deploy@100.10.3.1:
// 末尾要加':',会复制到家目录
// deploy用户登录服务器
// 确认有~/.ssh目录,没有则创建目录和文件,文件存储允许登录的公钥
touch ~/.ssh/authorized_keys
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
// 修改几个目录和文件的权限,只让deploy用户访问
chown -R deploy:deploy ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
禁用密码,禁止根用户登录
这样最安全
// /etc/ssh/sshd_config
PassWordAuthentication 设置为no
PermitRootLogin 设置为no
PHP-FPM
PHP FastCGI Process Manager(PHP FastCGI进程管理器)。它会创建一个主进程(root用户),
控制何时以及如何把HTTP请求转发给一个或多个子进程处理。PHP-FPM还需控制何时创建、销毁PHP子
进程。
全局配置
CentOS主配置文件:/etc/php-fpm.conf
建议修改默认配置:
emergency_restart_threshold = 10
// 指定时间内,失效的PHP-FPM子进程超过这个值,让PHP-FPM主进程优雅重启
emergency_resttart_interval = 1m
// 指定时间跨度
配置进程池
让各个PHP-FPM进程池都以指定的操作系统用户和用户组的身份运行,每个PHP用户一个非根用户,
这样查看和管理都很方便。
Nginx
配置虚拟主机
CentOS: /etc/nginx/conf.d/example.conf
server {
listen 80;
server_name example.com;
index index.php;
client_max_body_size 50M;
error_log /home/deploy/apps/logs/example.error.log;
access_log /home/deploy/apps/logs/example.access.log;
root /home/deploy/apps/example.com;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
}
}
location / {}
使用try_files
指令查找匹配所请求的URI文件,先查询所请求的URI文件,找
不到则查询目录,也找不到会改写URL为index.php开头的,交给location ~ \.php {}
处理。把
请求交给9000端口处理,前面已经设置PHP-FPM监听9000端口。
自动配置服务器
- Puppet
- Chef
- Ansible
- SaltStack
第八章:调优
php.ini文件
一般在/etc/php5/fpm/
, 命令行php运行的是另一个php.ini
文件,一般在/etc/php5/cli/
我也在安装目录下lib找到了这个文件。
内存
memory_limit = 128M
这个值可以考虑总共分配内存,和每个PHP进程占用内存,大概算出。也可以用apache bench或seige
做压测
Zend OPcache
主要是ini文件里一堆opcache开头的配置,用的时候查文档吧
文件上传
file_uploads = 1
upload_max_filesize = 10M
max_file_uploads = 3
默认同时上传20个,每个2M,不很合适。
最长执行时间
max_execution_time = 5
PHP进程最长用时,默认30秒太长了。
如果有长时间运行的任务,要在单独的职程中运行。
PHP中的exec()
函数调用bash的at命令。用于派生单独的非阻塞进程,不耽误当前PHP进程。
exec()
要使用escapeshellarg()
函数转义shell参数。比如要生成一个pdf文件,
需要等待10分钟,应该单独编写一个php文件create_report.php
,让
这个文件运行10分钟。
<?php
exec('echo "create_report.php" | at now');
echo 'Report pending...';
create_report.php
脚本在单独的后台执行,运营完毕后可以更新数据库或者通过电子邮件把
报告发给收件人。
如果要派生很多后台进程,最好用专门的队列。PHPResque等。
处理会话
php默认的会话处理会拖慢大型程序,因为需要把会话数据存储在硬盘。我们应该保存在内存中,使用
memcached或者redis。也便于伸缩,硬盘上数据不适合增加额外服务器。
使用memcashed需要安装PECL扩展,然后更改ini
缓存输出
使用较少的块发送更所数据,下面是等凑够4096字节再发
out_buffering = 4096
implict_flush = false
真实缓存路径
php会缓存应用使用的文件路径,这样每次包含或导入文件时就无需不断搜索包含路径了。这个缓存
叫真实路径缓存。
realpath_cache_size = 64k
第九章:部署
自动部署
- 让部署变得简单
- 部署结果可预知
- 部署可逆
Capistrano
capistrano运行在本地设备,通过ssh与远程服务器通信。
capistrano的工作方式
capistrano会在远程服务器中保存之前部署的应用,而且每次部署的版本放在各自的目录中。
capistrano还会创建一个current/
目录,通过符号连接指向当前部署的应用所在的目录。
当部署应用时,capistrano会首先从git仓库获取最新代码,然后把代码放到realeases/
的一个
新子目录,然后把current/
符号连接指向新目录。
其他工具
- Deployer
- Magallanes
- Rocketeer
第十章:测试
从长远来看,测试省钱,省精力
何时测试
- 开发前:把测试工具当做项目开发的重要依赖
- 开发中,每个功能都要编写并运行测试
- 开发后,编写新测试,确保修补缺陷的方式是正确的
测试什么
单元测试和功能测试
如何测试
- 单元测试:使用PHPUnit或者PHPSpec
- 测试驱动开发(TDD): 编写之前写测试,再开发,然后再写测试,再开发
- 行为驱动开发(BDD): 编写故事,描述应用的表现。
-
SpecBDD:也是单元测试,使用人类能读懂的语言。比如PHPUnit风格测试命名为
testRenderTemplate()
, 等价SpecBDD命名为itRendersTheTemplate()
, 而且会使用诸如
$this->shouldReturn()、$this->shouldbe()
之类易于理解的辅助方法。 -
StoryBDD:类似,但是更多关注整体行为。StoryBDD用于测试产品经理的需求(要生
成报告,并且电子邮件发送给用户),SpecBDD测试开发的需求(这个类方法只能接收一个数组)
-
SpecBDD:也是单元测试,使用人类能读懂的语言。比如PHPUnit风格测试命名为
PHPUnit
术语:PHPUnit测试在一起组成测试用例(test case),测试用例在一起组成测试组件(test suite),
PHPUnit会使用测试运行程序(test runner)运行测试组件。
一个测试用例是一个PHP类(且以Test结尾,文件名以Test.php结尾),扩展自
PHPUnit_Framework_TestCase类。测试用例中有一些以test开头的公开方法,一个方法是一个
测试,在方法中我们断言会发生什么事。
断言可能通过也可能失败,目标是使断言都通过。
测试运行程序默认使用命令行运行程序,调用phpunit命令。
安装
PHPUnit用于测试,用composer安装;XDebug用于生成覆盖度信息,是PHP扩展,用包管理器安装。
紧接着,书中有一个具体的测试用例,用的时候找更详细的blog看看吧
使用Travis CI持续测试
原生提供钩子,可以集成github仓库,每次提交后,都能自动测试,并在多个版本中测试。
第十一章:分析
指的是分析应用的性能。
什么时候使用?
当遇到性能瓶颈时再使用。
分析器种类
- 在开发环境:XDebug。它的结果人类读不懂,需要KCacheGrind或者WinCacheGrind形象化展示。
- 在生产环境:XHprof,使用XHGUI展示结果。
配置
为节省资源,配置成触发执行,具体配置略
接下来讨论的是PHP的未来。
第十二章:HHVM和HACK
HHVM
传统的PHP解释器是Zend Engine, HHVM(Hip Hop Virtual Machiane)由Facebook开发,目的是
提高性能,HHVM先把PHP代码转换成字节码,然后缓存字节码,然后使用JIT编译器(Just in Time)
转换并优化成x86_64机器码。这样传统的解释型语言就有了一些编译型语言的速度。JIT提供了很多
底层性能优化。
HHVM和Zend Engine是等价的。相当于PHP+PHP-FPM。
HHVM配置也是用php.ini文件
推荐使用Supervisord监控,HHVM挂掉后立即重启。
Hack语言
他们把自己看做PHP的方言,为PHP引入了新的数据类型和结构,以及静态类型。
从PHP转向Hack
把<?php
改成<?hh
类型
静态语言,通常都要编译,编译器提供类型检查和错误报告,通常更稳定。缺点是要先编译,反馈回路长。
动态语言,通常解释执行,在运行时发现错误。迭代速度快,反馈及时。缺点是,没有类型检查,缺少
内在的准确性。
hack两者兼有
hack基本兼容PHP
Hack与PHP比较
查了下最新(2017年12月)的情况,PHP7性能卓越,Hack优势不明显了,前景不明。
以上就是这本书的精华,不过瘾的话强烈推荐购买。欢迎交流