Nginx
1. Nginx基本概念
1.1 Nginx简介
-
Nginx是一个高性能HTTP和反向代理web服务器,同时提供了IMAP/POP3/SMTP服务。
-
特点是占有内存少,并发能力强。
-
官方数据测试最高支持5000个并发连接数的响应
-
支持热部署,启动特别容易,并且几乎可以做到24小时不间断运行。
详细介绍:https://lnmp.org/nginx.html
1.2 代理
1.2.1 正向代理(代理客户端)
Nginx不仅可以做反向代理,实现负载均衡,还可以用作正向代理来进行上网等功能。
正向代理:在客户端配置代理服务器,通过代理服务器进行访问。
1.2.2 反向代理(代理服务端)
反向代理,客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,再返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器的地址,隐藏了真实服务器的ip地址。
1.3 负载均衡
客户端发送多个请求到服务器,服务器请求处理,有一些可能要与数据库进行交互,服务器处理完毕后,再将结果返回给客户端。
这种架构模式相对单一,并发请求相对较少的情况下适合,成本低。但是性能太差!不适用。
**负载均衡:**增加服务器数量,然后将请求分发到各个服务器上。将负载分发到不同的服务器,这就是负载均衡。
Nginx提供的负载均衡策略有两种:内置策略和扩展策略。
内置策略为轮询,加权轮询,Ip hash。
轮询:每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,则自动剔除
加权轮询:根据权重分配,weight代表权重,默认为1,权重越高被分配的客户端越多
IP hash:ip hash对客户端请求你的ip进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给用一台服务器进行处理,可以解决session不共享的问题。
fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配
1.4 动静分离
为了加快解析速度,可以把动态页面和静态页面(如:css、html、jpg、js等等)由不同的服务器来解析,加快解析速度。
2. Nginx安装、常用命令和配置文件
2.1 在Linux中安装nginx
1.使用工具连接Linux系统
2.官网下载:http://nginx.org/en/download.html
- 如果的有的话不用
(1)安装pcre库
PCRE库支持正则表达式。如果我们在配置文件nginx.conf中使用了正则表达式,那么在编译Nginx时就必须把PCRE库编译进Nginx,因为Nginx的HTTP模块需要靠它来解析正则表达式。另外,pcre-devel是使用PCRE做二次开发时所需要的开发库,包括头文件等,这也是编译Nginx所必须使用的。
yum -y install pcre-devel
# pcre-config --version 安装后查看版本号
(2)安装zlip库
zlib库用于对HTTP包的内容做gzip格式的压缩,如果我们在nginx.conf中配置了gzip on,并指定对于某些类型(content-type)的HTTP响应使用gzip来进行压缩以减少网络传输量,则在编译时就必须把zlib编译进Nginx。zlib-devel是二次开发所需要的库。
yum -y install zlib-devel
(3)安装OpenSSL库
如果服务器不只是要支持HTTP,还需要在更安全的SSL协议上传输HTTP,那么需要拥有OpenSSL。另外,如果我们想使用MD5、SHA1等散列函数,那么也需要安装它。
yum -y install libssl-dev
4.安装nginx
# 解压
tar -xvf nginx.xx名字xxx
# 进入nginx目录
cd nginx.xx名字xxx
# 安装方式
./configure
make && make install
# 查看nginx目录
whereis nginx
5.测试
#进入nginx sbin文件
cd /usr/local/nginx/sbin
# 启动
./nginx
# 查看进程
ps -ef|grep nginx
默认端口:80
访问80端口
注意:如何连接不上,检查阿里云安全组是否开放端口,或者服务器防火墙是否开放端口!
相关命令:
# 开启
service firewalld start
# 重启
service firewalld restart
# 关闭
service firewalld stop
# 查看防火墙规则
firewall-cmd --list-all
# 查询端口是否开放
firewall-cmd --query-port=8080/tcp
# 设置开放80端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
# 移除端口
firewall-cmd --permanent --remove-port=8080/tcp
# 重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload
# 参数解释
1、firwall-cmd:是Linux提供的操作firewall的一个工具;
2、--permanent:表示设置为持久;
3、--add-port:标识添加的端口;
2.2 nginx常用命令
先用nginx操作命令前提:必须进入nginx的目录
# 进入nginx sbin文件
cd /usr/local/nginx/sbin
# 查看nginx版本号
./nginx -v
# 启动nginx
./nginx
# 关闭nginx 强制退出
./nginx -s stop
# 退出nginx 安全退出
./nginx -s quit
# 重新加载配置文件
./nginx -s reload
# 查看nginx进程
ps aux|grep nginx
# 当启动nginx端口被占用
fuser -k 80/tcp
2.3 nginx配置文件
2.3.1 配置文件位置
/usr/local/nginx/conf/nginx.conf
2.3.2 配置文件组成
配置文件:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
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 on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
-
第一部分 全局块
- 从配置文件开始到events块之间的内容,主要会设置一些影响nginx服务器整体运行的配置命令
worker_processes 1;
这是Nginx服务器并发处理服务的关键配置,worker_processes 值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约。
-
第二部分 events块
- events块涉及的指令主要影响Nginx服务器与用户的网络连接,常用的设置包括是否开启多work process下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种时间驱动模型来处理连接请求,每个word process可以同时支持的最大连接数等。
events { worker_connections 1024; }
上述例子表示 每个 work process支持的最大连接数为 1024
这部分的配置对Nginx的性能影响较大,在实际中应该灵活配置。
-
第三部分 http块
- 这是Nginx服务器配置中最繁琐的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。
- 需要注意:http块包括 http全局块、server块
① http 全局块
http全局块配置的指令包括文件引入、MIME-TYPE定义、日志自定义、连接超时时间、单链接请求数上限等…
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { ...... } }
② server 块
这块和虚拟主机有密切联系,虚拟主机从用户角度看,和一台独立的硬件主机是一致的,该技术的产生是为了节省互联网服务器硬件成本
每个http块可以包括多个 server块,而每个server块就相当于一个虚拟主机。
每个server块也分为全局server块,以及可以同时包含多个location块。
...... server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
1.全局server块
最常见的配置是本虚拟机主机的监听配置和本虚拟机主机的名称或IP配置。
2.location块
一个server块可以配置多个location块
这块主要作用是基于Nginx服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称(也可以是IP别名) 之外的字符串(例如 /uri-string)进行匹配,对特定的请求进行处理。地址定向。数据缓存和应答控制等功能,还有许多第三方模块的配置也在这类进行
3. Nginx配置实例
3.1 反向代理
3.1.1 location指令说明
- 该指令用于匹配URL
location ~ /uri/ {
}
- = :用于不含正则表达式的uri前,要求请求字符串与uri严格匹配,如果匹配成功,就停止向下搜索并立即处理该请求
- ~ :用于表示uri包含正则表达式,并且区分大小写
- ~* :用于表示uri包含正则表达式,并且不区分大小写
- ^~ :用于不含正则表达式的uri前,要求Nginx服务器找到标识uri和请求字符串匹配度最高的location后,立即使用此location处理请求,而不再使用location块中的正则uri和请求字符串做匹配。
注意:如果uri包含正则表达式,则必须要有或者*标识。
3.1.2 反向代理实例一
实现效果
- 打开浏览器,输入地址后,跳转到Linux系统的tomcat主页面中
1.准备工作
- 在Linux安装tomcat,使用默认端口8080
# 压缩包放入/usr/src
tar -xvf apache-tomcat # 解压
cd apache-tomcat # 进入
cd bin # 进入文件
./startup.sh # 启动tomcat服务器
- 对外访问的端口
firewall-cmd --add-port=8080/tcp --permanent # 添加8080
firewall-cmd -reload # 重启
#查看已经开发的端口号
firewall-cmd --list-all
-
在Windows系统中通过浏览器测试
-
访问过程分析
2.开始代理:
1.在windows系统的host文件进行域名和ip对应关系的配置
地址:C:\Windows\System32\drivers\etc
找到host文件 输入8.130.160.173 www.ghc1.com
2.在nginx进行请求转发的配置(反向代理配置)
# 进入配置文件
cd /usr/local/nginx/conf
vi nginx.conf # 修改
# 将server_name localhost -修改为-> server_name 8.130.160.173
#location中加入
proxy_pass 127.0.0.1:8080;
# 这样当访问8.130.160.173:80 就会转发到 127.0.0.1:8080;
3.测试
# 启动nginx
[root@ghc1 conf]# vi nginx.conf
[root@ghc1 conf]# cd /usr/local/nginx/sbin/
[root@ghc1 sbin]# ./nginx
输入网址:www.ghc1.com 进行测试
3.1.3 反向代理实例二
实现效果:使用Nginx反向代理,根据访问的路径跳转到不同端口的服务中
Nginx监听端口为9001
访问 http://127.0.0.1:9001/edu --直接跳转到–> 127.0.0.1:8080
访问 http://127.0.0.1:9001/vod --直接跳转到–> 127.0.0.1:8081
准备工作:
-
第一步,准备两个tomcat,一个8080端口,一个8081端口,并准备好测试的页面
cd /usr/src mkdir tomcat8080 mkdir tomcat8081 # 创建两个文件夹 并将tomcat压缩包放入 # 进入8080文件夹操作 cd tomcat8080 ps -ef|grep tomcat # 查看tomcat进程 kill -9 xxxx(root) # 关闭 tar -xvf tomcat.xxxx cd apache-tomcat-xxxx cd bin ./startup.sh # 进入8081文件夹 cd tomcat8081 tar -xvf tomcat.xxxx cd apache-tomcat-xxxx # 进去配置文件修改端口 cd conf vi server.xml # 进入后修改端口号 cd .. cd bin ./startup.sh # 启动 firewall-cmd --zone=public --add-port=8081/tcp --permanent # 若没开启端口,则要开启
测试:
-
第二步,创建文件夹和测试页面
1.进入tomcat8080/webapps/
2.创建edu文件,放入a.html
3.进入tomcat8081/webapps/
4.创建vod文件,放入b.html
5.测试:
8.130.173.8080/edu/a.html
8.130.173.8081/vod/b.html
-
第三步,具体配置
1.找到nginx配置文件,进行反向代理配置
# 进入配置文件 cd /usr/local/nginx/conf vi nginx.conf # 修改
# 监听9001 # location 根据路径转到不同路径 # 当访问edu 转到8080 # 当访问vod 转到8081 # ~ 表示正则表达式的形式,代表当有edu就转到8080 # 在配置文件中添加 server { listen 9001; server_name 8.130.160.173; location ~ /edu/ { proxy_pass http://localhost:8080; } location ~ /vod/ { proxy_pass http://localhost:8081; } }
2.开放对外访问的端口号 9001 8080 8081
# 重启nginx [root@ghc1 conf]# cd /usr/local/nginx/sbin [root@ghc1 sbin]# ./nginx -s reload
3.测试
3.2 负载均衡
- 负载均衡即是将负载分摊到不同的服务单元,既保证服务的可用性,又保证响应足够快,给用户良好的体验。
Nginx提供了集中分配方式(策略):
1.轮询(默认):
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,则自动剔除
......
upstream myserver{
server 8.130.160.173:8081;
server 8.130.160.173:8088;
}
......
2.weight(加权轮询):
weight代表权,默认为1,权重越高被分配的客户端越多
......
upstream myserver{
server 8.130.160.173:8081 weight=3;
server 8.130.160.173:8088 weight=1;
}
......
3.iphash:
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session问题。
......
upstream myserver{
ip_hash;
server 8.130.160.173:8081;
server 8.130.160.173:8088;
}
......
4.fair(第三方):
按后端服务器的响应时间来分配请求,响应时间短的优先分配
......
upstream server_pool{
server 8.130.160.173:8081;
server 8.130.160.173:8088;
fair;
}
......
实现效果:
- 浏览器输入地址:http://8.130.160.173/edu/a.html,负载均衡效果,请求平均分担到8080和8081端口中
准备工作:
- 准备两台tomcat服务器,8081和8082
- 在两台tomcat里面webapps目录中,创建名称是edu的文件夹,在edu文件中创建页面a.html,用于测试
- 在Nginx配置文件中,进行负载均衡配置
## 配置
http{
......
upstream myserver{
ip_hash;
server 8.130.160.173:8081 weight=1;
server 8.130.160.173:8088 weight=1;
}
......
server{
location / {
......
proxy_pass http://myserver;
proxy_connect_timeout 10;
}
......
}
}
测试:输入8.130.160.173/edu/a.html 每次刷新页面会按配置文件跳转
3.3 动静分离
-
动静分离简单来说就是把动态和静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开,可以理解成使用Nginx处理静态页面,Tomcat处理动态页面。
-
动静分离目前实现角度大致分两种:
- 把静态文件独立成单独的域名,放在独立的服务器上(主流方式)
- 动态和静态文件混合在一起发布,通过nginx来分开
通过location指定不同的后缀名实现不同的请求转发。通过expires参数设置,可以使浏览器缓存过期时间,减少与服务器之间的请求和流量。具体Expires定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。(此方法适合不经常变动的资源)
准备工作:
- 在Linux系统中准备静态资源,用于进行访问
mkdir data # 根目录下创建data
cd data
mkdir www # 放静态资源
mkdir image # 放图片
# www 放入a.html image 放入01.jpg
具体配置:
- 在nginx配置文件中进行配置
location /www/ {
root /data/;
index index.html index.htm;
}
location /image/ {
root /data/;
autoindex on; # 列出文件夹的内容
}
-
测试:
浏览器输入http://8.130.160.173/image/
输入http://8.130.160.173/www/a.html
4. Nginx配置高可用集群
问题:当Nginx宕机,请求无法实现效果
简介:
HA(hight avaliable)即高可用,又被叫双机热备
防止服务器中断,影响对外提供服务
协议:Heartbeat使用心跳进行通信和选举
含义:一般是指当集群中的任意一个节点失效的情况下,节点上的所有任务自动转移到其他正常的节点上,并且此过程不影响整个集群的运行,不影响业务的提供。
- 需要两台nginx服务器
- 需要keepalived服务
- 需要虚拟ip
配置高可用的准备工作:
-
需要两台服务器 ipxxxx 和 ipxxxx
-
在两台服务器上安装nginx
-
在两台服务器上安装keepalived
cd /usr yum install keepalived -y # 安装 rpm -q -a keepalived # 查看是否安装成功 cd /ect/keepalived # keepalived位置,里面有配置文件keepalived.conf
-
完成高可用配置(主从配置)
主服务器:
keepalived.conf
! Configuration File for keepalived #全局配置 global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL #通过这个名字能访问到主机,其余用处不大 vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } # 相关脚本配置 vrrp_script chk_http_port{ script "/usr/local/src/nginx_check.sh" interval 2 #检测脚本执行的间隔 weight 2 #权重。当脚本的条件成立,把当前的权重加2;如果值为负数(-20),就减少20。通过修改weight来改变主从服务器 } # 虚拟IP的配置 vrrp_instance VI_1 { state MASTER #主MATER 从BACKUP interface enp0s3 #网卡 通过ifconfig查看 virtual_router_id 51 #主从机的virtual_router_id必须相同 priority 100 #主从机取不同的优先级,主机值较大,备份机值较小 advert_int 1 #心跳时间间隔,用于检测主机或服务器是否还活着,默认1秒。表示每隔多长时间发生一个心跳 authentication { #权限校验方式 auth_type PASS auth_pass 1111 } virtual_ipaddress { #通过它就可以完成keepalived的配置 172.16.1.50 # VRRP H虚拟地址 } }
nginx_check.sh(检测脚本,检测nginx是否还活着)
# 检测脚本,如果能启动就访问,不能就切换 # !/bin/bash A=`ps -C nginx -no-header | wc -l` if [ $A -eq 0 ];then /usr/local/nginx/sbin/nginx # nginx启动路径 sleep 2 if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then killall keepalived # 如果嘱咐其挂掉,从服务器就替代主服务器 fi fi
keepalived.conf 放入 /etc/keepalived 中
nginx_check.sh 放入 /usr/local/src 中
主服务器配置完成!
从服务器:
修改keepalived.conf文件
# ...上面不变... # 修改state 为BACKUP、priority 90 (比主服务器小一点) # 虚拟IP的配置 vrrp_instance VI_1 { state BACKUP #主MATER 从BACKUP interface enp0s3 #网卡 通过ifconfig查看 virtual_router_id 51 #主从机的virtual_router_id必须相同 priority 100 #主从机取不同的优先级,主机值较大,备份机值较小 advert_int 1 #心跳时间间隔,用于检测主机或服务器是否还活着,默认1秒。表示每隔多长时间发生一个心跳 authentication { #权限校验方式 auth_type PASS auth_pass 1111 } virtual_ipaddress { #通过它就可以完成keepalived的配置 172.16.1.50 } }
keepalived.conf 放入 /etc/keepalived 中
nginx_check.sh 放入 /usr/local/src 中
从服务器配置完成!
-
启动两台服务器上的 nginx 和 keepalived
# 主服务器 cd /usr/local/nginx/sbin ./nginx -s stop # 关闭 ./nginx # 启动nginx systemctl start keepalived.service # 启动keepalived ps -ef|grep keepalived # keepalived查看进程
# 从服务器 cd /usr/local/nginx/sbin ./nginx -s stop # 关闭 ./nginx # 启动nginx systemctl start keepalived.service # 启动keepalived ps -ef|grep keepalived # keepalived查看进程
-
测试:
-
在浏览器输入虚拟IP地址 172.16.1.50 进入到nginx页面,即主服务器绑定成功!
-
把主服务 nginx 和 keepalived 停止,再输入地址
# 主服务器 systemctl stop keepalived.service # 停止keepalived ./nginx -s stop # 停止nginx
此时输入地址访问,进入到nginx页面,即从服务器绑定成功!
-
5. Nginx执行原理
5.1 master和worker
nginx中有master和worker进程
master是管理员,负责把任务分给不同的worker,worker执行具体的任务。
5.1.1 worker具体是怎么进行工作的?
当client发送一个请求到nginx中,首先要先到master中,然后master得到请求后,把请求分发给worker,让worker做具体的任务,
worker怎么得到任务呢?
不是平均分配和轮询的方式,而是争抢的机制,分发任务后,worker争抢之后做具体的事情。nginx本身不直接支持Java,Java操作还需要依赖于Tomcat,所以worker还需要做请求转发、反向代理等,通过tomcat查数据库,得到最终结果。
5.1.2 一个master和多个worker机制的好处
热部署:
生产环境中,nginx是不能停止的,使用热部署能解决此问题。
第一个worker1争抢到任务后,使用 ./nginx -s -reload 热部署,worker1不变,继续处理任务。其他未执行任务的worker就重新加载,而worker1则在完成任务后,再重新加载,获得最新的配置。
- 可以使用 nginx -s reload 命令,热部署方式。不需要重新启动,可以让nginx让修改完的配置生效。一个master-多个master利于热部署。
- 对于每个worker的进程来说,独立的进程,不需要加锁,所以省略了锁带来的开销。同时在编程以及问题查找时,也会方便很多。
- 采用独立的进程,可以让互相之间不受影响。一个进程退出后,其他进程继续进行争抢任务和工作,工作不会中断,master进程则很快启动新的worker进程。当然worker进程的异常退出,肯定是程序有bug了。异常退出,会导致当前worker让所有请求失败,不过不会影响到所有请求,所以降低了风险。
5.1.3 设置多少个worker是最合适的
- Nginx 同 Redis 类似都采用了IO多路复用机制,每个worker都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求,即使是成千上万个请求也不在话下。每个worker的线程可以把一个CPU的性能发挥到极致。所以worker数和服务器的CPU数相等是最为适宜的。设少了,浪费CPU;设多了会造成CPU频繁切换上下文带来的损耗。
- windows中没有IO多路复用机制,不能将性能发挥到最大,因此,nginx、redis通常安装到Linux中。
5.1.4 连接数 worker_connection
- 发送一个请求,占用了worker的几个连接数?
- 2或者4
- 只访问静态资源,占用2个连接数;当用tomcat访问数据库,占用4个连接数
- nginx有一个master,有4个worker,每个worker支持的最大连接数是1024,目前每个worker支持的最大并发数是多少?
- worker最大支持的连接数:4 * 1024
- worker最大支持的并发:4 * 1024 / 2或者4
- 普通的静态访问最大并发数:worker-connection * worker_processes / 2
- HTTP作为反向代理,最大并发数:worker-connection * worker_processes / 4
5.2 总结:
- nginx采用master-worker的方式
- worker采用争抢方式进行工作的
- 可以根据CPU数量设置worker数量
- 发送请求的时候,每个请求占有2个或4个连接数
- worker支持的最大并发数 worker-connection * worker_processes / 2 或者4