7、综合架构详解-网站服务

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特点

  1. 支持高并发,消耗内存少
  2. 具有多种功能
    • 网站web服务功能 ---apache
    • 网站负载均衡功能 ---LVS
    • 网站缓存服务 ---Squid
  3. 在多种系统平台都可以部署
  4. 在网络通讯时使用的是异步网络IO模型:epoll模型(apache--select模型)
select模型与epoll模型的对比

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服务配置文件

主区域关键参数

  1. worker_processes auto;
    nginx 进程数,建议按照cpu 数目来指定,一般为它的倍数 (如,2个四核的cpu计为8)。
  2. worker_cpu_affinity auto;
    自动为每个进程分配cpu
  3. worker_rlimit_nofile 65535;
    一个nginx 进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx 进程数相除,但是nginx 分配请求并不是那么均匀,所以最好与ulimit -n的值保持一致。

事件区域关键参数

  1. use epoll;
    使用epoll 的I/O 模型
  2. 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生效。想定义全局的rootindex文件,需要在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.confbbs.confblog.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 网站页面访问原理

  1. 将域名解析 www.bigsky.cn:8080---> 10.0.0.7
  2. 建立TCP连接,10.0.0.7:8080
  3. 应用层HTTP协议发出请求,请求头:host:www.bigsky.cn
  4. 如果服务端没有相同域名的server虚拟主机,会找满足端口要求(8080)的第一个虚拟主机,显示主机的网站页面

4.7.5 网站安全访问配置

4.7.5.1 根据用户地址进行限制

www.bigsky.cn/AV/ 目录:

  • 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

401 Authorization Required

401 Authorization Required


nginx/1.18.0
#使用用户名密码可以正常访问 [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。如果replacementhttp://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
    }

顺序匹配

  1. 检查用户请求的uri文件是否存在,存在则解析
  2. 检查uri/目录是否存在,存在则解析
  3. 如果都不存在,则访问对应站点目录中的index.php文件
  4. 都不匹配跳转到@s3 location

4.7.18 防盗链

盗链:html页面中,直接使用它站静态资源

通过客户端请求的referer信息来限制
referer会告诉服务器,引用页是谁
优点:规则简单,配置使用方便
缺点:referer信息可以伪造

Syntax: valid_referers none | blocked | server_names | string ...;
Default: —
Context: server, location

none:“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;    
}
  1. 服务端在将数据发送给客户端之前,首先计算应答数据的摘要(通常是MD5),把计算结果作为 ETag 的值,和数据一同发送给客户端。
  2. 客户端收到应答数据后,检测 HTTP Header 中是否有 ETag 字段,如有则缓存应答数据和 ETag 的值。
  3. 客户端再次发起同一请求时,读取上次缓存的 ETag 值,将其作为 If-None-Match 的值,并与请求数据一同发送给服务端。
  4. 服务端收到请求,执行请求,在把应答数据返回给客户端之前计算摘要,并与客户端上报的摘要比较,如果两次摘要相同,说明本次的应答数据与上一次请求的应答数据相同,且客户端已缓存该数据,则简单返回304。
  5. 客户端收到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.confserver配置文件

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;
}

你可能感兴趣的:(7、综合架构详解-网站服务)