0
点赞
收藏
分享

微信扫一扫

Visual Studio 2022 cmake配置opencv开发环境

茗越 2023-07-29 阅读 54

 一、初识Nginx

 1.1 Nginx概述

Nginx是一款轻量级的Web服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。Nginx 专为性能优化而开发,使用异步非阻塞事件驱动模型

常见服务器

  • Apache
  • Tomcat

 没有Nginx的情况

 有了Nginx的话

 1.2 Nginx 四大应用场景

 HTTP服务器

Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务器,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。

反向代理

反向代理应该是Nginx使用最多的功能了,反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。增强安全性。

负载均衡 

负载均衡也是Nginx常用的一个功能,负载均衡其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

 动静分离

动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路。

 1.3 为什么要使用Nginx

 背景

互联网飞速发展的今天,大用户量高并发已经成为互联网的主体.怎样能让一个网站能够承载几万个或几十万个用户的持续访问呢?

单机架构

引入反向代理实现负载均衡

 总结

 二、Nginx安装部署

2.1 环境准备

学习环境

操作系统:Centos7.5 X64

四项确认

  1. 确认网络
#使用以下命令检查centos系统能否上网
ping www.baidu.com

     2.确认yum可用

#使用如下命令检查yum源是否可用,出现一堆版本号表示可用。
yum list

     3.确认防火墙关闭

#查看防火墙是否关闭
firewall-cmd --state

#永久关闭防火墙
systemctl disable firewalld.service

    4.确认关闭SELinux安全防护

#进入配置文件
vim /etc/selinux/config

#修改该配置
SELINUX=disabled

 一项安装

yum -y install gcc make automake pcre-devel zlib zlib-devel openssl openssl-devel

2.2 Nginx下载与安装

下载Nginx源码

官网下载Nginx软件http://Nginx.org

 在虚拟机中下载源码

wget https://nginx.org/download/nginx-1.20.2.tar.gz

 解压文件到usr/local目录下

tar -zxvf nginx-1.20.2.tar.gz -C /usr/local

其中各个目录中存放的文件作用为:

配置ngix参数

#创建目录
[root@node1 Nginx-1.20.1]# mkdir -p /var/temp/nginx/client

#配置参数
[root@node1 Nginx-1.20.1]# ./configure \
--prefix=/usr/local/nginx \
--pid-path=/usr/local/nginx/logs/nginx.pid \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--with-http_ssl_module \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi

编译

make

安装

make install

如果出现ngnix文件就表示ngix安装成功啦! 

 2.3 Nginx目录详解

conf目录

Nginx所有配置文件的目录,极其重要。在该目录中包含一个Nginx.conf配置文件。

[root@node1 Nginx]# ll conf/
总用量 68
-rw-r--r-- 1 root root 1077 8月 27 15:37 fastcgi.conf
-rw-r--r-- 1 root root 1077 8月 27 15:37 fastcgi.conf.default
-rw-r--r-- 1 root root 1007 8月 27 15:37 fastcgi_params
-rw-r--r-- 1 root root 1007 8月 27 15:37 fastcgi_params.default
-rw-r--r-- 1 root root 2837 8月 27 15:37 koi-utf
-rw-r--r-- 1 root root 2223 8月 27 15:37 koi-win
-rw-r--r-- 1 root root 5231 8月 27 15:37 mime.types
-rw-r--r-- 1 root root 5231 8月 27 15:37 mime.types.default
-rw-r--r-- 1 root root 2656 8月 27 15:37 Nginx.conf
-rw-r--r-- 1 root root 2656 8月 27 15:37 Nginx.conf.default
-rw-r--r-- 1 root root 636 8月 27 15:37 scgi_params
-rw-r--r-- 1 root root 636 8月 27 15:37 scgi_params.default
-rw-r--r-- 1 root root 664 8月 27 15:37 uwsgi_params
-rw-r--r-- 1 root root 664 8月 27 15:37 uwsgi_params.default
-rw-r--r-- 1 root root 3610 8月 27 15:37 win-utf

html目录

Nginx的默认站点目录。

[root@node1 Nginx]# ll html/
总用量 8
-rw-r--r-- 1 root root 494 8月 27 15:37 50x.html #错误提示页面
-rw-r--r-- 1 root root 612 8月 27 15:37 index.html #访问Nginx时的首页

logs目录

存放Nginx的日志文件。 access.log error.log

#刚安装完Nginx,从未启动过的话logs目录下什么都没有,只有启动Nginx后,才会出现以下三个文件
[root@node1 Nginx]# ll logs/
总用量 4
-rw-r--r-- 1 root root 0 8月 27 16:29 access.log #记录正常访问的日志
-rw-r--r-- 1 root root 0 8月 27 16:29 error.log #错误日志
-rw-r--r-- 1 root root 6 8月 27 16:29 Nginx.pid #Nginx进程id
[root@node1 Nginx]# cat logs/Nginx.pid 
24514 #当前启动Nginx的master进程的id

sbin目录

Nginx命令的目录,如Nginx的启动命令。

[root@node1 Nginx]# ll sbin/
总用量 5884
-rwxr-xr-x 1 root root 6023208 8月 27 15:37 Nginx #启动关闭等操作的脚本
[root@node1 Nginx]# ./sbin/Nginx #启动Nginx
[root@node1 Nginx]# ps aux|grep Nginx #查看Nginx的进程
root   24514 0.0 0.1 45996 1136 ?     Ss  16:29  0:00 Nginx: master process ./sbin/Nginx
nobody  24515 0.0 0.1 46444 1876 ?     S  16:29  0:00 Nginx: worker process

2.4 Docker安装Nginx服务

拉取官方的Nginx镜像 

docker pull nginx

创建并运行Nginx容器

docker run --rm --name nginx-test -p 8080:80 -d nginx

 Nginx 服务部署,映射本地目录到Nginx容器

创建本地目录,用于存放Nginx的相关文件信息.

mkdir -p /opt/nginx/html  /opt/nginx/conf

拷贝容器内 Nginx 默认配置文件到本地当前目录下的 conf 目录,容器ID可以查看 docker ps 命令输入中的第一列 

docker cp 08a37:/etc/nginx/nginx.conf /home/nginx/conf/

 部署命令

docker run --rm -d -p 8081:80 --name nginx-test-web \
  -v /opt/nginx/html:/usr/share/nginx/html \
  -v /opt/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
  nginx

因为nginx配置较多,因此在后期的学习中使用的是源码的方式使用nginx。

2.5 Nginx启停服务

Nginx服务的启动

在Linux 平台下,启动Nginx服务器直接运行安装目录下sbin目录中的二进制文件即可。

./nginx (-h) #参数可选

查看nginx进程

ps -ef | grep nginx

在浏览器中打开nginx服务器

nginx服务默认占用的端口是80

 nginx已经启动。

Nginx服务的停止

快速停止,快速停止是指立即停止当前Nginx服务正在处理的所有网络请求,马上丢弃连接,停止工作。

./nginx -s stop   # 快速关闭

平缓停止,平缓停止是指允许Nginx服务将当前正在处理的网络请求处理完成,但不再接收新的请求,之后关闭连接,停止工作。

./nginx -s quit   # 等待工作进程处理完成后关闭

Nginx服务的重启

更改Nginx服务器的配置和加入新模块后,如果希望当前的Nginx服务应用新的配置或使新模块生效,就需要重启Nginx服务。当然我们可以先关闭Nginx服务,然后使用新的Nginx配置文件重启服务。

./nginx -s reload  # 向主进程发送信号,重新加载配置文件,热重启
./nginx -s reopen  # 重启 Nginx

三、Nginx配置指令详解

 最核心的配置文件是/nginx/conf/nginx.conf 文件 

3.1 全局块配置详解

配置运行Nginx服务器用户(组)

用于配置运行Nginx服务器用户(组)的指令是user。

user zj  zj;   #表示将nginx的生杀大权交给了zj用户zj组

如果希望所有用户都可以启动Nginx进程,有两种办法:一是将次指令注释:

# user zj zj;

或者把用户(和用户组)设置为nobody;

user nobody nobody;

 配置允许生成worker process数

worker process是Nginx服务器实现并发处理的关键所在。理论来说worker_process的值越大,可以支持的并发处理也越多。

worker_process number | auto

在默认的配置文件中,Number=1.启动Nginx服务器后,使用以下命令可以看出Nginx服务器除了主进程master process ../sbin/Nginx之外,还生成了一个worker_process。

ps aux|grep nginx

配置Nginx进程PID存放路径

Nginx进程作为系统的守护进程运行,我们需要在某文件中保存当前运行程序的主进程号。

pid file;

配置错误日志的存放路径 

在全局块、http块和 server 块中都可以对Nginx服务器的日志进行相关配置。这里首先介绍全局块下日志的存放配置,后两种情况的配置基本相同,只是作用域不同。

error_log_file | stderr[ debug|info | notice| warn |error|crit|alert]

配置文件的引入

在一些情况下,我们可能需要将其他的Nginx配置或者第三方模块的配置引用到当前的主配置文件中。Nginx 提供了include指令来完成配置文件的引入。

include file;

 其中,file是要引入的配置文件,它支持相对路径。

3.2 events块配置详解

配置事件驱动模型

 Nginx服务器提供了多种事件驱动模型来处理网络消息。配置文件中为我们提供了相关的指令来强制Nginx服务器选择哪种事件驱动模型进行消息处理。

use method;

其中,method可选择的内容有: select、poll、kqueue、epoll、rtsig、ldev/poll l以及 eventport。

配置最大连接数

指令worker_connections主要用来设置允许每一个worker process同时开启的最大连接数。其语法结构为

worker_connections number;

此指令的默认设置为512。

3.3 HTTP块配置详解

 定义MIME-Type

在常用的浏览器中,可以显示的内容有HTML、XML、GIF及Flash等种类繁多的文本、媒体等资源,浏览器为区分这些资源,需要使用MIME Type。换言之,MIME Type是网络资源的媒体类型。Nginx服务器作为Web服务器,必须能够识别前端请求的资源类型。

include    mime.types;     #mime.types是nginx目录下的一个配置文件
default_type  application/octet-stream;   #默认类型

看下mime.types片段:

 自定义服务日志

记录Nginx服务器提供服务过程应答前端请求的日志,我们将其称为服务日志以示区分。 Nginx服务器支持对服务日志的格式、大小、输出等进行配置,需要使用两个指令,分别是access _log 和 log_format指令。

access_log 指令的语法结构为:

access_log path[format[buffer=size]]

和access_log联合使用的另一个指令是log_format,它专门用于定义服务日志的格式,并且可以为格式字符串定义一个名字,以便access_log 指令可以直接调用。其语法格式为:

log_format name string ..;

配置连接超时时间

与用户建立会话连接后,Nginx服务器可以保持这些连接打开一段时间,指令 keepalive_timeout就是用来设置此时间的。

keepalive_timeout timeout [header timeout];
keepalive_timeout 120s 100s;

配置虚拟主机

server{} 包含在http{}内部,每一个server{}都是一个虚拟主机(站点)

server{


}

配置网络监听

配置监听使用指令listen,其配置方法主要有二种。

第一种配置监听的IP地址

listen address[:port] 

第二种配置监听端口

listen port;

基于名称虚拟主机配置

这里的“主机”,就是指此server块对外提供的虚拟主机。设置了主机的名称并配置好 DNS,用户就可以使用这个名称向此虚拟主机发送请求了。

server_name  name1  name2 name3 ...;
server_name  www.baidu.com     //精确匹配
server_name  *.baidu.com;       //通配
server_name  www.baidu.com  *baidu.com;

优先级

3.4 配置总结

#运行用户
user nobody;
#启动进程,通常设置成和cpu的数量相等
worker_processes  1;


#全局错误日志及PID文件
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;


#pid     logs/Nginx.pid;


#工作模式及连接数上限
events {
   #epoll是多路复用IO(I/O Multiplexing)中的一种方式,
   #仅用于linux2.6以上内核,可以大大提高Nginx的性能
   use  epoll; 


   #单个worker进程的最大并发链接数  
   worker_connections  1024;


   # 并发总数是 worker_processes 和 worker_connections 的乘积
   # 即 max_clients = worker_processes * worker_connections
   # 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4  为什么
   # 为什么上面反向代理要除以4,应该说是一个经验值
   # 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
   # worker_connections 值的设置跟物理内存大小有关
   # 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
   # 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右
   # 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
   # $ cat /proc/sys/fs/file-max
   # 输出 34336
   # 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内
   # 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置
   # 使得并发总数小于操作系统可以打开的最大文件数目
   # 其实质也就是根据主机的物理CPU和内存进行配置
   # 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
   # ulimit -SHn 65535


}




http {
   #设定mime类型,类型由mime.type文件定义
   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 指令指定 Nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
   #对于普通应用,必须设为 on,
   #如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
   #以平衡磁盘与网络I/O处理速度,降低系统的uptime.
   sendfile   on;
   #tcp_nopush   on;


   #连接超时时间
   #keepalive_timeout  0;
   keepalive_timeout  65;
   tcp_nodelay   on;


   #开启gzip压缩
   gzip  on;
   gzip_disable "MSIE [1-6].";


   #设定请求缓冲
   client_header_buffer_size   128k;
   large_client_header_buffers  4 128k;




   #设定虚拟主机配置
   server {
     #侦听80端口
     listen   80;
     #定义使用 www.Nginx.cn访问
     server_name  www.Nginx.cn;


     #定义服务器的默认网站根目录位置(编译的时候--prefix是整个Nginx的根目录,这里的html文件夹是相对--prefix的路径)
     root html;


     #设定本虚拟主机的访问日志
     access_log  logs/Nginx.access.log  main;


     #默认请求
     location / {
      
       #定义首页索引文件的名称
       index index.php index.html index.htm;  


     }


     # 定义错误提示页面
     error_page  500 502 503 504 /50x.html;
     location = /50x.html {
     }


     #静态文件,Nginx自己处理
     location ~ ^/(images|javascript|js|css|flash|media|static)/ {
      
       #过期30天,静态文件不怎么更新,过期可以设大一点,
       #如果频繁更新,则可以设置得小一点。
       expires 30d;
     }


     #PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI默认配置.
     location ~ .php$ {
       fastcgi_pass 127.0.0.1:9000;
       fastcgi_index index.php;
       fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
       include fastcgi_params;
     }


     #禁止访问 .htxxx 文件
       location ~ /.ht {
       deny all;
     }
   }
}

3.4 location指令

location以来处理不同的请求 。 

 配置location块

URL  // http://ip:port/


location [ = | ~ | ~* | ^~] uri { 
    ... 
}
匹配规则含义示例
=精确匹配location = /images/ {...}
~正则匹配,区分大小写location ~ .(jpg | gif)$ {...}
~*正则匹配,不区分大小写location ~* .(jpg | jif)$ {...}
^~匹配到即停止搜索location ^~ /images/ {...}
不带任何符号location / {...}

示例1:没有修饰符

没有修饰符 表示:必须以指定模式开始,如:

server {
  server_name *.*;
  location  /abc {
    ……
  }
}

#注意  /abc 前后都存在空格

 表示访问的路径中只要包含/abc就能访问到{}中的资源根路径。

示例2:=

= 表示:必须与指定的模式精确匹配

server {
   server_name *.*;
  location = /abc {
    ……
  }
}

 就是说浏览器必须访问192.168.66.100/abc才能访问到资源的根路径。

示例3:~

~ 表示:指定的正则表达式要区分大小写

server {
  server_name *.*;
  location ~ ^/abc$ {
    ……
  }
}

  ~ ^/abc$表示匹配的路径只能是小写的abc

示例4:~*

~* 表示:指定的正则表达式不区分大小写

server {
server_name *.*;
location ~* ^/abc$ {
    ……
  }
}

优先级

location  = / {
  # 只匹配请求 "/"
  [ configuration A ] 
}
location  / {
  # 匹配任何请求,因为所有请求都是以"/"开始
  # 但是更长字符匹配或者正则表达式匹配会优先匹配
  [ configuration B ] 
}
location /documents/ {
  # 匹配所有 /documents/ 开头的请求,在没有正则表达
  # 式匹配时选择该locaiton
  [ configuration C ]
}
location ^~ /images/ {
  # 匹配任何以 /images/ 开始的请求,并停止匹配其它location
  [ configuration D ] 
}
location ~* .(gif|jpg|jpeg)$ {
  # 匹配以 gif, jpg, or jpeg结尾的请求. 
  # 但是所有 /images/ 目录的请求将由 [Configuration D]处理.  
  [ configuration E ] 
}

 配置请求的根目录

Web服务器接收到网络请求之后,首先要在服务器端指定目录中寻找请求资源。在Nginx服务器中,指令root就是用来配置这个根目录的。

root path;

例如:

    server {

        #设置nginx端口号
        listen       80;
        server_name  localhost;

        #设置匹配规则
        location / {
            root   html;
            index  index.html index.htm;
        }

        ……
      }

这里的html实际上是nginx根目录下的html文件。这是一种相对路径的指定方式,当然我们还可以使用绝对路径指定资源的位置。

配置完成后需要重启nginx使配置生效一下:

[root@localhost sbin]# ./nginx -s reload

 此时,我们在访问192.168.66.100:80的时候,nginx会根据配置定位到html目录,此时在访问路径后面加上资源的名称,即可访问html目录下的相关的资源。例如:192.168.66.100:80/dog.png 表示访问的是html目录下的dog.png

四、Nginx虚拟主机

4.1虚拟主机的分类

虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供www服务,这样就可以实现一台主机对外提供多个web服务,每个虚拟主机之间是独立的,互不影响的。 

基于IP的虚拟主机

 通过不同的ip访问nginx里面不同的项目,在nginx配置文件nginx.conf中存在一个叫server的配置块,其实,一个server配置快就是一个虚拟主机。但是在工作中用的比较少。

基于端口的虚拟主机

 基于域名的虚拟主机

 4.2 基于单网卡多ip虚拟主机配置

 通过不同的IP区分不同的虚拟主机,此类虚拟主机对应的企业应用非常少见,一般不同业务需要使用多IP的常见都会在负载均衡器上进行VIP绑定,而不是在Web上通过绑定IP区分不同的虚拟机。

需求

一台Linux服务器绑定两个ip:192.168.66.100、192.168.66.103 访问不同的ip请求不同的html目录,即: 访问http://192.168.66.100将访问“html100”目录下的html网页 访问http://192.168.66.103将访问“html103”目录下的html网页

Linux绑定多IP

Linux操作系统允许绑定多IP。是在一块物理网卡上可以绑定多个lP地址。这样就能够在使用单一网卡的同一个服务器上运行多个基于IP的虚拟主机。但是在绑定多IP时需要将动态的IP分配方式修改为静态的指定IP。

#进入网卡的配置文件
vim /etc/sysconfig/network-scripts/ifcfg-ens33


#在配置文件中绑定多个ip
IPADDR0=192.168.66.100
IPADDR1=192.168.66.103


#使配置文件生效
service network restart


#查看该虚拟机绑定的ip
ip addr

在nginx服务器下创建两个虚拟主机的资源

 mkdir html100
 mkdir html103

#在html100文件夹下创建index.html文件,文件内容为this is html100
echo "this is html100"  > index.html

#同理在html103文件夹创建index.html文件
echo "this is html100"  > index.html

修改Nginx的配置文件ngnix.conf完成基于IP的虚拟主机配置

 vim /usr/local/nginx/conf/nginx.conf

#一个Server就是一个虚拟主机
  server {
    listen    80;
    server_name  192.168.66.100;   #为虚拟机指定IP或者是域名
    #主要配置路由访问信息
    location / {
      root  html100;      #用于指定访问根目录时,访问虚拟主机的web目录
      
      index index.html index.htm;   #在不指定访问具体资源时,默认的展示资源的列表
     }  
    error_page  500 502 503 504  /50x.html;
    location = /50x.html {
      root  html;
     }
   }
  #一个Server就是一个虚拟主机
  server {
    listen    80;
      #为虚拟机指定IP或者是域名
    server_name  192.168.66.103;
      #主要配置路由访问信息
    location / {
      #用于指定访问根目录时,访问虚拟主机的web目录
      root  html103;
      #在不指定访问具体资源时,默认的展示资源的列表
      index index.html index.htm;
     } 
    error_page  500 502 503 504  /50x.html;
    location = /50x.html {
      root  html;
     }
   }
}
#重启nginx服务
[root@localhost sbin]# ./nginx  -s reload

4.3 基于域名虚拟主机配置

需求

两个域名指向同一个nginx服务器,用户访问不同的域名时显示不同的内容。

域名规划:

1, http://www.qiantai.cn/ => 前台

2, http://www.houtai.cn/ =》 后台

 修改windows的hosts文件配置域名与ip的映射

文件路径:C:\Windows\System32\drivers\etc\hosts

192.168.66.100  www.qiantai.cn www.houtai.cn

在Nginx下创建两个文件夹分别叫qiantai和houtai 

分别在两个文件夹中创建index.html文件

[root@localhost qiantai]# echo "this is qiantai" > index.html

[root@localhost houtai]# echo "this is houtai" > index.html

修改nginx.conf配置文件

server {
  listen    80;
    #为虚拟机指定IP或者是域名
  server_name  www.qiantai.cn;
    #主要配置路由访问信息
  location / {
  #用于指定访问根目录时,访问虚拟主机的web目录
    root  qiantai;
  #在不指定访问具体资源时,默认的展示资源的列表
    index index.html index.htm;
   }
  error_page  500 502 503 504  /50x.html;
  location = /50x.html {
    root  html;
   }
}
#一个Server就是一个虚拟主机
server {
  listen    80;
#为虚拟机指定IP或者是域名
  server_name  www.houtai.cn;
#主要配置路由访问信息
  location / {
  #用于指定访问根目录时,访问虚拟主机的web目录
    root  houtai;
  #在不指定访问具体资源时,默认的展示资源的列表
    index index.html index.htm;
   } 
  error_page  500 502 503 504  /50x.html;
  location = /50x.html {
    root  html;
   }
}

 重启ngxin服务

[root@localhost sbin]# ./nginx -s reload

浏览器访问

 4.4.基于多端口虚拟主机配置

通过不同的端口来区分不同的虚拟主机。此类虚拟主机对应的企业应用主要为公司内部的网站。 

需求

Nginx对提供8888与9999两个端口的监听服务

请求8888端口则访问html8888目录下的index.html

请求9999端口则访问html9999目录下的index.html

还原IP地址为192.168.66.100:

vim /etc/sysconfig/network-scripts/ifcfg-ens33
#将:
IPADDR0=192.168.66.100
IPADDR1=192.168.66.101
#改为
IPADDR=192.168.66.100

#重启网络服务
systemctl restart network

在在Nginx下创建两个文件夹分别叫html8888和html9999,在文件夹中创建index.html文件

修改Nginx的配置文件完成基于端口的虚拟主机配置

#一个Server就是一个虚拟主机 基于端口
server {
   listen    8888;
    #为虚拟机指定IP或者是域名
   server_name 192.168.66.100;
    #主要配置路由访问信息
   location / {
  #用于指定访问根目录时,访问虚拟主机的web目录
     root  html8888;
  #在不指定访问具体资源时,默认的展示资源的列表
     index  index.html index.htm;
   }
   error_page  500 502 503 504  /50x.html;
   location = /50x.html {
     root  html;
   }
}
#一个Server就是一个虚拟主机
server {
   listen    9999;
    #为虚拟机指定IP或者是域名
   server_name 192.168.66.100;


    #主要配置路由访问信息
   location / {
        #用于指定访问根目录时,访问虚拟主机的web目录
     root  html9999;
        #在不指定访问具体资源时,默认的展示资源的列表
     index  index.html index.htm;
   }
   error_page  500 502 503 504  /50x.html;
   location = /50x.html {
     root  html;
   }
}

重启nginx服务

[root@localhost nginx]# sbin/nginx -s reload

浏览器访问

五、Nginx核心指令 

5.1 root和alias指令区别

区别

  • 共同点 : root和alias两者都都是用来指定URI和磁盘文件的映射关系;
  • 区别: root会将定义路径与URI叠加;而alias只取定义路径;

root示例

在之前的文章中介绍过,nginx的配置文件中的root表示的是目标资源的根路径。

    server {
        listen       80;

        server_name 192.168.66.100;


        location /aaa{
            root /usr/html/;
            index index.html;
        }

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

是不是访问/aaa/aaa.html就能访问到/usr/html/aaa.html这个文件呢?答案是否定的!

因为,使用root指令时,会root会将定义路径与URI叠加。也就是说当我们访问/aaa/aaa.html时,实际上访问的资源路径是/usr/html/aaa/aaa.html  ,但实际上根本没有aaa这层目录,所以访问不到aaa.html.

如何修改呢?只需要将/aaa改为/html,并删除root指令中的/html即可。

        location /html {
            root  /usr;
            index index.html;
        }


#重启nginx
[root@localhost sbin]# ./nginx -s reload

 alias示例

 alias不会拼接路径,访问uri就能定位到root 指定的目录。

        location /aaa {
            alias   /usr/html/;  #最后一定加上/
            index  index.html index.htm;
        }


#重启nginx
[root@localhost sbin]# ./nginx -s reload

5.2 return指令

return功能

  1. 停止处理请求,直接返回响应码或重定向到其他URL;
  2. 执行return指令后,location中后序指令将不会被执行;

return语法结构

  1. return code [text]; # 如果返回2XX的,text才有意义,text会在body中;
  2. return code URL; #主要用于重定向;
  3. return URL; #须以http或者https开头的;

code + text

        location / {
            return 200 "this is return";
        }

#重启nginx
[root@localhost sbin]# ./nginx -s reload

[root@localhost sbin]# curl http://192.168.66.100
this is return[root@localhost sbin]#

code + URL

#302 表示临时性重定向。访问一个Url时,被重定向到另一个url上。常用于页面跳转。
location  /  {
   return 302 /bbs;
}

location  /bbs  {
   root html;
   index index.html;
}

URL

直接访问百度

location  /  {
   return http://baidu.com;
}

5.3 rewrite指令

地址重写

地址重写是实际上是为了实现址标准化,就像访问www.baidu.cn可以出现www.baidu.com的首页,服务器会把www.baidu.cn重写成www.baidu.com,浏览器的地址栏也会显示www.baidu.com。

地址转发

地址转发一般发生在同一站点项目内,而地址重写则没有限制。

rewrite常用全局变量

变量说明
$args请求中的参数,如www.123.com/1.php?a=1&b=2的$args就是a=1&b=2
$body_bytes_sent服务器发送给客户端的响应body字节数
$content_lengthHTTP请求信息里的"Content-Length"
$conten_typeHTTP请求信息里的"Content-Type"
$document_rootnginx虚拟主机配置文件中的root参数对应的值
$document_uri当前请求中不包含指令的URI,如www.123.com/1.php?a=1&b=2的$document_uri就是1.php,不包含后面的参数
$http_referer记录此次请求是从哪个连接访问过来的,可以根据该参数进行防盗链设置
$host主机头,也就是域名
$http_user_agent客户端的详细信息,也就是浏览器的标识,用curl -A可以指定
$http_cookie客户端的cookie信息
$http_x_forwarded_for当前端有代理服务器时,设置web节点记录客户端地址的配置,此参数生效的前提是代理服务器也要进行相关的x_forwarded_for设置
$limit_rate如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0
$remote_addr客户端的公网ip
$remote_port客户端的port
$remote_user如果nginx有配置认证,该变量代表客户端认证的用户名
$request请求的URI和HTTP协议,如“GET /article-10000.html HTTP/1.1”
$request_body_file做反向代理时发给后端服务器的本地资源的名称
$request_method请求资源的方式,GET/PUT/DELETE等
$request_filename当前请求的资源文件的路径名称,相当于是$document_root/$document_uri的组合
$request_uri请求的链接,包括$document_uri和$args
$scheme请求的协议,如ftp,http,https
$server_protocol客户端请求资源使用的协议的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr服务器IP地址
$server_name服务器的主机名
$server_port服务器的端口号
$statushttp状态码,记录请求返回的状态码,例如:200、301、404等
$uri和$document_uri相同
$http_referer客户端请求时的referer,通俗讲就是该请求是通过哪个链接跳过来的,用curl -e可以指定
$time_local记录访问时间与时区,如18/Jul/2014:17:00:01 +0800

rewrite指令

该指令通过正则表达式的使用来改变URI。可以同时存在一个或者多个指令,按照顺序依次对URL进行匹配和处理。

该指令可以在server快或者location块中配置,其语法结构为:

rewrite regex replacement [flag];
关键字  正则  替代内容   flag标记

常用正则表达式 

字符描述
\将后面接着的字符标记为一个特殊字符或者一个原义字符或一个向后引用
^匹配输入字符串的起始位置
$匹配输入字符串的结束位置
*匹配前面的字符零次或者多次
+匹配前面字符串一次或者多次
?匹配前面字符串的零次或者一次
.匹配除“\n”之外的所有单个字符
(pattern)匹配括号内的pattern

rewrite 最后一项flag参数

标记符号说明
last本条规则匹配完成后继续向下匹配新的location URI规则
break本条规则匹配完成后终止,不在匹配任何规则
redirect返回302临时重定向
permanent返回301永久重定向

示例1

无论/search 后面跟什么内容,最后都会被永久重定向到百度页面

location /search {
   rewrite  ^/(.*)  http://baidu.com permanent;
}

示例2

创建三个文件夹,每个文件夹下有个1.html文件;

location /images {
   rewrite /images/(.*) /pics/$1;      //将URL  /images/1.html 重写为  /pics/1.html
}

location /pics {
   rewrite /pics/(.*)  /photos/$1;    //将URL  /pics/1.html 重写为  /photos/1.html
}

location /photos {

}

示例3

将URL /images/1.html 重写为 /pics/1.html, 并且不再匹配其他location段

location /images {
   rewrite /images/(.*) /pics/$1  break; 
}

示例4

将URL /images/1.html 重写为 /pics/1.html, 重新进入server段后匹配了/pics location段,然后又被重写。

location /images {
   rewrite /images/(.*) /pics/$1  last;
}

5.4 rewrite实战域名跳转

Nginx的rewrite功能在企业里应用非常广泛

  • 可以调整用户浏览的URL,看起来更规范,合乎开发及产品人员的需求。
  • 网址换新域名后,让旧的访问跳转到新的域名上。
  • 根据特殊变量、目录、客户端的信息进行URL调整等。

域名跳转

旧域名www.test.com直接跳转到新域名http://www.baidu.com

server {
   listen   80;
   server_name  www.test.com;
   rewrite ^/(.*) http://www.baidu.com/$1 permanent;
   }
   server {
     listen    80;
     server_name  www.baidu.com;
     location / {
       root  html;
       index  index.html index.htm;
     }
     access_log logs/brian.log main gzip buffer=128k flush=5s; 
     error_page  500 502 503 504  /50x.html;
     location = /50x.html {
       root  html;
     }
 }


[root@localhost sbin]# ./nginx -s reload

修改系统域名与IP映射关系:C:\Windows\System32\drivers\etc\hosts

192.168.66.100 www.test.com

访问www.test.com时会跳转到百度网址。

 5.5 if指令

 该指令用来支持条件判断,并根据条件判断结果选择不同的Nginx配置,可以在server块或locatio块中配置该指令。

if (condition)  { ... }

其中,花括号代表一个作用域,形成一个if配置块,是条件为真时的Nginx配置。condition为判断条件( true/false ),它可以支持以下几种设置方法:

  • 变量名-如果变量的值为空字符串或者“0”开头的任意字符串,if指令认为条件为false,其他情况为true,比如:
if ($slow) {
  .....   #Nginx配置 
}

  • 使用 "="(等于) 和 "!=" (不等于) 比较变量和字符串是否相等,相等时if指令为条件为true,反之为false。
if ($request_method = POST) {
  return 405;
}

变量与正则表达式

  • ~ 表示匹配过程对大小写敏感
  • ~* 表示匹配过程对大小写不敏感
  • !~ 表示匹配失败是if指令认为条件为true否则为false
if ($http_user_agent  ~  MSIE) {
  # $http_user_agent 的值中是否包含MSIE字符串,如果包含,为true
}

示例1

判断ip地址是否为192.168.66.10如果是返回“test if ok in Url /serach”

location /search {
  if ($remote_addr = "192.168.66.10"){
   return 200 "test if ok in url search"
  }
}


#发送请求
curl http://192.168.66.100/search

示例2

不允许谷歌浏览器访问,如果用谷歌浏览器报500

if ($http_user_agent ~ Chrome){
 return 500;
}

5.6 set和break指令

set指令

该指令用于设置一个新的变量。

set variable value

break指令

该指令用于中断当前相同作用域中的其他Nginx配置。

break;

示例:

location / {
  if ($slow){
   set $id $1 ; # 处于break指令之前,配置生效
   break;    
   limit_rate 10k; #处于break指令之后,配置无效
  }
}

5.7 Gzip压缩指令

Nginx开启Gzip压缩功能, 可以使网站的css、js 、xml、html 文件在传输时进行压缩,提高访问速度, 进而优化Nginx性能!

Gzip压缩作用

将响应报⽂发送⾄客户端之前可以启⽤压缩功能,这能够有效地节约带宽,并提⾼响应⾄客户端的速度。Gzip压缩可以配置http,server和location模块下。Nginx开启Gzip压缩参数说明:

指令含义
gzip on决定是否开启gzip模块,on表示开启,off表示关闭;
gzip_min_length 1k设置允许压缩的页面最小字节(从header头的Content-Length中获取) ,当返回内容大于此值时才会使用gzip进行压缩,以K为单位,当值为0时,所有页面都进行压缩。建议大于1k
gzip_buffers 4 16k;设置gzip申请内存的大小,其作用是按块大小的倍数申请内存空间,param2:int(k) 后面单位是k。这里设置以16k为单位,按照原始数据大小以16k为单位的4倍申请内存
gzip_http_version 1.1;识别http协议的版本,早起浏览器可能不支持gzip自解压,用户会看到乱码
gzip_comp_level 2;设置gzip压缩等级,等级越底压缩速度越快文件压缩比越小,反之速度越慢文件压缩比越大;等级1-9,最小的压缩最快 但是消耗cpu
gzip_types text/plain` `application/x-javascripttext/css` `application/xml``;设置需要压缩的MIME类型,非设置值不进行压缩,即匹配压缩类型
gzip_vary on;启用应答头"Vary: Accept-Encoding"
gzip_proxied off;nginx做为反向代理时启用,off(关闭所有代理结果的数据的压缩),expired(启用压缩,如果header头中包括"Expires"头信息),no-cache(启用压缩,header头中包含"Cache-Control:no-cache"), no-store(启用压缩,header头中包含"Cache-Control:no-store"),private(启用压缩,header头中包含"Cache-Control:private"),no_last_modefied(启用压缩,header头中不包含 "Last-Modified"),no_etag(启用压缩,如果header头中不包含"Etag"头信息),auth(启用压缩,如果header头中包含"Authorization"头信息)
gzip_disable msie6;(IE5.5和IE6 SP1使用msie6参数来禁止gzip压缩 )指定哪些不需要gzip压缩的浏览器(将和User-Agents进行匹配),依赖于PCRE库

如下是线上常使用的Gzip压缩配置:

http {
   gzip  on;
   gzip_min_length  1k;
   gzip_buffers   4 16k;
   gzip_http_version 1.1;
   gzip_comp_level 9;
   gzip_types    text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
   gzip_disable "MSIE [1-6]\.";
   gzip_vary on;
}

六、Nginx场景实践

6.1 浏览器缓存

浏览器缓存是为了加速浏览,浏览器在用户磁盘上,对最近请求过的文档进行存储。当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样,就可以加速页面的阅览,缓存的方式节约了网络的资源,提高了网络的效率。

 实现浏览器缓存步骤

 浏览器缓存可以通过expires指令输出Header头来实现。

语法:expires[time| epoch | max |off]
默认值:expires off
作用域:http、server、location

一个HTML页面,会引用一些JavaScript文件、图片文件、而这些格式的文件很少会被修改,则可以通过expires设置浏览器缓存。

示例1

比如,对常见格式的图片、Flash文件在浏览器本地缓存30天,对JS、CSS文件在浏览器本地缓存1小时,代码如下

location ~ .*\.(gif|jpg|png)$
{
   expires 30d;
}
location ~.*\.(js|css)?$
{
   expires 1h;
}

Cache-Control

设置相对过期时间, max-age指明以秒为单位的缓存时间. 若对静态资源只缓存一次, 可以设置max-age的值为315360000000 (一万年). 比如对于提交的订单,为了防止浏览器回退重新提交,可以使用Cache-Control之no-store绝对禁止缓存,即便浏览器回退依然请求的是服务器,进而判断订单的状态给出相应的提示信息!


location ~ .*\.(gif|jpg|png)$
{
  add_header Cache-Control no-cache;
  add_header Cache-Control private;
}
location ~.*\.(js|css)?$
{
   add_header Cache-Control no-cache;
   add_header Cache-Control private;
}

缓存流程

 企业实战示例

  1. 禁用html文件缓存,即cache control设置为no-cache;
  2. 对于js,图片,css,字体等,设置max-age=2592000. 也就是30天;
server{
  listen 80;
  server_name 192.168.66.100;
  location ~ \.  (css|js|gif|jpg|jpeg|png|bmp|swf|ttf|woff|otf|ttc|pfa)$ {
    root /data/web/kevin;
    expires 30d;
  } 
  location ~ \.(html|htm)$ {
    root /data/web/kevin;
    add_header Cache-Control no-cache;
  }
}

 6.2 防盗链技术

防盗链的概念

内容不在自己的服务器上,通过技术手段将其他网站的内容(比如一些音乐、图片、软件的下载地址)放置在自己的网站中,通过这种方法盗取其他网站的空间和流量。就是在自己的网站上使用其他人的资源作为自己页面的资源。

防盗链技术背景

防止第三方引用链接访问我们的图片,消耗服务器资源和网络流量,我们可以在服务器上做防盗链限制。

 防盗链设置思路

首要方式:区别那些请求是非正常的用户请求。

 基于http_refer防盗链配置模块

HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。


server{
  listen 80;
  server_name 192.168.66.100;
  location ~ \.  (css|js|gif|jpg|jpeg|png|bmp|swf|ttf|woff|otf|ttc|pfa)$ {
    root /data/web/kevin;
    expires 30d;
    valid_referers none blocked 192.168.66.100;
    if ($invalid_referer) {
       return 403;
     }
  } 
}
valid_referers none blocked 192.168.66.100;
if ($invalid_referer) {
   return 403;
}

 6.3 代理服务

正向代理

正向代理,是在用户端的。比如需要访问某些国外网站,我们可能需要购买vpn。简单讲,正向代理就是自己访问外网。

正向代理最大的特点:

  1. 客户端非常明确要访问的服务器地址;
  2. 服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;
  3. 正向代理模式屏蔽或者隐藏了真实客户端信息。

反向代理

客户端给服务器发送的请求,nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。此时请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,nginx扮演的就是一个反向代理角色。简单讲,反向代理就是外网访问nginx服务器再通过nginx服务器将请求发送到我们自己的服务器资源,这样可以保证安全。

反向代理,主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息。

 6.4 反向代理

 单体架构

反向代理设置指令:proxy_pass

学习Nginx服务器的反向代理服务,要涉及与后端代理服务器相关的配置指令比较重要,是为客户端提供正常Web服务的基础,大家应该熟练掌握尤其是proxy_pass指令,该指令用来设置被代理服务器的地址,可以是主机名称、IP地址加端口号等形式。在实际应用过程中需要注意一些配置细节,需要小心使用。

proxy_pass URL;

 示例:

server{
  ....
  listen 80;
  server_name *.*;
  location / {
    proxy_pass http://192.168.66.101:8080;
  }
}

反向代理实践

通过纯净虚拟机上的nginx访问到zk-1上的tomcta服务器。首先需要在zk-1虚拟机上安装jdk环境和tomcat,并启动tomcat。详见《生产环境部署与协同开发 Linux》然后在纯净虚拟机上配置反向代理,如上示例。在浏览器访问192.168.66.100即可访问到zk-1虚拟机上的tomcta首页。

 6.5 负载均衡

什么是负载均衡

负载均衡是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。

 没有负载均衡的 web 架构

 有负载均衡web架构

upstream指令

upstream块不属于虚拟主机(不写在server块中),只能在http块里配置,它定义了在反向代理时Nginx需要访问的后端服务器集群和负载均衡策略。

upstream  back_end {       # upstream 需要一个名字
  server 192.168.66.100 max_conns=2 fail_timeout=1s;
  server 192.168.66.101 weight = 1;
  server 192.168.66.102 weight = 1;
}
server{
  lisetn 80;
  server_name *.*;
  location / {
   proxy_set_header Host $host;  #转发原始请求的host头部(不是必须)
   proxy_pass http://back_end;  #转发到upstream块定义的服务器集群。 
  }
}


[root@localhost sbin]# ./nginx -s reload

浏览器请求:

6.6 负载均衡算法

轮询(默认)

轮询方式,依次将请求分配到各个后台服务器中,默认的负载均衡方式。 适用于后台机器性能一致的情况。 挂掉的机器可以自动从服务列表中剔除。轮询不是绝对的。

upstream bakend {  
 server 192.168.66.101;  
 server 192.168.66.102;  
}

轮询加权重

根据权重来分发请求到不同的机器中,指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。

upstream bakend {  
 server 192.168.0.14 weight=10;  
 server 192.168.0.15 weight=10;  
} 

IP_hash

每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题。俗称IP绑定。

upstream  backServer{
       server 127.0.0.1:8080 ;
        server 127.0.0.1:8081 ;
        ip_hash; 
    }
    
    server {
     listen    80;
     server_name  www.itmayiedu.com;
     location / {
           ### 指定上游服务器负载均衡服务器
           proxy_pass http://backServer;
       index  index.html index.htm;
     }
   } 

url_hash

按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。

fair

比 weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间 来分配请求,响应时间短的优先分配。Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair模块。

6.7 第三方fair模块安装

模块介绍 

fair采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面大小、加载时间长短智能的进行负载均衡。

模块安装

将nginx-upstream-fair-master.zip压缩文件上传到Linux并解压到/usr/local下。

切换到nginx-1.20.2目录执行一下操作(之前通过编译该文件得到了nginx文件)

[root@localhost nginx-1.20.2]# ./configure --prefix=/usr/local/nginx/ --add-module=/usr/local/nginx-upstream-fair-mastercal/nginx-upstream-fair-master

编译

[root@localhost nginx-1.20.2]# make

 替换原来的 nginx 命令文件

cp /usr/local/nginx-1.20.2/objs/nginx /usr/local/nginx/sbin/nginx

配置实现fair算法

upstream backserver { 
 fair; 
 server 192.168.66.100; 
 server 192.168.66.101; 
} 


#重启
./nginx -s reload

 6.8 Nginx配置故障转移

当上游服务器(真实访问服务器),一旦出现故障或者是没有及时相应的话,应该直接轮训到下一台服务器,保证服务器的高可用。

故障转移的条件

1.后端返回504、505状态码。

2.执行超时错误

 Nginx配置代码

server {
     listen    80;
     server_name  www.itmayiedu.com;
     location / {
           ### 指定上游服务器负载均衡服务器
           proxy_pass http://backServer;
 
           #http_502 http_504:后端的服务器返回502、50
           #error:连接服务器发生错误
           #timeout:连接服务器超时错误
           #invalid_header:服务器返回空或者错误的应答
           proxy_next_upstream http_502 http_504 error timeout invalid_header; 

           #nginx与上游服务器(真实访问的服务器)超时时间 后端服务器连接的超时时间_发起握手等候响应超时时间
           proxy_connect_timeout 1s;

           ###nginx发送给上游服务器(真实访问的服务器)超时时间
           proxy_send_timeout 1s;

           ### nginx接受上游服务器(真实访问的服务器)超时时间(发送消息没回应的时间)
           proxy_read_timeout 1s;

           #重试次数
           proxy_next_upstream_tries = 3
           index  index.html index.htm;
     }
   }

6.9 跨域问题

为什么会出现跨域问题

出于浏览器的同源策略限制。同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

什么是跨域

当一个请求URL的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。

当前页面url被请求页面url是否跨域原因
http://www.test.com/http://www.test.com/index.html同源(协议、域名、端口号相同)
http://www.test.com/https://www.test.com/index.html跨域协议不同(http/https)
http://www.test.com/百度一下,你就知道跨域主域名不同(test/baidu)
http://www.test.com/http://blog.test.com/跨域子域名不同(www/blog)
http://www.test.com:8080/http://www.test.com:7001/跨域端口号不同(8080/7001)

解决跨域问题

  location / { 
   add_header Access-Control-Allow-Origin *;
   add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
   add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';


   if ($request_method = 'OPTIONS') {
     return 204;
   }
} 

6.10 动静分离

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

什么是动静分离

动:必须依赖服务器生存的文件 比如jsp。 静:不需要依赖容器的比如css/js或者图片等文件

动静分离的好处

  • Nginx本身就是一个高性能的静态web服务器
  • 其实静态文件有一个特点就是基本上变化不大,所以动静分离以后我们可以对静态文件进行缓存、或者压缩提高网站性能

静态资源的类型

在Nginx的conf目录下,有一个mime.types文件里边列出了 静态资源的类型,如下:

 动静分离实战

通过请求分离 

 将一张图片aaa.jpg上传到/usr/local/nginx/static下,然后在配置文件中添加如下配置:

upstream  webservers  {
     server 192.168.66.101:8080 weight=5;
     server 192.168.66.102:8080 weight=5;
}
   server {
     listen    80;
     server_name  *.*;
     location / {
       root  html;
       index  index.html index.htm;
       proxy_set_header Host $host;
       proxy_pass http://webservers;
     }

     //访问image会定位到/static/image目录
     location /image/ {
       root static;
     }
     
     //访问web会定位到反向代理指定的服务(也就是占8080端口的tomcat)
     location /web/ {
       proxy_set_header Host $host;
       proxy_pass http://webservers;
     }
   }
}

根据扩展名分离

upstream  webservers {
     server 192.168.66.101:8080 weight=5;
     server 192.168.66.102:8080 weight=5;
}
   server {
     listen    80;
     server_name  *.*;
     location / {
       root  html;
       index  index.html index.htm;
       proxy_set_header Host $host;
       proxy_pass http://webservers;
     }

     #正则表达式,请求包含如下的会定位到static目录
     location ~ .*.(jpg|png|gif|css|js)$ {
     root static;
     }
   }
}

6.11 限流

生活中的限流

春运,一项全人类历史上最大规模的迁移活动,抢火车票一直是每年跨年以后的热点话题。

为什么需要限流

系统设计时一般会预估负载,当系统暴露在公网中时,恶意攻击或正常突发流量等都可能导致系统被压垮,而限流就是保护措施之一。

 限流算法

漏桶算法

令牌桶算法

漏桶 vs 令牌桶的区别

漏桶的天然特性决定了它不会发生突发流量,就算每秒1000个请求到来,那么它对后台服务输出的访问速率永远恒定。而令牌桶则不同,其特性可以“预存”一定量的令牌,因此在应对突发流量的时候可以在短时间消耗所有令牌,其突发流量处理效率会比漏桶高,但是导向后台系统的压力也会相应增多。

限流实现

根据nginx官网提供的说法,有两种算法,一种是漏桶算法,一种是令牌桶算法

  • limit_req_zone 用来限制单位时间内的请求数目,以及速度限制。
  • limit_req_conn 用来限制同一时间连接数,即并发限制。

 Nginx限速配置指令

放在http{} 内

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;

 放在server{}内或者location里面

limit_req zone=mylimit burst=1 nodelay;

 Nginx并发限制配置指令

ngx_http_limit_conn_module 提供了限制连接数的能力,利用 limit_conn_zone 和 limit_conn 两个指令即可。

http{
  #ip limit
  limit_conn_zone $binary_remote_addr zone=perip:10m;
  limit_conn_zone $server_name zone=perserver:10m;
}

在需要 限制并发数 和 下载带宽 的网站配置 server {}里加上如下代码:

server {
   limit_conn perip 10;
   limit_conn perserver 100;
}

设置白名单

限流主要针对外部访问,内网访问相对安全,可以不做限流,通过设置白名单即可。利用 Nginx ngx_http_geo_module 和 ngx_http_map_module 两个工具模块即可搞定。

查看是否具有该功能

./configure --help |grep http_limit_req_module
./configure --help |grep http_geo_module
./configure --help |grep http_map_module

在 nginx.conf 的 http 部分中配置白名单:

geo $limit {
   default 1;
   39.100.243.125 0;
   192.168.0.0/24 0;
   172.20.0.35 0;
}
map limit limit_key {
   0 "";
   1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=myRateLimit:10m rate=10r/s;

6.12 WEB缓存机制

 proxy Cache缓存机制

 配置proxy_cache模块

在nginx.conf文件中添加如下代码:

http{
   ......
   proxy_cache_path /data/nginx/tmp-test levels=1:2 keys_zone=tmp-test:100m inactive=7d max_size=1000g;
}

 如何使用proxy_cache

location /tmp-test/ {
  proxy_cache tmp-test;
  proxy_cache_valid  200 206 304 301 302 10d;
  proxy_cache_key $uri;
  proxy_set_header Host $host:$server_port;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header  X-Forwarded-For      $proxy_add_x_forwarded_for;
  proxy_pass http://127.0.0.1:8081/media_store.php/tmp-test/;
}

提出问题

到此,就完成了最基本的proxy_cache配置和访问过程介绍,但是最基本的配置,往往无法满足我们的业务需求,我们往往会提出以下疑问和需求:

需要主动清理缓存文件

location /tmp-test/ {
    allow 127.0.0.1; //只允许本机访问
    deny all; //禁止其他所有ip
    proxy_cache_purge tmp-test $uri;  //清理缓存
}

6.13 Nginx高可用

什么是高可用?

高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。如果一个系统能够一直提供服务,那么这个可用性则是百分之百,但是天有不测风云。所以我们只能尽可能的去减少服务的故障。

 

双机热备方案 

这种方案是国内企业中最为普遍的一种高可用方案,双机热备其实就是指一台服务器在提供服务,另一台为某服务的备用状态,当一台服务器不可用另外一台就会顶替上去。

6.14 LVS负载均衡

 LVS是一个开源的软件,可以实现传输层四层负载均衡。LVS是Linux Virtual Server的缩写,意思是Linux虚拟服务器。

 

LVS的八种调度算法

  1. 轮叫调度 rr
  2. 加权轮叫 wrr
  3. 最少链接 lc
  4. 加权最少链接 wlc
  5. 基于局部性的最少连接调度算法 lblc
  6. 复杂的基于局部性最少的连接算法 lblcr
  7. 目标地址散列调度算法 dh
  8. 源地址散列调度算法 sh

6.15 keepalived健康监测

LVS可以实现负载均衡,但是不能够进行健康检查,比如一个rs出现故障,LVS 仍然会把请求转发给故障的rs服务器,这样就会导致请求的无效性。keepalive 软件可以进行健康检查,而且能同时实现 LVS 的高可用性,解决 LVS 单点故障的问题,其实 keepalive 就是为 LVS 而生的。

keepalived工作原理

keepalived是基于VRRP协议实现的保证集群高可用的一个服务软件,主要功能是实现真机的故障隔离和负载均衡器间的失败切换,防止单点故障。

VRRP协议

VRRP是一种容错协议,它保证当主机的下一跳路由器出现故障时,由另一台路由器来代替出现故障的路由器进行工作,从而保持网络通信的连续性和可靠性。

 6.16 企业双机热备方案

 环境服务配置

两台Nginx服务器
Nginx 主服务器  192.168.66.100
Nginx 备服务器  192.168.66.101
Lvs 虚拟VIP   192.168.66.99

环境搭建

yum install -y  keepalived

keepalived 常用命令

service keepalived start
service keepalived stop

使用keepalived虚拟VIP

修改主keepalived信息

修改主Nginx服务器keepalived文件, /etc/keepalived/keepalived.conf  

State 为MASTER

! Configuration File for keepalived


vrrp_script chk_nginx {
   script "/etc/keepalived/nginx_check.sh" #运行脚本,脚本内容下面有,就是起到一个nginx宕机以后,自动开启服务
   interval 2 #检测时间间隔
   weight -20 #如果条件成立的话,则权重 -20
}
# 定义虚拟路由,VI_1 为虚拟路由的标示符,自己定义名称
vrrp_instance VI_1 {
   state MASTER #来决定主从
   interface ens33 # 绑定虚拟 IP 的网络接口,根据自己的机器填写
   virtual_router_id 121 # 虚拟路由的 ID 号, 两个节点设置必须一样
   mcast_src_ip 192.168.212.141 #填写本机ip
   priority 100 # 节点优先级,主要比从节点优先级高
   nopreempt # 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
   advert_int 1 # 组播信息发送间隔,两个节点设置必须一样,默认 1s
   authentication {
     auth_type PASS
     auth_pass 1111
   }
   # 将 track_script 块加入 instance 配置块
   track_script {
     chk_nginx #执行 Nginx 监控的服务
   }


   virtual_ipaddress {
     192.168.212.110 # 虚拟ip,也就是解决写死程序的ip怎么能切换的ip,也可扩展,用途广泛。可配置多个。
   }
}

修改从keepalived信息

修改主Nginx服务器keepalived文件, /etc/keepalived/keepalived.conf

State 为BACKUP

! Configuration File for keepalived


vrrp_script chk_nginx {
   script "/etc/keepalived/nginx_check.sh" #运行脚本,脚本内容下面有,就是起到一个nginx宕机以后,自动开启服务
   interval 2 #检测时间间隔
   weight -20 #如果条件成立的话,则权重 -20
}
# 定义虚拟路由,VI_1 为虚拟路由的标示符,自己定义名称
vrrp_instance VI_1 {
   state BACKUP #来决定主从
   interface ens33 # 绑定虚拟 IP 的网络接口,根据自己的机器填写
   virtual_router_id 121 # 虚拟路由的 ID 号, 两个节点设置必须一样
   mcast_src_ip 192.168.212.141 #填写本机ip
   priority 100 # 节点优先级,主要比从节点优先级高
   nopreempt # 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
   advert_int 1 # 组播信息发送间隔,两个节点设置必须一样,默认 1s
   authentication {
     auth_type PASS
     auth_pass 1111
   }
   # 将 track_script 块加入 instance 配置块
   track_script {
     chk_nginx #执行 Nginx 监控的服务
   }


   virtual_ipaddress {
     192.168.212.110 # 虚拟ip,也就是解决写死程序的ip怎么能切换的ip,也可扩展,用途广泛。可配置多个。
   }
}

Nginx+keepalived实现高可用

写入nginx_check.sh脚本 /etc/keepalived/nginx_check.sh

#!/bin/bash
A=`ps -C nginx –no-header |wc -l`
if [ $A -eq 0 ];then
   /usr/local/nginx/sbin/nginx
   sleep 2
   if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
     killall keepalived
   fi
fi
举报

相关推荐

0 条评论