1、前言
本文主要记录运维过程中经常遇到的状态码,并进行模拟实现。
2、2XX状态码
2XX状态码表示一个成功的HTTP请求,这个是我们最希望看到的状态码,在此不需做模拟测试
3、3XX状态码
3XX 类型状态码主要表示HTTP请求URL重定向行为,最常见的3XX状态码有301,302,304
3.1 301
3.1.1 测试用例
server {
listen 80;
server_name laifu.liang;
root /usr/local/nginx/html;
access_log off;
rewrite ^(.*)$ /index.html permanent;
location / {
index index.html;
}
}
3.1.2 说明
URL永久重定向,在Nginx中通过rewrite指令结合permanent标记实现
3.1.3 测试
# curl laifu.liang -I
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 18 Jul 2022 08:51:56 GMT
Content-Type: text/html
Content-Length: 162
Location: http://laifu.liang/index.html
Connection: keep-alive
3.2 302
3.2.1 测试用例
server {
listen 80;
server_name laifu.liang;
root /usr/local/nginx/html;
access_log off;
rewrite ^(.*)$ /index.html redirect;
location / {
index index.html;
}
}
3.2.2 说明
URL临时重定向:在Nginx通过rewrite指令结合redirect标记实现
3.2.3 测试
#curl laifu.liang -I
HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Mon, 18 Jul 2022 08:56:08 GMT
Content-Type: text/html
Content-Length: 138
Location: http://laifu.liang/index.html
Connection: keep-alive
3.3 301 VS 302
301和302状态码都是URL重定向。301永久重定向,302临时重定向。不管是永久还是临时,但对⽤户⽽⾔这两者没有任何感官上的区别。都是在访问链接A的时候跳转到了链接B,并看到浏览器上的地址由A变成了B。
既然如此,那为什么还要同时存在301和302呢?
它们主要区别在于搜索引擎。搜索引擎是要建⽴索引规则和权重的,如果链接A被设定为永久重定向到链接B,那搜索引擎可以确定A的地址永久改变了,就会把B当做唯⼀有效的⽬标地址。这时搜索引擎会把⽼地址相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的⽼地址。⽽搜索引擎对于302则没有这样的⾏为。
3.4 304
3.4.1 测试用例
server {
listen 80;
server_name laifu.liang;
root /usr/local/nginx/html;
access_log off;
location / {
expires 1d;
}
}
3.4.2 说明
客户端缓存,通过Nginx中的expires指令完成
3.4.3 测试
当客户端浏览器经过第一次访问后,第二次访问时只要访问资源没有过期,状态码就为304,说明使用了上一次请求时候的响应资源
4、4XX状态码
4XX 类型状态码主要表示客户端错误。
客户端发起的HTTP请求头不完整、使⽤的⽤户名、密码错误等等。都会被标示为客户端错误。常⻅的有 400、401、403等。
4.1 400
当WEB服务器遇到不完整的HTTP请求头时,会返回400状态码。请求头信息或者Cookie信息过⼤,通常是导致不完整的请求头的原因。那多⼤的请求头算过⼤呢?
这个值由WEB服务器端配置决定。在Nginx 这类WEB服务器中,决定这个值的配置字段是large_client_header_buffers。 我们通过调⼩这个字段,来模拟400状态码。
4.1.1 测试用例
server {
listen 80;
server_name laifu.liang;
root /usr/local/nginx/html;
access_log off;
# 此指令在Nginx的HTTP段和SERVER段都可以⽣效
# 若实验发现在SERVER段中不⽣效,可以在HTTP段中设置
large_client_header_buffers 1 1k;
location / {
index index.html;
}
}
4.1.2 测试
# 设置一个超过1k的cookie
curl --cookie "user=fnwnffefwegwegwgewfwjggjwejjjgwengengnwgnwegnwengwengwekngewkngwkgnwkjengjwengkjewngwjengejwkngejwngwejkngjwekngewjenfw" laifu.liang -I
HTTP/1.1 400 Bad Request
Server: nginx
Date: Tue, 19 Jul 2022 03:36:12 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 14 Jul 2022 09:32:50 GMT
4.2 401
权限验证错误。就是需要⽤户名、密码等权限认证,但是客户端没有通过认证。
在Nginx中要想模拟这种状态码,必须将Nginx调整成认证模式。
4.2.1 生成授权用户和密码
htpasswd -c /etc/laifu.db laifu
4.2.2 测试用例
server {
listen 80;
server_name laifu.liang;
root /usr/local/nginx/html;
access_log off;
location / {
auth_basic "secret";
auth_basic_user_file /etc/laifu.db;
index index.html;
}
}
4.2.3 测试
打开浏览器输入正确用户名和密码访问即可
4.3 403
没有权限访问,文件权限过小或者设置不允许某个IP地址访问等,都会出现403状态码
4.3.1 设置一个最小权限文件
#cd /usr/local/nginx/html/
#touch test.html
#chmod 0 ./test.html
#ll test.html
---------- 1 root root 0 7月 19 15:49 test.html
4.3.2 测试用例
server {
listen 80;
server_name laifu.liang;
root /usr/local/nginx/html;
access_log off;
location / {
index index.html;
}
}
4.3.3 测试
curl http://laifu.liang/test.html -I
HTTP/1.1 403 Forbidden
Server: nginx
Date: Tue, 19 Jul 2022 07:55:33 GMT
Content-Type: text/html
Content-Length: 146
4.4 404
文件不存在,当我们访问一个不存在的文件时,就会出现这个错误
4.4.1 测试用例
server {
listen 80;
server_name laifu.liang;
root /usr/local/nginx/html;
access_log off;
location / {
index index.html;
}
}
4.4.2 测试
访问一个不存在的文件
curl http://laifu.liang/test1.html -I
HTTP/1.1 404 Not Found
Server: nginx
Date: Tue, 19 Jul 2022 07:55:33 GMT
Content-Type: text/html
Content-Length: 146
Connection: keep-alive
4.5 499
499这个状态码并不是http协议中定义的标准状态码,⽽是Nginx⾃⼰定义的⼀个状态码。当客户端主动断开连接的时候,Nginx就会返回499的状态码。按照这个状态码的定义,只要在Nginx返回结果之前主动断开客户端连接,就会复现这个状态码。
4.5.1 创建脚本
创建一个PHP脚本,并将脚本放在Nginx的root目录下,模拟一个很长时间的响应
cat sleep.php
<?php
sleep(80);
echo "ok"
?>
4.5.2 启动PHP服务
systemctl start php-fpm
systemctl status php-fpm
4.5.3 测试用例
server {
listen 80;
server_name laifu.liang;
root /usr/local/nginx/html;
access_log logs/test.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;
}
}
4.5.4 测试
不等请求正常结束,CTRL + C直接退出
curl http://laifu.liang/sleep.php -I
^C
在curl模拟测试同时查看test.log(日志文件可自己修改)
#tail -f /usr/local/nginx/logs/test.log
"HEAD /sleep.php HTTP/1.1" 499 0 "-" "curl/7.29.0"
5、5XX状态码
5XX 类型状态码主要表示服务端错误,此时跟客户端没太大关系了
5.1 500
修改499 php脚本,使其PHP语法出现错误
# cat sleep.php
<?php
echo "aa"
sleep(80);
echo "ok"
?>
5.1.1 测试用例
测试用例同499状态码用例
5.1.2 测试
#curl http://laifu.liang/sleep.php -I
HTTP/1.1 500 Internal Server Error
5.1.3 500错误原因
1、web脚本错误,如php语法错误,lua语法错误等等
2、访问量大的时候,由于系统资源限制,而不能打开过多的文件
5.1.4 分析思路
1、查看nginx error log ,查看php error log
2、如果是too many open files,修改nginx的worker_rlimit_nofile参数
3、使用ulimit查看系统打开文件限制,通过/etc/security/limits.conf配置文件调整
4、如果是脚本的问题,则需要修复脚本错误,并优化代码
5、各种优化都做好,还是出现too many open files的话,那就要考虑做负载均衡,把流量分散到不同服务器上去了
5.1.5 错误原因总结
磁盘空间满了
使用 df -h 查看硬盘空间
Nginx配置文件错误
这里不是指语法错误,Nginx如果配置文件有语法错误,启动的时候就会提示。
当配置rewrite的时候,有些规则处理不当会出现500错误,请仔细检查自己的rewrite规则。如果配置文件里有些变量设置不当,也会出现500错误,比如引用了一个没有值的变量。
并发数太多
数据库问题
5.2 502
502 Bad Geteway
Nginx 502错误的原因⽐较多,主要是因为在代理模式下后端服务器出现问题引起的。这些错误⼀般都不是Nginx本身的问题,⼀定要从后端找原因。⽐如这⾥复现⼀种后端PHP-FPM进程挂掉的情况,就会出现502错误
5.2.1 关闭PHP服务
systemctl stop php-fpm
systemctl status php-fpm
5.2.2 测试用例
同500测试用例
5.2.3 模拟测试
curl http://laifu.liang/sleep.php -I
HTTP/1.1 502 Bad Gateway
5.3 503
服务暂时不可用
1、由于临时服务器维护或者过载,服务器当前无法处理请求,这个状态是临时的,并且将在一段时间以后恢复
2、多半是因为网站访问量过大,造成流量请求过多,Nginx不向后端转发了,或者Upstream的地址,端口问题。先检查CPU,内存,负载特别高,如果没有问题的话就检查配置
3、升级空间到更佳配置,要么检查网站系统程序使之更佳
4、单个IP并发设置过小会导致503报错
5.4 504
504 Gateway Time-out
顾名思义,就是超时了。当PHP-FPM的执⾏时间⼤于Nginx的读超时间,此时就会出现 504状态码。
服务器作为网关或代理,但是没有及时从上游服务器收到请求。 就是客户端发出请求没有到达网关,请求没有到可以执行的php-fpm;
5.4.1 分析
1、可能与Nginx.conf配置有关系,Nginx连接超时时间
2、当PHP-FPM执行时间超过大于Nginx的读超时时间
6、小结
1XX # 表示临时响应并需要请求者继续执行操作的状态码
200 # 表示一个HTTP请求得到了正确响应
301 # 永久重定向
302 # 临时重定向
401 # 需要授权
403 # 访问被拒绝,没有权限
404 # 页面找不到,服务器找不到请求页面
410 # 如果请求资源已被永久删除,服务器会返回此响应
500 # 服务器内部错误