Nginx ——(反向代理 负载均衡 动静分离)

1、引出nginx

  1. 引出nginx——访问不同微服务、轮询访问微服务
    在这里插入图片描述
  2. 解决方案nginx——动静分离
    在这里插入图片描述

2、基本介绍

是什么?Nginx(“engine x”)是一个高性能的 HTTF 和反向代理WEB服务器
能干什么?反向代理 负载均衡 动静分离
牛逼之处?高性能,高负载 有报告表明能支持高达 50,000个并发连接数
详细说明:https://Inmp.org/nginx.html

官方资料:
官网:https://nginx.org/
使用文档:https://nginx.org/en/docs/

3、Nginx核心功能

正向代理

一句话: 如果我们要访问www.google.com,但是直接访问不到,则需要通过代理服务器来访问,这种代理服务就称为正向代理
在这里插入图片描述

图解:
1.我们知道www.google.com,但是访问不到。
2.所以使用代理服务器帮助我们(即客户端)来上网,注意帮助的对象是客户端,这种代理,我们称正向代理。
3.正向代理同时也隐藏了客户端信息.。
4.再次说明,正向代理帮助的是客户端,因此可以把 客户端+正向代理服务,视为一个整体。

反向代理

一句话:客户端将请求发送到代理服务器,由代理服务器去选择目标服务器获取数据后,返回给客户端,这种代理方式为反向代理

在这里插入图片描述

图解
1.项目设计者,不希望客户端直接访问目标Web服务器(比如目标Web服务器是集群,如果直接访问就会提供多个公网IP),而是希望提供一个统一的访问IP,这个是理解反向代理的前提,即为什么要反向代理.
2.反向代理帮助的对象是目标Web服务器
3.当客户端请求达到反向代理服务后,由反向代理服务来决定如何访问目标Web服务器(或者是 哪个Web服务器), 这个过程对客户端是透明的.
4.反向代理服务会暴露公共的IP,只要能上网,就可以访问,但是对于反向代理服务器管理的/代理的Web服务器通常是在局域网内,不能直接访问,只能通过反向理来访问.
5.我们可以将反向代理服务+反向代理服务代理的Web服务器视为一个整体
6.反向代理会屏蔽内网服务器(也就是他代理的服务)信息,并实现负载均衡访问

负载均衡

一句话:当客户端向反向代理服务器(比如Nginx)发出请求,如果Nginx代理了多个WEB服务器(集群),Nginx会将请求/负载分发到不同的服务器,也就是负载均衡
在这里插入图片描述

动静分离

一句话:为了加快网站的解析速度,可以把动态资源和静态资源由不同的服务器来解析,降低单个服务器的压力。

传统的项目资源部署:
在这里插入图片描述

动静分离项目资源部署:
在这里插入图片描述

4、nginx下载&安装&启动

下载
https://nginx.org/en/download.html
在这里插入图片描述
版本:nginx-1.20.2.tar.gz

具体安装步骤

  1. 搭建gcc环境
    yum -y install gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel

提示:执行上面指令的时候,可能会报Centos Another app is currently holding the yum lock…错误,是因为yum不时会自动升级,占用了端口或文件,解决方案(1)可以重启Linux,立即执行该指令(2)或者等一会再执行(3)或者参考其他

  1. 将nginx-1.20.2.tar.gz上传至/opt/,并解压
    tar -zxcf nginx-1.20.2.tar.gz
  2. 将解压好的文件移动到指定位置
    mv nginx-1.20.2 /usr/local/nginx
  3. 进入/usr/local/nginx目录
  4. 配置nginx路径,在当前路径控制台输入:
    ./configure --prefix=/usr/local/nginx --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --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 --http-scgi-temp-path=/var/temp/nginx/scgi --conf-path=/usr/local/nginx/nginx.conf

在这里插入图片描述

  1. 补全nginx配置目录
    mkdir /var/temp/nginx -p

  2. 编译并安装
    make && make install

  3. 测试配置文件nginx是否正常,当出现successful即可
    ./sbin/nginx -t
    在这里插入图片描述

  4. nginx指定配置文件启动
    ./sbin/nginx -c nginx.conf

  5. 查看进程/或端口
    ps -ef | grep nginx
    在这里插入图片描述

  6. 如果遇到错误,如 "open error log file: open() "/usr/local/nginx/logs/error.log" failed (2: No such file or directory)",这通常意味着 Nginx 试图写入一个不存在的日志文件目录。
    解决办法:
    修改conf/nginx.conf
    在这里插入图片描述
    新建文件夹:mkdir /usr/local/nginx/logs

  7. 验证是否安装成功
    在这里插入图片描述

  8. 配置防火墙开放端口,让windows可以访问Nginx
    firewall-cmd --zone=public --add-port=80/tcp --permanent # 配置防火墙开放 80端口
    firewall-cmd --reload # 更新防火墙配置
    firewall-cmd --zone=public --list-ports # 查看已经开放的端口号

5、命令行参数

指令说明:https://nginx.org/en/docs/switches.html

启动:/usr/local/nginx/nginx -c nginx.conf
停止:/usr/local/nginx/nginx -s stop
重新加载:/usr/local/nginx/nginx -s reload
查看版本:/usr/local/nginx/nginx -v
查看版本、配置参数:/usr/local/nginx/nginx -V

6、nginx.conf配置详解

介绍

使用/usr/local/nginx/sbin/nginx启动Nginx,默认用的是目录\nginx.conf配置文件

作用:完成对Nginx的各种配置,包括端口,并发数,重写写规则等。

nginx.conf组成:

#Nginx用户及组:用户 组。window下不指定
#user  nobody;
 
#工作进程:数目。根据硬件调整,通常等于CPU数量或者2倍于CPU。
worker_processes  1;
 
#错误日志:存放路径。
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
 
#pid(进程标识符):存放路径
pid       /usr/local/nginx/logs/nginx.pid;
 
#一个进程能打开的文件描述符最大值,理论上该值因该是最多能打开的文件数除以进程数。
#但是由于nginx负载并不是完全均衡的,所以这个值最好等于最多能打开的文件数。
#LINUX系统可以执行 sysctl -a | grep fs.file 可以看到linux文件描述符。
worker_rlimit_nofile 65535;
 
 
events {
	#使用epoll的I/O 模型。linux建议epoll,FreeBSD建议采用kqueue,window下不指定。
	use epoll;
	
	#单个进程最大连接数(最大连接数=连接数*进程数)
    worker_connections  1024;
	
	#客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,
	#一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
	#client_header_buffer_size 4k;
}
 
 
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"';
	
		
	#用了log_format指令设置了日志格式之后,需要用access_log指令指定日志文件的存放路径
	#记录了哪些用户,哪些页面以及用户浏览器、ip和其他的访问信息
	#access_log  logs/host.access.log  main;
	#access_log  logs/host.access.404.log  log404;
	
	#服务器名字的hash表大小
    server_names_hash_bucket_size 128;
	
	#客户端请求头缓冲大小。
    #nginx默认会用client_header_buffer_size这个buffer来读取header值,
    #如果header过大,它会使用large_client_header_buffers来读取。
    #如果设置过小HTTP头/Cookie过大 会报400 错误 nginx 400 bad request
    #如果超过buffer,就会报HTTP 414错误(URI Too Long)
    #nginx接受最长的HTTP头部大小必须比其中一个buffer大
    #否则就会报400的HTTP错误(Bad Request)
    #client_header_buffer_size 32k;
    #large_client_header_buffers 4 32k;
	
	
	#隐藏ngnix版本号
    #server_tokens off;
	
	#忽略不合法的请求头
    #ignore_invalid_headers   on;
	
	#让 nginx 在处理自己内部重定向时不默认使用  server_name设置中的第一个域名
    #server_name_in_redirect off;
	
	
	#客户端请求体的大小
    #client_body_buffer_size    8m;
   
  
    #开启文件传输,一般应用都应设置为on;若是有下载的应用,则可以设置成off来平衡网络I/O和磁盘的I/O来降低系统负载
    sendfile        on;
	
	
	#告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送。
    #tcp_nopush     on;
	
	#tcp_nodelay off 会增加通信的延时,但是会提高带宽利用率。在高延时、数据量大的通信场景中应该会有不错的效果
    #tcp_nodelay on,会增加小包的数量,但是可以提高响应速度。在及时性高的通信场景中应该会有不错的效果
	tcp_nodelay on;
	
 
    #长连接超时时间,单位是秒
    keepalive_timeout  65;
 
    #gzip模块设置,使用 gzip 压缩可以降低网站带宽消耗,同时提升访问速度。
    #gzip  on;                     #开启gzip
    #gzip_min_length  1k;          #最小压缩大小
    #gzip_buffers     4 16k;       #压缩缓冲区
    #gzip_http_version 1.0;        #压缩版本
    #gzip_comp_level 2;            #压缩等级
    #gzip_types   text/plain text/css text/xml text/javascript application/json application/x-javascript application/xml application/xml+rss;#压缩类型
    
	
	
	
    #负载均衡
	#max_fails为允许请求失败的次数,默认为1
	#weight为轮询权重,根据不同的权重分配可以用来平衡服务器的访问率。
    # upstream myServer{
    #   server  192.168.247.129:8080 max_fails=3 weight=2;
    #   server  192.168.247.129:8081 max_fails=3 weight=4;	
    # }
	
	
	
    #server {
    #    listen       80;
	#	
	#	#IP/域名可以有多个,用空格隔开
	#	server_name  192.168.247.129;
	#	#server_name  www.test.com;
	#
    #    #charset koi8-r;
	#
    #    #access_log  logs/host.access.log  main;
	#	
	#   #反向代理配置,
    #   #将所有请求为www.test.com的请求全部转发到upstream中定义的目标服务器中。
    #   location / {
	#   			
	#	    #此处配置的域名必须与upstream的域名一致,才能转发。
	#	    proxy_pass http://myServer;
	#	    #proxy_pass http://192.168.247.129:8080;
	#		
	#		 proxy_connect_timeout 20;          #nginx跟后端服务器连接超时时间(代理连接超时)
	#		
    #        #client_max_body_size       10m;   #允许客户端请求的最大单文件字节数
    #        #client_body_buffer_size    128k;  #缓冲区代理缓冲用户端请求的最大字节数
	#		 #proxy_send_timeout         300;   #后端服务器数据回传时间(代理发送超时)
    #        #proxy_read_timeout         300;   #连接成功后,后端服务器响应时间(代理接收超时)
    #        #proxy_buffer_size          4k;    #设置代理服务器(nginx)保存用户头信息的缓冲区大小
    #        #proxy_buffers              4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
    #        #proxy_busy_buffers_size    64k;   #高负荷下缓冲大小(proxy_buffers*2)
    #        #proxy_temp_file_write_size 64k;   #设定缓存文件夹大小,大于这个值,将从upstream服务器传    		
	#		
	#		root   html;
	#		
	#		#定义首页索引文件的名称
	#		index  index.html index.htm;
    #    }
	#
    #   #动静分离 静态资源走linux 动态资源走tomcat
    #   # 注意 /source/image/下面寻找资源
    #   location /image/ {
    #       root /source/;
	#       autoindex on;
    #   } 		
	#
	#
	#    # 出现50x错误时,使用/50x.html页返回给客户端
    #    error_page   500 502 503 504  /50x.html;
    #    location = /50x.html {
    #        root   html;
    #    }
    #}
		
		
		
	#下面是配置生产环境中既支持HTTP又支持HTTPS,保证用户在浏览器中输入HTTP也能正常访问
	
	# SSL证书 配置                                 
	ssl_certificate     	cert/yphtoy.com.pem;   #加密证书路径
	ssl_certificate_key	cert/yphtoy.com.key;       #加密私钥路径
	ssl_protocols		TLSv1 TLSv1.1 TLSv1.2;     #加密协议
	ssl_session_cache	shared:SSL:1m;             #加密访问缓存设置,可以大大提高访问速度
	ssl_session_timeout	10m;                       #加密访问缓存过期时间
	ssl_ciphers		HIGH:!aNULL:!MD5;              #加密算法
	ssl_prefer_server_ciphers on;	               #是否由服务器决定采用哪种加密算法
	
	# 负载均衡
	upstream api_upstream
	{
	    server 127.0.0.1:8080 max_fails=3 weight=1;
		server 127.0.0.1:8081 max_fails=3 weight=1;
	}
	
	#api 接口(兼容HTTP)
	server{
	    listen 80;
		server_name api.test.com;
		# 301重定向跳转到HTTPS接口
		return 301 https://$server_name$request_uri;
		error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
	}
	
	#api 接口(兼容HTTPS)
	server{
	    listen 443 ssl;
		server_name api.test.com;
		location / {
		   root html;
		   index  index.html index.htm;
		   proxy_pass http://api_upstream;
		   
		   #语法: proxy_cookie_path oldpath replacepath;
		   #oldpath就是你要替换的路径 replacepath 就是要替换的值
		   #作用:同一个web服务器下面多个应用之间能获取到cookie
		   proxy_cookie_path /api/ /;
		   
		   #服务端接收的请求头Cooke值不变
		   proxy_set_header Cookie $http_cookie;
		}
	}
	
	#管理后台端(兼容HTTP)
	server{
	    listen 80;
		server_name manage.test.com;
		# 301重定向跳转到HTTPS接口
		return 301 https://$server_name/$request_uri;
		error_page 500 502 503 504 /50x.html;
		location = /50x.html{
			 root html	
		}
	}
	
	#管理后台端(兼容HTTPS)
	server{
	    listen 443 ssl;
		server_name manage.test.com;
		location / {
		    root /home/test/web/dist
			
			index /index.html;
			
			
			#语法:try_files 【$uri】 【 $uri/】 【参数】
			#当用户请求https://manage.test.com/login时,
			#一.如果配置了上面的默认index,会依次请求
			#1./home/test/web/dist/login       查找有没有login这个文件,没有的话
			#2./home/test/web/dist/index.html  有就直接返回
			
			#二.如果没有配置了上面的默认index或者配置了没有找到对应的资源,会依次请求
			#1./home/test/web/dist/login        查找有没有login这个文件,没有的话
			#2./home/test/web/dist/login/       查找有没有login这个目录,没有的话
		    #3.请求https://manage.test.com/index.html  nginx内部做了一个子请求
			
			#三.总的来说,index的优先级比try_files高,请求会先去找index配置,这里最后一个参数必须存在
			try_files $uri $uri/ /index.html;	
			
			
			
			#解决跨域问题
            #允许跨域请求地址(*表示全部,但是无法满足带cookie请求,因为cookie只能在当前域请求)
            add_header Access-Control-Allow-Origin $http_origin;
            #允许接收cookie和发送cookie
            add_header Access-Control-Allow-Credentials 'true';
            #允许请求的方法
            add_header Access-Control-Allow-Methods 'GET,POST,DELETE,PUT,OPTIONS';
            #允许请求头(Content-Type:请求数据/媒体类型 x-requested-with:判断请求是异步还是同步 自定义header 比如 token)
            add_header Access-Control-Allow-Headers $http_access_control_request_headers;
            #浏览器缓存请求头信息,1800秒内,只会有1次请求,不会出现"OPTIONS"预请求,节约资源
            #add_header Access-Control-Max-Age '1800';
		    if ($request_method = 'OPTIONS') {
                    return 204;
            }
			
			
			#服务端HttpServletRequest可以获得用户的真实ip
		    proxy_set_header X-Real-IP $remote_addr;
			
			#服务端HttpServletRequest可以获得用户的真实ip和经过的每一层代理服务器的ip
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			
			#服务端接收的请求头Host值不变
            proxy_set_header Host  $http_host;
			
            proxy_set_header X-Nginx-Proxy true;
		}
	}
}

全局块

1.从配置文件开始到events块之间的内容
2.主要会设置一些影响 nginx服务器整体运行的配置指令,主要包括配置运行Nginx服务器的用户(组)、允许生成的worker process数,进程PID存放路径、日志存放路径和类型以及配置文件的引入等
3.#这是 Nginx服务器并发处理服务的关键配置,worker_processes值越大,可以支持的并发处理量也越 多,但是会受到硬件、软件等设备的制约

events 块

1.events块涉及的指令主要影响Nginx服务器与用户的网络连接

2.常用的设置包括是否开启对多 work process下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个word process可以同时支持的最大连接数等。

server 块

  1. 这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
  2. 每个 http块可以包括多个server块,而每个 server 块就相当于一个虚拟主机。
  3. 每个 server 块也分为全局server 块,以及可以同时包含多个locaton 块
    (1) 全局 server 块
    最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或IP配置。
    (2) location 块
    一个server 块可以配置多个location 块
  4. 小结:这块的主要作用是基于 Nginx服务器接收到的请求字符串(例如server_name/uri-string),虚拟主机名称(也可以是IP别名)之外的字符串(例如前面的/uri-string)进行匹配,对特定的请求进行处理。比如地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

7. 反向代理案例

需求:在window通过浏览器访问Linux的Nginx服务,Nginx代理访问到Tomcat,实际访问到资源是Tomcat,此过程客户端并不知道Tomcat的存在,Tomcat理解为隐藏起来的服务,称反向代理。

前提:在Linux安装了Nginx和Tomcat,并且处于启动状态,防火墙开放相应的端口(80,8080)
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

8. Location语法规则

Location规则

语法规则:location [=|\~|\~*|^~] /url/{...}
首先匹配 = ,其次匹配^~,是按文件中顺序正常匹配,最后是交给/通用匹配,当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

符号含义
== 开头表示精确匹配
^~^~ 开头表示uri以某个常规字符串开头,理解为匹配url路径即可。nginx不对uri做编码,因此请求为/static/20%/aa,可以被规则 ^~/static/ /aa 匹配到(注意是空格)
~~ 开头表示区分大小写的正则匹配
~*~* 开头表示不区分大小写的正则匹配
! ~ 和 ! ~*! ~ 和 ! ~* 分别表示为区分大小写不匹配不区分大小写不匹配的正则
/用户所使用的代理(一般为浏览器)
$http_x_forwarded_for可以记录客户端IP,通过代理服务器来记录客户端的ip地址
$http_referer可以记录用户是从哪个链接访问过来的

匹配规则示例

location = / {
 # 规则A
}

location = /login {
 # 规则B
}

location ^~ /static/ {
 # 规则C
}

location  ~ \.(gif|jpg|png|js|css)$ {
 # 规则D (区分大小写匹配)
}

location  ~* \.(gif|jpg|png|js|css)$ {
 # 规则E (不区分大小写匹配)
}

location  !~ \.xhtml$ {
 # 规则F
}

location  !~* \.xhtml$ {
 # 规则G
}

location / {
 # 规则H
}

产生效果如下:
1.访问根目录/,比如 http://localhost/将匹配规则A
2.访问 http://localhost/login,将匹配规则B,http://localhost/register,将匹配规则H
3.访问 http://localhost/static/a.html, 将匹配规则C
4.访问 http://localhost/a.gif,http://localhost/b.jpg 将匹配规则D和E,但是规则D顺序优先,规则E不起作用,而http://localhost/static/c.png则优先匹配规则C
5.访问 http://localhost/a.PNG 匹配规则E,而不会匹配规则D,因为规则E不区分大小写
6.访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML 不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会用到。
7.访问 http://localhost/category/id/111 最终会匹配规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如:FaseCGI(PHP),tomcat(jsp),nginx作为反向代理服务器存在。

实际常用规则

#直接匹配网站根目录,通过域名访问网站首页比较频繁,使用这个会加速处理。
#这里是直接转发给后端应用服务器了,也可以是一个静志首页
#第一个必选规则
location = / {
	proxy_pans http://tomcat:8000/index;
}

#第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
#有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
	# 请求/static/a.txt 将被映射到实际目录文件:/webroot/res/static/a.txt
	root /webroot/res/;
}

location  ~* \.(gif|jpg|jpeg|png|html|js|css|ico)$ {
 	root /webroot/res/;
}

# 第三个规则就是通用规则,用来转发动态请求到后端应用服务器
# 非静态文件请求就默认是动态请求,自己根据实际把握
# 毕竟目前的一些框架的流行,带.pho,.jsp后缀的情况更少了
location  / {
 	proxy_pass http://tomcat:8080/;
}

Location 解析过程

在这里插入图片描述
在这里插入图片描述

解读:

1、先判断精确命中,如果命中,立即返回结果并结束解析过程
2、判断普通命中,如果多个命中,“记录下来最长”的命中结果(记录但是不结束,最长的为准)。
3、继续判断正则表达式的解析结果,按配置里的正则表达式顺序为准,由上至下开始匹配,一旦匹配成功1个就立即返回结果,并结束解析过程。
4、普通命中顺序无所谓,是因为按照命中的长短来确定。正则命中,顺序有所谓,因为是从前往后命中的。

nginx的location指令配置语法如下:

location [= | ~ | ~* | ^~ ] /url/ {...}

说明:
= 表示精准匹配
~ 表示正则匹配(区分大小写)
~* 表示正则匹配(不区分大小写)
^~表示普通匹配完成后不使用正则匹配(可以看完下面匹配顺序之后再来理解)uri之前不包含=、~、~ *、^~时为普通匹配
location指令可以嵌套,所以可以出现在server指令内部和location指令内部。
location匹配规则:
nginx为了找到匹配请求的location,搜索匹配规则如下:
判断是否精准匹配,如果匹配,直接返回结果并结束搜索匹配过程。
判断是否普通匹配,如果匹配,看是否包含^~前缀,包含则返回,否则记录匹配结果,(如果匹配到过个location时返回或记录最长匹配的那个)
判断是否正则匹配,按配置文件里的正则表达式的顺序,由上到下开始匹配,一旦匹配成功,直接返回结果,并结束搜索匹配过程。
如果正则匹配没有匹配到结果,则返回步骤2记录的匹配结果。

注:
多个普通匹配的location时,和location的顺序无关,总是匹配所有的location,然后取匹配最长的location作为结果多个正则匹配的location时,和顺序有关,从上到下依次匹配,一旦匹配成功便结束,直接返回结果

location配置实例案例

需求: 在Linux的Tomcat安装目录下,新建webapps/product/hi.html,在Windows的Tomcat安装目录下,新建webapps/memeber/hi.html。通过Linux的Nginx10000端口访问,演示使用Location语法规则。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

9. 负载均衡

负载均衡配置规则

——负载均衡就是将负载分摊到不同的服务单元,既保证服务的可用性,又保证响应足够快
——linux下有 Nginx、LVS、Haproxy等等服务可以提供负载均衡服务,Nginx 提供了几种分配方式(策略)

1、轮轮(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down 掉,能自动剔除
2、weight
weight 代表权,重默认为1,权重越高被分配的客户端越多指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。例如

upstream lxcservers{
server 192.168.31.59:8080 weight=1;
server 192.168.31.59:8081 weight=2
}

3、ip_hash
每个请求按访问ip的hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题
例如:

upstream lxcservers{
ip_hash;
server 192.168.31.59:8081;
server 192.168.31.59:8080;
}

4、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配

upstream lxcservers{
server 192.168.31.59:8080;
server 192.168.31.59:8081;
fair;
}

实现步骤

配置nginx:
在这里插入图片描述

1、在Linux下的Tomcat安装目录下创建webapps\search\look.html(内容自定)
2、在Linux下重新安装一份Tomcat,并将端口修改成8081
在这里插入图片描述
修改另一个Tomcat的conf\server.xml,注意要修改如下位置,否则该Tomcat是不能正常工作
在这里插入图片描述
在这里插入图片描述

3、在Linux的Tomcat 8081创建webapps\search\look.html

4、启动两个Tomcat,启动Nginx,浏览器输入:http://192.168.31.59/search/look.html ,查看默认是轮询访问的

在这里插入图片描述
在这里插入图片描述

注意事项和避免的坑
1.nginx.conf的upstream 不能带下划线,否则会失败,但是语法检测不到
2.如果你的浏览器是无痕上网,负载均衡可能失效,因为Nginx无法采集到相关信息, 用其它浏览器即可(比如chrome)
3.提示:如果某Tomcat没有监听对应端口,说明启动失败了,可以尝试先执行 shutdown.sh 再执行startup.sh 解决

文档: Nginx的upstream配置技巧
1、基本介绍
Nginx是一个反向代理软件,大部分的网站都采用Nginx作为网站/平台的服务器软件。Nginx除了可以直接作为web服务器使用外,更多的情况是通过反向代理将请求转发给上游服务器
配置上游服务器可以使用upstream进行设置,通过upstream可以实现服务的负载均衡规则,可以提高服务器的高可用性。
2、地址:
https://zhuanlan.zhihu.com/p/409693332

10. 动静分离

介绍

1.Nginx动静分离简单来说就是把动态跟静态请求分开,可以理解成使用Nginx处理静态页面/资源Tomcat 处理动态页面。
2.动静分离可以减轻Tomcat压力,静态请求由Nginx处理,提供系统整体性能。

需求:在Tomcat处理后台计算.jsp文件,在nginx则处理静态资源文件(如:图片资源)。客户端访问时,Tomcat处理返回jsp, Nginx处理返回图片,各自分工。

实现步骤

  1. 在两个Tomcat 新建 webapps/search/cal.jsp, 内容如下:
<%@ page contentType="texthtml;charset=UTF-8" language="java" %>
<html>
<head>
<title>hello, jsp</title></head>
<body>
<img src="image/cal.jpg"/>
<h1>JSP,计算器 8081</h1>
<%
        int i = 20;
        int j = 80;
        int res = i + j;
        out.println(i +"+"+ j + "=" + res);
%>
</body>
</html>

  1. nginx.conf 新增静态资源文件路径访问。
    在这里插入图片描述
  2. nginx的目录下,新建html/search/image/cal.jpg,放一张图片cal.jpg。
  3. 启动两个Tomcat,启动Nginx, 浏览器输入:192.168.32.59/search.jsp
    在这里插入图片描述
    在这里插入图片描述

11. Nginx 工作机制&参数设置

master-worker 机制

master-worker工作原理图

在这里插入图片描述
图解
一个master管理多个worker
在这里插入图片描述

一说master-worker 机制

争抢机制示意图
在这里插入图片描述

图解:
1.一个master Process 管理多个worker process r结构.,也就是说Nginx采用的是多进程结构,而不是多线程
2.当 client 发出请求(任务)时,master Proeess 会通知管理的 worker process
3.worker process 开始争抢任务,争抢到的worker process 会开启连接,完成任务
4.每个 worker 都是一个独立的进程,每个进程里只有一个主线程
5.Nginx采用了 IO 多路复用机制(需要在Linux环境),使用IO多路复用机制,是Nginx在使用为数不多的worker process 就可以实现高并发的关键

二说master-worker 机制

在这里插入图片描述
在这里插入图片描述
对上图说明
MeMaster-Worker模式
1、Nginx在启动后,会有一个 master 进程和多个相互独立的 worker 进程。
2、Master 进程接收来自外界的信号,向各worker 进程发送信号,每个进程都有可能来处理这个连接。
3、Master进程能监控Worker进程的运行状态,当worker 进程退出后(异常情况下),会自动启动新的worker 进程。

accept_mutex解决"惊群现象

1、所有子进程都继承了父进程的sockfd,当连进来时,所有子进程都将收到通知并“争着"与它建立连接这就叫"惊群现象”。
2、大量的进程被激活又挂起,只有一个进程可以ccept()到这个连接,会消耗系统资源。
3、Nginx 提供了一个
accept_mutex
,这是一个加在accept上的一把共享锁。即每个worker进程在行accept之前都需要先获取锁,获取不到就放弃执行 accept()。有了这把锁之后,同一时刻,就只会有一进程去accpet(),就不会有惊群问题了。
4、当一个 worker 进程在 accept() 这个连接,后,就开始读取请求,解析请求,处理请求,产生数据后再返回给客户端,最后才断开连接,完成一个完整的请求。
5、一个请求,完全由 worker 进程来处理,而且只能在一个 worker 进程中处理。

用多进程结构而不用多线程结构的好处/理论

1、节省锁带来的开销,每个worker进程都是独立的进程,不共享资源,不需要加锁。在编程以及问题查上时也会方便很多。
2、独立进程,减少风险。采用独立的进程,可以上互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快重新启动新的worker 进程

实现高并发的秘密-IO多路复用

1、对于Nginx来讲,一个进程只有一个主线程那么它是怎么实现高并发的呢?

2、采用了IO多路复用的原理,通过异步非阻塞的事件处理机制,epol模型,实现了轻量级和高并发
3、Nginx是如何具体实现的呢,举例来说:每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻寒的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么傻等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。此时,如果再有request 进来,他就可以很快再按这种方式处理。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个reguest才会接着往下走。由于webserver的工作性质决定了每个request的大部份生命都是在网络传输中,实际上花费在server机器上的时间片不多,这就是几个进程就能解决高并发的秘密所在.

小结:Nginx的master-worker工作机制的优势
1、支持 nginx-s reload 热部署,这个特征在前面我们使用过
2、对于每个 worker 进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多
3、每个 worker 都是一个独立的进程,但每个边程里只有一个主线程,通过异步非阳塞的方式/IO多路复用来处理请求,即使是高并发请求也能应对。
4、采用独立的进程,互相之间不会影响,一个wrker进程退出后,其它worker进程还在工作,服务不会中断,master进程则很快启动新的worker进程
5.一个worker 分配一个CPU,那么worker的线程可以把一个cpu的性能发挥到极致

参数设置

worker processes

需要设置多少个 worker
每个 worker 的线程可以把一个cpu的性能发挥到极致。所以 worker 数和服务器的 cpu数相等是最为适宜的。设少了会浪费cpu,设多了会造成cpu 频繁切换上下文带来的损耗。

设置 worker 数量,Nginx默认没有开启利用多核cpu,可以通过增加worker_cpu_affinity配置参数来充分利用多核cpu的性能

#2核cpu,开启2个进程
worker processes	2;
worker_cpu affinity 01 10;

#2核cpu,开启4个进程,
worker processes 	4;
worker_cpu affinity 01 10 01 10:

#4核cpu,开启2个进程,0101表示开启第一个和第三个内核,1010表示开启第二个和第四个内核;
worker processes	2;
worker cpu affinity 0101 1010;

#4个cpu,开启4个进程
worker processes	4;
worker_cpu_affinity 0001 0010 0100 1000;

#8核cpu,开启8个进程
worker processes	8;
worker_cpu_affinity 00000001 00000010  00000100 00001000 00010000 00100000 01000000  10000000;

worker_cpu_affinity理解
在这里插入图片描述

worker_connection

1.worker_connection 表示每个 worker 进程所能建立连接的最大值,所以,一个 nginx 能建立的最大连接数,应该是worker connections * worker processes
(1)默认:worker_connections: 1024
(2)调大:worker connections:60000,(调大到6万连接)
(3)同时要根据系统的最大打开文件数来调整

系统的最大打开文件数>=worker_connections*worker_process
根据系统的最大打开文件数来调整,worker_connections进程连接数量要小于等于系统的最大打开文件数,worker_connections进程连接数量真实数量=worker connections * worker process

查看系统的最大打开文件数
ulimit -a lgrep "open files"
open files (-n) 65535

2.根据最大连接数计算最大并发数:如果是支持http1.1的浏览器每次访问要占两个连接,所以普通的静态访问最大并发数是: workerconnections * workerprocesses / 2,而如果是HTTP 作 为反向代理来说,最大并发数量应该是worker connections * worker_processes / 4。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接,看一个示意图
在这里插入图片描述

配置Linux最大打开文件数

1.使用ulimit -a可以查看当前系统的所有限制值,使用ulimit -n 可以查看当前的最大打开文件数。
2.新装的linux默认只有1024,当作负载较大的服务器时,很容易遇到error:too many open files。因此,需要将其改大。
3.使用 ulimit -n 65535 可即时修改,但重启后就无效了。(注ulimit -SHn 65535 等效 ulimit -n 65535,-S指soft,-H指hard)
4.有如下三种修改方式:
(1)在/etc/rc.local 中增加一行 ulimit -SHn 65535
(2)在/etc/profile 中增加一行 ulimit -SHn 65535
(3)在/etc/security/limits.conf最后增加如下两行记录
* soft nofile 65535
* hard nofile 65535
在CentOS中使用第1种方式无效果,使用第3种方式有效果,而在Debian中使用第2种有效果

5.参考: https://blog.csdn.net/weixin_43055250/article/details/124980838

12. 搭建高可用集群

Keepalived+Nginx高可用集群(主从模式)

集群架构图

示意图
在这里插入图片描述
解读
1.准备两台 Nginx服务器,一台做主服务器,一台做备份服务器
2.两台Nginx服务器的IP地址,可以自己配置(具体配置看 Linux 网络配置章节)
3.安装keepalived,保证主从之间的通讯
4.对外提供统一的访问IP(虚拟IP-VIP)

搭建步骤

1、 准备两台Linux服务器 192.168.xx.xx和192.168.xx.xx

  1. 可以克隆来完成
  2. 也可以直接拷贝一份
    在这里插入图片描述在这里插入图片描述

ifconfig 看下这两台随机的ip是:92.168.31.194 和 192.168.31.254,下面以这两个ip展开演示。

在这里插入图片描述
在这里插入图片描述

2、 在两台Linux服务器,修改原来的配置Nginx和Tomcat,启动并验证,没问题往下。

  1. 安装配置Nginx步骤前面讲过,如果你克隆的Linux,本身就有安装好了Nginx,直接使用即可
  2. 验证安装是否成功,在windows可以通过IP访问到Nginx,具体的操作步骤和注意事项,前面也都是说过
  3. 因为我们是拷贝了一份Linux,而新的Linux的Ip 已经变化了,所以需要克隆的Linux的nginx.conf文件中的IP地址,做相应的修改
    在这里插入图片描述
    在这里插入图片描述
    3、在两台Linux服务器,安装 keepalived
  1. 下载keepalived-2.0.20.tar.gz 源码安装包https://keepalived.org/download.html在这里插入图片描述

  2. 上传到两台Linux/root 目录下

  3. mkdir /root/keepalived

  4. 解压文件到指定目录: tar -zxvf keepalived-2.0.20.tar.gz -C ./keepalived

  5. 进入目录:cd /root/keepalived/keepalived-2.0.20

  6. 执行:./configure --sysconf=/etc --prefix=/usr/local
    说明:将配置文件放在/etc目录下,安装路径在/usr/local

  7. make && make install
    说明:编译并安装

  8. 如果成功,就会安装好keepalived 【可以检查一下
    说明: keepalived 的配置目录在/etc/keepalived/ keepalived.conf
    keepalived 的启动指令在/usr/local/sbin/keepalived

  9. 提示:两台Linux都要安装keepalived

完成高可用集群配置:

1、将其中一台Linux(比如192.168.31.194)指定为Master: vi /etc/keepalived/keepalived.conf
在这里插入图片描述

2、将其中一台Linux(比如192.168.31.254)指定为Backup(备份服务器):vi /etc/keepalived/keepalived.conf
在这里插入图片描述

3、启动 两台Linux的keepalived 指令: /usr/local/sbin/keepalived
4、观察两台linux的ens33 是否已经绑定192.168.31.18 指令: ip a
在这里插入图片描述

在这里插入图片描述

测试

1、首先保证 windows 可以连通 192.168.31.18这个虚拟IP
在这里插入图片描述
2、访问http://192.168.31.18/search/cal.jsp
在这里插入图片描述

说明:大家可以看到,因为192.168.31.194是Master他的优先级高,所以访问的就是192.168.1.31.194的Nginx,同时仍然是支持负载均衡的。

3、停止 192.168.31.194的keepalived 服务或者直接关闭192.168…31.194 主机再次访问 http://192.168.31.18/search/cal.jsp,这时虚拟IP 绑定发生漂移,绑定到192.168.31.254 Backup服务,访问效果如图:
这里直接关闭192.168.31.194 Master的 keepalived 来测试
在这里插入图片描述

在这里插入图片描述
注意事项和细节
1、keepalived启动后无法ping通VIP,提示ping:sendmsg: Operation not permitted
https://blog.csdn.net/xjuniao/article/details/101793935

2、nginx+keepalived配置说明和需要避开的坑
https://blog.csdn.net/qq_42921396/article/details/123074780

自动检测Nginx异常,终止keepalived

如果Master主服务器Nginx挂了,Client还一直访问这个服务器Nginx就会出错,无法切换到Backup从服务器Nginx,这个时候就需要来一个能自动检测主服务器Nginx异常的程序脚本来终止该服务器下的keepalived,以达到切换访问Backup从服务器Nginx的效果。
实现步骤:
1、编写shell脚本: vi /etc/keepalived/ch_nginx.sh
简单说明:下面的脚本就是去统计ps -C nginx --no-header的行数,如果为0,说明nginx已经异常终止了就执行 killall keepalived

#!/bin/bash
num = `ps -C nginx --no-header | wc -l`
if [ $num -eq 0 ];then 
	killall keepalived
fi

2、修改ch_nginx.sh权限chmod 755 ch_nginx.sh
3、修改192.168.31.194 主Master 配置文件,指令: vi /etc/keepalived/keepalived.conf

在这里插入图片描述

4、新启动192.168.31.194 Master的keepalived,这时因为Master的优先级高,会争夺到VIP优先绑定.
5、手动关闭 192.168.31.194 Master的Nginx,这时脚本就开始运行,关闭keepalived
在这里插入图片描述
注意观察 keepalived也终止了

6、再次访问nginx,发现192.168.31.18这个虚拟IP 又和 192.168.131.254备份服务器绑定了。
在这里插入图片描述
注意事项
1、keepalived vrrp_script脚本不执行解决办法
打开日志观察:
tail -f /var/log/messages

重启keepalived:
systemctl restart keepalived.service

曾经出现过文件找不到可以修改执行脚本文件名,不要有_就OK

2.如果配置的定时检查Nginx异常的脚本,需要先启动nginx,在启动 keepalived,否则keepalived一起动就被killall 了

配置文件keep alive的.conf详解

#这里只注释要修改的地方
global_defs {
notification_email(
	test@foxmail.com  #接收通知的邮件地址
}
notification_email_from Alexandre.Cassen@frewall.loc #发送邮件的邮箱
smtp _server 192.168.200.1 #smtp server 地址
smtp_connect timeout 30
router_id Node132 # #Node132为号机标识 
vrrp_skip check_adv_ addr
#vrrp_strict  #这里需要注释,避免虚拟ip无法ping通
vrrp _garp interval 0
vrrp gna interval 0
}
vrrp_instance VI_1 {
	state MASTER   		#主节点MASTER备用节点为BACKUP
	interface ens33		#网卡名称
	virtual router id 51 #VRRP组名,两个节点的设置必须一样,指明属于同-VRRP组
	priority 100 		#主节点的优先级(1-254之间),备用节点必须比主节点优先级低
	advert int 1	 	#组播信息发送间隔,两个节点设置必须一样
	authentication(  	 #设置验证信息,两个节点必须一致
		auth _type PASS
		auth pass 1111
	}
	
	virtual ipaddress{
		192.168.200.16		#指定虚拟IP,两个节点设置必须一样
	}
}

小结

Keepalived+Nginx 是高可用集群(主从模式)的一种解决方案,不一定都会用到这个Keepalived,小伙伴还可以查找其他的产品解决方案,这里是提供了一种解决思路。

  • 26
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦境之冢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值