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状态码的更多相关文章

  1. Nginx状态码499

    1.问题描述 140.207.202.187 - - [18/May/2016:10:30:58 +0800] "POST/v3/violations HTTP/1.1" 499 ...

  2. Nginx状态码和日志

    目录 一.Nginx状态返回码 二.Nginx日志统计 一.Nginx状态返回码 http返回状态码(Status-Code), 以3位数字组成 200 成功 301 永久重定向(redirect) ...

  3. nginx状态码

    200:服务器成功返回网页 403:服务器拒绝请求.404:请求的网页不存在 499:客户端主动断开了连接.500:服务器遇到错误,无法完成请求.502:服务器作为网关或代理,从上游服务器收到无效响应 ...

  4. nginx 状态码整理

    状态代码    状态信息     含义 100 Continue 初始的请求已经接受,客户应当继续发送请求的其余部分.(HTTP 1.1新)101 Switching Protocols 服务器将遵从 ...

  5. zabbix监控nginx日志状态码

    监控需求 监控Nginx常见的状态码并对其进行监控,对常见的错误状态码创建相对应的触发器以下按照分钟对数据进行抓取 Zabbix_Agentd创建监控脚本 1)创建脚本之前核对Nginx日志格式我这里 ...

  6. lunix nginx安装 报错页面 状态码

    web服务器软件IIS  (windows底下的web服务器软件) Nginx (Linux底下新一代高性能的web服务器)  Tengine   www.taobao.com  这是淘宝 Apach ...

  7. nginx 499 状态码优化

    在grafana界面中发现不少499的状态码,在网上了解到出现499的原因大体都是说服务端处理时间过长,客户端主动关闭了连接.   既然原因可能是服务端处理时间太长了,看一下upstream_resp ...

  8. Nginx_HTTP 499 状态码 nginx下 499错误

    日志记录中HTTP状态码出现499错误有多种情况,我遇到的一种情况是nginx反代到一个永远打不开的后端,就这样了,日志状态记录是499.发送字节数是0. 老是有用户反映网站系统时好时坏,因为线上的产 ...

  9. Nginx的 HTTP 499 状态码处理

    1.前言 今天在处理一个客户问题,遇到Nginx access log中出现大量的499状态码.实际场景是:客户的域名通过cname解析到我们的Nginx反向代理集群上来,客户的Web服务是由一个负载 ...

随机推荐

  1. OSG程序设计之更新回调

    更新回调(Update Callback)涉及到一个类:osg::NodeCallback.这个类重载了函数调用操作符.当回调动作发生时,将会执行这一操作符的内容. 如果节点绑定了更新回调函数,那么在 ...

  2. JavaScript 循环判断练习题

    JavaScript 循环判断练习题 小明有一组水果("苹果","梨子","香蕉","葡萄","西瓜" ...

  3. F. Cards and Joy

    F. Cards and Joy 题目大意: 给你n个人,每一个人恰好选k张牌. 第一行是 n 和 k 第二行有n*k个数,代表有n*k张牌,每张牌上的数字 第三行有n个数,代表第i个人喜欢的数字 第 ...

  4. STM32 时钟树配置快速入门

    layout: post tags: [STM32] comments: true 文章目录 layout: post tags: [STM32] comments: true 为什么要了解时钟树? ...

  5. [hdu5525 Product]暴力

    题意:给定n和a[],令N = ∏(1≤i≤n)ia[i],求N的所有约数的积(取模1e9+7) 思路: 假定N因式分解后的结果是2p1*3p2*5p3*...,如何计算答案呢? 单独看2p1这一项, ...

  6. WIn7系统下配置Java环境变量

    给个官网下载地址  :https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 1.首先 ...

  7. 省市县三级联动sql文件

    截止于2018年,中国有34个省级, 地级行政区划单位334个 县级行政区划单位2851个 乡级行政区划单位39888个 例如 湖南省有多少个市级单位: 先拿到湖南省的code,再查city表: SE ...

  8. 2018-06-26 jq选择器

    0.选择器的目的就是为了方便快速找到元素从而操作元素! 1.基本选择器 *  -> 所有标签 #id ->id选择器 .class -> 类选择器 h1,h2 -> 组合选择器 ...

  9. 我的.vimrc配置

    termux平台下,通过pkg update && pkg upgrade && pkg install vim来获得vim.可是,当我配置.vimrc时发现如果我每在 ...

  10. RobotFramework自动化测试之元素定位

    前言:最近在做基于RF框架的Web自动化测试,其中涉及到元素的定位,主要用到id.name.xpath.css四中定位方法,尤其后面的两种方法特别有效,可以解决大部分的定位问题. id和name定位 ...