PHP 是一种流行的通用脚本语言,特别适合于 Web 开发。
PHP 快速,灵活且实用,为您的博客到世界上最受欢迎的网站提供了强大的支持。
本文在 Debian 系统中通过添加源的方式,apt 安装最新版(或者指定版本) PHP 和相关组件。
Nginx
Nginx 是一个异步框架的 Web 服务器,也可以用作反向代理,负载平衡器和 HTTP 缓存。该软件由 Igor Sysoev 创建,并于 2004 年首次公开发布。同名公司成立于 2011 年,以提供支持。Nginx 是一款免费的开源软件,根据类 BSD 许可证的条款发布
安装
安装先决条件:
apt install curl gnupg2 ca-certificates lsb-release
要为稳定的 nginx 软件包设置 apt 仓库,请运行以下命令:
echo "deb http://nginx.org/packages/debian `lsb_release -cs` nginx" \
| tee /etc/apt/sources.list.d/nginx.list
curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
验证您现在是否具有正确的密钥:
apt-key fingerprint ABF5BD827BD9BF62
输出应包含完整指纹 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62
如下:
pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62
uid [ unknown] nginx signing key
要安装 nginx,请运行以下命令:
sudo apt update
sudo apt install nginx
常用命令
开机启动
systemctl enable nginx
重启
systemctl restart nginx
检查配置是否正确
nginx -t
热加载(不重启的情况下刷新配置)
nginx -s reload
安装 PHP-fpm
在 Debian 10 / Debian 9 上安装 PHP 7.4
apt update
安装以下软件包
sudo apt install -y curl wget gnupg2 ca-certificates lsb-release apt-transport-https
使用以下命令导入密钥
wget https://packages.sury.org/php/apt.gpg
sudo apt-key add apt.gpg
将 SURY 存储库添加到系统
sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
更新存储库索引
sudo apt update
使用以下命令安装 PHP 7.4
apt install -y php7.4-fpm
nginx链接php
server {
# 其他代码
location ~* \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
安装 PHP 扩展
PHP 扩展为您的代码启用了特定的功能和支持。 例如,安装 PHP MySQL 扩展将使您的 PHP 代码与 MySQL 数据库连接。
要安装 MySQL 对 PHP 7.4 的支持,可以安装 php7.4-mysql 软件包
sudo apt install -y php7.4-mysql
CMS 的 PHP 常用扩展
WordPress 的 PHP 扩展
需要以下扩展,才能在 Debian 系统上安装和运行 WordPress。
WordPress 建议安装 PHP 7.3 或更高版本
apt install -y \
php7.4-mysql \
php7.4-dom \
php7.4-simplexml \
php7.4-ssh2 \
php7.4-xml \
php7.4-xmlreader \
php7.4-curl \
php7.4-exif \
php7.4-ftp \
php7.4-gd \
php7.4-iconv \
php7.4-imagick \
php7.4-json \
php7.4-mbstring \
php7.4-posix \
php7.4-sockets \
php7.4-tokenizer
Typecho 的 PHP 扩展
需要以下扩展,才能在 Debian 系统上安装和运行 Typecho。
Typecho 建议安装 PHP5.1 或更高版本
apt install -y \
php7.4-xml \
php7.4-curl \
php7.4-mysql \
php7.4-mbstring
Joomla 的 PHP 扩展
需要以下扩展,才能在 Debian 系统上安装和运行 Joomla。
Joomla 需要 PHP v7.1 或更高版本
apt install -y \
php7.4-mysql \
php7.4-xml \
php-pear \
php7.4-json
Drupal 的 PHP 扩展
以下扩展是在 Debian 系统上安装和运行 Drupal 所必需的。
Drupal 需要 PHP v7.1 或更高版本
apt install -y \
php7.4-mysql \
php7.4-dom \
php7.4-gd \
php7.4-json \
php7.4-pdo \
php7.4-simplexml \
php7.4-tokenizer \
php7.4-xml
Nginx性能调优
适用于nginx Vhost虚拟主机 生产环境
nginx.conf 文件配置
配置依据 nginx/1.20.1 进行配置
首先备份文件
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
用户身份
默认为www-data:www-data
可以按需创建用户
注意用户需要和php-fpm中listen.owner1
和 listen.group
用户一致
user www-data www-data;
优化 Nginx worker 进程数
worker_processes auto;
默认情况下,Nginx 的多个进程有可能跑在某一个 CPU 或 CPU 的某一核上,导致 Nginx 进程使用硬件的资源不均,因此绑定 Nginx 进程到不同的 CPU 上是为了充分利用硬件的多 CPU 多核资源。
建议修改这个配置为:
[root@localhost ~]# grep -c processor /proc/cpuinfo # 查看CPU核数
2
worker_processes 2; # 2核CPU的配置
worker_cpu_affinity 01 10;
worker_processes 4; # 4核CPU的配置
worker_cpu_affinity 0001 0010 0100 1000;
worker_processes 8; # 8核CPU的配置
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 1000000;
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
高层的配置
nginx.conf
文件中,Nginx中有少数的几个高级配置在模块部分之上。
worker_rlimit_nofile 100000;
user和pid应该按默认设置 - 我们不会更改这些内容,因为更改与否没有什么不同。
worker_rlimit_nofile 更改worker进程的最大打开文件数限制。如果没设置的话,这个值为操作系统的限制。设置后你的操作系统和Nginx可以处理比“ulimit -a”更多的文件,所以把这个值设高,这样nginx就不会有“too many open files”问题了。
Events模块
events模块中包含nginx中所有处理连接的设置。
events {
worker_connections 2048;
multi_accept on;
use epoll;
}
worker_connections设置可由一个worker
进程同时打开的最大连接数。如果设置了上面提到的worker_rlimit_nofile
,我们可以将这个值设得很高。
记住,最大客户数也由系统的可用socket连接数限制(~ 64K)
,所以设置不切实际的高没什么好处。
multi_accept告诉nginx
收到一个新连接通知后接受尽可能多的连接。
use 设置用于复用客户端线程的轮询方法。如果你使用Linux 2.6+
,你应该使用epoll
。如果你使用*BSD
,你应该使用kqueue
。想知道更多有关事件轮询?看下维基百科吧(注意,想了解一切的话可能需要neckbeard和操作系统的课程基础)
(值得注意的是如果你不知道Nginx该使用哪种轮询方法的话,它会选择一个最适合你操作系统的)
HTTP 模块
HTTP模块控制着nginx http处理的所有核心特性。因为这里只有很少的配置,所以我们只节选配置的一小部分。所有这些设置都应该在http模块中,甚至你不会特别的注意到这段设置。
http {
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
...
}
server_tokens 并不会让nginx
执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的。
sendfile可以让sendfile()
发挥作用。sendfile()
可以在磁盘和TCP socket
之间互相拷贝数据(或任意两个文件描述符)。Pre-sendfile是传送数据之前在用户空间申请数据缓冲区。之后用read()将数据从文件拷贝到这个缓冲区,write()
将缓冲区数据写入网络。
sendfile()是立即将数据从磁盘读到OS缓存。因为这种拷贝是在内核完成的,sendfile()
要比组合read()
和write()
以及打开关闭丢弃缓冲更加有效(更多有关于sendfile)
tcp_nopush告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送
tcp_nodelay告诉nginx不要缓存数据,而是一段一段的发送--当需要及时发送数据时,就应该给应用设置这个属性,这样发送一小块数据信息时就不能立即得到返回值。
日志
参考链接 https://segmentfault.com/a/1190000013377493
error_log /var/log/nginx/error.log notice;
level
可以是debug
, info
, notice
, warn
, error
, crit
, alert
,emerg
中的任意值。可以看到其取值范围是按紧急程度从低到高排列的。只有日志的错误级别等于或高于level指定的值才会写入错误日志中。默认值是error
access_log /var/logs/nginx-access.log buffer=32k gzip flush=1m;
访问日志主要记录客户端的请求。客户端向Nginx服务器发起的每一次请求都记录在这里。客户端IP,浏览器信息,referer,请求处理时间,请求URL等都可以在访问日志中得到。当然具体要记录哪些信息,你可以通过log_format指令定义。
access_log off;
error_log /var/log/nginx/error.log crit;
access_log设置nginx是否将存储访问日志。关闭这个选项可以让读取磁盘IO操作更快(aka,YOLO)
error_log告诉nginx只能记录严重的错误
一个完整的配置 Demo
#用户设置
user www-data www-data;
#CPU线程设置
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
pid /var/run/nginx.pid;
worker_rlimit_nofile 100000;
events {
worker_connections 2048;
multi_accept on;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
#日志配置
access_log off;
error_log /webstaion/logs/nginx/error.log crit;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 10;
client_header_timeout 10;
client_body_timeout 10;
reset_timedout_connection on;
send_timeout 10;
#压缩配置
gzip on;
gzip_disable "msie6";
gzip_proxied any;
gzip_min_length 1000;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
#文件缓存
open_file_cache max=100000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
#防止攻击配置
#用户的 IP 地址作为 Key,每个 IP 地址最多有 10 个并发连接 否则返回 503
#limit_conn_zone $binary_remote_addr zone=TotalConnLimitZone:10m ;
#limit_conn TotalConnLimitZone 10;
#limit_conn_log_level notice;
#用户的 IP 地址作为 Key,每个 IP 地址每秒处理 10 个请求
#limit_req_zone $binary_remote_addr zone=ConnLimitZone:10m rate=10r/s;
#limit_req_log_level notice;
#Vhost配置
include /etc/nginx/conf.d/*.conf;
}
注意防攻击配置中使用以下方法启用
location ~ \.php$ {
#防止攻击应用
limit_req zone=ConnLimitZone burst=5 nodelay;
...其他配置...
}
PHP7.4-fpm性能调优
生产之前最基本就是安全
安全配置
多用户多个vhost虚拟主机安全配置
1.创建vhost专用用户和组
groupadd webstation
useradd -g webstation webstation
以上命令创建了名为为webstation
用户和同名组
2.创建vhost目录
自定义一个网站根目录,常用根目录为
/home/[username]/wwwroot/
/var/www/html
...
本文在根目录创建
mkdir -p /webstation/www/public_html
mkdir -p /webstation/www/conf
mkdir -p /webstation/www/logs
然后准备好上好的文件 部署解压到 public_html
下
3.设定目录权限
文件准备好后使用以下命令设定目录权限归属
chown -R webstation:webstation /webstation/www
4.部署好的文件权限检查
注意777这种权限的问题
php.sock 文件准备
默认的配置我们不动,我们使用新的sock文件来配置
如正确安装好php7.4-fpm后 配置文件位置应该如下
/etc/php/7.4/fpm/pool.d/www.conf
编译安装的按编译时的路径,找不到可以find
一下
find / -name www.conf
确定位置后 复制一份
1.准备配置文件
cp /etc/php/7.4/fpm/pool.d/www.conf /etc/php/7.4/fpm/pool.d/webstation.conf
2.修改配置
按需修改
; pool name ('www' here)
[webstation] #pool名称
...
user = webstation #使用上一步建立的用户名
group = webstation #使用上一步建立的用户名
...
;这里的名称随意但一定要自定义不能和默认www中冲突
listen = /run/php/php7.4-webstation.sock ...
;此处用户和组需和nginx使用的用户和组一致
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
...
其他配置按需
3.配置检查
php-fpm7.4 -t
无问题的话重启php
systemctl restart php7.4-fpm
4.防跨站 跨目录
网站根目录下增加 .user.ini
文件。
在php.ini
中找到
user_ini.filename
ser_ini.cache_ttl
去掉前面的分号。
也就是说我们可以通过.user.ini这种形式来对每一个网站甚至是每一个目录设置open_basedir属性值
首先修改php.ini,去掉user_ini.filename和user_ini.cache_ttl前面的分号。
open_basedir=/webstaion/nginx/public_html:/tmp/:/proc/