Nginx
进程模型
- master:主进程
- worker:工作进程
master会监控worker,一个worker挂掉,master会再开启一个worker
./nginx -s stop
./nginx -s quit
./nginx -s reload
./nginx -t
这些nginx都是master交给worker去执行的
图为imooc课程,感谢大佬
worker抢占机制
这两张图讲的是,一个传统的服务器处理客户端请求,是一个client访问,一个worker去处理,此时阻塞,master会fork一个新的worker去处理别的请求
在大量请求涌入服务后,这种服务器会承担非常大的压力
下来我们讲讲nginx
nginx使用一个worker就可以处理多个client的请求
worker使用epoll模型去
多用复用的模型
nginx.conf配置结构
nginx核心配置
#user nobody;
默认的使用用户是nobody,可以换成root
user root;
:wq保存
/nginx/sbin/nginx -s reload
可以看到我们现在操作nginx的用户为root,权限更高
日志级别
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log logs/error.log info;
启动的端口号
#pid logs/nginx.pid;
events {
#使用epoll模型
use epoll;
#每个worker可以处理的请求数量
worker_connections 10240;
}
http {
# 引用一个类型,vim同级别目录mine文件可查看
include mime.types;
default_type application/octet-stream;
# 开启日志,记录访问请求信息
#access_log logs/access.log main;
# 文件传输,开启此配置,才可以开下面这个tcp积累开启
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
# 保留存活65,这一段时间请求进来可以继续使用
keepalive_timeout 65;
# 压缩静态资源文件,提升访问速度,降低cpu运行效率
#gzip on;
# 真正核心模块
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 {
}
}
如果pid不见了,或者配置出现问题,可以通过nginx -c /nginx/conf/nginx.conf
重新对nginx进行配置
nginx常用命令
#快速停止
./nginx -s stop
#优雅停止,暂停接受新请求,等待现有请求处理结束,关闭服务
./nginx -s quit
./nginx -s reload
# 检查配置文件
./nginx -t
# 查看版本
./nginx -v
# 查看可用参数
./nginx -?
nginx日志切割
todo待补充
大概思路,使用crontabs,进行设置定时任务,去切分日志
静态文件服务
使用alias可以隐藏路径
开启gzip
开启gzip压缩功能
gzip on;
location
精准匹配
loaction = /
正则匹配,*代表不区分大小写
location ~* \.(gif|png|bmp|jpg|jpeg)
以某个字符开头,只能以这个开头的资源路径访问
location ^~ /qyk/img
解决跨域问题
todo
nginx的模块化体系
进入src目录
nginx底层是用c语言写的,不看了,怕秃~
负载均衡
通过nginx的一个upstream进行配置,一个请求可能会被nginx代理到不同的tomcat
四层负载均衡
主要是为了将请求分流到不同服务器
- F5硬负载均衡,基于硬件、商业化
- LVS四层负载
- Haproxy四层负载
- Nginx四层负载
七层负载均衡
基于应用层HTTP协议进行负载均衡
- Nginx七层负载
- haproxy七层负载
- apache七层负载
四层主要是tcp、udp转发请求,而不是处理请求
七层会处理请求,可以过滤、压缩、缓存等
DNS地域负载均衡
可以根据请求者地域,分配到最近的服务器
减少网络传输的损耗
负载均衡-轮训
配置好一个tomcat集群,默认就是轮训访问
负载均衡-权重轮训
可以对不同服务配置权重,权重越高,访问次数被分配越多
upstream指令参数
max_conns:最大连接数,超过连接数会返回502
slow_start:慢启动,不能使用hash负载、两个以上服务器才能使用这个参数,会慢慢从1升级到设置权重
down:标示这台服务器挂了,不能用的状态
backup:
max_fails:最大失败次数,超过以后就踢出集群
fail_timeout:失败超时时间,会把请求暂时导向别的健康服务
keeplive提高吞吐量
使用keeplive参数,官方提供32,设置长连接,减少创建销毁连接过程
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream tomcats{
server 47.94.138.137:8088 weight=1;
server 47.94.138.137:8089 weight=2;
keepalive 32;
}
server {
listen 80;
server_name 47.94.138.137;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://tomcats;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
25,13 72%
配置 keepalive 32;
与location里
proxy_http_version 1.1;
proxy_set_header Connection “”;
开启
负载均衡之IP_HASH
通过hash(ip)%node_counts = index
算出用户访问的服务器具体是哪一台
保证用户访问的服务器是同一台,保持会话一致
进入nginx源码查看
分段进行计算,同一片区域,会访问到一个里
hash算法带来的问题
当一台机器挂了以后,服务器的hash算法需要重新求模计算,加上之前的服务器会被导向不同的服务器,静态资源缓存都会重新加载,用户体验变差,服务器性能受到威胁
使用一致性hash算法进行计算
根据hash算法,将节点存放在这个环上,顺时针放上去
用户也会进行hash计算,访问的顺时针的第一台机器上
就算有一台机器突然挂掉离开,我们的3节点的用户会被迁移到4节点上,保证其余两台机器不会收到影响
增加节点,会把原先导向3的部分用户导向2.5这台机器上
负载均衡之url_hash
看看图,不用多说,换汤不换药
通过配置hash $request_uri
开启url_hash
nginx缓存
nginx会缓存一部分静态文件
expires [time],可以设置过期时间,控制浏览器缓存,方便后期项目的更新迭代
expires @time,浏览器会倒计时计算静态资源文件过期时间,时间到期自动请求新的资源
expires -time 设置距离现在起,之前的资源都失效
expires -epoch 不去设置cache
expires off 默认,关闭不代表没有,浏览器默认有
expires max 基本不会到期
nginx反向代理缓存
proxy_cache_path设置路径缓存地址,
key_zone设置空间、大小
max_size 大小
inactive 超过时间,自动清除
use_temp_path关闭临时目录
proxy_cache_path /usr/local//nginx/cache key_zone=mycache:5m max_size=1g inactive=30s use_temp_path=off
在server里配置
proxy_cache mycache;
proxy_cache_valid 200 304 8h;
nginx高可用HA
只有主节点挂了,从节点才可以上位
可以解决nginx高可用问题
keepalived
解决单点故障
组件免费
双机主备原理
原先用户通过虚拟ip访问主机,主机会向从节点发送心跳,从节点keepalived检测心跳发现主机挂了,就把请求都导向从节点了
两台机器最好使用同样的高配置,不然万一主机挂了,从机扛不住压力也是假的
安装keepalived
./configure --prefix=/usr/local/keepalived --sysconf=/etc
make && make install
vim /etc/keepalived/keepalived.conf
global_defs {
#全局变量-路由id,标识主机id
router_id keep_137
}
#计算机节点
vrrp_instance VI_1 {
#标示当前机器为主节点,从节点backup
state MASTER
#当前网卡
interface eth0
#保持主备机一致
virtual_router_id 51
#权重,最高的当选下一任主机
priority 100
#检查时间间隔1s
advert_int 1
#认证授权,防止非法节点进入
authentication {
auth_type PASS
auth_pass 1111
}
#虚拟ip
virtual_ipaddress {
172.17.219.228
}
}
最后虚拟ip,需要先查看你本机器ip
[root@iZkpcpzbqiupj6Z sbin]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:16:3e:0a:0d:d7 brd ff:ff:ff:ff:ff:ff
inet 172.17.219.229/20 brd 172.17.223.255 scope global eth0
[root@iZkpcpzbqiupj6Z sbin]#
可以看到我的网卡是eth0,我选的228为我的虚拟ip
[root@iZkpcpzbqiupj6Z keepalived-2.0.18]# cd /usr/local/keepalived/sbin/
[root@iZkpcpzbqiupj6Z sbin]# ll
总用量 2020
-rwxr-xr-x 1 root root 2064950 5月 31 11:15 keepalived
[root@iZkpcpzbqiupj6Z sbin]#
Display all 1370 possibilities? (y or n)
[root@iZkpcpzbqiupj6Z sbin]# ./keepalived
[root@iZkpcpzbqiupj6Z sbin]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:16:3e:0a:0d:d7 brd ff:ff:ff:ff:ff:ff
inet 172.17.219.229/20 brd 172.17.223.255 scope global eth0
inet 172.17.219.228/32 scope global eth0
启动后我们看到228已经是和我们的主机进行绑定了
我们启动多个从机,他们的虚拟ip都是172.17.219.228,配置文件的state设置为backup
当我们访问虚拟ip时,我们keepalived会将请求导向我们的主节点上去,我们把主节点宕机,再去备机上ip addr查看,就会发现备机
inet 172.17.219.228/32 scope global eth0
虚拟ip绑定到了备机上,我们访问的请求也就到达了备机节点
刚才我们讲的是keepalived主节点挂了,那我们的nginx挂了怎么办??
设置nginx心跳检测
将这个脚本文件保存到/etc/keepalived文件夹下,明明xxx(自己命名吧),记得下面授权语句授权
chmod +x xxx.sh
执行这个脚本后,会检测nginx,挂掉会重启nginx
我们将它配置到keepalived配置文件里
vrrp_script check_nginx_alive {
script "/etc/keepalived/xxx.sh"
interval 2 #每隔两秒钟运行脚本检测
weight 10 #脚本运行成功,升级权重+10
}
#计算机节点
vrrp_instance VI_1 {
#标示当前机器为主节点,从节点backup
state MASTER
#当前网卡
interface eth0
#保持主备机一致
virtual_router_id 51
#权重,最高的当选下一任主机
priority 100
#检查时间间隔1s
advert_int 1
#认证授权,防止非法节点进入
authentication {
auth_type PASS
auth_pass 1111
}
#虚拟ip
virtual_ipaddress {
172.17.219.228
}
#在此执行上 面的定时器
track_script{
check_nginx_alive
}
}
这样我们就能保证高可用的架构了,但是双机主备会有资源浪费的问题,主机永远不挂机,备机白干活儿,年年100w不干活儿,让老板知道抓着你锤!!!
双主热备
通过DNS轮训制作双主热备,防止资源浪费问题
下面是原先主机配置,现在添加一个虚拟ip做个备机,即是277备机,又是278主机
global_defs {
#全局变量-路由id,标识主机id
router_id keep_137
}
vrrp_script check_nginx_alive {
script "/etc/keepalived/xxx.sh"
interval 2 #每隔两秒钟运行脚本检测
weight 10 #脚本运行成功,升级权重+10
}
#228主节点
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.17.219.228
}
track_script{
check_nginx_alive
}
}
#227从节点
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 52
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.17.219.227
}
track_script{
check_nginx_alive
}
}
这是原先备机那台,我们做个虚拟ip来个主机,即是278备机,又是277主机
global_defs {
#全局变量-路由id,标识主机id
router_id keep_137
}
vrrp_script check_nginx_alive {
script "/etc/keepalived/xxx.sh"
interval 2 #每隔两秒钟运行脚本检测
weight 10 #脚本运行成功,升级权重+10
}
#228主节点
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.17.219.228
}
track_script{
check_nginx_alive
}
}
#227从节点
vrrp_instance VI_2 {
state MASTER
interface eth0
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.17.219.227
}
track_script{
check_nginx_alive
}
}
现在我们的 机器就是互为主备,双主热备搞定了,配置好DNS轮训就可以让我们的一个服务获得非常稳定的保障了