NGINX 从入门到精通,学会这些就够了

https://learnku.com/articles/46237

工作这么多年一直用的都是 NGINX,也一直想写总结,不过之前都是在上班,下班后就比较懒了,所以一直搁置着,趁着现在离职了有时间,就想把之前欠下的都补上,也算是对自己近年来工作技能的总结,希望这篇文章能帮助到你。

什么是 nginx
Nginx(发音同 “engine X”)是异步框架的网页服务器,也可以用作反向代理、负载平衡器和 HTTP 缓存。该软件由伊戈尔・赛索耶夫创建并于 2004 年首次公开发布。2011 年成立同名公司以提供支持。2019 年 3 月 11 日,Nginx 公司被 F5 Networks 以 6.7 亿美元收购。

nginx 的应用场景
反向代理服务器
负载均衡服务器
HTTP 缓存服务器
与 PHP 集成
nginx 安装下载 nginx_modules(ps: 编译的时候会用到)
链接: pan.baidu.com/s/1MjVdVkF4EAjhPfLIm... 密码: wwgb
#!/usr/bin/env bash

DIR=/Users/shiwenyuan/webserver
mkdir -p $DIR
cd $DIR
mkdir run

tar -zxvf /Users/shiwenyuan/totalXbox/project/phpstorm/xlegal/devops/opbin/nginx_modules.tgz -C $DIR

mkdir tmp
cd tmp

wget http://nginx.org/download/nginx-1.8.1.tar.gz -O nginx-1.8.1.tar.gz

tar -zxvf nginx-1.8.1.tar.gz

cd nginx-1.8.1

./configure
--with-http_realip_module
--with-http_stub_status_module
--with-http_addition_module
--add-module=$DIR/nginx_modules/echo-nginx-module-master
--add-module=$DIR/nginx_modules/headers-more-nginx-module-master
--add-module=$DIR/nginx_modules/memc-nginx-module-master
--add-module=$DIR/nginx_modules/nginx-http-concat-master
--add-module=$DIR/nginx_modules/ngx_devel_kit-master
--add-module=$DIR/nginx_modules/ngx_http_consistent_hash-master
--add-module=$DIR/nginx_modules/ngx_http_enhanced_memcached_module-master
--add-module=$DIR/nginx_modules/ngx_http_upstream_ketama_chash-0.6
--add-module=$DIR/nginx_modules/srcache-nginx-module-master
--with-pcre=$DIR/nginx_modules/pcre-8.38
--prefix=$DIR
if [[ $? -ne 0 ]];then
echo 'error occured '
exit 1
fi
make && make install
cd $DIR
/bin/rm -rf tmp
/bin/rm -rf node_modules

/sbin/nginx -t
nginx 命令行常用命令
nginx # 启动 nginx
nginx -s reload # 向主进程发送信号,重新加载配置文件,热重启
nginx -s reopen # 重启 Nginx
nginx -s stop # 快速关闭
nginx -s quit # 等待工作进程处理完成后关闭
nginx -t # 查看当前 Nginx 配置是否有错误
nginx -t -c <配置路径> # 检查配置是否有问题,如果已经在配置目录,则不需要 - c
nginx 配置文件详解线上应用常常都是一个 nginx 上面会配置好几个域名,每个域名都会放到一个单独的配置文件里。然后在 nginx.conf 中引用这些文件,所以可以理解为每次 nginx 启动的时候都会默认加载 nginx.conf,nginx.conf 会把相关的 server 配置都引用进来形成一个大的 nginx 文件。


main: 全局设置
events: 配置影响 Nginx 服务器或与用户的网络连接
http:http 模块设置
upstream: 负载均衡设置
server:http 服务器配置,一个 http 模块中可以有多个 server 模块
location:url 匹配配置,一个 server 模块中可以包含多个 location 模块
一个 nginx 配置文件的结构就像 nginx.conf 显示的那样,配置文件的语法规则:

配置文件由模块组成
使用#添加注释
使用 $ 使用变量
使用 include 引用多个配置文件
nginx 与 php 通信
访问路径

www.example.com/index.php
|
|
Nginx
|
|
php-fpm监听127.0.0.1:9000地址
|
|
www.example.com/index.php请求转发到127.0.0.1:9000
|
|
nginx的fastcgi模块将http请求映射为fastcgi请求
|
|
php-fpm监听fastcgi请求
|
|
php-fpm接收到请求,并通过worker进程处理请求
|
|
php-fpm处理完请求,返回给nginx
|
|
nginx 与 php 通信方式
tcp-socket
tcp socket 通信方式,需要在 nginx 配置文件中填写 php-fpm 运行的 ip 地址和端口号,该方式支持跨服务器,即 nginx 和 php-fpm 不再同一机器上时。

location ~ .php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
unix-socket
unix socket 通信方式,需要在 nginx 配置文件中填写 php-fpm 运行的 pid 文件地址。unix socket 又叫 IPC(inter process communication 进程间通信)socket,用于实现统一主机上进程间通信。

location ~ .php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
}
两者间的区别
Unix socket 不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。所以其效率比 tcp socket 的方式要高,可减少不必要的 tcp 开销。不过,unix socket 高并发时不稳定,连接数爆发时,会产生大量的长时缓存,在没有面向连接协议的支撑下,大数据包可能会直接出错不返回异常。而 tcp 这样的面向连接的协议,可以更好的保证通信的正确性和完整性。

所以,如果面临的是高并发业务,则考虑优先使用更可靠的 tcp socket,我们可以通过负载均衡、内核优化等手段来提供效率。

nginx 配置动静分离
什么是动静分离
在 Web 开发中,通常来说,动态资源其实就是指那些后台资源,而静态资源就是指 HTML,JavaScript,CSS,img 等文件。
在使用前后端分离之后,可以很大程度的提升静态资源的访问速度,同时在开发过程中也可以让前后端开发并行可以有效的提高开发时间,也可以有效的减少联调时间 。

动静分离方案
直接使用不同的域名,把静态资源放在独立的云服务器上,这个种方案也是目前比较推崇的。
动态请求和静态文件放在一起,通过 nginx 配置分开
server {
location /www/ {
root /www/;
index index.html index.htm;
}

location /image/ {
root /image/;
}
}
nginx 配置反向代理
反向代理常用于不想把端口暴露出去,直接访问域名处理请求。

server {
listen 80;
server_name www.phpblog.com.cn;
location /swoole/ {
proxy_pass http://127.0.0.1:9501;
}
location /node/ {
proxy_pass http://127.0.0.1:9502;
}

}
nginx 配置负载均衡
upstream phpServer{
server 127.0.0.1:9501;
server 127.0.0.1:9502;
server 127.0.0.1:9503;
}
server {
listen 80;
server_name www.phpblog.com.cn;
location / {
proxy_pass http://phpServer;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_next_upstream error timeout invalid_header;
proxy_max_temp_file_size 0;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
常见的负载均衡策略
round-robin / 轮询: 到应用服务器的请求以 round-robin / 轮询的方式被分发
upstream phpServer{
server 127.0.0.1:9501 weight=3;
server 127.0.0.1:9502;
server 127.0.0.1:9503;
}
在这个配置中,每 5 个新请求将会如下的在应用实例中分派: 3 个请求分派去 9501, 一个去 9502, 另外一个去 9503.

least-connected / 最少连接:下一个请求将被分派到活动连接数量最少的服务器
upstream phpServer{
least_conn;
server 127.0.0.1:9501;
server 127.0.0.1:9502;
server 127.0.0.1:9503;
}
当某些请求需要更长时间来完成时,最少连接可以更公平的控制应用实例上的负载。

ip-hash/IP 散列: 使用 hash 算法来决定下一个请求要选择哪个服务器 (基于客户端 IP 地址)
upstream phpServer{
ip_hash;
server 127.0.0.1:9501;
server 127.0.0.1:9502;
server 127.0.0.1:9503;
}
将一个客户端绑定给某个特定的应用服务器;

nginx 配置跨域
由于浏览器同源策略的存在使得一个源中加载来自其它源中资源的行为受到了限制。即会出现跨域请求禁止。
所谓同源是指:域名、协议、端口相同。

server {
listen 80;
server_name www.phpblog.com.cn;
root /Users/shiwenyuan/blog/public;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT, PATCH';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-XSRF-TOKEN';

location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
Access-Control-Allow-Origin:允许的域名,只能填 *(通配符)或者单域名。
Access-Control-Allow-Methods: 允许的方法,多个方法以逗号分隔。
Access-Control-Allow-Headers: 允许的头部,多个方法以逗号分隔。
Access-Control-Allow-Credentials: 是否允许发送 Cookie。
nginx 配置 https此处可以参考我之前写的一篇文章
nginx 配置 https 证书认证
nginx 伪静态
应用场景
seo 优化
安全
流量转发
location ^~ /saas {
root /home/work/php/saas/public;
index index.php;
rewrite ^/saas(/[^?]*)?((?.*)?)$ /index.php$1$2 last;
break;
}
日常工作中的奇淫技巧
日志切割脚本
#!/bin/bash
#设置你的日志存放的目录
log_files_path="/mnt/usr/logs/"
#日志以年/月的目录形式存放
log_files_dir=${log_files_path}"backup/"
#设置需要进行日志分割的日志文件名称,多个以空格隔开
log_files_name=(access.log error.log)
#设置nginx的安装路径
nginx_sbin="/mnt/usr/sbin/nginx -c /mnt/usr/conf/nginx.conf"
#Set how long you want to save
save_days=10

############################################
#Please do not modify the following script #
############################################
mkdir -p $log_files_dir

log_files_num=${#log_files_name[@]}
#cut nginx log files
for((i=0;i<$log_files_num;i++));do
mv ${log_files_path}${log_files_name[i]} ${log_files_dir}${log_files_name[i]}_$(date -d "yesterday" +"%Y%m%d")
done
$nginx_sbin -s reload
图片防盗链
server {
listen 80;
server_name *.phpblog.com.cn;

# 图片防盗链
location ~* .(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers none blocked server_names ~.google. ~.baidu. *.qq.com;
if ($invalid_referer){
return 403;
}
}
}
nginx 访问控制
location ~ .php$ {
allow 127.0.0.1; #只允许127.0.0.1的访问,其他均拒绝
deny all;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
丢弃不受支持的文件扩展名的请求
location ~ .(js|css|sql)$ {
deny all;
}
后话
创作不易,希望对你有所帮助。
如果本篇博客有任何错误,请批评指教,不胜感激!!!

文章将持续更新中,也可以通过微信搜索 [石先生的私房菜] 或者下方二维码关注第一时间阅读和催更,除了博客以外还会定期发送 leetcode 的 php版题解。

2020-06-22: 感谢 @轻描淡写提交了一处错别字,已修正。
2020-06-24: 感谢 @Jiannei 提交了一处错别字,已修正。
2020-07-03: 感谢 @bigbug 提交的文字优化,已修正。
2020-07-03: 感谢 @MasterPoser 提交的文字优化,已修正。

————————————————
原文作者:北行
转自链接:https://learnku.com/articles/46237
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请保留以上作者信息和原文链接。

原文地址:https://www.cnblogs.com/linus-tan/p/14836176.html