08 . Nginx状态码
HTTP状态码
本篇文章主要介绍运维过程中经常遇到的状态码,并通过业界流行的Nginx进行模拟实现。
2XX状态码
2XX类型状态码表示一个HTTP请求成功,最典型的就是200
# 200状态码
# 这个使我们最希望看到的状态码,表示一个HTTP请求得到了正确的响应,在此不做模拟测试
3XX状态码
# 3XX 类型状态码主要表示HTTP请求URL重定向行为,最常见的3XX状态码有301,302,304
301
测试用例
# URL: 永久性重定向,在Nginx中通过rewrite指令结合permanent标记实现.
server {
listen 80;
server_name test.com;
root /usr/share/nginx/html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
rewrite ^(.*)$ /index.html permanent;
location / {
index index.html index.htm;
}
}
curl 127.0.0.1 -I
# TTP/1.1 301 Moved Permanently
302
测试用例
# URL: 临时重定向,在Nginx通过rewrite指令结合redirect标记实现
server {
listen 80;
server_name test.com;
root /usr/share/nginx/html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
rewrite ^(.*)$ /index.html redirect;
location / {
index index.html index.htm;
}
}
curl 127.0.0.1 -I
# HTTP/1.1 302 Moved Temporarily
301 VS 302
# 301和302状态码都是URL重定向。其中301永久重定向,302临时重定向。不管是永久还是临时,但对⽤户⽽⾔这两者没有任何感官上的区别。都是在访问连接A的时候跳转到了连接B,并看到浏览器上的地址同样由A变成了B。既然如此,那为什么还要同时存在301和302呢?
# 它们主要区别在于搜索引擎。搜索引擎是要建⽴索引规则和权重的,如果连接A被设定为永久重定向到连接B,那搜索引擎可以确定A的地址永久改变了,就会把B当做唯⼀有效的⽬标地址。这时搜索引擎会把⽼地址相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的⽼地址。⽽搜索引擎对于302则没有这样的⾏为。
304
测试用例
# 客户端缓存,通过Nginx中的expires指令完成
server {
listen 80;
server_name test.com;
root /usr/share/nginx/html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|html)$ {
expires 1d;
}
}
# 当客户端浏览器经过第一次访问后,第二次访问时只要访问资源没有过期,状态码就为304,说明使用了上一次请求时候的响应资源
4XX状态码
# 4XX 类型状态码主要表示客户端错误。客户端发起的HTTP请求头不完整、客户度使⽤的⽤户名、密码错误等等。都会被标示为客户端错误。常⻅的4XX状态码有 400、401、403等。
400
# 当WEB服务器遇到不完整的HTTP请求头时,会返回400状态码。请求头信息或者Cookie信息过⼤,通常是导致不完整的请求头的原因。那多⼤的请求头算过⼤呢?
# 这个值由WEB服务器端配置决定。在Nginx 这类WEB服务器中,决定这个值的配置字段是large_client_header_buffers。 我们通过调⼩这个字段,来模拟400状态码。
测试用例
server {
listen 80;
server_name test.com;
root /usr/share/nginx/html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# 此指令在NGINX的HTTP段和SERVER段都可以⽣效。
# 若实验发现在SERVER段中不⽣效,可以在HTTP段中设置。
large_client_header_buffers 1 1k;
location / {
index index.html index.htm;
}
}
# 测试
# 设置一个远超过1K的cookie
curl --cookie "user=sidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidisidisisidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisisidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidisidisisidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisisidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidisidisisidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisisidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidisidisisidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisissisisisisisisisisisisisisisiisissiissisisisiissi" 127.0.0.1 -I
HTTP/1.1 400 Bad Request
Server: nginx/1.18.0
Date: Mon, 04 May 2019 11:05:55 GMT
Content-Type: text/html
Content-Length: 233
Connection: close
401
# 权限验证错误。就是需要⽤户名、密码等权限认证,但是客户端⼜没有通过认证。在Nginx中要想模拟这种状态码,必须将Nginx调整成认证模式。
测试用例
生成授权用户名和密码
htpasswd -c /etc/passwd.db youmen
# Nginx授权配置
server {
listen 80;
server_name test.com;
root /usr/share/nginx/html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
auth_basic "secret";
auth_basic_user_file /etc/passwd.db;
index index.html index.htm;
}
}
# 测试
# test.com 在本地hosts文件中进行绑定,然后开浏览器输入正确用户名和密码访问
403
# 没有权限访问,文件权限过小或者认为设置不允许某个IP地址访问等,都会浮现403状态码
测试用例
# 将⽂件权限设置为最⼩
# ll /usr/share/nginx/html/index.html
-rw-r--r-- 1 root root 3700 3⽉ 6 04:26 /usr/share/nginx/html/index.html
# chmod 0 /usr/share/nginx/html/index.html
# ll /usr/share/nginx/html/index.html
---------- 1 root root 3700 3⽉ 6 04:26 /usr/share/nginx/html/index.html
# Nginx配置文件
server {
listen 80;
server_name test.com;
root /usr/share/nginx/html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
index index.html index.htm;
}
}
curl http://127.0.0.1/index.html -I
# HTTP/1.1 403 Forbidden
404
# 文件不存在,当我们访问一个不存在文件时,就会出现这个错误
# 还原403状态码配置属主属组,随意输入URL访问
curl http://127.0.0.1/youmen -I
# HTTP/1.1 404 Not Found
499
# 499这个状态码并不是http协议中定义的标准状态码,⽽是Nginx⾃⼰定义的⼀个状态码。当客户端主动断开连接的时候,Nginx就会返回499的状态码。按照这个状态码的定义,只要在Nginx返回结果之前主动断开客户端连接,就应该会复现这个状态码。
测试用例
# 创建一个PHP脚本,并将脚本放在Nginx的root目录中,以此脚本模拟一个很长时间的响应
cat sleep.php
<?php
sleep(80);
echo "ok"
?>
# 开启PHP-FPM服务
systemctl start php-fpm
# 测试Nginx配置文件
server {
listen 80;
server_name test.com;
root /usr/share/nginx/html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|html)$ {
expires 1d;
}
location / {
# 确保 fastcgi.conf 中存在 SCRIPT_FILENAME 配置, 以下5XX案例中也要确保存
在
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi.conf;
# PHP-FPM 默认开启了9000端⼝。若做了个性化配置,请⼿动调整。
fastcgi_pass 127.0.0.1:9000;
}
}
# 测试
# 不要等程序正常结束,CTRL + C直接退出
curl http://127.0.0.1/sleep.php -I
^C
# 在CURL模拟测试同时查看access.log
tail -f /var/log/nginx/access.log
127.0.0.1 - - [13/May/2019:23:24:33 -0400] "HEAD /sleep.php HTTP/1.1" 499 0
"-" "curl/7.29.0"
5XX状态码
# 5XX 类型状态码主要表示服务端错误,此时不要纠结客户端问题了
500
一般有以下几种情况
测试用例
# 将Nginx 的root ⽬录中的sleep.php 随意个更改,让它的PHP语法出现问题。
# cat sleep.php
<?php
echo "aa"
sleep(80);
echo "ok"
?>
# 测试Nginx配置文件
server {
listen 80;
server_name test.com;
root /usr/share/nginx/html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|html)$ {
expires 1d;
}
location / {
# 确保 fastcgi.conf 中存在 SCRIPT_FILENAME 配置, 以下5XX案例中也要确保存
在
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi.conf;
# PHP-FPM 默认开启了9000端⼝。若做了个性化配置,请⼿动调整。
fastcgi_pass 127.0.0.1:9000;
}
}
curl http://127.0.0.1/sleep.php -I
# HTTP/1.1 500 Internal Server Error
# 1.web脚本错误,如php语法错误,lua语法错误等.
# 2.访问量大的时候,由于系统资源限制,而不能打开过多的文件.
# 一般分析思路:
# 查看nginx error log ,查看php error log
# 如果是too many open files,修改nginx的worker_rlimit_nofile参数,
# 使用ulimit查看系统打开文件限制,修改/etc/security/limits.conf
# 如果是脚本的问题,则需要修复脚本错误,并优化代码
# 各种优化都做好,还是出现too many open files,
# 那就要考虑做负载均衡,把流量分散到不同服务器上去了
错误原因总结:
1.硬盘空间满了
使用 df -k 查看硬盘空间是否满了。清理硬盘空间就可以解决500错误。nginx如果开启了access log,在不需要的情况下,最好关闭access log。access log会占用大量硬盘空间。
2.nginx配置文件错误
这里不是指语法错误,nginx如果配置文件有语法错误,启动的时候就会提示。当配置rewrite的时候,有些规则处理不当会出现500错误,请仔细检查自己的rewrite规则。如果配置文件里有些变量设置不当,也会出现500错误,比如引用了一个没有值的变量。
3.如果上面的问题都不存在可能是模拟的并发数太多了,需要调整一下nginx.conf的并发设置数
3 . 系统打开文件限制
解决方法是:
vim /etc/security/limits.conf
soft nofile 65535
hard nofile 65535
# 再打开/etc/nginx/nginx.conf
# 在worker_processes下面增加一行
vim /etc/nginx/nginx.conf
worker_rlimit_nofile 65535;
systemctl reload nginx
kill -9 `ps -ef | grep php | grep -v grep | awk '{print $2}'`
/usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -C 100 -u www-data -f /usr/bin/php-cgi
killall -HUP nginx
# 重启后再看nginx的错
重启后再看nginx的错误日志,也没有发现500报错的情况了。
有可能是数据库问题我的在nginx日志php日志都没有发现什么问题, 最后发现数据库访问不了,修正后问题解决。
502
# 502 Bad Geteway。Nginx 502错误的原因⽐较多,主要是因为在代理模式下后端服务器出现问题引起的。这些错误⼀般都不是Nginx本身的问题,⼀定要从后端找原因。⽐如这⾥复现⼀种后端PHP-FPM进程挂掉的情况,就会出现502错误
模拟
# 先将后端的PHP-FPM进程关闭。
# systemctl stop php-fpm
# 模拟测试
curl http://127.0.0.1/sleep.php -I
# HTTP/1.1 502 Bad Gateway
是指请求的php-fpm已经执行,但是由于某种原因没有执行完毕,最终导致php-fpm进程终止,错误原因比较多,一般不是Nginx本身,从后端找原因,比如PHP挂掉;
对于PHP,造成502原因常见的就是脚本执行时间超过了Timeout设置时间,或者设置过大,导致PHP长时间不能释放,没有worker进程出来接请求;
适当增加PHP执行时间,先清除502,优化要花费更多时间;
控制php执行时间选型有两个,
1> 在php.ini中max_execution(厄涩Q熏)_timeout
2> 也有可能跟php执行程序性能有关,网站访问量大,而php-cgi的进程数偏少,针对这种情况,只需要增加php-cgi的进程数,将php-fpm.conf中的max_children值适当增加.这个数据根据你的VPS或独立服务器的配置进行设置,一般一个php-cgi进程占20M内存,自己算算适量增多.
503
服务暂时不可用
由于临时服务器维护或者过载,服务器当前无法处理请求,这个状态是临时的,并且将在一段时间以后恢复;
多半是因为网站访问量过大,造成流量请求过多,Nginx不向后端转发了,或者Upstream的地址,端口问题,先检查CPU,内存,负载特别高,如果没有检查配置;
升级空间到更佳配置,要么检查网站系统程序使之更佳;
单个IP并发设置过小会导致503报错.
504
# 504 Gateway Time-out。顾名思义,就是超时了。当PHP-FPM的执⾏时间⼤于Nginx的读超时间,此时就会出现 504状态码。
# 将上面示例中脚本中的时间超过php-fpm最大超时时间就行了
服务器作为网关或代理,但是没有及时从上游服务器收到请求。 就是客户端发出请求没有到达网关,请求没有到可以执行的php-fpm;
# 1>可能与Nginx.conf配置有关系,Nginx连接超时时间;
# 2>当PHP-FPM执行时间超过大于Nginx的读超时时间;
小结
1XX # 表示临时响应并需要请求者继续执行操作的状态码
200 # 表示一个HTTP请求得到了正确响应
301 # 永久重定向
302 # 临时重定向
401 # 需要授权
403 # 访问被拒绝,没有权限
404 # 页面找不到,服务器找不到请求页面
410 # 如果请求资源已被永久删除,服务器会返回此响应
500 # 服务器内部错误
08 . Nginx状态码的更多相关文章
- Nginx状态码499
1.问题描述 140.207.202.187 - - [18/May/2016:10:30:58 +0800] "POST/v3/violations HTTP/1.1" 499 ...
- Nginx状态码和日志
目录 一.Nginx状态返回码 二.Nginx日志统计 一.Nginx状态返回码 http返回状态码(Status-Code), 以3位数字组成 200 成功 301 永久重定向(redirect) ...
- nginx状态码
200:服务器成功返回网页 403:服务器拒绝请求.404:请求的网页不存在 499:客户端主动断开了连接.500:服务器遇到错误,无法完成请求.502:服务器作为网关或代理,从上游服务器收到无效响应 ...
- nginx 状态码整理
状态代码 状态信息 含义 100 Continue 初始的请求已经接受,客户应当继续发送请求的其余部分.(HTTP 1.1新)101 Switching Protocols 服务器将遵从 ...
- zabbix监控nginx日志状态码
监控需求 监控Nginx常见的状态码并对其进行监控,对常见的错误状态码创建相对应的触发器以下按照分钟对数据进行抓取 Zabbix_Agentd创建监控脚本 1)创建脚本之前核对Nginx日志格式我这里 ...
- lunix nginx安装 报错页面 状态码
web服务器软件IIS (windows底下的web服务器软件) Nginx (Linux底下新一代高性能的web服务器) Tengine www.taobao.com 这是淘宝 Apach ...
- nginx 499 状态码优化
在grafana界面中发现不少499的状态码,在网上了解到出现499的原因大体都是说服务端处理时间过长,客户端主动关闭了连接. 既然原因可能是服务端处理时间太长了,看一下upstream_resp ...
- Nginx_HTTP 499 状态码 nginx下 499错误
日志记录中HTTP状态码出现499错误有多种情况,我遇到的一种情况是nginx反代到一个永远打不开的后端,就这样了,日志状态记录是499.发送字节数是0. 老是有用户反映网站系统时好时坏,因为线上的产 ...
- Nginx的 HTTP 499 状态码处理
1.前言 今天在处理一个客户问题,遇到Nginx access log中出现大量的499状态码.实际场景是:客户的域名通过cname解析到我们的Nginx反向代理集群上来,客户的Web服务是由一个负载 ...
随机推荐
- Spring Boot 集成 Flyway 实现数据库版本控制
在项目迭代开发中,难免会有更新数据库 Schema 的情况,比如添加新表.在表中增加字段或者删除字段等,那么当我对数据库进行一系列操作后,如何快速地在其他同事的电脑上同步?如何在测试/生产服务器上快速 ...
- React Native超简单完整示例-tabs、页面导航、热更新、用户行为分析
初学React Native,如果没有人指引,会发现好多东西无从下手,但当有人指引后,会发现其实很简单.这也是本人写这篇博客的主要原因,希望能帮到初学者. 本文不会介绍如何搭建开发环境,如果你还没有搭 ...
- LTE基站开局流程脚本的具体含义
1.全局参数配置MOD ENODEB(修改基站): ENODEBID=2015(基站标识2015), NAME="安职-1"(基站名称), ENBTYPE=DBS3900_LTE( ...
- 多表同步 ES 的问题
原始需求 对跨业务域数据提供联查搜索能力. 比如:对退款单提供根据退款单.退款状态.发货状态的联查,其中退款状态和发货状态是跨业务域. 比如:对订单提供根据订单号.订单状态.退款状态的联查,其中订单状 ...
- Leetcode_236. 二叉树的最近公共祖先
求二叉树的LCA code /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *le ...
- 写了shell脚本想一键启动三台虚拟机的Zookeeper,却不知道为啥总是启动不了
首先,一键启动的shell脚本是这样的 #! /bin/bash case $1 in "start"){ for i in node01 node02 node03 do ssh ...
- 【Hadoop离线基础总结】网站流量日志数据分析系统
目录 点击流数据模型 概述 点击流模型 网站流量分析 网站流量模型分析 网站流量来源 网站流量多维度细分 网站内容及导航分析 网站转化及漏斗分析 流量常见分析角度和指标分类 指标概述 指标分类 分析角 ...
- STM32 标准库3.5修改默认外部8M晶振为16M晶振
ST官方标准库V3.5默认的外部晶振频率为8M,实际使用中外部晶振需要修改为16M: 经过实验,修改有效,具体的patch如下: 修改 HSE_VALUE 值 diff --git "a/L ...
- 配置centos7 java环境
一.环境 centos7 jdk-8u231-linux-x64.tar.gz 二.安装jdk 使用ftp或者 WinScp软件把下载在win10电脑上的jdk安装包上传到linux 解压到/opt/ ...
- C# LinQ的基本子句、协变与异变
//1.from 子句: , , , , , , , , , }; var query = from n in arr select n; foreach (var i in query) { Con ...