一、cgi/fast-cgi/php-fpm
1. cgi
cgi,通用网关协议,它在职责、通信方式、实现要求和安全性上,对 server 和 cgi 程序进行了规范,使得很多语言能在满足 cgi 协议的前提下,和 server 分工合作,实现 web 开发。但 cgi 协议缺少对「server 如何执行 cgi 程序」的规范,使得 cgi 模式下,还停留在 fork-execute-destroy 的模式下,性能抵消。
2. fast-cgi
fast-cgi 主要在「cgi执行方式」和「cgi功能角色」两方面进行了优化。它让 server 和 cgi 以 socket 通信的方式,使得 server 和 cgi 能够单独部署。同时,fast-cgi 协议下,cgi 程序不再是单出的 responser 的角色,还有 authenticate 和 filter 的功能。
3. php-cgi
php-cgi 是 fast-cgi 的一个 php 实现。
4. php-fpm
php-fpm 是 php-cgi 的一个进程管理模型,它以父子进程的方式,让父进程负责:与server通信、加载配置、管理子进程,子进程抢占式获取cgi请求后,负责执行cgi程序获得结果,并返回给父进程。同时,php-fpm提供了平滑终止、平滑启动等进程管理方式。
5. php-fpm 如何平滑终止、平滑重启?
kill -USR2 平滑重启。
kill -INI 平滑终止。
6. nginx 内部执行流程
从 cig 协议上看,server 工作流程:接受客户端 http 请求 -> 选择 cgi 程序处理此请求 -> 将 http 请求转化成 cgi 请求 -> 执行 cgi 程序 -> 得到 cgi 结果响应客户端。
7. nginx 和 php-fpm 通信方式
因为 fast-cgi 中规范了 server 和 cgi 以 socket 方式通信,单独部署。因此,根据 socket 域不同,分为 xxx.sock 本地域和 ip:port 的网络域。在 nginx 中,网络域下直接 upstream 的方式,负载均衡。
8. php-fpm 进程管理方式及适用场景。
- static 静态。启动固定数量个子进程。没有频繁的进程新建和销毁,适合内存、CPU配置高的机器。进程数量=内存/30MB。
- dynamic 动态。进程数量在 min/max/idle 间动态调整。适合配置低的机器,能够有效利用硬件性能。
- 按需。需要多少启动多少。不适合并发突增的业务场景,很少使用。
MySQL
1. 事务问题
- 脏读:B事务读到了A事务未提交的数据。
- 不可重复度:事务A在事务B提交前后,两次读取到的数据不一致。
- 幻读:事务A更新成功后,事务B修改或新增提交后,事务A发现「没有全部更新成功」
2. 事务级别
- 读未提交:存在脏读、不可重复读、幻读;基本不用;
- 读已提交:存在不可重复度、幻读;
- 可重复读:存在幻读;
- 串行化:顺序执行,效率低;
3. MySQL锁
- 锁性质:共享锁 & 排它锁
- 锁粒度:行锁 & 表锁
- 加锁方式:悲观锁 & 乐观锁
- 锁类型:意向锁 & 行锁 & 表锁 & 间隙锁
4. MySQL的RR如何解决幻读?
InnoDB 组合使用行锁Record Lock
和间隙锁Gap Lock
将:索引中,本记录和本记录两侧值锁定了,无法更新和插入,所以没有幻读问题。
5. 悲观锁 & 乐观锁
- 悲观锁,认为别人修改他需要的数据的几率很高,所以一开始就锁住他需要的数据,避免别人更新。如:
select * from xxx where account='123456' for update
。直到它处理完提交事务后才释放。 - 悲观锁,并发性能不好,降低吞吐量。
- 乐观锁,认为别人修改他需要的数据的几率很低,直到
准备提交所做的修改到数据库的时候才会将数据锁住,判断在取数据和更新数据期间是否有人修改过这个数据
,因此会存在不可重复读、幻读等问题。 - 乐观锁,加锁时间短,性能好。