Joyber 的博客 - nginx
type: channel
link: https://blog.qqvbc.com/tag/nginx/
items: nginx 配置调优参数 参考
items: nginx 配置 PHP 的时候出现 File not found 疑难问题解决方法
items: sed 处理nginx访问日志，提取客户端IP地址
items: nginx 记录 客户端IP和CDN IP
items: samba 集成DEV开发环境 php 监控某目录下文件变动，自动执行某些命令操作 重启nginx ，nginx 实现动态域名，动态配置加载
items: 在 Nginx 中将爬虫过来的请求转到指定的后端服务
items: ERR_INCOMPLETE_CHUNKED_ENCODING 错误
items: nginx增加图片处理能力的方法
items: nginx 封IP 禁止IP/IP段访问
items: nginx 批量的禁止访问

nginx 配置调优参数 参考
type: item
date: 2021-07-16T10:02:00+08:00
description: 语法： sendfile on | off; 默认值： sendfile off; 上下文： http，server，location，if in location }指定是否使用sendfile系统调用来传输文件。sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作)，从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝，操作效率很高，被称之为零拷贝。参考文章：https://www.jianshu.com/p/70e1c396c320Syntax: tcp_nopush on | off; Default: tcp_nopush off; Context: http, server, locationTCP_NOPUSH 是 FreeBSD 的一个 socket 选项，对应 Linux 的 TCP_CORK，Nginx 里统一用 tcp_nopush 来控制它，并且只有在启用了 sendfile 之后才生效。启用它之后，数据包会累计到一定大小之后才会发送，减小了额外开销，提高网络效率。Syntax: tcp_nodelay on | off; Default: tcp_nodelay on; Context: http, server, locationTCP_NODELAY 也是一个 socket 选项，启用后会禁用 Nagle 算法，尽快发送数据，某些情况下可以节约 200ms（Nagle 算法原理是：在发出去的数据还未被确认之前，新生成的小数据先存起来，凑满一个 MSS 或者等到收到确认后再发送）。Nginx 只会针对处于 keep-alive 状态的 TCP 连接才会启用 tcp_nodelay。当连接转换为keep-alive状态时，启用该选项。此外，它在SSL连接上启用，用于无缓冲代理和WebSocket代理。可以看到 TCP_NOPUSH 是要等数据包累积到一定大小才发送，TCP_NODELAY 是要尽快发送，二者相互矛盾。实际上，它们确实可以一起用，最终的效果是先填满包，再尽快发送。官方文档参考：http://nginx.org/en/docs/http/ngx_http_core_module.html#tcp_nodelaySyntax: keepalive_timeout timeout [header_timeout]; Default: keepalive_timeout 75s; Context: http, server, location第一个参数设置一个超时，在这个超时期间，保持活动的客户端连接将在服务器端保持打开。0值禁用保持连接的客户端连接。第二个可选参数在Keep-Alive: timeout=time响应报头字段中设置一个值。两个参数可能不同。Keep-Alive: timeout=time报头字段被Mozilla和Konqueror识别。MSIE会在大约60秒内自行关闭保持连接。keepalive_timeout 60;fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 256k; fastcgi_intercept_errors on;fastcgi模块参数gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_disable "MSIE [1-6]\.";开启gzip压缩server_tokens off;启用或禁用在错误页面和服务器响应报头字段中发出nginx版本。build参数(1.11.10)允许随nginx版本一起发出build名称。此外，作为我们商业订阅的一部分，从版本1.9.13开始，错误页面上的签名和服务器响应头字段值可以使用变量字符串显式设置。空字符串禁止发送Server字段。map $http_x_forwarded_for $cli…

nginx 配置 PHP 的时候出现 File not found 疑难问题解决方法
type: item
date: 2021-07-08T11:46:00+08:00
description: 环境 centos8，编译方式安装的nginx/1.20.1, php 是dnf安装的php/7.2.24nginx 执行用户、php 执行用户、文件权限都检查了，确定没有问题nginx 的php配置也确定没有问题，但就是访问php页面出现 File not found查看nginx报错内容，看到如下错误："Primary script unknown"2021/07/07 20:40:02 [error] 8853#0: *164 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 192.168.1.95, server: localhost, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/run/php-fpm/www.sock:", host: "192.168.1.69"最终解决的方法：#/www/wwwroot/phpwebdir/是我的网站根目录 chcon -R -t httpd_sys_content_t /www/wwwroot/phpwebdir/ chcon -R -t httpd_sys_content_t /www/server/nginx/sbin/nginx /www/server/nginx/sbin/nginx -s reload原因是selinux 在作祟，如上命令是配置 网站目录和nginx执行文件的 selinux 上下文具体selinux这个安全机制至今还没有搞明白咋玩用以下命令可以查看文件或目录的上下文ll -dZ /www/wwwroot/phpwebdir/修改之前是drwxrw-rw-. 7 www www unconfined_u:object_r:admin_home_t:s0 4096 Jul 7 20:28 /www/wwwroot/phpwebdir/修改之后是drwxrw-rw-. 7 www www unconfined_u:object_r:httpd_sys_content_t:s0 4096 Jul 7 20:28 /www/wwwroot/phpwebdir/或者干脆关闭selinux（需要重启服务器）/etc/selinux/config ：SELINUX=disabled

sed 处理nginx访问日志，提取客户端IP地址
type: item
date: 2021-06-16T09:55:00+08:00
description: 现在被恶意请求了，把恶意请求单独打到一个日志文件，然后提取客户端IP，去重，然后封掉这些IP创建文件vim filterIp.sh文件内容#! /bin/bash sed 's/src:\([0-9\.]\+\).*/\1/g' $1 | sort -n | uniq用这个脚本处理日志文件, 提取到客户端IP，这些IP是排序，去重了的chmod a+x filterIp.sh ./filterIp.sh xxx.log我的 xxx.log 的日志格式是这样的，如果保存日志不一样，则需要改一下 filterIp.sh 中的sed处理规则src:60.173.147.155 cdn:58.215.115.71 - [16/Jun/2021:10:02:01 +0800] "GET /xx.html?xx3 HTTP/1.1" 403 564 "xx" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)"

nginx 记录 客户端IP和CDN IP
type: item
date: 2020-07-24T15:29:16+08:00
description: http {} 中：map $http_x_forwarded_for $clientRealIp { "" $remote_addr; ~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr; } log_format main 'src:$clientRealIp cdn:$remote_addr $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent"'; access_log logs/access.log main;

samba 集成DEV开发环境 php 监控某目录下文件变动，自动执行某些命令操作 重启nginx ，nginx 实现动态域名，动态配置加载
type: item
date: 2020-07-24T11:02:00+08:00
description: 测试环境：centos 7系统，预先安装好bt 宝塔系统，安装好samba，宝塔里面安装好 lnmp软件，php设置 取消 exec 函数限制：将www用户添加到dev组usermod -G dev wwwphp 写了一个脚本，实现监控目录下文件的变量，然后重启nginx的例子：<?php class NginxRewrite { public $dir = "/www/wwwroot/"; private $files = []; public function __construct() { $this->files = $this->readDir(); } public function run() { $oldFiles = $this->files; while (true) { $_files = $this->readDir(); foreach ($_files as $f=>$t) { if (!isset($oldFiles[$f]) || $oldFiles[$f]!=$t) { $oldFiles = $_files; @exec("nginx -t", $out, $status); if ($status === 0) { echo "rewrite change, nginx reload\n"; @exec("nginx -s reload"); } break; } } sleep(10); } } //目录目标目录 private function readDir($dir = null) { $dir = $dir ? $dir : $this->dir; $files = scandir($dir); $deep = count(explode(DIRECTORY_SEPARATOR, $this->dir)); //var_dump($deep); $res = []; foreach ($files as $file) { if ($file == '..' || $file == '.') continue; $_path = rtrim($dir, '\\/') . DIRECTORY_SEPARATOR . $file; $_deep = count(explode(DIRECTORY_SEPARATOR, $_path)); if (is_dir($_path) && $_deep - $deep < 2) { //var_dump($_deep - $deep, $_path); $res = array_merge($res, $this->readDir($_path)); } elseif (is_file($_path) && preg_match("/nginx\.htaccess$/", $file)) { $res[$_path] = filemtime($_path); } } return $res; } } $mod = new NginxRewrite(); $mod->run(); nginx 实现了动态域名，动态加载用户的匹配文件的方法/root/nginx_config_tpl/www.nginx.tplserver { listen 80; server_name ~^(\w+)\.USER_NAME\.tell520\.com$; set $www $1; index index.php index.html index.htm default.php default.htm default.html; root /www/wwwroot/USER_NAME/$www; #SSL-START SSL相关配置，请勿删除或修改下一行带注释的404规则 #error_page 404/404.html; #SSL-END #ERROR-PAGE-START 错误页配置，可以注释、删除或修改 #error_page 404 /404.html; #error_page 502 /502.html; #ERROR-PAGE-END #PHP-INFO-START PHP引用配置，可以注释或修改 include enable-php-71.conf; #PHP-INFO-END #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效 location / { include /www/wwwroot/USER_NAME/*/nginx.htaccess; access_log /www/wwwroot/USER_NAME/nginx.log; } #REWRITE-END #禁止访问的文件或目录 location ~ ^…

在 Nginx 中将爬虫过来的请求转到指定的后端服务
type: item
date: 2020-04-13T10:11:02+08:00
description: 一般识别爬虫的方法是通过 UserAgent，这种办法最直接，但也很容易伪造，先不管这个了。实现在 Nginx 中使用 map 指令来匹配一个变量：map $http_user_agent $is_bot { default 0; ~[a-z]bot[^a-z] 1; ~[sS]pider[^a-z] 1; 'Yahoo! Slurp China' 1; 'Mediapartners-Google' 1; }在这里我们生成了一个名为 $is_bot 的变量，该变量默认值是 0 ，如果匹配到上述 4 种正则表达式的情况后，值就变成1。你可以继续往 map 中添加新的表达式规则。然后在 location 中使用该变量：location / { error_page 418 =200 @bots; if ($is_bot) { return 418; } proxy_pass http://tomcat_for_normal_visitors; }@bots 的定义：location @bots { proxy_pass http://tomcat_for_bot; }当判断当前请求是爬虫的时候，返回 418 错误码。通过 error_page 将 418 错误码改为 200 （正常请求响应码），然后进入 @bots 这个 location 进行下一步处理。@bots 中将请求反向代理到你指定的后端应用。如此便可将正常的用户访问和爬虫访问独立开来，使二者不会互相影响。

ERR_INCOMPLETE_CHUNKED_ENCODING 错误
type: item
date: 2019-07-01T19:31:46+08:00
description: 可能的情况：1、服务器磁盘满了，查看磁盘https://blog.csdn.net/dujianxiong/article/details/84288658df -h2、nginx的fastcgi_temp目录没有读写权限，查看nginx的error日志，会发现：2010/03/13 02:52:19 [crit] 3396#0: *10 open() "/usr/local/nginx/fastcgi_temp/2/00/0000000002" failed (13: Permission denied)处理方法，给目录增加权限或者修改所有者为nginx worker的运行用户chown www:www /usr/local/nginx/fastcgi_temp -R分析 fastcgi_temp 错误以及 Nginx 的 Buffer 机制: https://blog.csdn.net/crx05/article/details/70210323

nginx增加图片处理能力的方法
type: item
date: 2019-05-31T11:23:00+08:00
description: 文章来源：https://blog.csdn.net/revitalizing/article/details/55505853必要工具库一、libgd的安装 export LD_LIBRARY_PATH=/Path/to/libgd.so:$LD_LIBRARY_PATH当然也还有更简单的方法，直接yum安装也行，自己配置好yum源，然后：yum install gd-devel pcre-devel libcurl-devel因为libcurl也是需要的一部分，所以一起安装。二、nginx with-http_image_filter_module模块安装编辑安装nginx的时候需要加上这些参数--with-http_image_filter_module --with-pcre=../pcre-8.36使用：一般情况下，nginx一般都需要用到正则表达式，所以对于图片处理器pcre就更不能少了，如果有pcre，我们的配置就可以写成下面这样： #图片处理，固定返回最大长边尺寸 location ~* /(.+)\.(jpg|gif|png)$ { access_log off; expires 30d; #根据给定的长宽生成缩略图 image_filter resize 800 800; #原图最大2M，要裁剪的图片超过2M返回415错误，需要调节参数image_filter_buffer image_filter_buffer 8M; image_filter_interlace on; image_filter_jpeg_quality 95; image_filter_sharpen 100; image_filter_transparency on; #error_page 415 /images/notfound.jpg; try_files /$1.$2 /notfound.jpg; } #图片处理，支持_1x1.jpg这样的自定义尺寸 location ~* /(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ { access_log off; expires 30d; set $w $2; set $h $3; if ($h = "0") { rewrite /(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ /$1 last; } if ($w = "0") { rewrite /(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ /$1 last; } #根据给定的长宽生成缩略图 image_filter resize $w $h; #原图最大2M，要裁剪的图片超过2M返回415错误，需要调节参数image_filter_buffer image_filter_buffer 8M; image_filter_interlace on; image_filter_jpeg_quality 95; image_filter_sharpen 100; image_filter_transparency on; #error_page 415 /images/notfound.jpg; try_files /$1 /notfound.jpg; }访问处理后的图片：http://xxxx.xxx.xxx/test.jpg >> http://xxxx.xxx.xxx/test.jpg_500x200.jpg各参数的注释：image_filter off; #关闭模块 image_filter test; #确保图片是jpeg gif png否则返415错误 image_filter size; #输出有关图像的json格式：如下显示{ "img" : { "width": 100, "height": 100, "type": "gif" } } 出错显示：{} image_filter rotate 90|180|270; #旋转指定度数的图像，参数可以包括变量，单独或一起与resize crop一起使用。 image_filter resize width height; #按比例减少图像到指定大小，公减少一个可以另一个用"-"来表示,出错415，参数值可包含变量，可以与rotate一起使用，则两个一起生效。 image_filter crop width height; #按比例减少图像比较大的侧面积和另一侧多余的载翦边缘，其它和rotate一样。没太理解 image_filter_buffer 10M; #设置读取图像缓冲的最大大小，超过则415错误。 image_filter_interlace on; #如果启用，最终的图像将被交错。对于JPEG，最终的图…

nginx 封IP 禁止IP/IP段访问
type: item
date: 2018-12-10T10:34:00+08:00
description: 在nginx的安装目录下面,新建屏蔽ip文件，命名为blockips.conf。 加入如下内容#deny 1.2.3.4; #deny 91.212.45.0/24; deny 115.239.212.0/24; deny 180.97.106.0/24; deny 115.239.212.0/24; deny 220.243.135.0/24; deny 180.97.106.0/24;保存一下。3.在nginx的配置文件nginx.conf中加入如下配置，可以放到http, server, location, limit_except语句块，需要注意相对路径，本例当中nginx.conf，blockips.conf在同一个目录中。include blockips.conf;

nginx 批量的禁止访问
type: item
date: 2018-07-09T10:33:56+08:00
description: 方法一：将下面的内容保存到nginx.conf同级目录，比如：deny1.conf# 针对单个ip的形式 deny 171.94.171.205; deny 115.29.166.101; deny 182.247.251.48; deny 61.147.89.17; # 针对网段的形式 deny 66.249.227.0/24;然后在nginx.conf 的 http 段 引入这个文件，重启生效(注意这个是整体全部的网站配置的禁止这些IP访问了，谨慎使用)：include deny1.conf; 方法二：有针对性的阻止，比如有些人工的发起请求，或许其他的你不想要的访问，通常是异常的客户端UA，可以这么做：将下面的内容也保存到一个文件，也是nginx.conf同级目录，比如：deny2.conf#禁止常用工具的抓取 if ($http_user_agent ~* "Scrapy|Curl|HttpClient|Java") { return 403; } #禁止指定UA及UA为空的访问 if ($http_user_agent ~* "Baidu-YunGuanCe|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Feedly|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|YisouSpider|MJ12bot|heritrix|EasouSpider|LinkpadBot|Ezooms|^$" ) { return 403; } 这里注意需要把里面的正则表达式修改成你需要的正则表达式，以免达不到你要的效果然后在nginx.conf 的 server 段（也就是某个网站的配置而不是http段） 引入这个文件，重启生效：http{ ... server { ... include deny2.conf; ... } ... }先测试有没有配置错误nginx -t再重启服务nginx -s reload