Jinyun's Notes 🚀

没什么天赋,爱好也不多,但愿坚持做些喜欢的事情

0%

魔术方法

PHP 将所有以 __(两个下划线)开头的类方法保留为魔术方法。所以在定义类方法时,除了心下魔术方法,建议不要以 __ 为前缀

🔥 阅读全文 »

概述

PHP 提供了一种 CLI SAPI - Server Application Programming Interface,服务端应用编程接口的支持,意为 CLI - Command Line Interface,即命令行接口。也是 Web 脚本语言 PHP 在系统命令行(Shell)下的另一种形式,用户可以在系统命令中使用 PHP 编写交互代码

作用

开发外壳应用

CLI SAPI 和其它 SAPI 模块的区别

  • 与 CGI SAPI 不同,其输出没有任何头信息
  • CLI SAPI 强制覆盖了 php.ini 中的某些设置,因为这些设置在外壳环境下是没有意义
  • 为了减轻外壳环境下的工作,定义了如下常量
名称描述备注
STDIN一个已打开的指向 stdin 的流,调用方法:$stdin = fopen('php://stdin', 'r');
STDOUT一个已打开的指向 stdout 的流,调用方法:$stdout = fopen(‘php://stdout’, ‘w’);
STDERR一个已打开的指向 stderr 的流, 调用方法:$stderr = fopen(‘php://stderr’, ‘w’);
  • CLI SAPI 不会将当前目录改为已运行的脚本所在的目录

CLI SAPI 模块的三种运行方式

让 PHP 运行指定文件

1
2
3
$ php test.php
或者
$ php -f test.php

在命令行直接运行 PHP 代码

1
$ php -r 'print_r(get_defined_constants());'

通过标准输入 stdin 提供需要运行的 PHP 代码

PHP CLI 应用场景

多线程应用

  • 使用多进程,子进程结束以后,内核会负责回收资源
  • 使用多进程,子进程异常退出不会导致整个进程 Thread 退出,父进程还有机会重建流程
  • 一个常驻主进程,只负责任务分发,逻辑理清楚

定时执行 PHP 程序

利用 Linux 的 crontab 命令,文件路径建议使用绝对路径。

1
2
3
4
5
<?php

// The task you plan to perform

echo 'PHP is the best programming language.';
1
2
3
4
5
6
$ crontab -e
// 每分钟执行一次脚本并且输出
* * * * * /usr/bin/php /usr/local/src/test.php

// 每分钟执行一次脚本并且在后台运行
* * * * * /usr/bin/php /usr/local/src/test.php >/dev/null 2>&1

开发桌面程序

使用 PHP CLI 和 GTK 包。

Linux 下编写 PHP 的 Shell 脚本

PHP CLI 实例

PHP CLI 进阶

PHP 实现两个日期之间相差的几年、几月、几日……,可以采用 PHP 内置的类 DateTime 和函数 strtotime() 实现,推荐使用内置类 DateTime 去实现,DateTime 把每个月天数的差异自动处理了,使用 strtotime() 函数需要自行处理。

🔥 阅读全文 »

概念

Persistent HTTP connections have a number of advantages

HTTP 协议采用请求-应答模式,当使用普通模式,即非 KeepAlive 模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP 协议为无连接的协议);当使用 Keep-Alive 模式(又称持久连接/连接重用)时,Keep-Alive 功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive 功能避免了建立或者重新建立连接。

支持 keep alive

当使用 nginx 作为反向代理时,为了支持长连接,需要做到两点

  • 从 client 到 nginx 的连接是长连接
  • 从 nginx 到 server 的连接是长连接

保持和 client 的长连接

  • client 发送的 HTTP 请求要求 keep alive
  • nginx 设置上支持 keep alive

HTTP 配置

keepalive_timeout

默认 75s,一般情况下也够用,对于一些请求比较大的内部服务器通讯的场景,适当加大为 120s 或者 300s。第二个参数通常可以不用设置

第一个参数设置 keep-alive 客户端连接在服务器端保持开启的超时值。值为 0 会禁用 keep-alive 客户端连接。可选的第二个参数在响应的 header 域中设置一个值 Keep-Alive: timeout=time。这两个参数可以不一样

keepalive_requests

默认 100,对于 QPS 较高的场景,非常有必要加大这个参数,以避免出现大量连接被生成再抛弃的情况,减少 TIME_WAIT。这个参数的真实含义是指一个 keep alive 建立之后,nginx 就会为这个连接设置一个计数器,记录这个 keep alive 的长连接上已经接收并处理的客户端请求的数量。如果达到这个参数设置的最大值时,则 nginx 会强行关闭这个长连接,逼迫客户端不得不重新建立新的长连接

用于设置一个 keep-alive 连接上可以服务的请求的最大数量。当最大请求数量达到时,连接被关闭

保持和 server 的长连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
http {
keepalive_timeout 100s;
keepalive_requests 1000;

upstream dev.proxy.com {
server 192.168.10.11:8081 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.10.10:8081 weight=1 max_fails=2 fail_timeout=30s;
keepalive 300;
}

server {
listen 80 default_server;
listen [::]:80 ipv6only=on;
server_name dev.proxy.com;
charset utf-8;

location / {
index index.php index.html index.htm;
proxy_pass http://dev.proxy.com/;
proxy_set_header Host $Host;
proxy_set_header x-forwarded-for $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
add_header Cache-Control no-store;
add_header Pragma no-cache;
proxy_http_version 1.1;
proxy_set_header Connection "";

client_max_body_size 3072k;
client_body_buffer_size 128k;
}
}
}

合理的设置 keep-alive 值可以非常有效的缓冲请求和应答不均匀,缓解连接数量的反复震荡

连接数量震荡的两个表现

  • 连接不够用,造成新建连接
  • 连接空闲,造成关闭连接

统计在一台前端机上高峰时间 TCP 连接的情况

1
$ netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a,S[a]}'

导致 nginx 端出现大量 TIME_WAIT 的两种情况

  • keepalive_requests 设置比较小,高并发下超过此值后 nginx 会强制关闭和客户端保持的keepalive 长连接(主动关闭连接后导致 nginx 出现 TIME_WAIT)
  • keepalive 设置的比较小(空闲数太小),导致高并发下 nginx 会频繁出现连接数震荡(超过该值会关闭连接),不停的关闭开启和后端 server 保持的 keep-alive 长连接

导致后端 server 端出现大量 TIME_WAIT 的情况

  • nginx 没有打开和后端的长连接,即:没有设置 proxy_http_version 1.1; 和proxy_set_header Connection ""; 从而导致后端 server 每次关闭连接,高并发下就会出现 server 端出现大量 TIME_WAIT