Nginx 配置文件解析
参考文章:浅析 Laravel 官方文档推荐的 Nginx 配置
server { # 代表一个独立的 server
listen 80; # 监听 80 端口
server_name example.com; # 域名配置
root /srv/example.com/public; # 站点根目录,laravel 的要配置到 public 下。
# 添加几条有关安全的响应头;与 Google+ 的配置类似,详情参见文末。
add_header X-Frame-Options "SAMEORIGIN"; # SAMEORIGIN:不允许被本域以外的页面签入,DENY:不允许被任何页面嵌入
add_header X-XSS-Protection "1; mode=block"; # 启用 xss 保护,检查到攻击时,停止渲染页面
add_header X-Content-Type-Options "nosniff"; # 禁用浏览器的类型猜想
index index.php index.html index.htm; # 站点默认页面,可以指定多个,按照顺序匹配。
charset utf-8; # 指定字符集为 utf-8
#laravel 默认重写规则,删除将导致 laravel 路由失效且 nginx 响应为 404
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# 关闭 [/favicon.ico] 和 [/robots.txt] 的访问日志。
# 并且即使它们不存在,也不写入错误日志。
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
# 将 404 错误交给 index.php 处理,使用 laravel 渲染错误页面,否则也可以定义一个页面。
error_page 404 /index.php;
# URI 符合正则表达式 [.php$]的请求将进入此段配置
location ~ .php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; # 配置 FastCGI 服务地址,可以为 IP:端口,也可以为 Unix socket。
fastcgi_index index.php; # 配置 FastCGI 的主页为 index.php。
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; #动态添加了一行 fastcgi 的配置,内容为告知管理进程,cgi 脚本名称。和下面的配置文件不冲突
include fastcgi_params; #引入 fastcgi 配置文件
}
# 除符合正则表达式 [/.(?!well-known).*] 之外的 URI,全部拒绝访问
# 也就是说,拒绝公开以 [.] 开头的目录,[.well-known] 除外
location ~ /.(?!well-known).* {
deny all;
}
}
知识点:
1. try_files
try_files
指令可让 Nginx 按照特定的顺序查找文件。按照以下配置为例:
try_files $uri $uri/ /index.php?$query_string;
假设你正在访问 /api/status?query=example
:
- Nginx 会首先尝试
$uri
是否存在(这是个 Nginx 内置变量,表示请求 URI),也就是/网站根目录/api/status
。 - 如果
$uri
不存在,则尝试$uri/
,也就是/网站根目录/api/status/
。 - 如果
$uri/
也不存在,则最终尝试/index.php?$query_string
($query_string
也是 Nginx 的内置变量,表示 URI 内的查询字符串),也就是/网站根目录/index.php?query=example
。 - 按照 Laravel 的目录结构,
/网站根目录/index.php
是必定存在的,但如果该文件确实不存在,Nginx 将会返回 404。
需要注意的是,严格地说,/api/status
与 /api/status/
这两个 URI 并不指向同一个资源。同理,https://www.google.com
与 https://www.google.com/
也不等效。有兴趣可 Google trailing slash in uri
之类的关键词获取更多细节。
2. fastcgi_pass 中配置的 nginx 和 php-fpm 之间的通信方式
参考文章:
-
unix socket 通信
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
-
tcp socket 通信
fastcgi_pass 127.0.0.1:9000;
区别:
由于 Unix socket 不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。所以其效率比 tcp socket 的方式要高,可减少不必要的 tcp 开销。不过,unix socket 高并发时不稳定,连接数爆发时,会产生大量的长时缓存,在没有面向连接协议的支撑下,大数据包可能会直接出错不返回异常。而 tcp 这样的面向连接的协议,可以更好的保证通信的正确性和完整性。
tcp socket 的优点是可以跨服务器,当 nginx 和 php-fpm 不在同一台机器上时,只能使用这种方式。还是推荐用 TCP Scoket 这种方式。