1 HTTP协议简介
1.1 HTTP协议请求报文
HTTP请求报文共分为四个部分
1.1.1 请求行
请求行包含请求方法、请求信息、请求协议
GET index.html HTTP 1.1
请求方法:
1)GET,读/看
2)POST,写/提交
请求信息:
GET的默认请求信息是index.html(首页文件)
请求协议:
默认是http 1.1
HTTP 1.0
- 无状态:服务器不跟踪不记录请求过的状态
- 无连接:浏览器每次请求都需要建立tcp连接
无状态
对于无状态的特性可以借助cookie/session机制来做身份认证和状态记录
无连接
无连接导致的性能缺陷有两种:
1.无法复用连接
每次发送请求,都需要进行一次tcp连接(即3次握手4次挥手),使得网络的利用率非常低
2.队头阻塞
http1.0规定在前一个请求响应到达之后下一个请求才能发送,如果前一个阻塞,后面的请求也给阻塞的
HTTP 1.1
- 长连接:新增Connection字段,可以设置keep-alive值保持连接不断开
- 管道化:基于上面长连接的基础,管道化可以不等第一个请求响应继续发送后面的请求,但响应的顺序还是按照请求的顺序返回
- 缓存处理:新增字段cache-control
- 断点传输
长连接
http1.1默认保持长连接,数据传输完成保持tcp连接不断开,继续用这个通道传输数据
管道化
基于长连接的基础,我们先看没有管道化请求响应:
tcp没有断开,用的同一个通道
请求1 > 响应1 --> 请求2 > 响应2 --> 请求3 > 响应3
管道化的请求响应:
请求1 --> 请求2 --> 请求3 > 响应1 --> 响应2 --> 响应3
即使服务器先准备好响应2,也是按照请求顺序先返回响应1
虽然管道化,可以一次发送多个请求,但是响应仍是顺序返回,仍然无法解决队头阻塞的问题。
缓存处理
当浏览器请求资源时,先看是否有缓存的资源,如果有缓存,直接取,不会再发请求,如果没有缓存,则发送请求通过设置字段cache-control来控制
断点传输
在上传/下载资源时,如果资源过大,将其分割为多个部分,分别上传/下载,如果遇到网络故障,可以从已经上传/下载好的地方继续请求,不用从头开始,提高效率。
在 Header 里两个参数实现的,客户端发请求时对应的是 Range 服务器端响应时对应的是 Content-Range
HTTP 2.0
- 二进制分帧
- 多路复用: 在共享TCP链接的基础上同时发送请求和响应
- 头部压缩
- 服务器推送:服务器可以额外的向客户端推送资源,而无需客户端明确的请求
二进制分帧
将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码
多路复用
基于二进制分帧,在同一域名下所有访问都是从同一个tcp连接中走,http消息被分解为独立的帧,乱序发送,服务端根据标识符和首部将消息重新组装起来
1.1.2 请求头
Accept: image/gif,image/jpeg #接受什么类型的文件
Accept-Language: zh-cn #接受什么类型的语言
Host: www.baidu.com #www(主机)、mail(邮件)、bbs(论坛)是主域名的子域名。
HTTP-User-Agent: firefox IE Chrome #用户终端
1.1.3 空行
用于隔开请求头和请求主体
1.1.4 请求主体
使用get方法时,没有请求主体信息
使用post方法时,具有请求主体信息
1.2 HTTP协议响应报文
1.2.1 起始行
HTTP/1.1 200 OK
响应的状态码
状态码 | 描述 |
---|---|
200 - OK | 返回成功 |
301 - Moved Permanently | 资源永久移动到新的位置,并且这个响应默认情况下会被缓存,只有在第一次的时候,才会去真正的发起第一个请求,后面的都会被缓存起来,直接跳转到 redirect 的请求。例如www.360buy.com跳转到www.jd.com |
302 - Moved Temporarily | 临时跳转请求,默认情况下不会缓存。 |
403 - Forbidden | 禁止访问,虽然请求合法,但是服务器侧拒绝了用户的请求。此类问题一般为权限配置不当导致 |
404 - Not Found | 请求的内容在服务器上不存在 |
500 - Internal Server Error | 内部服务器错误,服务器遇到了意想不到的情况,不能完成用户请求。一般为内部程序代码有问题,或程序服务的文件权限不正确。 |
502 - Bad Gateway | 代理服务器请求后端时,后端不可用或无响应。通常是反向代理服务器下面的节点出问题,反向代理无法与后面的web服务器建立联系。服务器PHP没启动会导致此问题。 |
503 - Service Unavailable | 服务当前不可用,可能是服务器超载或停机维护,或者是反向代理后面没有能够提供服务的节点 |
504 - Gateway Timeout | 网关超时,网关代理服务器请求后端时,后端没有在规定的时间内完成处理请求。多数是服务器过载导致 |
1.2.2 响应头部
Server: nginx/1.6.2 #使用什么服务响应
Date: Wed 11 Mar 2015 09:33:17 GMT
Content-Type: Type txt/html
charset=utf-8
Vary: Accept-Encoding
1.2.3 空行
用于分隔响应头和响应主体
1.2.4 响应主体
具体html文档内容
1.3 HTTP协议资源
URL 统一资源定位符
URI 统一资源标识符
1.3.1 网站页面静态资源
没有后台数据库,不含程序(PHP、JSP、ASP等),不可交互的资源。如纯文本、图片、视频、音频等。
特点:
1)网页内容固定不变,容易被搜索引擎收录
2)没有数据库的支持,制作和维护工作量大
3)交互性差,在程序功能实现方面有较大限制
4)对于用户的请求,服务器直接从磁盘文件系统上返回数据,不用做任何解析
1.3.2 网站页面动态资源
一般以数据库技术为基础,可以实现与用户的交互,常见扩展名后缀:asp、aspx、php、js、do、cgi等。
特点:
1)采用动态资源可以实现更多功能,如用户注册、用户登录、在线调查、投票、订单处理、发博文等
2)动态资源页面会出现"?" "&"等特殊符号,不便于被搜索引擎收录
3)接收到用户请求,需要让动态服务和数据库服务进行处理
1.3.3 伪静态资源(动态页面)
1.便于被搜索引擎收录
2.有数据库支持,实现网页交互
2 评测网站好坏的指标
IP:根据用户IP地址数量进行统计
PV:页面访问量
UV:记录独立访客数量,根据用户cookie进行统计
cookie:标识用户身份信息,会保存在用户客户端本地
session:记录用户的一些会话,记录在服务端。例如:用户登录信息
网站的并发量:单位时间内能够处理的最大连接数
3 常用网站服务软件
处理静态资源的服务:
apache、nginx
处理动态资源的服务:
PHP:终端浏览器进行访问
Tomcat(java):利用移动端查看网页
Python:开发难度比较低
4 Nginx
4.1 Nginx特点
- 支持高并发,消耗内存少
- 具有多种功能
- 网站web服务功能 ---apache
- 网站负载均衡功能 ---LVS
- 网站缓存服务 ---Squid
- 在多种系统平台都可以部署
- 在网络通讯时使用的是异步网络IO模型:epoll模型(apache--select模型)
4.2 安装Nginx
4.2.1 yum安装
配置官方yum源
vim /etc/etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
yum安装软件
yum -y install nginx
4.2.2 编译安装
下载源码包
wget http://nginx.org/download/nginx-1.18.0.tar.gz
安装依赖包
yum install gcc pcre-devel zlib-devel openssl-devel -y
创建nginx用户
useradd -s /sbin/nologin nginx
解压源码包后,进入目录编译安装
./configure --prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
make && make install
配置软链接
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/nginx
创建PID目录
mkdir -p /var/run/nginx
chown -R nginx:nginx /var/run/nginx
配置systemd启动脚本vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/var/run/nginx/nginx.pid
ExecStart=/usr/local/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
4.2.2.1 编译安装的nginx系统文件
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
4.2.2.2 编译安装添加模块
首先查看之前的编译参数nginx -V
[root@host-10-109-250-166 ~]$ nginx -V
...
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
进入源码目录,重新编译,将原有的参数和新加入的模块参数都添加进去,这里以添加ipv6模块--with-ipv6
为例
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module \
--with-ipv6
make
停掉nginx服务,替换nginx文件
systemctl stop nginx
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
cp objs/nginx /usr/local/nginx/sbin/
chown nginx:nginx /usr/local/nginx/sbin/nginx
重启nginx服务
systemctl start nginx
4.3 Nginx目录结构
4.3.1 /etc/logrotate.d
实现nginx日志文件定时切割处理
日志切割方法一:利用脚本实现切割处理
#!/bin/bash
mv /var/log/nginx/access.log /var/log/nginx/access_`date +%F`.log
systemctl restart nginx
日志切割方法二:利用专用软件logrotate
4.3.2 /etc/nginx/
配置文件目录
4.3.3 /var/log/nginx
日志文件
4.3.4 /usr/sbin/nginx
命令文件
4.3.5 /usr/share/nginx/html/
站点目录,存放index.html、图片、视频等网站元素
4.4 Nginx服务进程
有两类服务进程:
master:主进程,负责管理服务是否能够正常运行,root用户管理
worker:工作进程,负责处理用户的访问请求,worker用户管理
root 23906 0.0 0.1 46464 1132 ? Ss Dec21 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx 23907 0.0 0.2 46856 2100 ? S Dec21 0:00 nginx: worker process
4.5 Nginx服务配置文件
主区域关键参数
-
worker_processes auto;
nginx 进程数,建议按照cpu 数目来指定,一般为它的倍数 (如,2个四核的cpu计为8)。 -
worker_cpu_affinity auto;
自动为每个进程分配cpu -
worker_rlimit_nofile 65535;
一个nginx 进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx 进程数相除,但是nginx 分配请求并不是那么均匀,所以最好与ulimit -n的值保持一致。
事件区域关键参数
-
use epoll;
使用epoll 的I/O 模型 -
worker_connections 65535;
每个进程允许的最多连接数, 理论上每台nginx服务器的最大连接数为worker_processes*worker_connections。
4.5.1 yum安装的配置文件
/etc/nginx/nginx.conf
主配置文件
#1.主区域配置
user nginx; #定义worker进程管理的用户
worker_processes auto; #定义有几个worker进程
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn; #定义错误日志
pid /var/run/nginx.pid; #定义pid文件
#2.事件区域
events {
use epoll;
worker_connections 65535; #一个worker进程可以同时接收1024个访问请求
}
#3.http区域
http {
include /etc/nginx/mime.types; #加载一个配置文件
default_type application/octet-stream; #指定默认识别文件类型
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' #定义日志的格式
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; #指定日志路径
sendfile on;
#tcp_nopush on; #将多个包一次发送,用于提升网络传输效率,大文件推荐开启
keepalive_timeout 65; #指定超时时间,单位秒
gzip on;
include /etc/nginx/conf.d/*.conf; #加载配置文件
}
/etc/nginx/conf.d/default.conf
扩展配置文件(虚拟主机配置文件)
#4.server区域(配置一个网站 www/bbs/blog -- 一个网站是一个虚拟主机)
server {
listen 80; #指定监听的端口
server_name localhost; #网站域名
location / { #对于请求行uri的匹配,/是默认匹配
root /usr/share/nginx/html; #站点目录位置
index index.html index.htm; #首页文件
}
error_page 500 502 503 504 /50x.html; #优雅显示页面信息
location = /50x.html {
root /usr/share/nginx/html;
}
}
注意1:location
表示的位置是相对于root
的位置,首页文件等所有的文件需要放到location
所示位置下。/
是默认的location
,当其他location
均不匹配时,匹配这个location
。用户请求到来时,会用location
信息匹配uri
,匹配到location
信息,进行文件查询响应。查不到相应文件,会报404错误。
注意2:location {}
内部是局部的配置,其中定义的root
目录和index
文件只针对匹配的location
生效。想定义全局的root
和index文件
,需要在location
外配置。
server {
listen 80;
server_name www.bigsky.cn;
root /usr/share/nginx/html; #全局站点目录
index index.html; #全局index文件
...
...
}
4.5.2 编译安装的配置文件
主配置文件vim /usr/local/nginx/conf/nginx.conf
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
pid /var/run/nginx/nginx.pid;
events {
use epoll;
worker_connections 65535;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /usr/local/nginx/logs/access.log main;
sendfile on;
keepalive_timeout 65;
include /usr/local/nginx/conf.d/*.conf;
}
创建conf.d
目录
mkdir /usr/local/nginx/conf.d
编辑server
配置文件vim /usr/local/nginx/conf.d/server.conf
server {
listen 8080;
server_name localhost;
location / {
root /www/html;
index index.php;
}
location ~ \.php$ {
root /www/html;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
}
}
4.6 Nginx命令参数
nginx
命令不加参数,启动nginx进程
Options:
-?,-h : 查看帮助
-t : 检查配置文件语法
-T : 检查配置文件语法并显示配置文件内容
-s signal : send signal to a master process: stop, quit, reopen, reload
控制服务停止或者重新启动
4.7 Nginx搭建网站
4.7.1 搭建单个网站
/etc/nginx/conf.d/
目录下编写www.conf
server {
listen 80;
server_name www.bigsky.cn;
location /bigsky {
root /usr/share/nginx/html;
index bigsky.html;
}
}
由于location写了/bigsky,所以在站点目录下需要新建bigsky文件夹,将index文件放到bigsky文件夹中
站点目录下创建相应文件夹和主页文件
mkdir /usr/share/nginx/html/bigsky
echo "hello world" > /usr/share/nginx/html/bigsky/bigsky.html
重启nginx服务
systemctl reload nginx
4.7.2 搭建多个网站
/etc/nginx/conf.d/
目录下编写www.conf
、bbs.conf
、blog.conf
#vim www.conf
server {
listen 80;
server_name www.bigsky.cn;
location / {
root /html/www;
index index.html;
}
}
#vim bbs.conf
server {
listen 80;
server_name bbs.bigsky.cn;
location / {
root /html/bbs;
index index.html;
}
}
#vim blog.conf
server {
listen 80;
server_name blog.bigsky.cn;
location / {
root /html/blog;
index index.html;
}
}
创建站点目录和主页文件
mkdir -p /html/{www,bbs,blog}
for WEB in {www,bbs,blog};do echo "10.0.0.7 $WEB.bigsky.cn" > /html/$WEB/index.html ;done
重启nginx服务
systemctl reload nginx
4.7.3 nginx配置只监听指定地址
更改配置文件中的listen
信息
server {
listen 10.0.0.7:80;
server_name www.bigsky.cn;
location / {
root /html/www;
index index.html;
}
}
更改监听地址后,必须restart
重启服务,reload
无法让地址监听修改生效
4.7.4 网站页面访问原理
- 将域名解析 www.bigsky.cn:8080---> 10.0.0.7
- 建立TCP连接,10.0.0.7:8080
- 应用层HTTP协议发出请求,请求头:host:www.bigsky.cn
- 如果服务端没有相同域名的server虚拟主机,会找满足端口要求(8080)的第一个虚拟主机,显示主机的网站页面
4.7.5 网站安全访问配置
4.7.5.1 根据用户地址进行限制
- 10.0.0.7/24 不能访问
- 172.16.1.7/24 可以访问
利用到了ngx_http_access_module,修改www.conf
,增加location
配置
server {
listen 80;
server_name www.bigsky.cn;
location / {
root /html/www;
index index.html;
}
location /AV {
allow 172.16.1.7/24;
deny 10.0.0.7/24;
root /html/www;
index index.html;
}
}
语法配置:
Syntax: allow(deny) address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except
4.7.5.2 用户访问需进行认证
利用到了ngx_http_auth_basic_module,修改www.conf
配置
location / {
auth_basic "closed site"; #开启认证功能,off为关闭,其他string为开启
auth_basic_user_file conf/htpasswd; #用户密码文件,必须是密文密码,可由htpasswd生成
}
注意:auth_basic_user_file 里面的相对路径是/etc/nginx目录,而不是配置文件目录。
本例中的完整路径是/etc/nginxconf/htpasswd
curl访问验证
#错误提示401,需要进行验证
[root@web01 nginx]$ curl www.bigsky.cn
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
#使用用户名密码可以正常访问
[root@web01 nginx]$ curl www.bigsky.cn -u bigsky:123456
10.0.0.7 www.bigsky.cn
4.7.6 Nginx搭建文件共享服务器
利用到了ngx_http_autoindex_module,修改www.conf
配置
location / {
autoindex on; #开启站点目录索引功能
}
注意:访问站点目录会默认读取index.html首页文件,需要将站点目录下的首页文件删除或重命名
设置完后,访问站点文件可以出现目录索引
站点目录中的文件,符合
/etc/nginx/mime.types
配置识别类型的文件后缀,能够直接显示内容,没有配置过的文件后缀会直接下载。
4.7.7 Nginx设置字符编码
location / {
charset utf-8; #设置站点的字符编码
}
4.7.8 Nginx设置网站别名
主要用于负责均衡的情况下,定位特定的服务器
server {
listen 80;
server_name www.bigsky.cn sky.cn; #别名设置为sky.cn
...
}
4.7.9 监控网站状态
4.7.9.1 修改网站配置文件
状态模块ngx_http_stub_status_module
server {
listen 80;
server_name www.bigsky.cn sky.cn;
location / {
root /html/www;
index index.html;
auth_basic "closed site";
auth_basic_user_file password/htpasswd;
autoindex on;
charset utf-8;
}
location /AV {
allow 172.16.1.0/24;
deny 10.0.0.0/24;
root /html/www;
index index.html;
}
location /basic_status {
stub_status; #开启状态监控
}
}
直接访问相应域名的目录,就可以看到服务器状态
[root@web01 conf.d]$ curl www.bigsky.cn/basic_status
Active connections: 1
server accepts handled requests
3 3 11
Reading: 0 Writing: 1 Waiting: 0
4.7.9.2 状态信息详解
Active connections: 1
server accepts handled requests
16 16 49
Reading: 0 Writing: 1 Waiting: 0
详解:
Active connections:激活的连接数
accepts:接收的TCP连接数汇总,重启nginx服务清零
handled:处理的TCP连接数汇总,一般等于accepts,除非服务器遇到瓶颈
requests:总计的HTTP请求数量,一次TCP连接可以发送多个HTTP请求
Reading:正在读取请求报文的数量
Writing:正在发送响应报文的数量
Waiting:nginx队列机制,将要读取或响应的报文进行缓存
4.7.10 Nginx日志功能配置
访问日志:/var/log/nginx/access.log
错误日志:/var/log/nginx/error.log
4.7.10.1 错误日志
错误日志配置语法
Syntax: error_log file [level];
Default:
error_log logs/error.log error;
Context: main, http, mail, stream, server, location
错误级别:
debug, info, notice, warn, error, crit, alert, or emerg
默认在/etc/nginx/nginx.conf
,中配置
error_log /var/log/nginx/error.log warn;
4.7.10.2 访问日志
默认在/etc/nginx/nginx.conf
,中配置。默认只定义了main
格式的显示方式,好可以配置其他格式。
#定义日志文件格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#调用日志文件格式
access_log /var/log/nginx/access.log main;
格式参数详解:
$remote_addr:客户端IP
$remote_user:认证用户的用户名
$time_local:访问网站时间
"$request":请求报文的请求行
$status:用户访问的返回码
$body_bytes_sent:显示响应的报文尺寸Byte
"$http_referer":记录调用网站资源的链接地址信息(防止用户盗链)
"$http_user_agent":记录用户使用什么客户端软件
"$http_x_forwarded_for":记录反向代理发送的x_forwarded_for地址
默认所有站点的访问日志都记录在一个文件中,可以通过在conf.d
目录下的每个站点配置文件中,添加特定的日志记录位置。例如配置www.conf
,单独设置www.bigsky.cn日志
server {
listen 80;
server_name www.bigsky.cn;
access_log /var/log/nginx/www_access.log main;
...
}
4.7.11 Nginx location功能配置
location对用户uri进行匹配,有多种匹配书写语法
location = / #=精确匹配,优先级01 最高
location / #默认匹配
location /documents/ #按照目录进行匹配,优先级03
location ^~ /images/ #^~优先匹配(不识别uri中的特殊符号),优先级02
location ~* (gif|jpg|jpeg)$ #~*不区分大小写匹配,优先级03
location ~ \.php$ #~区分大小写匹配.php结尾的uri
4.7.12 配置优雅的错误显示
编辑虚拟主机配置文件
location / {
root /html/www/;
index index.html;
error_page 404 /error.jpg;
}
4.7.13 rewrite实现页面的跳转功能
使用场景:
1.地址跳转,如域名变更
2.协议跳转,访问http跳转到https
3.伪静态,将动态页面显示为静态页面,便于搜索引擎的录入,同时减少动态URL对外暴露过多参数
4.搜索引擎,SEO优化依赖于url路径,好记的url便于支持搜索引擎录入
利用ngx_http_rewrite_module模块的rewrite
指令。
rewrite
指令是使用指定的正则表达式regex
来匹配请求的URI
,如果匹配成功,就使用replacement
修改URI
。如果replacement
以http://
、https://
或$scheme
开头,就停止处理后续内容,并将replacement
的内容返回给客户端。
Syntax: rewrite regex replacement [flag];
rewrite 正则的信息 替换的信息
Default: —
Context: server, location, if
正则的语法举例:
rewrite ^/(.*) http://www.bigsky.cn/$1 permanent;
解释:
1)uri为/(.*),代表匹配任意
2)replacement以http://开头,$1表示之前的(.*),最终将http://www.bigsky.cn/.*返回给客户端
3)flag:permanent,永久跳转,301响应,浏览器会记录,第二次直接访问跳转后的地址
4)flag:redirect,临时跳转(常用!!),302响应,浏览器不会记录,每次访问都访问原地址
5)flag:break,后续所有rewrite/return规则都不再执行,只会执行本location中的root或者proxypass
6)flag:last,停止当前匹配,并根据rewrite匹配的规则重新发起一个请求。新请求又从第一阶段开始执行
为了避免循环跳转,有两种配置文件写法
4.7.13.1 单独写跳转server
需求将bigsky.cn跳转到www.bigsky.cn,为跳转部分单独写一个server段落
# bigsky.cn 部分
server {
listen 80;
server_name bigsky.cn ;
rewrite ^/(.*) http://www.bigsky.cn/$1 permanent;
}
# www.bigsky.cn 部分
server {
listen 80;
server_name www.bigsky.cn ;
access_log /var/log/nginx/www_access.log main;
location / {
root /html/www;
index index.html;
}
}
4.7.13.2 使用if判断
需求将bigsky.cn跳转到www.bigsky.cn,在同一个server段落中,使用if判断
#本例中使用~*进行忽略大小写的匹配
server {
listen 80;
server_name www.bigsky.cn bigsky.cn;
access_log /var/log/nginx/www_access.log main;
if ($host ~* "^bigsky.cn$"){
rewrite ^/(.*) http://www.bigsky.cn/$1 permanent;
}
location / {
root /html/www;
index index.html;
}
}
4.7.14 return实现页面的跳转功能
利用ngx_http_rewrite_module模块的return
指令。
Syntax: return code [text];
return code URL;
return URL;
Default: —
Context: server, location, if
举例:
return 301 http://xxxx
4.7.15 配置用户请求报文大小限制
nginx默认的大小限制是1M,用户上传大于1M的附件会拒绝。可以修改配置文件进行修改。
Syntax: client_max_body_size size;
Default:
client_max_body_size 1m;
Context: http, server, location
修改blog站点配置文件blog.conf
server {
listen 80;
server_name blog.bigsky.cn;
client_max_body_size 5M;
......
4.7.16 防止通过IP地址访问网站
server {
listen 80 default_server; # default_server表示符合条件时默认优先选择
server_name _; # _表示无域名
return 302 http://bigsky.cn
}
4.7.17 try_files检查文件是否存在
location / {
try_files $uri $uri/ /index.php @s3;
index index.php;
}
location @s3{
proxy_pass http://127.0.0.1:8080
}
顺序匹配
- 检查用户请求的uri文件是否存在,存在则解析
- 检查uri/目录是否存在,存在则解析
- 如果都不存在,则访问对应站点目录中的index.php文件
- 都不匹配跳转到@s3 location
4.7.18 防盗链
盗链:html页面中,直接使用它站静态资源
通过客户端请求的referer信息来限制
referer会告诉服务器,引用页是谁
优点:规则简单,配置使用方便
缺点:referer信息可以伪造
Syntax: valid_referers none | blocked | server_names | string ...;
Default: —
Context: server, locationnone:“Referer”字段为空
blocked:“Referer”字段不为空,但是不以http://或者https://开头;
server_names:来源头部包含XX域名,可以正则匹配,正则匹配以~开头;
例子
location ~ .*\.(jpg|jpeg|gif|png)$ {
# 指定合法的来源referer,$invalid_referer被设置为0,否则设置为1
valid_referers none blocked *.bigsky.cn server_names ~\.google\.;
if ($invalid_referer) {
return 403;
#将访问重定向到指定图片
rewrite ^(.*)$ 特定图片目录 break;
}
}
4.7.19 跨域访问
跨域访问:在网站代码中调用访问其他站点
浏览器会读取服务器返回的Access-Control-Allow-Origin信息,如果服务端允许则浏览器不会拦截,如果不允许则会报错原站不允许
例子:
location ~ .*\.(html|htm)$ {
# 允许哪些域名跨站访问
add_header Access-Control-Allow-Origin *.bigsky.cn;
# 允许哪些http请求
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
}
5 Nginx性能优化
5.1 修改文件描述符限制
vim /etc/security/limits.conf
* - nofile 65535
vim /usr/local/nginx/conf/nginx.conf
worker_rlimit_nofile 65535;
...
events {
...
}
5.2 允许复用time_wait状态的端口
vim /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 1
---------------------------------------------------------------------
$ sysctl -p
5.3 让浏览器缓存静态资源
location ~ \.(png|jpg|gif|jpeg)$ {
# 让浏览器缓存1天
expires 1d;
}
location ~ \.(js|css)$ {
# 让浏览器缓存30天
expires 30d;
}
- 服务端在将数据发送给客户端之前,首先计算应答数据的摘要(通常是MD5),把计算结果作为 ETag 的值,和数据一同发送给客户端。
- 客户端收到应答数据后,检测 HTTP Header 中是否有 ETag 字段,如有则缓存应答数据和 ETag 的值。
- 客户端再次发起同一请求时,读取上次缓存的 ETag 值,将其作为 If-None-Match 的值,并与请求数据一同发送给服务端。
- 服务端收到请求,执行请求,在把应答数据返回给客户端之前计算摘要,并与客户端上报的摘要比较,如果两次摘要相同,说明本次的应答数据与上一次请求的应答数据相同,且客户端已缓存该数据,则简单返回304。
- 客户端收到304,直接读取本地缓存的数据返回给调用网络模块的业务方。
Last-Modified与Etag类似。不过Last-Modified表示响应资源在服务器最后修改时间而已。Etag的优先级高于Last-Modified,Last-Modified不足为:
(1)Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间;
(2)如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存;
(3)有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形。
5.4 大文件开启tcp_nopush
将多个包一次发送,用于提高网络传输效率。
/usr/local/nginx/conf/nginx.conf
主配置文件,开启tcp_nopush
,需要同时开启sendfile
...
events {
...
}
http {
...
sendfile on;
tcp_nopush on;
...
}
5.5 提高网络传输实时性,开启tcp_nodelay
(1)tcp_nodelay off,会增加通信的延时,但是会提高带宽利用率。在高延时、数据量大的通信场景中应该会有不错的效果
(2)tcp_nodelay on,会增加小包的数量,但是可以提高响应速度。在及时性高的通信场景中应该会有不错的效果
开启
tcp_nodelay
,需要同时开启keepalive_timeout
,与tcp_nopush
互斥
/usr/local/nginx/conf/nginx.conf
主配置文件
...
events {
...
}
http {
...
tcp_nodelay on;
keepalive_timeout 65;
...
}
5.6 静态资源压缩
对图片和静态文档进行压缩
/usr/local/nginx/conf.d/server.conf
server配置文件
server {
listen 80;
server_name localhost;
root /www/html/phpipam;
...
location ~ .*\.(txt|xml)$ {
gzip on;
#使用压缩相应的,最低版本http协议
gzip_http_version 1.1;
#压缩的级别,从1到9,递增
gzip_comp_level 1;
#压缩的资源种类,在mime.types文件中查找
gzip_types text/plain text/xml,;
}
}
6 通用配置文件
创建所需的目录并授权
mkdir -p /var/log/nginx
mkdir -p /var/run/nginx
chown -R nginx:nginx /var/log/nginx
chown -R nginx:nginx /var/run/nginx
通用配置文件
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx/nginx.pid;
events {
use epoll;
worker_connections 10240; #限制每个进程能处理多少个连接,10240*CPU核心
}
http {
include mime.types;
default_type application/octet-stream;
charset utf-8;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
server_tokens off; #禁止浏览器显示nginx版本号
client_max_body_size 200m; #文件上传大小限制
# 静态资源服务器建议开启
sendfile on;
tcp_nopush on;
# 动态资源服务器建议开启
tcp_nodelay on;
keepalive_timeout 65;
gzip on;
gzip_disable "MSIE [1-6]\."; #对于IE1-6不启用压缩
gzip_http_version 1.1;
include /usr/local/nginx/conf.d/*.conf;
}