fa

1.1  Nginx WEB入门简介

Nginx ("engine x") 是一个高性能HTTP 和 反向代理 服务器、IMAP、POP3、SMTP 服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。

由于Nginx的高性能、轻量级,目前越来越多的互联网企业开始使用Nginx WEB服务器。据Netcraft统计,在2017年4月份,世界上最繁忙的网站中有28.72 %使用Nginx作为其服务器或者代理服务器。

nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev.

For a long time, it has been running on many heavily loaded Russian sites including YandexMail.RuVK, and Rambler.

According to Netcraft, nginx served or proxied 28.72% busiest sites in April 2017. Here are some of the success stories: Netflix,Wordpress.comFastMail.FM.

The sources and documentation are distributed under the 2-clause BSD-like license.

Commercial support is available from Nginx, Inc.

它已经在众多流量很大的俄罗斯网站上使用了很长时间,这些网站包括YandexMail.RuVKontakte,以及Rambler。目前互联网主流公司京东、360、百度、新浪、腾讯、阿里都在使用Nginx作为自己的WEB服务器。

Nginx特点是占有内存少,并发能力强,事实上Nginx的并发能力确实在同类型的网页服务器中表现较好。

Nginx相对于Apache优点如下:

q  高并发响应性能非常好,官方Nginx处理静态文件并发5w/s;

q  负载均衡及反向代理性能非常强;

q  系统内存和CPU占用率低;

q  可对后端服务进行健康检查;

q  支持PHP cgi方式和FastCGI方式;

q  可以作为缓存服务器、邮件代理服务器;

q  配置代码简洁且容易上手。

1.2  Nginx工作原理

Nginx WEB服务器最主要就是各种模块的工作,模块从结构上分为核心模块、基础模块和第三方模块,其中三类模块分别如下:

q  核心模块:HTTP模块、EVENT模块和MAIL模块等;

q  基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块;

q  第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块、Limit_req模块、Upstream check module等;

Nginx的模块从功能上分为如下三类。

Handlers(处理器模块):此类模块直接处理请求,并进行输出内容和修改headers信息等操作,Handlers处理器模块一般只能有一个;

Filters (过滤器模块):此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出;

q  Proxies (代理类模块):此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。

Nginx由Nginx内核和模块组成,其中内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端的请求映射到一个location block,而location是Nginx配置中的一个指令,用于访问的URL匹配,而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作,如图14-1所示:

图14-1 Nginx WEB工作流程图

Nginx的高并发得益于其采用了epoll模型,与传统的服务器程序架构不同,epoll是Linux内核2.6以后才出现的,Nginx采用epoll模型,异步非阻塞,而apache采用的是select模型:

Select特点:select 选择句柄的时候,是遍历所有句柄,也就是说句柄有事件响应时,select需要遍历所有句柄才能获取到哪些句柄有事件通知,因此效率是非常低。

epoll的特点:epoll对于句柄事件的选择不是遍历的,是事件响应的,就是句柄上事件来就马上选择出来,不需要遍历整个句柄链表,因此效率非常高。

Nginx默认以80端口监听在服务器上,并且启动一个master进程,同时有master进程生成多个工作进程,当浏览器发起一个HTTP连接请求,每个进程都有可能处理这个连接,怎么做到的呢?怎么保证同一时刻一个HTTP请求被一个工作进程处理呢。

首先每个worker进程都是从Master进程fork出来,在Master进程里面,建立好需要listen的socket(listenfd)之后,会fork出多个worker进程。

所有worker进程的listenfd会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有worker进程在注册listenfd读事件前抢accept_mutex,抢到互斥锁的那个进程注册listenfd读事件,在读事件里调用accept接受该连接。

当一个worker进程在accept这个连接之后,就开始读取请求、解析请求、处理请求,产生数据后,再返回给客户端,最后才断开连接,这样形成一个完整的请求流程。如图14-2所示:

图14-2 Nginx Worker进程工作原理

1.3  Nginx安装配置

Nginx WEB安装时可以指定很多的模块,默认需要安装Rewrite模块,也即是需要系统有PCRE库,安装Pcre支持Rewrite功能。如下为安装Nginx WEB服务器方法:

源码的路径,而不是编译后的路径,否则会报错。

#安装PCRE库支持

yum install pcre-devel pcre -y

#下载Nginx源码包

cd /usr/src

wget -c http://nginx.org/download/nginx-1.12.0.tar.gz

#解压Nginx源码包

tar -xzf nginx-1.12.0.tar.gz

#进入解压目录,然后sed修改Nginx版本信息为JWS

cd nginx-1.12.0 ; sed -i -e 's/1.12.0//g' -e 's/nginx\//JWS/g' -e

's/"NGINX"/"JWS"/g' src/core/nginx.h

#预编译Nginx

useradd www ;./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module

#.configure预编译成功后,执行make命令进行编译

make

#make执行成功后,执行make install 正式安装

make install

#至此Nginx WEB服务器安装完毕。

测试Nginx服务安装是否正确,同时启动Nginx WEB 服务,代码命令如下:

/usr/local/nginx/sbin/nginx  -t  检查nginx配置文件是否正确,返回OK即正确。

[root@localhost ~]# /usr/local/nginx/sbin/nginx -t

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@localhost ~]#

然后启动nginx,/usr/local/nginx/sbin/nginx 回车即可。查看进程是否已启动:

[root@localhost ~]# ps -ef |grep nginx

nobody    5381 30285  0 May16 ?        09:04:31 nginx: worker process        

root     30285     1  0  2017 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx

root     32260 32220  0 12:34 pts/0    00:00:00 grep nginx

[root@localhost ~]#

通过浏览器访问Nginx默认测试页面,如图14-3所示:

图14-3 Nginx WEB浏览器访问

1.4  Nginx管理及升级

Nginx WEB服务器安装完毕,可以执行如下命令对其进管理和维护,命令如下:

#查看nginx进程

ps -ef|grep nginx

#平滑启动nginx

kill -HUP `cat /var/run/nginx.pid`

或者

nginx -s reload

其中进程文件路径在配置文件nginx.conf中可以找到。

平滑启动的意思是在不停止nginx的情况下,重启nginx,重新加载配置文件,启动新的工作线程,完美停止旧的工作线程。

#完美停止nginx

kill -QUIT `cat /var/run/nginx.pid`

#快速停止nginx

kill -TERM `cat /var/run/nginx.pid`

或者

kill -INT `cat /var/run/nginx.pid`

#完美停止工作进程(主要用于平滑升级)

kill -WINCH `cat /var/run/nginx.pid`

#强制停止nginx

pkill -9 nginx

#检查对nginx.conf文件的修改是否正确

nginx -t -c /etc/nginx/nginx.conf 或者 nginx -t

#停止nginx的命令

nginx -s stop或者pkill nginx

#查看nginx的版本信息

nginx -v

#查看完整的nginx的配置信息

nginx -V

Nginx WEB服务器定期更新,如果需要将低版本升级或者将高版本降级,升级或者降级方法如下,分为四个步骤,包括软件下载、预编译、编译、配置,具体方法如下:

wget http://www.nginx.org/download/nginx-1.4.2.tar.gz 

获取旧版本nginx的configure选项

/usr/local/nginx/sbin/nginx -V

编译新版本的Nginx

tar  -xvf  nginx-1.4.2.tar.gz

cd nginx-1.4.2

./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module

make

备份旧版本的nginx可执行文件,复制新版本的nginx这行文件

mv /usr/local/nginx/sbin/nginx  /usr/local/nginx/sbin/nginx.old

cp objs/nginx /usr/local/nginx/sbin/

测试新版本nginx是否正常

/usr/local/nginx/sbin/nginx -t

平滑重启升级nginx

kill -QUIT `cat /usr/local/nginx/log/nginx.oldbin` ##关闭旧版nginx

验证nginx是否升级成功

/usr/local/nginx/sbin/nginx  -V显示最新编译的版本信息即可。

1.5  Nginx配置文件优化一

学习Nginx服务的难点在于对配置文件的理解和优化,熟练掌握Nginx配置文件参数的含义可以更快的掌握Nginx,如下为Nginx.conf配置文件常用参数详解:

#定义Nginx运行的用户和用户组

user  www  www;

#启动进程,通常设置成和cpu的数量相等

worker_processes  8

worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000

#为每个进程分配cpu,上例中将8个进程分配到8个cpu,当然可以写多个,或者将一个进程分配到多个cpu。

worker_rlimit_nofile  102400

#该指令是当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n的值保持一致。

#全局错误日志及PID文件

error_log  /usr/local/nginx/logs/error.log info;

#错误日志定义等级,[ debug | info | notice | warn | error | crit ]

pid        /usr/local/nginx/nginx.pid;

#工作模式及连接数上限

events {

use   epoll                 

#epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能。

worker_connections  10000  

#单个后台worker process进程的最大并发链接数 (最大连接数=连接数*进程数)

multi_accept  on;

#尽可能多的接受请求.

}

#设定http服务器,利用它的反向代理功能提供负载均衡支持

http {

#设定mime类型,类型由mime.type文件定义

include       mime.types;

default_type  application/octet-stream;

#设定日志格式

access_log    /usr/local/nginx/log/nginx/access.log;

sendfile      on;

#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用必须设为 on

#如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime。

#autoindex  on; 

#开启目录列表访问,合适下载服务器,默认关闭。

tcp_nopush on;  

#防止网络阻塞

keepalive_timeout  65

#keepalive超时时间,客户端到服务器端的连接持续有效时间,当出现对服务器的后继请求时,keepalive-timeout功能可避免建立或重新建立连接。(节省服务器资源、CPU、内存、网卡)

tcp_nodelay   on;

#提高数据的实时响应性

#开启gzip压缩

gzip on;

gzip_min_length  1k;

gzip_buffers     4 16k;

gzip_http_version 1.1;

gzip_comp_level  2;

#压缩级别大小,最大为9,值越小,压缩后比例越小,CPU处理更快。

#值越大,消耗CPU比较高。

gzip_types       text/plain application/x-javascript text/css application/xml;

gzip_vary on;

client_max_body_size 10m;     

#允许客户端请求的最大单文件字节数

client_body_buffer_size 128k;

#缓冲区代理缓冲用户端请求的最大字节数.

proxy_connect_timeout 90     

#nginx跟后端服务器连接超时时间(代理连接超时)

proxy_send_timeout 90         

#后端服务器数据回传时间(代理发送超时)

proxy_read_timeout 90         

#连接成功后,后端服务器响应时间(代理接收超时)

proxy_buffer_size 4k;         

#设置代理服务器(nginx)保存用户头信息的缓冲区大小

proxy_buffers 4 32k;          

#proxy_buffers缓冲区,网页平均在32k以下的话,这样设置

proxy_busy_buffers_size  64k;  

#高负荷下缓冲大小(proxy_buffers*2)

#设定请求缓冲

large_client_header_buffers  4 4k;

client_header_buffer_size 4k

#客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k

#不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。

open_file_cache max=102400 inactive=20s;

#这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。

open_file_cache_valid 30s;

#这个是指多长时间检查一次缓存的有效信息。

open_file_cache_min_uses 1;

#open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive

#包含其它配置文件,如自定义的虚拟主机

include vhosts.conf;

1.6  Nginx配置文件优化二

Nginx WEB默认发布静态页面,也可以均衡后端动态网站,用户发起HTTP请求,如果请求静态页面,Nginx直接处理并返回,如果请求的是动态页面,Nginx收到请求之后会进行判断,转到后端服务器去处理。

Nginx实现负载均衡需要基于upstream模块,同时需要设置location proxy_pass转发指令实现。

如下为Ningx应用负载均衡集群配置,根据后端实际情况修改即可,jfedu_www为负载均衡模块的名称,可以任意指定,但必须跟vhosts.conf、Nginx.conf虚拟主机的proxy_pass段保持一致,否则不能将请求转发至后端的服务器,weight表示配置权重,在fail_timeout内检查max_fails次数,失败则剔除均衡。

upstream jfedu_www {
        url_hash;

              #server   127.0.0.1:8080  weight=1  max_fails=2  fail_timeout=15;

              server   127.0.0.1:8081 weight=1  max_fails=2  fail_timeout=15s;

       }

#虚拟主机配置

       server {

              #侦听80端口

        listen       80;

        #定义使用www.jfedu.net访问

        server_name  www.jfedu.net;

        #设定本虚拟主机的访问日志

        access_log  logs/access.log  main;

              root   /data/webapps/www;  #定义服务器的默认网站根目录位置

        index index.php index.html index.htm;   #定义首页索引文件的名称

        #默认请求

        location ~ /{

          root   /data/webapps/www;      #定义服务器的默认网站根目录位置

          index index.php index.html index.htm;   #定义首页索引文件的名称

          #以下是一些反向代理的配置.

                proxy_next_upstream http_502 http_504 error timeout invalid_header;

                #如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。

          proxy_redirect off;

          #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP

          proxy_set_header Host $host;

          proxy_set_header X-Real-IP $remote_addr;

          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                proxy_pass  http://jfedu_www;     #请求转向后端定义的均衡模块

       }

        # 定义错误提示页面

                     error_page   500 502 503 504 /50x.html; 

            location = /50x.html {

            root   html;

        }

              #配置Nginx动静分离,定义的静态页面直接从Nginx发布目录读取。

              location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$

              {

                     root /data/webapps/www;

                     #expires定义用户浏览器缓存的时间为3天,如果静态页面不常更新,可以设置更长,这样可以节省带宽和缓解服务器的压力,在浏览器保存该类型文件的天数。

                     expires      3d

              }

        #PHP脚本请求全部转发到 FastCGI处理. 使用FastCGI默认配置.

        location ~ \.php$ {

            root /root;

            FastCGI_pass 127.0.0.1:9000;

            FastCGI_index index.php;

            FastCGI_param SCRIPT_FILENAME /data/webapps/www$FastCGI_script_name;

            include FastCGI_params;

        }

        #设定查看Nginx状态的地址

        location /NginxStatus {

            stub_status  on;

        }

     }

}

通过Expires参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。具体Expires定义是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。

如果静态文件不常更新,Expires可以设置为30d,表示在这30天之内再次访问该静态文件,浏览器会发送一个HTTP请求,会比对服务器该文件最后更新时间是否有变化,如果没有变化,则不会从服务器抓取,返回HTTP状态码304,如果有修改,则直接从服务器重新下载,返回HTTP状态码200。

1.7  Nginx虚拟主机实战

在真实的企业服务器环境中,为了充分利用服务器的资源,单台Nginx WEB服务器同时会配置N个网站,也可称之为配置N个虚拟域名的主机,即多个域名对应同一个80端口。

在Nginx.conf中加入server代码,Nginx虚拟主机完整代码如下:

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

#virtual hosts config 2017/5/18

server {

        listen       80;

        server_name  www.jf1.com;

        access_log  logs/jf1.access.log;

        location / {

            root   html/jf1;

            index  index.html index.htm;

        }

}

server {

        listen       80;

        server_name  www.jf2.com;

        access_log  logs/jf2.access.log;

        location / {

            root   html/jf2;

            index  index.html index.htm;

        }

 }

}

创建两个不同的目录mkdir -p /usr/local/nginx/html/{jf1,jf2},然后分别在两个目录创建两个不同的index.html网站页面即可。通过Windows客户端配置hosts绑定IP与两个域名的对应关系,在IE浏览器访问测试效果,如图14-4(a)、14-4(b)所示:

图14-4(a) Nginx 虚拟主机www.jf1.com

图14-4(b) Nginx 虚拟主机www.jf2.com

1.8  Nginx Location深入剖析

Nginx由内核和模块组成,其中内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端的请求映射到一个location block,而location是Nginx配置中的一个指令,用于访问的URL匹配,而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。

默认Nginx.conf配置文件中至少存在一个location /,即表示客户端浏览器请求的URL为:域名+/,如果location /newindex/,则表示客户端浏览器请求的URL为:域名+/newindex/。常见Location匹配URL的方式如下:

=                                                     字面精确匹配;

^~                                                    最大前缀匹配;

/                                                      不带任何前缀:最大前缀匹配;

~                                                     大小写相关的正则匹配;

~*                                                    大小写无关的正则匹配;

@                                                     location内部重定向的变量。

其中Location =、^~、/属于普通字符串匹配,Location ~、~*属于正则表达式匹配,Location优先级与其在Nginx.conf配置文件中的先后顺序无关。

Location = 精确匹配会第一个被处理,如果发现精确匹配,Nginx则停止搜索其他任何Location的匹配。

普通字符匹配,正则表达式规则和完整URL规则将被优先和查询匹配,^~为最大前缀匹配,如果匹配到该规则,Nginx则停止搜索其他任何Location的匹配,否则nginx会继续处理其他location指令。

正则匹配"~"和"~*",如果找到相应的匹配,则Nginx停止搜索其他任何Location的匹配;当没有正则表达式或者没有正则表达式被匹配的情况下,那么匹配程度最高的逐字匹配指令会被使用。

Location规则匹配优先级总结如下:

(location =) > (location 完整路径) > (location ^~ 路径) > (location ~|~* 正则顺序) > (location 部分起始路径) > (location  /)

       如下为Nginx Location规则案例演示:

location  = / {

  [ configuration  L1 ]

  #只会匹配/,优先级比Location /低。

}

location  = /index.html {

  [ configuration  L2 ] 

#只会匹配/index.html,优先级最高。

}

location  / {

  [ configuration L3 ]

  #匹配任何请求,因为所有请求都是以"/"开始;

  #但是更长字符匹配或者正则表达式匹配会优先匹配,优先级最低。

}

location = /images/ {

  [ configuration L4 ]

  #匹配任何以/images/开始的请求,并停止匹配其它location;

}

location ~* \.(html|txt|gif|jpg|jpeg)$ {

  [ configuration L5]

  # 匹配以html、txt、gif、jpg、jpeg结尾的URL文件请求;

  # 但是所有/images/目录的请求将由 [Configuration L4]处理。

}

浏览器发起HTTP Request URI案例与Location规则案例匹配如下:

q  / ->匹配configuration L3;

q  /index.html匹配configuration L2;

q  /images/匹配configuration L4;

q  /images/logo.png匹配configuration L4;

q  /img/test.jpg匹配configuration L5。

企业生产环境中无需在Nginx.conf配置文件中同时添加五种规则匹配,如下为企业生产环境Nginx Location部分配置代码:

location /

{

    root /var/www/html/;

       expires      60d;

}

location ~ .*\.(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$

{

       root /var/www/html/;

       expires      60d;     

}

location ~ .*\.(jsp|php|cgi|do)$

{

       root /var/www/html/;

       proxy_pass http://linux_web;

    proxy_http_version 1.1;

    proxy_set_header Connection "";

    proxy_set_header Host  $host;

    proxy_set_header X-Real-IP $remote_addr;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    

}

location =/newindex.html

{

    root /var/www/newwww/;

       expires      60d;

}

1.9  企业实战Nginx动静分离架构

Nginx动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开,可以理解成使用Nginx处理静态页面,Tomcat、Resin、PHP、ASP处理动态页面。

动静分离从目前实现角度来讲大致分为两种,一种是纯粹的把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;另外一种方法就是动态跟静态文件混合在一起发布,通过Nginx来分开。

Nginx线上WEB服务器动静分离及Nginx.conf完整配置文件代码如下:

user www www;

worker_processes 8;

worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

pid /usr/local/nginx/nginx.pid;

worker_rlimit_nofile 102400;

events

{

use epoll;

worker_connections 102400;

}

http

{

  include       mime.types;

  default_type  application/octet-stream;

  FastCGI_intercept_errors on;

  charset  utf-8;

  server_names_hash_bucket_size 128;

  client_header_buffer_size 4k;

  large_client_header_buffers 4 32k;

  client_max_body_size 300m;

  sendfile on;

  tcp_nopush     on;

  keepalive_timeout 60;

  tcp_nodelay on;

  client_body_buffer_size  512k;

  proxy_connect_timeout    5;

  proxy_read_timeout       60;

  proxy_send_timeout       5;

  proxy_buffer_size        16k;

  proxy_buffers            4 64k;

  proxy_busy_buffers_size 128k;

  proxy_temp_file_write_size 128k;

  gzip on;

  gzip_min_length  1k;

  gzip_buffers     4 16k;

  gzip_http_version 1.1;

  gzip_comp_level 2;

  gzip_types       text/plain application/x-javascript text/css application/xml;

  gzip_vary on;

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

              '$status $body_bytes_sent "$http_referer" '

              '"$http_user_agent"  $request_time';

upstream  jvm_web1 {

    server   192.168.149.130:8080  weight=1  max_fails=2  fail_timeout=30s;

    server   192.168.149.130:8081  weight=1  max_fails=2  fail_timeout=30s;

}

include vhosts.conf;

}

如下为vhosts.conf配置文件中内容:

server

  {

    listen       80;

    server_name www.jf1.com;

    index  index.jsp index.html index.htm;

    root  /data/webapps/www1;

    location /

    {

         proxy_next_upstream http_502 http_504 error timeout invalid_header;

         proxy_set_header  Host  $host;

         proxy_set_header  X-Real-IP  $remote_addr;

         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

         proxy_pass http://jvm_web1;

    }

    location ~ .*\.(php|jsp|cgi|shtml)?$

    {

         proxy_set_header Host  $host;

         proxy_set_header X-Real-IP $remote_addr;

         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

         proxy_pass http://jvm_web1;

    }

    location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$

    {

              root /data/webapps/www1;

              expires      30d;

    }

              access_log  /data/logs/jvm_web1/access.log main;

              error_log   /data/logs/jvm_web1/error.log  crit;

}

配置文件代码中:location ~ .*\.(php|jsp|cgi|shtml)表示匹配动态页面请求,然后将请求proxy_pass到后端服务器,而location ~ .*\.(html|htm|gif|jpg|jpeg |ico|txt|js|css)表示匹配静态页面请求本地返回。

检查Nginx配置是否正确即可,然后测试动静分离是否成功,在192.168.149.130服务器启动8080、8081 Tomcat服务或者LAMP服务,删除后端Tomcat或者LAMP服务器上的某个静态文件,测试是否能访问该文件,如果可以访问说明静态资源Nginx直接返回了,如果不能访问,则证明动静分离不成功。

1.10   企业实战LNMP高性能服务器

公共网关接口”(Common Gateway Interface,CGI),是HTTP服务器与本机或者其它机器上的程序进行通信的一种工具,其程序须运行在网络服务器上。

CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量,如php、perl、tcl等。

FAST-CGI:WEB服务器与处理程序之间通信的一种协议(App server 和Web server 之间的通信协议),是CGI的改进方案。CGI程序反复加载是CGI性能低下的主要原因,如果CGI程序保持在内存中并接受FastCGI进程管理器调度,则可以提供良好的性能、伸缩性、Fail-Over特性等。FastCGI是常驻型的CGI,它可以一直运行,在请求到达时,不会花费时间去fork一个进程来处理。

FastCGI是语言无关的、可伸缩架构的CGI开放扩展,将CGI解释器进程保持在内存中,以此获得较高的性能。FastCGI是一个协议,php-fpm实现了这个协议,php-fpm的FastCGI协议需要有进程池,php-fpm实现的FastCGI进程叫php-cgi,所以php-fpm其实是他自身的FastCGI或php-cgi进程管理器,如图14-5所示:

图14-5 Nginx+FastCGI通信原理图

企业级LNMP(Nginx+PHP(FastCGI)+MySQL)主流架构配置方法如下,分别安装Nginx、MYSQL、PHP服务,步骤如下:

(1)           Nginx安装配置

wget -c http://nginx.org/download/nginx-1.12.0.tar.gz

tar -xzf nginx-1.12.0.tar.gz

cd nginx-1.12.0

useradd www ;./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module

make

make install

(2)           MYSQL安装配置

yum  install  cmake  ncurses-devel ncurses –y

wget http://down1.chinaunix.net/distfiles/mysql-5.5.20.tar.gz

tar  -xzf  mysql-5.5.20.tar.gz

cd  mysql-5-5.20

cmake  . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql55 \

-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \

-DMYSQL_DATADIR=/data/mysql \

-DSYSCONFDIR=/etc \

-DMYSQL_USER=mysql \

-DMYSQL_TCP_PORT=3306 \

-DWITH_XTRADB_STORAGE_ENGINE=1 \

-DWITH_INNOBASE_STORAGE_ENGINE=1 \

-DWITH_PARTITION_STORAGE_ENGINE=1 \

-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

-DWITH_MYISAM_STORAGE_ENGINE=1 \

-DWITH_READLINE=1 \

-DENABLED_LOCAL_INFILE=1 \

-DWITH_EXTRA_CHARSETS=1 \

-DDEFAULT_CHARSET=utf8 \

-DDEFAULT_COLLATION=utf8_general_ci \

-DEXTRA_CHARSETS=all \

-DWITH_BIG_TABLES=1 \

-DWITH_DEBUG=0

make

make install

(3)           PHP安装配置

wget  http://museum.php.net/php5/php-5.3.10.tar.gz

yum -y install gd curl curl-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel

cd php-5.3.10

./configure --prefix=/usr/local/php5  --enable-fpm --enable-debug --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --enable-mbstring --with-curl --with-mysql=/usr/local/mysql55/ --with-mysqli=/usr/local/mysql55/bin/mysql_config --with-config-file-path=/usr/local/php5/etc

make

make install

cp  php.ini-development   /usr/local/php5/etc/php.ini

cp  /usr/local/php5/etc/php-fpm.conf.default  /usr/local/php5/etc/php-fpm.conf

/usr/local/php5/sbin/php-fpm

cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm

(4)           Nginx配置文件配置

server { 

 include port.conf; 

 server_name www.jfedu.net jfedu.net; 

  location / { 

 index index.html index.php; 

 root /usr/local/nginx/html; 

 } 

 location  ~ \.php$ { 

            root           html; 

            FastCGI_pass   127.0.0.1:9000; 

            FastCGI_index  index.php; 

            FastCGI_param  SCRIPT_FILENAME  html$FastCGI_script_name; 

            include        FastCGI_params; 

        } 

}

(5)           测试LNMP架构测试,创建index.php测试页面,如图14-6所示:

图14-6 LNMP企业实战测试页面

1.11   Nginx Rewrite规则详解一

Rewirte规则也称为规则重写,主要功能是实现浏览器访问HTTP URL的跳转,其正则表达式是基于Perl语言。通常而言,几乎所有的WEB服务器均可以支持URL重写。Rewrite URL规则重写的用途:

q  对搜索引擎优化(Search Engine Optimization,SEO)友好,利于搜索引擎抓取网站页面;

q  隐藏网站URL真实地址,浏览器显示更加美观;

q  网站变更升级,可以基于Rewrite临时重定向到其他页面。

Nginx Rewrite规则使用中有三个概念需要理解,分别是:Rewrite结尾标识符、Rewrite规则常用表达式、Nginx Rewrite变量,如下为三个概念的详解:

(1)           Nginx Rewrite结尾标识符,用于Rewrite规则末尾,表示规则的执行属性。

last :相当于Apache里的(L)标记,表示完成rewrite匹配;

break:本条规则匹配完成后,终止匹配,不再匹配后面的规则。 

redirect:返回302临时重定向,浏览器地址会显示跳转后的URL地址。 

permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址。 

其中last和break用来实现URL重写时,浏览器地址栏URL地址不变。

(2)           Nginx Rewrite规则常用表达式,主要用于匹配参数、字符串及过滤设置。

.                                                      匹配任何单字符;

[word]                                              匹配字符串:word;

[^word]                                         不匹配字符串:word;

jfedu|jfteach                                   可选择的字符串:jfedu|jfteach;

?                                                      匹配0到1个字符;

*                                                      匹配0到多个字符;

+                                                     匹配1到多个字符;

^                                                      字符串开始标志;

$                                                      字符串结束标志;

\n                                                     转义符标志。

(3)           Nginx Rewrite变量,常用于匹配HTTP请求头信息、浏览器主机名、URL等。

HTTP headers:HTTP_USER_AGENT, HTTP_REFERER, HTTP_COOKIE, HTTP_HOST, HTTP_ACCEPT;

connection & request: REMOTE_ADDR, QUERY_STRING;

server internals: DOCUMENT_ROOT, SERVER_PORT, SERVER_PROTOCOL;

system stuff: TIME_YEAR, TIME_MON, TIME_DAY。

详解如下:

HTTP_USER_AGENT                用户使用的代理,例如浏览器;

HTTP_REFERER                       告知服务器,从哪个页面来访问的;

HTTP_COOKIE                       客户端缓存,主要用于存储用户名和密码等信息;

HTTP_HOST                              匹配服务器ServerName域名;

HTTP_ACCEPT                          客户端的浏览器支持的MIME类型;      

REMOTE_ADDR                    客户端的IP地址

QUERY_STRING                       URL中访问的字符串;

DOCUMENT_ROOT                   服务器发布目录;

SERVER_PORT                          服务器端口;

SERVER_PROTOCOL                服务器端协议;

TIME_YEAR                             年;

TIME_MON                               月;

TIME_DAY                                日;

(4)           Nginx Rewrite以下配置均配置在nginx.conf或者vhosts.conf中,企业中常用的Nginx Rewrite案例如下:

  1. 将jfedu.net跳转至www.jfedu.net。

if ($host = 'jfedu.net' ) {

        rewrite ^/(.*)$ http://www.jfedu.net/$1  permanent;

}

  1. 访问www.jfedu.net跳转www.test.com/new.index.html

rewrite   ^/$  http://www.test.com/index01.html  permanent;

  1. 访问/jfedu/test01/跳转至/newindex.html,浏览器地址不变。

rewrite   ^/jfedu/test01/$     /newindex.html     last;

  1. 多域名跳转到www.jfedu.net。

if ($host != ‘www.jfedu.net’ ) {

rewrite ^/(.*)$  http://www.jfedu.net/$1  permanent;

}

  1. 访问文件和目录不存在跳转至index.php。

if ( ! -e $request_filename )
{
rewrite  ^/(.*)$  /index.php  last;
}

  1. 目录对换 /xxxx/123456  ====>  /xxxx?id=123456。

rewrite    ^/(.+)/(\d+)      /$1?id=$2       last;

  1. 判断浏览器User Agent跳转。

if( $http_user_agent  ~ MSIE)
{
rewrite ^(.*)$ /ie/$1 break;
}

  1. 禁止访问以.sh,.flv,.mp3为文件后缀名的文件。

location ~ .*\.(sh|flv|mp3)$
{
       return 403;

  1. 将移动用户访问跳转至移动端。

if ( $http_user_agent ~* "(Android)|(iPhone)|(Mobile)|(WAP)|(UCWEB)" )

{

rewrite ^/$      http://m.jfedu.net/       permanent;

}

  1. 匹配URL访问字符串跳转。

if ($args ~* tid=13){

 return 404;

}

  1. 访问/10690/jfedu/123跳转至/index.php?tid/10690/items=123,[0-9]表示任意一个数字,+表示多个,(.+)表示任何多个字符。

rewrite   ^/([0-9]+)/jfedu/(.+)$     /index.php?tid/$1/items=$2     last;

1.12   Nginx WEB日志分析

在企业服务器运维中,当Nginx服务器正常运行后,SA会经常密切关注Nginx的访问日志,发现有异常的日志信息需要进行及时处理。

Nginx默认日志路径/usr/local/nginx/logs/,其中包含访问日志access.log 和错误记录日志error.log,如图查看nginx访问日志:cat /usr/local/nginx/logs/access.log |more,如图14-7所示:

 

图14-7 Nginx访问日志信息

Nginx访问日志打印的格式可以自定义,例如Nginx日志打印格式配置如下,Log_format 用来设置日志格式,Name(模块名)  Type(日志类型),可以配置多个日志模块,分别供不同的虚拟主机日志记录所调用:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                  '$status $body_bytes_sent "$http_referer" '

              '"$http_user_agent"  $request_time';

Nginx日志格式内部变量及函数参数说明:

$remote_addr                    记录客户端IP地址;

$server_name              虚拟主机名称;

$http_x_forwarded_for     HTTP的请求端真实的IP;

$remote_user                   记录客户端用户名称;

$request                           记录请求的URL和HTTP协议;

$status                             记录返回HTTP请求的状态;

$uptream_status              upstream的状态;

$ssl_protocol             SSL协议版本;

$body_bytes_sent             发送给客户端的字节数,不包括响应头的大小;

$bytes_sent                      发送给客户端的总字节数;

$connection_requests        当前通过一个连接获得的请求数量;

$http_referer                    记录从哪个页面链接访问过来的;

$http_user_agent              记录客户端浏览器相关信息;

$request_length                请求的长度,包括请求行,请求头和请求正文;

$msec                    日志写入时间;

$request_time                      请求处理时间,单位为秒,精度毫秒,Nginx接受用户请求的第一个字节到发送完响应数据的时间,包括:接收请求数据时间、程序响应时间、输出、响应数据时间。

$upstream_response_time 应用程序响应时间,Nginx向后端服务建立连接开始到接受完数据然后关闭连接为止的总时间。

通过Nginx日志,可以简单分析WEB网站的运行状态、数据报表、IP、UV(unique visitor)、PV(page view)访问量等需求,如下为常用需求分析:

(1)           统计Nginx服务器独立IP数。 

awk  '{print $1}' access.log |sort -r|uniq -c | wc -l

(2)           统计Nginx服务器总PV量。

awk  '{print $7}' access.log |wc -l

(3)           统计Nginx服务器UV统计。

awk  '{print $11}' access.log |sort -r|uniq -c |wc -l

(4)           分析Nginx访问日志截止目前为止访问量前20的IP列表。

awk  '{print  $1}'  access.log|sort |uniq -c |sort -nr |head -20

(5)           分析Nginx访问日志早上9点至中午12点的总请求量。

sed  -n  "/2016:09:00/,/2016:12:00/"p access.log

awk  '/2017:09:00/,/2017:12:00/' access.log|wc –l

(6)           分析Nginx访问日志总的独立IP数。

awk  '{print $1}'  access.log |sort |uniq -c|wc -l

(7)           分析Nginx访问日志截止目前为止访问量前20的IP列表。

awk  '{print  $1}'  access.log|sort |uniq -c |sort -nr |head -20

(8)           分析Nginx访问日志截止目前为止访问量前20的IP列表。

awk  '{print  $1}'  access.log|sort |uniq -c |sort -nr |head -20

(9)           分析Nginx访问日志状态码404、502、503、500、499等错误信息页面,打印错误出现次数大于20的IP地址。

awk '{if ($9~/502|499|500|503|404/) print $1,$9}' access.log|sort|uniq –c|sort –nr | awk '{if($1>20) print $2}'

(10)       分析Nginx访问日志访问最多的页面。

awk  '{print $7}'   access.log |sort |uniq -c|sort -nr|head -20

(11)       分析Nginx访问日志请求处理时间大于5秒的URL,并打印出时间、URL、访客IP。

awk  '{if ($NF>5)  print $NF,$7,$1}'  access.log|sort -nr|more

1.13   Nginx日志切割案例

Nginx WEB服务器每天会产生大量的访问日志,而且不会自动地进行切割,如果持续天数访问,将会导致该access.log日志文件容量非常大,不便于SA查看相关的网站异常日志。

可以基于Shell 脚本结合Crontab计划任务对Nginx日志进行自动、快速的切割,其切割的方法使用mv命令即可,如图14-8所示。

#!/bin/bash

#auto mv nginx log shell

#by author jfedu.net

S_LOG=/usr/local/nginx/logs/access.log

D_LOG=/data/backup/`date +%Y%m%d`

echo -e "\033[32mPlease wait start cut shell scripts...\033[1m"

sleep 2

if [ ! -d $D_LOG ];then

        mkdir -p  $D_LOG

fi

mv $S_LOG  $D_LOG

kill  -USR1  `cat /usr/local/nginx/logs/nginx.pid`

echo "-------------------------------------------"

echo "The Nginx log Cutting Successfully!"

echo "You can access backup nginx log $D_LOG/access.log files."

图14-8 Nginx日志切割

将如上脚本内容写入auto_nginx_log.sh文件,crontab /var/spool/cron/root文件中添加如下代码,每天凌晨自动切割日志:

0  0  *  *  *  /bin/sh  /data/sh/auto_nginx_log.sh >>/tmp/nginx_cut.log 2>&1

1.14   Nginx防盗链配置案例配置

防盗链的含义是网站内容本身不在自己公司的服务器上,而通过技术手段,直接在调用其他公司的服务器网站数据,而向最终用户提供此内容。一些小网站盗链高访问量网站的音乐、图片、软件的链接,然后放置在自己的网站中,通过这种方法盗取高访问量网站的空间和流量。

网站每天访问量很大,而且占用了很多不必要的带宽,浪费资源,所以必须采取一些限制措施。防盗链其实就是采用服务器端编程技术,通过URL过滤、主机名等实现的防止盗链的软件。

例如http://www.jfedu.net/linux/页面,如果没有配置防盗链,别人就能轻而易举的在其的网站上引用该页面。Nginx防盗链配置代码如下:

server {

        listen       80;

        server_name  jfedu.net www.jfedu.net;

        location / {

            root   html/b;

            index  index.html index.htm;

        }

        location ~* \.(gif|jpg|png|swf|flv)$ {

                valid_referers none blocked  jfedu.net  *.jfedu.net;

                root   html/b;

        if ($invalid_referer) {

                #rewrite ^/ http://www.jfedu.net/403.html;

                return 403;

                }

        }

}

Nginx防盗链参数详解:

valid_referers表示可用的referers设置

none 表示没有referers,直接通过浏览器或者其他工具访问。

blocked表示有referers,但是被代理服务器或者防火墙隐藏;

jfedu.net 表示通过jfedu.net访问的referers;

*.jfedu.net 表示通过*.jfedu.net访问的referers,*表示任意host主机。

除了以上方法,按照如下方法设置也可以实现防盗链:

location ~* \.(gif|jpg|png|swf|flv)$

if ($host !=’*.jfedu.net’) {

return 403;

}

防盗链测试,找另外一台测试服务器,基于Nginx发布如下test.html页面,代码如下,去调用www.jfedu.net官网的test.png图片,由于www.jfedu.net官网设置了防盗链,所以无法访问该图片。

<html>

<h1>TEST Nginx PNG</h1>

<img src="http://www.jfedu.net/test.png">

</html>

默认没有配置Nginx防盗链,网站正常调用www.jfedu.net的logo图片,访问如图14-9所示:

图14-9 Nginx无防盗链正常调用图片

配置Nginx防盗链,网站无法正常调用www.jfedu.net的logo图片,访问如图14-10所示:

 

图14-10 Nginx防盗链403禁止访问

第2章   HTTP协议详解

超文本传输协议(Hyper Text Transfer Protocol,HTTP)是互联网上应用最为广泛的一种网络协议。所有的WWW服务器都基于该协议。HTTP设计最初的目的是为了提供一种发布WEB页面和接收WEB页面的方法。

本章向读者介绍TCP、HTTP协议、HTTP资源定位、HTTP请求及响应头详细信息、HTTP状态码及MIME类型详解等。

2.1  TCP协议与HTTP协议

1960年美国人Ted Nelson构思了一种通过计算机处理文本信息的方法,并称之为超文本(hyper text),为HTTP超文本传输协议标准架构的发展奠定了根基。Ted Nelson组织协调万维网协会(World Wide Web Consortium)和互联网工程工作小组(Internet Engineering Task Force )共同合作研究,最终发布了一系列的RFC,其中著名的RFC 2616定义了HTTP 1.1。

很多读者对TCP协议与HTTP协议存在疑问,这两者有什么区别呢,从应用领域来说,TCP协议主要用于数据传输控制,而HTTP协议主要用于应用层面的数据交互,本质上两者没有可比性。

HTTP协议属于应用层协议,是建立在TCP协议基础之上,HTTP协议以客户端请求和服务器端应答为标准,浏览器通常称为客户端,而WEB服务器称之为服务器端。客户端打开任意一个端口向服务端的指定端口(默认为80)发起HTTP请求,首先会发起TCP三次握手,TCP三次握手的目的是建立可靠的数据连接通道,TCP三次握手通道建立完毕,进行HTTP数据交互,如图9-1(a)、9-1(b)所示:

图9-1(a) HTTP与TCP关系结构图

图9-1(b) HTTP客户端与服务器

当客户端请求的数据接收完毕后,HTTP服务器端会断开TCP连接,整个HTTP连接过程非常短。HTTP连接也称为无状态的连接,无状态连接是指客户端每次向服务器发起HTTP请求时,每次请求都会建立一个新的HTTP连接,而不是在一个HTTP请求基础上进行所有数据的交互。

2.2  资源定位标识符

发起HTTP请求的内容资源由统一资源标示符(Uniform Resource Identifiers,URI)来标识,关于资源定位及标识有三种:URI、URN、URL,三种资源定位详解如下:

q  统一资源标识符(uniform resource identifier,URI),用来唯一标识一个资源;

q  统一资源定位器(uniform resource locator,URL),是一种具体的URI。URL可以用来标识一个资源,而且访问或者获取该资源;

q  统一资源命名(uniform resource name,URN),通过名字来标识或识别资源。

如图9-2所示,可以直观区分URI、URN、URL的区别:

图9-2 URI、URN、URL关联与区别

三种资源标识,其中URL资源标识方式使用最为广泛,完整的URL标识格式如下:

protocol://host[:port]/path/.../[?query-string][#anchor]

protocol                       基于某种协议,常见协议:http、https、ftp、rsync等;

host                      服务器的IP地址或者域名;

port                        服务器的端口号,如果是HTTP 80端口,默认可以省略。

path                      访问资源在服务器的路径;

query-string                    传递给服务器的参数及字符串;

anchor-                   锚定结束;

Http URL案例演示如下:

http://www.jfedu.net/newindex/plus/list.php?tid=2#jfedu

protocol:                   http协议;

host:                    www.jfedu.net;

path:                    /newindex/plus/list.php

Query String:             tid=2

Anchor:                 jfedu

2.3  HTTP与端口通信

HTTP WEB服务器默认在本机会监听80端口,不仅HTTP会开启监听端口,其实每个软件程序在Linux系统中运行,会以进程的方式启动,程序就会启动并监听本地接口的端口,为什么会引入端口这个概念呢?

端口是TCP/IP协议中应用层进程与传输层协议实体间的通信接口,端口是操作系统可分配的一种资源,应用程序通过系统调用与某个端口绑定后,传输层传给该端口的数据会被该进程接收,相应进程发给传输层的数据都通过该端口输出。

在网络通信过程中,需要唯一识别通信两端设备的端点,就是使用端口识别运行于某主机中的应用程序。如果没有引入端口,则只能通过PID进程号进行识别,而PID进程号是系统动态分配的,不同的系统会使用不同的进程标识符,应用程序在运行之前没有明确的进程号,如果需要运行后再广播进程号则很难保证通信的顺利进行。

而引入端口后,就可以利用端口号识别应用程序,同时通过固定端口号来识别和使用某些公共服务,例如如HTTP默认使用80端口,而FTP使用21、20端口,MYSQL则使用3306端口。

使用端口还有一个原因是随着计算机网络技术的发展,物理机器上的硬件接口已不能满足网络通信的要求,而TCP/IP协议模型作为网络通信的标准就解决了这个通信难题。

TCP/IP协议中引入了一种被称为套接字(Socket)的应用程序接口。基于Socket接口技术,一台计算机就可以与任何一台具有Socket接口的计算机进行通信,而监听的端口在服务器端也称之为Socket接口。

2.4  HTTP Request与Response详解

客户端浏览器向WEB服务器发起Request, Web服务器接到Request后进行处理,会生成相应的Response信息返给浏览器,客户端浏览器收到服务器返回的Response信息,会对信息进行解析处理,最终用户看到浏览器展示WEB服务器的网页内容。

客户端发起Request,Request消息分为三个部分,分别包括:Request line、Request header、Body,如图9-3所示:

图9-3 HTTP Request Message组成

Unix/Linux系统中执行CURL -v命令可以打印访问WEB服务器的Request及Response详细处理流程,如图9-4所示:

curl  -v  http://192.168.111.131/index.html

图9-4 Request及Response请求回应流程

(1)           Request信息详解如表9-1所示:

GET /index.html  HTTP/1.1

请求行

 

 

 

Request Message

User-Agent: curl/7.19.7

Host: 192.168.111.131

Accept: */*

……

 

请求头部

空行

请求Body

第一部分:请求行,指定请求类型,访问的资源及使用的HTTP协议版本。

GET表示Request请求类型为GET;/index.html表示访问的资源;HTTP/1.1表示协议版本。

第二部分:请求头部,请求行下一行起,指定服务器要使用的附加信息;

User-Agent 表示用户使用的代理软件,常指浏览器;HOST表示请求的目的主机。

第三部分:空行,请求头部后面的空行表示请求头发送完毕。

第四部分:请求数据也叫Body,可以添加任意的数据,Get请求的Body内容默认为空。

表9-1 Request请求头详解

(2)           Response信息详解如表9-2所示:

HTTP/1.1 200 OK

响应行

 

 

 

Response Message

Server: nginx/1.10.1

Date: Thu, 11 May 2017

Content-Type: text/html

……

 

响应头部

空行

<h1>www.jf1.com Pages</h1>

响应Body

第一部分:响应状态行,包括HTTP协议版本号、状态码、状态消息。

HTTP/1.1表示HTTP协议版本号;200表示返回状态码;OK表示状态消息。

第二部分:消息报头,响应头部附加信息。

Date表示生成响应的日期和时间,Content-Type表示指定MIME类型的HTML(text/html),编码类型是UTF-8,记录文件资源的Last-Modified时间。

第三部分:空行,表示消息报头响应完毕。

第四部分:响应正文,服务器返回给客户端的文本信息。

表9-2 Request请求头详解

(3)           Request请求方法根据请求的资源不同,有如下请求方法:

GET方法,向特定的资源发出请求,获取服务器端数据;

POST方法,向WEB服务器提交数据进行处理请求,常指提交新数据;

PUT方法,向WEB服务器提交上传最新内容,常指更新数据;

DELETE方法,请求删除Request-URL所标识的服务器资源;

TRACE方法,回显服务器收到的请求,主要用于测试或诊断;

CONNECT方法,HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器;

OPTIONS方法,返回服务器针对特定资源所支持的HTTP请求方法;

HEAD方法,HEAD方法跟GET方法相同,只不过服务器响应时不会返回消息体。

2.5  HTTP 1.0/1.1协议区别

HTTP 协议定义服务器端和客户端之间文件传输的沟通方式HTTP1.0运行方式,如图9-5所示:

图9-5 HTTP1.0 客户端、服务器传输模式

q  基于HTTP协议的客户/服务器模式的信息交换过程,如图所示,它分四个过程,建立连接、发送请求信息、发送响应信息、关闭连接;

q  浏览器与WEB服务器的连接过程是短暂的,每次连接只处理一个请求和响应。对每一个页面的访问,浏览器与WEB服务器都要建立一次单独的连接;

q  浏览器到WEB服务器之间的所有通讯都是完全独立分开的请求和响应。

HTTP1.1运行方式,如图9-6所示:

 

图9-6 HTTP1.1 客户端、服务器传输模式

q  在一个TCP连接上可以传送多个HTTP请求和响应;

q  多个请求和响应过程可以重叠;

q  增加了更多的请求头和响应头,比如Host、If-Unmodified-Since请求头等。

2.6  HTTP状态码详解

HTTP状态码(HTTP Status Code)是用来表示WEB服务器HTTP Response状态的3位数字代码,常见的状态码范围分类:

100-199                       用于指定客户端应相应的某些动作;

200-299                       用于表示请求成功;

300-399                       已移动的文件且被包含在定位头信息中指定新的地址信息;

400-499                       用于指出客户端的错误;

500-599                       用于支持服务器错误。

       HTTP协议Response常用状态码详解表9-3所示:

HTTP状态码

状态码英文含义

状态码中文含义

100

Continue

HTTP/1.1新增状态码,表示继续,客户端继续请求HTTP服务器;

101

Switching Protocols

服务器根据客户端的请求切换协议,切换到HTTP的新版本协议;

200

OK

HTTP请求完成,常用于GET、POST请求中;

301

Moved Permanently

永久移动,请求的资源已被永久的移动到新URI;

302

Found

临时移动,资源临时被移动,客户端应继续使用原有URI;

304

Not Modified

文件未修改,请求的资源未修改,服务器返回此状态码时,常用于缓存;

400

Bad Request

客户端请求的语法错误,服务器无法解析或者访问;

401

Unauthorized

请求要求用户的身份认证;

402

Payment Required

此状态码保留,为以后使用;

403

Forbidden

服务器理解请求客户端的请求,但是拒绝执行此请求;

404

Not Found

服务器没有该资源,请求的文件找不到;

405

Method Not Allowed

客户端请求中的方法被禁止;

406

Not Acceptable

服务器无法根据客户端请求的内容特性完成请求;

499

Client has closed connection

服务器端处理的时间过长;

500

Internal Server Error

服务器内部错误,无法完成请求;

502

Bad Gateway

服务器返回错误代码或者代理服务器错误的网关;

503

Service Unavailable

服务器无法响应客户端请求,或者后端服务器异常;

504

Gateway Time-out

网关超时或者代理服务器超时;

505

HTTP Version not supported

服务器不支持请求的HTTP协议的版本,无法完成处理。

表9-3 HTTP常用状态码

2.7  HTTP MIME 类型支持

浏览器接收到WEB服务器的Response信息,浏览器会进行解析,在解析页面之前,浏览器必须启动本地相应的应用程序来处理获取到的文件类型。

基于多用途互联网邮件扩展类型 (Multipurpose Internet Mail Extensions,MIME),可以明确某种文件在客户端用某种应用程序来打开,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开,设计之初是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它使得HTTP传输的不仅是普通的文本,可以支持更多文件类型、多媒体音、视频等。

在HTTP协议中,HTTP Response消息,MIME类型被定义在Content-Type header中,例如:Content-Type: text/html,表示默认指定该文件为html类型,在浏览器端会以HTML格式来处理。

在最早的HTTP协议中,并没有附加的数据类型信息,所有传送的数据都被客户程序解释为超文本标记语言HTML文档,为了支持多媒体数据类型,新版HTTP协议中就使用了附加在文档之前的MIME数据类型信息来标识数据类型,如表9-4所示:

Mime-Types(MIME类型)

Dateiendung (扩展名)

Bedeutung

application/msexcel

*.xls *.xla

Microsoft Excel Dateien

application/mshelp

*.hlp *.chm

Microsoft Windows Hilfe Dateien

application/mspowerpoint

*.ppt *.ppz *.pps *.pot

Microsoft Powerpoint Dateien

application/msword

*.doc *.dot

Microsoft Word Dateien

application/octet-stream

*.exe

exe

application/pdf

*.pdf

Adobe PDF-Dateien

application/post******

*.ai *.eps *.ps

Adobe Post******-Dateien

application/rtf

*.rtf

Microsoft RTF-Dateien

application/x-httpd-php

*.php *.phtml

PHP-Dateien

application/x-java******

*.js

serverseitige Java******-Dateien

application/x-shockwave-flash

*.swf *.cab

Flash Shockwave-Dateien

application/zip

*.zip

ZIP-Archivdateien

audio/basic

*.au *.snd

Sound-Dateien

audio/mpeg

*.mp3

MPEG-Dateien

audio/x-midi

*.mid *.midi

MIDI-Dateien

audio/x-mpeg

*.mp2

MPEG-Dateien

audio/x-wav

*.wav

Wav-Dateien

image/gif

*.gif

GIF-Dateien

image/jpeg

*.jpeg *.jpg *.jpe

JPEG-Dateien

image/x-windowdump

*.xwd

X-Windows Dump

text/css

*.css

CSS Stylesheet-Dateien

text/html

*.htm *.html *.shtml

-Dateien

text/java******

*.js

Java******-Dateien

text/plain

*.txt

reine Textdateien

video/mpeg

*.mpeg *.mpg *.mpe

MPEG-Dateien

video/vnd.rn-realvideo

*.rmvb

realplay-Dateien

video/quicktime

*.qt *.mov

Quicktime-Dateien

video/vnd.vivo

*viv *.vivo

Vivo-Dateien

表9-4  HTTP MIME类型详解

猜你喜欢

转载自www.cnblogs.com/zhj5551/p/10056200.html
fa