Nginx

正向代理

  • 正向代理,代理客户端,客户端需要配置代理 ()

    ​ 将虚拟机之中的服务代理到外部的过程,叫做正向代理也叫做接口映射,添加接口映射后我们可以将虚拟机之中的服务提供给外部进行调用。这个行为就相当于在客户端和服务器之间添加一个服务,帮助客户端 / 服务器端跨过某些两者之间无法访问的东西实现相互之间的访问。

    典型的案例是通过正向代理来实现在防火墙内的局域网客户端提供访问Internet的途径。

反向代理

  • 反向代理,代理服务端,客户端无感知

    ​ 反向代理就相比于nginx的正向代理要出名多了,我们通常认为反向代理其实才是nginx的主要功能。所谓反向代理十分简单,一般认为所谓的反向代理其实就是,将一个服务器集群以一个(虚拟)URL的方式提供给外部进行访问。

    典型的案例是通过反向代理来实现多个服务器一提提供某个资源的服务。以这种方式,我们可以通过使用一个IP地址,来提供多台服务器的相关服务

负载均衡

​ Nginx的异步框架可以处理很大的并发请求,把这些并发请求 hold 住之后就可以分发给后台服务端(backend servers,也叫做服务池, 后面简称 backend)来做复杂的计算、处理和响应,这种模式的好处是相当多的:隐藏业务主机更安全,节约了公网 IP 地址,并且在业务量增加的时候可以方便地扩容后台服务器。

​ 这时候集群的概念产生了,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服器,也就是我们所说的负载均衡。

就是相当于加了一层缓冲层,并且将缓冲层之中的请求,逐步的分发到对应的集群服务器之中的某台服务之中。需要注意的是

动静分离(nginx + tomcat)

​ 利用tomcat和nginx我们可以分别对网站的静态页面和动态页面进行区分部署,降低服务器的压力(现在基本没有纯静态页面了...)

Nginx的安装和启动

Linux版本安装

  1. Linux下,单机安装Nginx我们可以以离线的方式,安装Nginx,只需要先将Nginx的Linux版本下载,然后将Nginx上传到虚拟机/对应的机器上面,然后通过tar -zvxf[nginx压缩包全名]的方式,将Nginx解压出来。

    cd nginx压缩包目录
    tar -zvxf [nginx压缩包全名]
    
  2. 安装openssl相关依赖

    yum -y install make zlib zlib-devel gcc-c++ libtool  openssl openssl-devel
    
  3. 进入nginx的根目录,执行./configure

    ./configure
    
  4. 在命令行之中再执行make与make install

    make
    make install
    
  5. 到sbin文件夹之下启动nginx

    cd /usr/local/nginx/
    
  6. 根据nginx.conf之中的配置的端口,到防火墙之中开放相应的接口

    查看开发的端口号

    firewall-cmd --list-all
    
  7. 设置开放的端口号

    firewall-cmd --add-service=http –permanent
    
    sudo firewall-cmd --add-port=80/tcp --permanent
    
  8. 重启防火墙

    firewall-cmd -reload
    

Nginx的启动和关闭

Nginx
  1. 启动命令:在/usr/local/nginx/sbin 目录之下执行 ./nginx
  2. 关闭命令:在/usr/local/nginx/sbin 目录之下执行 ./nginx -s stop
  3. 重新加载命令: 在/usr/local/nginx/sbin 目录下执行 ./nginx -s reload·

设置Nginx为自启动服务

  1. 修改 linux 启动脚本 /etc/rc.d/rc
  2. 加入 : /usr/local/nginx/sbin/nginx

Nginx的配置文件(重点)

​ nginx安装目录下,其默认的配置文件都放在conf目录下,而主配置文件中的nginx.conf也在其中,nginx的相关配置基本都是在该文件上进行配置的。

nginx.conf文件的配置大概如下

user www-data;
worker_processes  1;
pid /run/nginx.pid
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
include nginx/otherSetting.conf

events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
    } 
}

我们可以根据nginx.cong配置文件可以分为三个部分:

第一部分:全局块

user www-data;            # 设置使用的用户/用户组
worker_processes  1;      # 设置并发连接数的,一般最好设置和cpu一致(可设置为auto)
pid /run/nginx.pid						# 设置 nginx 服务启动的时候pid存放位置
error_log logs/error.log; #warn error	# 设置 nginx 的错误记录的日志文件位置
#error_log logs/error.log notice;
#error_log logs/error.log info;
include nginx/otherSetting.conf 		#引入其他的配置文件,可使得配置灵活
daemon on; 			# 设置Nginx是否以守护线程启动Nginx,不随着控制终端结束而结束
					# 该部分默认为 daemon on,可设置为默认不为守护线程

​ 全局块的主要作用是影响nginx服务器整体运行的配置指令,主要包括有配置运行Nginx服务器的用户(组)、允许生成的worker process数进程PID存放路径、日志存放路径和类型以及配置文件的引入等。

总结

全局块可以设置 使用的用户、并发处理的数量、错误日志的位置、nginx使用的pid存放位置、引入其他配置文件、设置Nginx为守护线程(关闭终端不结束)

第二部分:events块

events {
    worker_connections  1024;     # 表示单个work peocess支持最大连接数为1024
    accept_mutex on;     # 表示设置Nginx网络连接序列化
    multi_accept;       # 用来设置是否允许同时接受多个网络连接
    use [???]        # 设置Nginx服务器选择用哪一种事件驱动处理网络消息
}

​ events 块涉及到的指令主要是影响着Nginx服务器与用户的网络连接,常用的设置包括是否开启对多 work process 下的网络连接进行序列化,即是否允许同时接受多个网络连接,选取哪一种事件驱动模型来处理连接请求,每个 work process 可以同时支持的最大连接数。

accept_mutex

默认为on ,已是性能优化过的处理方式 - accept_mutex on;

​ 该配置的主要作用是用来解决常说的“惊群”的问题,大致的意思是在某一个时刻,客户端发来一个请求链接,Nginx后端是以多进程的工作模式,也就是说有多个worker进程会被同时唤醒,但是最终只会有一个进程可以获得连接,如果每次唤醒的进程数目太多,就会影响Nginx的性能。将该上述值设置为 on (默认就是on),就会将请求连接设置为序列化,一个个的唤醒接收,防止了争抢情况的发生。

multi_accept

默认设置为off - multi_accept off;

​ 该配置决定nginx的一个工作进程是否只能接收一个新链接,否则一个工作进程可以接受当前所有的新连接。

use

默认设置 ??? 由操作系统决定

​ 该配置是nginx事件处理模型优化部分的一个重要的内容,method的可选值有select/poll/epoll/kqueue等,之前在准备centos环境的时候,我们强调过要使用linux内核在2.6以上,就是为了能使用epoll函数来优化Nginx。另外这些值的选择,我们也可以在编译的时候使用--with-select_module--without-select_module--with-poll_module--without-poll_module来设置是否需要将对应的事件驱动模块编译到Nginx的内核。

总结

event块可以设置NGINX网络连接处理方式、以及Nginx的最大连接数

第三部分:http块

​ 该部分是我们使用nginx的时候配置最常用,最经常配置的地方,该部分包括有代理、缓存和日志的定义等绝大多数的功能和第三方模块的配置都在这里。

需要注意的是:HTTP块还包含有http全局块和server块

3.1 HTTP全局块

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 logs/access.log main;
     sendfile    on;
     #tcp_nopush   on;
     #keepalive_timeout 0;
     keepalive_timeout 65;
     #开启gzip压缩功能
     #gzip on;
     server{
     	··· ···
     }
 }
include

默认值 MIME-TYPE - include MIME-TYPE;

​ 这里的include和公共块的include有所不同,我们浏览器之中可以显示的内容有HTML、XML、GIF等种类繁多的文件、媒体等资源,浏览器为了区分这些资源,就需要使用到MIMEType。所以说MIME Type是网络资源的媒体类型。Nginx作为web服务器,也需要能够识别前端请求的资源类型。

这里的include mime.types,其实是指引用mime.types文件之中MIMT类型与相关文件的文件后缀名的对应关系全部加入到当前的配置文件中的意思。

default_type

默认值 application/octet-stream - default_type application/octet-stream;

​ default_type的配置是配置于nginx响应前端段请求默认的MIME类型。

log_format main

默认值

'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

​ 可以通过修改日志文件的配置格式,来改变日志保存下来后的格式样

以下是相关可添加参数和示例

$remote_addr 客户端地址
$remote_user 客户端用户名称
$time_local 访问时间和时区
$request 请求的URI和HTTP协议
$status HTTP请求状态
$body_bytes_sent 发送给客户端文件内容大小
$http_referer url跳转来源
$http_user_agent 用户终端浏览器等信息
$http_host 请求地址,即浏览器中你输入的地址(IP或域名)
$request_time 处理请求的总时间,包含了用户数据接收时间
$upstream_response_time 建立连接和从上游服务器接收响应主体的最后一个字节之间的时间
$upstream_connect_time 花费在与上游服务器建立连接上的时间
$upstream_header_time 建立连接和从上游服务器接收响应头的第一个字节之间的时间

添加时间参数的日志格式

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$request_time" "$upstream_response_time"';
access_log

默认值 logs/access.log main; - access_log logs/access.log main;

​ 该参数的设置可以让我们设置日志存放的地址

sendfile

默认值 on - sendfile on;

​ 该参数可以开启Nginx高效传输方式

sendfile = off 时,应用程序读取磁盘中的文件以字节流的形式从磁盘中加载文件,然后再将文件以字节流的形式复制到内核中。内核在把文件推送到NC。
sendfile = on 时,应用程序直接向内核发送指令,让内核去读文件。读完文件内核直接推送给NC。只有一次复制操作,实现异步网络IO形式。因此,性能会有很大的提升。
具体还要根据实际使用情况来配置sendfile。当读取服务不能解析大量的文件时。还是建议将sendfile配置为off
**总结:  ** 开启sendfile之后,读取一些小的文件的时候,可以减去缓冲的过程而直接的让内核去读取磁盘文件,提供了性能

tcp_nopush

默认值 on - tcp_nopush on;

​ 激活tcp_nopush参数可以允许httpresponse header和文件的开始放在一个文件里发布,可以减少网络报文段的数量(基本不用改动这个)

keepalive_time

默认值 0 - keepalive_time 0;

​ 设置长连接的超时时间,这里设置的其实是HTTP所依靠的TCP的连接保持时间,就是HTTP1.1及其以后版本提供的链接复用的一个体现之一,在这里我们可以对该TCP的时长进行设置,在这个期间内如果有新的HTTP请求,就可以复用上次的链接。

keepalive_request

默认值 100 - keepalive_request 100;

​ 设置一个keep-alive最多可以被复用的次数。

gzip

默认值 on - gzip on;

​ 当设置为on之后,就会自动开启nginx的压缩功能。

开启了该功能之后,Nginx就可以对网络中的一些静态资源在传输的时候进行压缩处理,经过gzip的压缩之后,资源的大小就可以变得为原先的30%甚至更小,但是对图片和大文件而言基本是没有作用的。

更详细的参数如下

#开启gzip
gzip  on;  
#低于1kb的资源不压缩 
gzip_min_length 1k;
#压缩级别1-9,越大压缩率越高,同时消耗cpu资源也越多,建议设置在5左右。 
gzip_comp_level 5; 
#需要压缩哪些响应类型的资源,多个空格隔开。不建议压缩图片.
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;  
#配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
gzip_disable "MSIE [1-6]\.";  
#是否添加“Vary: Accept-Encoding”响应头
gzip_vary on;

3.2 Server块(虚拟主机[可有多个])

server {
        listen       80;
        server_name  localhost;
    	# 服务的证书
    	ssl_certificate cert.pem
        # 服务端key
        ssl_certificate_key cert.key
        # 会话缓存
        ssl_session_cache shared:SSL:1m
        # 会话超时时间
        ssl_session_timeout 5m;
    	# 加密算法
		ssl_ciphers HIGH:!aNULL:!MD5;
    	# 启动加密算法
    	ssl_prefer_server_ciphers on;
        location / {
            root   html;
            index  index.html index.htm;
        }
    }
listen

默认值 80 - listen 80;

​ 某个Server块下的listen配置的其实是在指定该虚拟主机的端口号。比如配置listen为80之后,nginx就会监听nginx当前所在的机器上的80端口,当然如果机器存在多张网卡的话,那么我们也可以直接指定某个网卡的端口号。

(1):listen unix:/var/run/nginx.sock 我们监听一个unix socket的地址;

(2):listen 127.0.0.1:8000; 监听一个地址加端口,因为可能有多个地址

(3):listen 127.0.0.1; 监听只指向一个地址,会默认使用80端口;

(4):listen 8000; 只监听了一个端口,但是并没有指明地址;

(5):listen *:8000; 当只有一张显卡的时候,效果和第四种情况一致

server_name

默认值 localhost - sever_name localhost;

文档之中,server_name后跟特定域名(请求的网址)/IP地址,此时第一个域名为主域名。也就是

设置为域名时

​ server_name example.com www.example.com

​ 特别的,example.com和*.example.com可以合并为一个,语法为

​ server_name .example.com

设置为IP时

​ server_name 127.0.0.1

access_log

默认值 /usr/local/nginx/ - access_log logs/host.access.log.main

​ 该配置项为配置当前虚拟主机的日志存放地点

location(location一般网页配置)

决定最终映射的是哪一个网页的页面和文件

location / {
        root /sites/default;
}

重点配置内容

​ 一个server块可以配置多个location块(就好像一台电脑可以启动多个网站),这一个块的实际作用主要是基于Nginx服务器接收到的请求字符串,然后根据请求的字符串,去到server中的与域名进行匹配,匹配到就可以进入匹配内部的location的配置路径,如果匹配成功,那么就有该项目的根路径去进行处理。

以下是通过示例对location进行解释

# 第一类,从根目录进行匹配
# 第一种
location / {       
    root /web; 
    #相应策略     
}
# 第二种
location /bbs {
    root "/web";
    # 相应策略
}

# 第二类,从指定路径后缀进行匹配
# 第一种
location  /prefix/ {
    root /;
}
# 或者是
location  = /prefix/  {
    return 507;          # 返回错误页面507 (如果没有配置,则直接返回507)
}

# 第三类,正则表达式匹配
# (匹配命中的文件是不区分大小写)
location ~ /bbs {
    root /;
}
# (匹配命中的文件要求区分大小写)
location ~* /bbs {
    root /;
}

第一类(以xxx开始的url都能命中)

​ 第一类的第一种表示,当前路径及其子路径之下的所有对象都有效,但是优先度最低(用户所有请求,都能被他匹配到)。并且root /web表示,网页的根目录在/web下,访问的时候只需要直接访问http://127.0.0.1或者是他的域名即可。

​ 第一类的第二种表示,匹配路径是根目录下的bbs之中。说明网页根目录位于/web/bbs之中。访问的时候只需要直接访问http://127.0.0.1/bbs或者是http://127.0.0.1/bbs/子路径的时候,就能被匹配到。

匹配示例

​ 如果同时配置了第一种和第二种两种情况配置的情况下,匹配成功取决于最长路径的匹配规则,如果访问的是 http://127.0.0.1/bbs/子路径时,两个location的配置都会被命中,但是最终命中的会是匹配后缀长的一个。

第二类(完全匹配命中)

​ 第二类的第一种表示,仅当完全匹配路径的时候才能命中,但凡有后续的后缀都无法命中该location配置。例如:第二类之中的第一种location配置仅当访问的url是 http://127.0.0.1/prefix 才能正确的匹配命中,访问的路径就算是 http://127.0.0.1/preifx/a 都不可以正确访问到

第三类(正则表达式匹配)

​ 第三类的第一种表示当后缀之中是以bbs结束的(即是正则表达式的匹配规则),即可在ngixn的使用之中匹配命中。例如:第三类之中的第一种location配合仅当访问的url是 http://127.0.0.1/bbs,即可命中相应目录[实例中是根目录下bbs]()相应的文件,大小写不影响命中。如果是第二种,即会因为大小写影响是否命中。

优先度关系

​ 这么多配置的方式,在实际运行的时候自然会导致出现多个命中的情况出现。那么他们之间命中的优先级就成为了最终调用的是哪一个网页的关键了。

优先级如下:location = (第二类) > location [正则表达式] > location最大前缀(即是第一类中第二种/bss) > location /

location(错误页面配置)
#error_page 404       /404.html;
 
# 将服务器错误页面重定向到静态页面/50x.html

error_page  500 502 503 504 /50x.html;
location = /50x.html { #/usr/local/nginx/html/50x.html
	root  html;
}    

步骤

  1. 配合error_page配置,我们可以对出现错误访问的时候返回的页面进行配置
  2. 添加对错误URL,及返回内容配置即可

多Server块配合示例

#server块和“虚拟主机”的概念有密切联系。
 server {
   #监听端口
   listen    80;
   server_name localhost;
   #编码识别
   #charset koi8-r;
   #日志格式及日志存放路径 /usr/local/nginx/
   #access_log logs/host.access.log main;
   location / {
     #站点根目录,即网站程序存放目录 /usr/local/nginx/html
     root  html;
     #首页排序
     index index.html index.htm;
   }
   #错误页面
   #error_page 404       /404.html;
   # 将服务器错误页面重定向到静态页面/50x.html
   error_page  500 502 503 504 /50x.html;
   location = /50x.html { #/usr/local/nginx/html/50x.html
     root  html;
   }    
  
   #代理PHP脚本到Apache上监听127.0.0.1:80
   location ~ \.php$ {
     proxy_pass  http://127.0.0.1;
   }
 
   #将PHP脚本传递到正在监听127.0.0.1:9000的FastCGI服务器
   location ~ \.php$ {
     root      html;
     fastcgi_pass  127.0.0.1:9000;
     fastcgi_index index.php;
     fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
     include    fastcgi_params;
   }
 
   # 如果Apache的文档根目录与nginx的根目录一致,则拒绝访问.htaccess文件
   location ~ /\.ht {
     deny all;
   }
}

#另一个虚拟主机,混合使用IP、名称和基于端口的配置
server {
  listen    8000;
  listen    somename:8080;
  server_name somename alias another.alias;
  location / {
    root  html;
    index index.html index.htm;
}