nginx 入门到精通

nginx 相关

nginx 相关

1. nginx 安装

1.1. 下载以及上传

  • 去官网http://nginx.org/下载对应的nginx包,推荐使用稳定版本
  • 上传nginx到linux系统
[root@izbp1den9djvvjxevz15wgz software]# pwd
/home/software
[root@izbp1den9djvvjxevz15wgz software]# ll
total 211316
-rw-r--r-- 1 root root   9699102 Jun  5 10:38 apache-tomcat-8.5.41.tar.gz
-rw-r--r-- 1 root root  10914435 Jun  5 10:38 apache-tomcat-9.0.24.tar.gz
-rw-r--r-- 1 root root 191753373 Jun  5 10:38 jdk-8u191-linux-x64.tar.gz
-rw-r--r-- 1 root root   1015958 Jun  6 09:54 keepalived-2.0.18.tar.gz
-rw-r--r-- 1 root root   1032630 Jun  6 09:54 nginx-1.16.1.tar.gz
-rw-r--r-- 1 root root   1959445 Dec 12  2018 redis-5.0.3.tar.gz

1.2. 安装依赖环境

  • 安装gcc环境

yum install gcc-c++

  • 安装PCRE库,用于解析正则表达式

yum install -y pcre pcre-devel

  • zlib压缩和解压缩依赖,

yum install -y zlib zlib-devel

  • SSL 安全的加密的套接字协议层,用于HTTP安全传输,也就是https

yum install -y openssl openssl-devel

  • 解压,需要注意,解压后得到的是源码,源码需要编译后才能安装

tar -zxvf nginx-1.16.1.tar.gz

  • 编译之前,先创建nginx临时目录,如果不创建,在启动nginx的过程中会报错

mkdir /var/temp/nginx -p

  • 在nginx目录,输入如下命令进行配置,目的是为了创建makefile文件

cd nginx-1.16.1


        ./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

    • 注: 代表在命令行中换行,用于提高可读性
    • 配置命令:
–prefix 指定nginx安装目录
–pid-path 指向nginx的pid
–lock-path 锁定安装文件,防止被恶意篡改或误操作
–error-log 错误日志
–http-log-path http日志
–with-http_gzip_static_module 启用gzip模块,在线实时压缩输出数据流
–http-client-body-temp-path 设定客户端请求的临时目录
–http-proxy-temp-path 设定http代理临时目录
–http-fastcgi-temp-path 设定fastcgi临时目录
–http-uwsgi-temp-path 设定uwsgi临时目录
–http-scgi-temp-path 设定scgi临时目录
  • make编译

make

  • 安裝

make install

  • 查看安装路径

whereis nginx

路径 nginx: /usr/local/nginx

  • 进入目录

cd /usr/local/nginx

  • 进入sbin目录启动nginx

cd sbin

./nginx

停止:./nginx -s stop
重新加载:./nginx -s reload
  • 打开浏览器,访问虚拟机所处内网ip即可打开nginx默认页面,显示如下便表示安装成功:
  • 注意事项
1. 如果在云服务器安装,需要开启默认的nginx端口:80
2. 如果在虚拟机安装,需要关闭防火墙
3. 本地win或mac需要关闭防火墙

1.3. 同步与异步阻塞与非阻塞

同步与异步,阻塞与非阻塞。

阻塞与非阻塞、同步与异步,很多人可能会认为同步就是阻塞,异步就是非阻塞,有啥区别,如果学习过的可以当做复习,如果不太清楚的,可以好好的了解一番,因为这些概念往往在面试过程中有可能会被面试官问到。

这四个概念两两组合,会形成4个新的概念,如下:

  1. 同步阻塞: 客户端发送请求给服务端,此时服务端处理任务时间很久,则客户端则被服务端堵塞了,所以客户端会一直等待服务端的响应,此时客户端不能做其他任何事,服务端也不会接受其他客户端的请求。这种通信机制比较简单粗暴,但是效率不高。
  2. 同步非阻塞: 客户端发送请求给服务端,此时服务端处理任务时间很久,这个时候虽然客户端会一直等待响应,但是服务端可以处理其他的请求,过一会回来处理原先的。这种方式很高效,一个服务端可以处理很多请求,不会在因为任务没有处理完而堵着,所以这是非阻塞的
  3. 异步阻塞: 客户端发送请求给服务端,此时服务端处理任务时间很久,但是客户端不会等待服务器响应,它可以做其他的任务,等服务器处理完毕后再把结果响应给客户端,客户端得到回调后再处理服务端的响应。这种方式可以避免客户端一直处于等待的状态,优化了用户体验,其实就是类似于网页里发起的ajax异步请求。
  4. 异步非阻塞: 客户端发送请求给服务端,此时服务端处理任务时间很久,这个时候的任务虽然处理时间会很久,但是客户端可以做其他的任务,因为他是异步的,可以在回调函数里处理响应;同时服务端是非阻塞的,所以服务端可以去处理其他的任务,如此,这个模式就显得非常的高效了
以上四点,除了第三点,其余的分别为BIO/NIO/AIO,面试官如果问你“请简述一下BIO/NIO/AIO之间的概念与区别”,那么你就可以组织一下语言来回答,或者通过如下生活实例来阐述也是可以的:
  • BIO: 我去上厕所,这个时候坑位都满了,我必须等待坑位释放了,我才能上吧?!此时我啥都不干,站在厕所里盯着,过了一会有人出来了,我就赶紧蹲上去。
  • NIO: 我去上厕所,这个时候坑位都满了,没关系,哥不急,我出去抽根烟,过会回来看看有没有空位,如果有我就蹲,如果没有我出去接着抽烟或者玩会手机。
  • 异步阻塞: 我去上厕所,这个时候坑位都满了,没事我等着,等有了新的空位,让他通知我就行,通知了我,我就蹲上去。
  • AIO: 我去上厕所,这个时候坑位都满了,没事,我一点也不急,我去厕所外面抽根烟再玩玩手机,等有新的坑位释放了,会有人通知我的,通知我了,我就可以进去蹲了。

从这个生活实例中能可以看得出来:

  1. 同步就是我需要自己每隔一段时间,以轮训的方式去看看有没有空的坑位;
  2. 异步则是有人拉完茅坑会通知你,通知你后你再回去蹲;
  3. 阻塞就是在等待的过程中,你不去做其他任何事情,干等着;
  4. 非阻塞就是你再等待的过程中可以去做其他的事,比如抽烟、喝酒、烫头、玩手机。

小结:异步的优势显而易见,大大优化用户体验,非阻塞使得系统资源开销远远小于阻塞模式,因为系统不需要创建新的进程(或线程),大大地节省了系统的资源,如此多出来的系统资源可以给其他的中间件去服务了

1.4. nginx核心配置文件

########### 每个指令必须有分号结束。#################
#user administrator administrators;  #配置用户或者组,默认为nobody nobody。
#worker_processes 2;  #允许生成的进程数,默认为1
#pid /nginx/pid/nginx.pid;   #指定nginx进程运行文件存放地址
error_log log/error.log error;  #制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
events {
    accept_mutex on;   #设置网路连接序列化,防止惊群现象发生,默认为on
    multi_accept on;  #设置一个进程是否同时接受多个网络连接,默认为off
    #use epoll;      #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
    worker_connections  1024;    #最大连接数,默认为512
}
http {
    include       mime.types;   #文件扩展名与文件类型映射表
    default_type  application/octet-stream; #默认文件类型,默认为text/plain
    #access_log off; #取消服务日志    
    log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
    access_log log/access.log myFormat;  #combined为日志格式的默认值
    sendfile on;   #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
    sendfile_max_chunk 100k;  #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
    keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。
  1. 设置worker进程的用户,指的linux中的用户,会涉及到nginx操作目录或文件的一些权限,默认为nobody

user root;

  1. worker进程工作数设置,一般来说CPU有几个,就设置几个,或者设置为N-1也行

worker_processes 1;

  1. nginx 日志级别debug | info | notice | warn | error | crit | alert | emerg,错误级别从左到右越来越大
  2. 设置nginx进程 pid

pid logs/nginx.pid;

  1. 设置工作模式
events {
    # 默认使用epoll
    use epoll;
    # 每个worker允许连接的客户端最大连接数
    worker_connections  10240;
}
  1. http 是指令块,针对http网络传输的一些指令配置

http {}

  1. include 引入外部配置,提高可读性,避免单个配置文件过大

include mime.types;

  1. 设定日志格式,main为定义的格式名称,如此 access_log 就可以直接使用这个变量了
 log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
 access_log log/access.log myFormat;  #combined为日志格式的默认值
  1. sendfile使用高效文件传输,提升传输性能。启用后才能使用tcp_nopush,是指当数据表累积一定大小后才发送,提高了效率。
sendfile        on;
tcp_nopush      on;
  1. keepalive_timeout设置客户端与服务端请求的超时时间,保证客户端多次请求的时候不会重复建立新的连接,节约资源损耗。
#keepalive_timeout  0;
keepalive_timeout  65
  1. gzip启用压缩,html/js/css压缩后传输会更快

gzip on;

  1. server可以在http指令块中设置多个虚拟主机
  • 设置
    • listen 监听端口
    • server_name localhost、ip、域名
    • location 请求路由映射,匹配拦截
    • root 请求位置
    • index 首页设置
     server {
              listen       88;
              server_name  localhost;
      
              location / {
                  root   html;
                  index  index.html index.htm;
              }
      }
    
  1. 导入配置server


    image.png
  • test.conf 文件内容
  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;
        }

    }

  • 访问静态资源
    • 上传到/hone 文件中foodie-shop
    • 添加nginx.conf server如图90端口
    • 访问ip:90
image.png
  • 配置多个location
   server {
           listen       90;
           server_name  localhost;

           location / {
               root   /home/foodie-shop;
               index  index.html index.htm;
           }

          location /imooc {
               root   /home;
           }

       }

image.png
image.png
  • 使用别名
 server {
           listen       90;
           server_name  localhost;

           location / {
               root   /home/foodie-shop;
               index  index.html index.htm;
           }

          location /imooc {
               root   /home;
           }
           #使用别名 访问http://192.168.126.143:90/hello/img/face1.png,
           #相当于 访问http://192.168.126.143:90/imooc/img/face1.png
          location /hello {
              alias /home/imooc;
          }

       }

root 与 alias

image.png

假如服务器路径为:/home/imooc/files/img/face.png
root 路径完全匹配访问配置的时候为:
location /imooc {
   root /home
}
用户访问的时候请求为:url:port/imooc/files/img/face.png
alias 可以为你的路径做一个别名,对用户透明
配置的时候为

location /hello {
    alias /home/imooc
}
用户访问的时候请求为:url:port/hello/files/img/face.png,如此相当于为目录imooc做一个自定义的别名。
location 的匹配规则
image.png
空格:默认匹配,普通匹配

location / {
     root /home;
}
=:精确匹配

location = /imooc/img/face1.png {
    root /home;
}
~*:匹配正则表达式,不区分大小写

#符合图片的显示
location ~* .(GIF|jpg|png|jpeg) {
    root /home;
}
~:匹配正则表达式,区分大小写

#GIF必须大写才能匹配到
location ~ .(GIF|jpg|png|jpeg) {
    root /home;
}
^~:以某个字符路径开头

location ^~ /imooc/img {
    root /home;
}

1.5. nginx启动报错

错误信息

nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: No such file or directory)

解決


[root@localhost sbin]# ll
总用量 3772
-rwxr-xr-x. 1 root root     332 6月   7 22:33 cut_my_log.sh
-rwxr-xr-x. 1 root root 3857520 6月   7 22:12 nginx
[root@localhost sbin]# ./nginx -s reload
nginx: [error] open() "/var/run/nginx/nginx.pid" failed (2: No such file or directory)
[root@localhost sbin]# 


# 1. cd 查看是否存在该目录
[root@localhost sbin]# cd /var/run/nginx
-bash: cd: /var/run/nginx: 没有那个文件或目录
您在 /var/spool/mail/root 中有新邮件
[root@localhost sbin]# 

    # 1.1 如果不存在,创建
    [root@izbp1den9djvvjxevz15wgz nginx]# mkdir /var/run/nginx

# 2.再次重启
[root@izbp1den9djvvjxevz15wgz nginx]# ./nginx -s reload
# 错误信息
nginx: [error] open() "/var/run/nginx/nginx.pid" failed (2: No such file or directory)
# 进入到sbin
[root@localhost sbin]# cd /usr/local/nginx/sbin/
# 查看nginx 信息
[root@localhost sbin]# ./nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
# 再次重启
[root@localhost sbin]# ./nginx -s reload
# 报错信息
nginx: [error] invalid PID number "" in "/var/run/nginx/nginx.pid"
# 查看nginx 

[root@localhost sbin]# ./nginx -h
nginx version: nginx/1.16.1
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit
  -T            : test configuration, dump it and exit
  -q            : suppress non-error messages during configuration testing
  -s signal     : send signal to a master process: stop, quit, reopen, reload
  -p prefix     : set prefix path (default: /usr/local/nginx/)
  # 重点
  -c filename   : set configuration file (default: conf/nginx.conf)
  -g directives : set global directives out of configuration file

# 执行指定命令
[root@localhost sbin]#  ./nginx -c /usr/local/nginx/conf/nginx.conf
# 重启完成
[root@localhost sbin]# ./nginx -s reload

1.6. Nginx日志切割

(手动)

现有的日志都会存在 access.log 文件中,但是随着时间的推移,这个文件的内容会越来越多,体积会越来越大,不便于运维人员查看,所以我们可以通过把这个大的日志文件切割为多份不同的小文件作为日志,切割规则可以以天为单位,如果每天有几百G或者几个T的日志的话,则可以按需以每半天或者每小时对日志切割一下。

  • 查看nginx日志

cd /var/log/nginx/

  • 查看nginx配置日志路径

/usr/local/nginx/sbin/nginx -V

具体步骤如下:

  • 进入sbin目录
  • cd /usr/local/nginx/sbin/
    创建一个shell可执行文件:cut_my_log.sh,内容为:
#!/bin/bash
LOG_PATH="/var/log/nginx/"
RECORD_TIME=$(date -d "yesterday" +%Y-%m-%d+%H:%M)
PID=/var/run/nginx/nginx.pid
mv ${LOG_PATH}/access.log ${LOG_PATH}/access.${RECORD_TIME}.log
mv ${LOG_PATH}/error.log ${LOG_PATH}/error.${RECORD_TIME}.log

#向Nginx主进程发送信号,用于重新打开日志文件
kill -USR1 `cat $PID`

为cut_my_log.sh添加可执行的权限:

chmod +x cut_my_log.sh

测试日志切割后的结果:

./cut_my_log.sh

Nginx 日志切割-定时
使用定时任务

安装定时任务:

yum install crontabs
crontab -e 编辑并且添加一行新的任务:
*/1 * * * * /usr/local/nginx/sbin/cut_my_log.sh
重启定时任务:

service crond restart
附:常用定时任务命令

相关命令

service crond start //启动服务
service crond stop //关闭服务
service crond restart //重启服务
service crond reload //重新载入配置
crontab -e // 编辑任务
crontab -l // 查看任务列表
定时任务表达式:
Cron表达式是,分为5或6个域,每个域代表一个含义,如下所示:

分 时 日 月 星期几 年(可选)
取值范围 0-59 0-23 1-31 1-12 1-7 2019/2020/2021/…
常用表达式:
每分钟执行:

*/1 * * * *
每日凌晨(每天晚上23:59)执行:

59 23 * * *
每日凌晨1点执行:

0 1 * * *
参考文献

2. nginx高级配置

2.0. nginx跨域配置

image.png

设置
image.png

#允许跨域请求的域,*代表所有 
add_header 'Access-Control-Allow-Origin' *; 
#允许带上cookie请求 
add_header 'Access-Control-Allow-Credentials' 'true'; 
#允许请求的方法,比如 GET/POST/PUT/DELETE 
add_header 'Access-Control-Allow-Methods' *;
#允许请求的header 
add_header 'Access-Control-Allow-Headers' *;

2.1. nginx防盗链配置

#对源站点验证 
valid_referers *.imooc.com; 
#非法引入会进入下方判断 
if ($invalid_referer) {
    return 404; 
    
}
image.png

2.2 负载均衡url_hash与least_conn

根据每次请求的url地址,hash后访问到固定的服务器节点。

upstream tomcats {
   # url hash 
   hash $request_uri; 
   # 最少连接数 
   # least_conn 
   server 192.168.1.173:8080; 
   server 192.168.1.174:8080; 
   server 192.168.1.175:8080; 
       
}
server {
   listen 80;
   server_name www.tomcats.com; 
   
   location / { 
   proxy_pass http://tomcats; 
       
   } 
}

2.3. Nginx的缓存

  1. 浏览器缓存:
    • 加速用户访问,提升单个用户(浏览器访问者)体验,缓存在本地
  1. Nginx缓存
    • 缓存在nginx端,提升所有访问到nginx这一端的用户
    • 提升访问上游(upstream)服务器的速度
    • 用户访问仍然会产生请求流量
  1. 控制浏览器缓存
location /files { 
    alias /home/imooc;
    # expires 10s;
    # expires @22h30m;
    # expires -1h;
    # expires epoch;
    # expires off;
    expires max; 
    
}

测试

<html> <body><h1>Hello, Nginx ~ !~ </h1> </body> </html>

2.4. Nginx的反向代理缓存

# proxy_cache_path 设置缓存目录
# keys_zone 设置共享内存以及占用空间大小
# max_size 设置缓存大小 
# inactive 超过此时间则被清理
# use_temp_path 临时目录,使用后会影响nginx性能 proxy_cache_path /usr/local/nginx/upstream_cache keys_zone=mycache:5m max_size=1g inactive=1m use_temp_path=

配置

location / { 
    proxy_pass http://tomcats; 
    # 启用缓存,和keys_zone一致 
    proxy_cache mycache; 
    # 针对200和304状态码缓存时间为8小时 
    proxy_cache_valid 200 304 8h;
}

2.5. 使用nginx配置https域名证书

  1. 安装SSL模块
    要在nginx中配置https,就必须安装ssl模块,也就是: http_ssl_module 。
进入到nginx的解压目录: /home/software/nginx-1.16.1
新增ssl模块(原来的那些模块需要保留)

./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 \ --with-http_ssl_module
  • 编译和安装
make 
make install
  1. 配置HTTPS
    把ssl证书 *.crt 和 私钥 *.key 拷贝到 /usr/local/nginx/conf 目录中。
  2. 新增 server 监听 443 端口:
server { 
    listen 443; 
    server_name www.imoocdsp.com; 
    # 开启ssl ssl on; 
    # 配置ssl证书 
    ssl_certificate 1_www.imoocdsp.com_bundle.crt; 
    # 配置证书秘钥 
    ssl_certificate_key 2_www.imoocdsp.com.key; 
    # ssl会话cache 
    ssl_session_cache shared:SSL:1m; 
    # ssl会话超时时间 
    ssl_session_timeout 5m; 
    # 配置加密套件,写法遵循 openssl 标准 
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; 
    location / {
        proxy_pass http://tomcats/;
        
    }
}

3. keepalived

image.png

3.1. 安装

  1. 下载地址
  2. 通过ftp工具上传到linux中,/home/software
image.png
  1. 解压

tar -zxvf keepalived-2.0.18.tar.gz

4.解压后进入到解压出来的目录,看到会有 configure ,那么就可以做配置了(配置安装和nginx一模一样)


image.png
  1. 使用configure命令配置安装目录与核心配置文件所在位置

./configure --prefix=/usr/local/keepalived --sysconf=/etc

    • prefix:keepalived安装的位置
    • sysconf:keepalived核心配置文件所在位置,固定位置,改成其他位置则keepalived启动不了,/var/log/messages中会报错

    5.1. 配置过程中可能会出现警告信息,如下所示:

    *** WARNING - this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.

    5.2. 安装libnl/libnl-3依赖 多执行几次

    yum -y install libnl libnl-deve

    yum -y install libnl libnl-devel

    5.3. 重新configure一下,此时OK。

  1. 安装keepalived

make && make install

  1. 进入到/etc/keepalived,该目录下为keepalived核心配置文件


    image.png
  2. 如果忘记安装配置的目录,则通过如下命令找到:


    image.png
  3. 将keepalived添加到系统服务中


    image.png
    • 找到keepallived解压后释放的文件夹 注:不是安装目录,是下载后的压缩包解压后的文件夹

    • 进入keepalived/etc文件夹

    [root@localhost etc]# pwd -->
    /home/sofware/keepalived-2.0.18/keepalived/etc

- 将 init.d/keepalived 复制到 /etc/init.d/ 下
> cp init.d/keepalived /etc/init.d/

- 将 sysconfig/keepalived 复制到/etc/sysconfig/ 下
> cp sysconfig/keepalived /etc/sysconfig/

> 注:如果提示覆盖,按y即可

- 刷新配置
> systemctl daemon-reload

- 配置成功后,可用如下命令进行操作
# 启动keepalived
systemctl start keepalived
# 停止keepalived
systemctl stop keepalived
# 重启keepalived
systemctl restart keepalived

3.2. 配置keepalived主

  1. 通过命令 vim keepalived.conf 打开配置文件
    1.1 查看当前路径
drwxr-xr-x. 2 root root 4096 6月   9 10:09 samples
[root@localhost keepalived]# clear
[root@localhost keepalived]# pwd
/etc/keepalived
[root@localhost keepalived]# ^C
[root@localhost keepalived]# ll
总用量 8
-rw-r--r--. 1 root root 3550 6月   9 10:09 keepalived.conf
drwxr-xr-x. 2 root root 4096 6月   9 10:09 samples
[root@localhost keepalived]# 

# 如下  通过命令 vim keepalived.conf 打开配置文件

global_defs { 
    # 路由id:当前安装keepalived的节点主机标识符,保证全局唯一 
    router_id keep_171
}

vrrp_instance VI_1 { 
    # 表示状态是MASTER主机还是备用机BACKUP
    state MASTER 
    # 该实例绑定的网卡 
    interface ens33 
    # 保证主备节点一致即可
    virtual_router_id 51
    # 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选 
    
    priority 100 
    # 主备之间同步检查时间间隔,单位秒
    advert_int 2
    # 认证权限密码,防止非法节点进入
    authentication {
        auth_type PASS auth_pass 1111
        }
    # 虚拟出来的ip,可以有多个(vip) 
    virtual_ipaddress {
        192.168.1.161 
        
    }
}

附:查看网卡名称


image.png
  1. 启动 Keepalived

[root@localhost etc]# cd /usr/local/keepalived/sbin/

在sbin目录中进行启动(同nginx),如下图:


image.png

3.3. 配置keepalived备

  1. 通过命令 vim keepalived.conf 打开配置文件
global_defs { 
    router_id keep_172 
    
}
vrrp_instance VI_1 { 
        # 备用机设置为BACKUP 
        state BACKUP 
        interface ens33 
        virtual_router_id 51 
        # 权重低于MASTER 
        priority 80 
        advert_int 2 
        authentication { 
            auth_type PASS auth_pass 1111 
            
        }
        virtual_ipaddress { 
        # 注意:主备两台的vip都是一样的,绑定到同一个vip 
        192.168.1.161
        } 
}
  1. 启动 Keepalived
    # 启动keepalived 
    systemctl start keepalived 
    # 停止keepalived 
    systemctl stop keepalived 
    # 重启keepalived 
    systemctl restart keepalived
  1. 查看进程

ps -ef|grep keepalived

image.png
  1. 查看vip

在网卡ens33下,多了一个192.168.1.161,这个就是虚拟ip


image.png

配置 Keepalived - 备

  1. 通过命令 vim keepalived.conf 打开配置文件
global_defs {
   router_id keep_172
}

vrrp_instance VI_1 {
    # 备用机设置为BACKUP
    state BACKUP
    interface ens33
    virtual_router_id 51
    # 权重低于MASTER
    priority 80
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        # 注意:主备两台的vip都是一样的,绑定到同一个vip
        192.168.1.161
    }
}
  1. 启动 Keepalived
# 启动keepalived
systemctl start keepalived
# 停止keepalived
systemctl stop keepalived
# 重启keepalived
systemctl restart keepalived
  1. 查看进程

ps -ef|grep keepalived


image.png

4.此时杀死主备nginx 或者主备keepalived 访问虚拟ip 验证效果


image.png

3.4. keepalived配置nginx自动重启题

  1. 增加Nginx重启检测脚本

vim /etc/keepalived/check_nginx_alive_or_not.sh

#!/bin/bash

A=`ps -C nginx --no-header |wc -l`
# 判断nginx是否宕机,如果宕机了,尝试重启
if [ $A -eq 0 ];then
    /usr/local/nginx/sbin/nginx
    # 等待一小会再次检查nginx,如果没有启动成功,则停止keepalived,使其启动备用机
    sleep 3
    if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
        killall keepalived
    fi
fi

  • 增加运行权限

chmod +x /etc/keepalived/check_nginx_alive_or_not.sh

  1. 配置keepalived监听nginx脚本
vrrp_script check_nginx_alive {
    script "/etc/keepalived/check_nginx_alive_or_not.sh"
    interval 2 # 每隔两秒运行上一行脚本
    weight 10 # 如果脚本运行成功,则升级权重+10
    # weight -10 # 如果脚本运行失败,则升级权重-10
}
image.png
  1. 在 vrrp_instance 中新增监控的脚本
track_script { 
    check_nginx_alive # 追踪 nginx 脚本 
    
}
image.png
  1. 重启Keepalived使得配置文件生效

systemctl restart keepalived

  1. 完整keepalived.conf完整代码
global_defs {
   router_id keep_136
}


vrrp_script check_nginx_alive {
    script "/etc/keepalived/check_nginx_alive_or_not.sh"
    interval 2 # 每隔两秒运行上一行脚本
    weight 10 # 如果脚本运行成功,则升级权重+10
}



vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }

    track_script {
        check_nginx_alive   # 追踪 nginx 脚本
    }


    virtual_ipaddress {
        192.168.84.161
    }
}


3.5. 配置keepalived双主热备

  1. 以一个虚拟ip分组归为同一个路由
    主节点配置
global_defs {
   router_id keep_171
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.161
    }
}

vrrp_instance VI_2 {
    state BACKUP
    interface ens33
    virtual_router_id 52
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.162
    }
}

备用节点配置

    global_defs {
   router_id keep_172
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.161
    }
}

vrrp_instance VI_2 {
    state MASTER
    interface ens33
    virtual_router_id 52
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.162
    }
}
        

别忘记分别重启两条Keepalived

systemctl restart keepalived

4. 搭建LVS-DR模式

4.1. 使用ipvsadm配置集群规则

  1. 创建LVS节点,用户访问的集群调度者

ipvsadm -A -t 192.168.1.150:80 -s rr -p 5

    • -A:添加集群
    • -t tcp协议
    • ip地址:设定集群的访问ip,也就是LVS的虚拟ip
    • -s:设置负载均衡的算法,rr表示轮询
    • -p:设置连接持久化的时间
  1. 创建2台RS真实服务器
ipvsadm -a -t 192.168.1.150:80 -r 192.168.1.171:80 -g 
ipvsadm -a -t 192.168.1.150:80 -r 192.168.1.172:80 -g
    • -a:添加真实服务器
    • -t:tcp协议
    • -r:真实服务器的ip地址
    • -g:设定DR模式
  1. 保存到规则库,否则重启失效

ipvsadm -S

  1. 检查集群
    • 查看集群列表

    ipvsadm -Ln

    • 查看集群状态

    ipvsadm -Ln --stats

  1. 其他命令:
# 重启ipvsadm,重启后需要重新配置 
service ipvsadm restart 
# 查看持久化连接 
ipvsadm -Ln --persistent-conn 
# 查看连接请求过期时间以及请求源ip和目标ip 
ipvsadm -Lnc 
# 设置tcp tcpfin udp 的过期时间(一般保持默认) 
ipvsadm --set 1 1 1
# 查看过期时间 
ipvsadm -Ln --timeout

4.2. LVS的负载均衡算法

静态算法
静态:根据LVS本身自由的固定的算法分发用户请求.

  1. 轮询(Round Robin 简写’rr’):轮询算法假设所有的服务器处理请求的能力都一样的,调度器会把所有的请求平均分配给每个真实服务器。(同Nginx的轮
  2. 加权轮询(Weight Round Robin 简写’wrr’):安装权重比例分配用户请求。权重越高,被分配到处理的请求越多。(同Nginx的权重)
  3. 源地址散列(Source Hash 简写’sh’):同一个用户ip的请求,会由同一个RS来处理。(同Nginx的ip_hash)
  4. 目标地址散列(Destination Hash 简写’dh’):根据url的不同,请求到不同的RS。(同Nginx的url_hash)

动态算法
动态:会根据流量的不同,或者服务器的压力不同来分配用户请求,这是动态计算的。

  1. 最小连接数(Least Connections 简写’lc’):把新的连接请求分配到当前连接数最小的服务器。
  2. 加权最少连接数(Weight Least Connections 简写’wlc’):服务器的处理性能用数值来代表,权重越大处理的请求越多。Real Server 有可能会存在性能上
    动态获取不同服务器的负载状况,把请求分发到性能好并且比较空闲的服务器。
  3. 最短期望延迟(Shortest Expected Delay 简写’sed’):特殊的wlc算法。举例阐述,假设有ABC三台服务器,权重分别为1、2、3 。如果使用wlc算法的话
    求进来,它可能会分给ABC中的任意一个。使用sed算法后会进行如下运算:
A:(1+1)/1=2
B:(1+2)/2=3/2
C:(1+3)/3=4/3
  1. 最少队列调度(Never Queue 简写’nq’):永不使用队列。如果有Real Server的连接数等于0,则直接把这个请求分配过去,不需要在排队等待运算了

总结

LVS在实际使用过程中,负载均衡算法用的较多的分别为wlc或wrr,简单易用。

作为架构师,对lvs集群的负载算法有一定的了解即可,因为你要和运维人员进行有效沟通;但是如果作为运维的话那么是要深入钻研LVS了,一个企业如果发
使用到LVS了,那么业务量是十分巨大的,并且也会有专门的运维团队来负责网络架构的。

5. 总结

先来说说第一个部分 - Nginx入门基础

本阶段开篇讲了Nginx介绍,啥是Nginx,有啥作用,啥叫反向代理,和正向代理有啥区别,并且也举例说明了。随后就进行了Nginx的安装和配置,讲解了Nginx
以及核心配置文件的内容。当nginx运行后,可以通过一些常用的命令去操作nginx。此外日志是一种生产服务器上调试的手段,可以通过日志来排查问题,但是
切割,否则就是一份大文件,所以我们讲解了如何定时的自动进行日志切割,可以按照时间日期进行切分。随后我们讲解了如何通过nginx的虚拟主机功能映射不
这种场景就是当有多个域名但是只有一个服务器的时候,可以用nginx来构建虚拟主机。
当网站里有css、js、html、图片等文件,可以通过gzip来压缩内容,这样可以节省网络带宽,提高用户的访问效率,减少交互时间。
location匹配规则也是用的比较多,其实也就是路由功能,根据不同的请求url来分配不同的访问。
除了JSONP和SpringBoot解决跨域问题外,也能通过Nginx来解决,所以我们也讲解了如何进行配置,虽然是在nginx.conf中配置,但是原理和springboot配置都
对于静态资源,尤其是图片,往往我们可以设置防盗链,避免被其他网站的引用,这也是平日里用的比较多的。

再来说说第二个部分 - Nginx进阶

这一部分主要涉及到Nginx构建集群与负载均衡,首先讲了模块化设计,因为反向代理是属于其中的一个模块的。
随后就简介了集群与负载均衡的原理,并且构建了tomcat集群。集群涉及到相应的负载均衡算法,默认为轮询,当然我们也讲了其他的算法,包括加权轮询、ip_
ash等。
此外upstream还提供了一些额外的指令,比如有:max_conns、slow_start、down、backup、max_fails、fail_timeout。当然还能通过keepalive来提升系统的吞
在讲到ip_hash、url_hash的时候,我们讲了一致性哈希算法的原理,这个在面试过程中可能会被问到,所以需要理解。
在使用nginx的时候,我们往往会设置缓存,一个是浏览器缓存,通过nginx可以控制,另外一个则是反向代理缓存,可以把其他节点的内容缓存到Nginx这一点,
用户请求效率。
最后呢我们通过云服务器来演示了ssl的配置,因为https在现如今是非常重要的。并且呢我们也吧Nginx部署到了云端,规避了tomcat的端口暴露。

高可用集群 LVS + Keepalived

这一部分主要是针对高可用,为了解决nginx的高可用,我们结合了keepalived来配置双机主备或者双主热备,要理解这两者区别,核心是VIP,用户通过VIP来访
为了保证nginx自动重启,提供7x24的不间断服务,需要自行添加脚本使得keepalived对nginx进行检测。
当然,单个nginx往往是不够的,因为他的并发量还是有限,所以很多企业会采用LVS,LVS是四层负载,LVS涉及到NAT|TUN|DR这三种模式,我们也讲了他们
原理,并且实现了DR模式,当然,为了保证LVS的高可用,咱们也配合使用了Keepalived,因为Keepalived可以说就是为lvs量身打造的。需要注意,当keepaliv
以后,nginx作为lvs的集群,就无需和keepalived结合了。
那么这一部分可以说是精华部分,如果能够在面试过程中聊到这一块内容,并且有条不紊,那么有很大的几率会得到青睐收到offer噢~~

总结: 集群架构是在单体架构后必经的一个演变过程,而且也是最简单的提高并发能力的架构。课程中我们演示了Nginx的集群、反向代理以及负载均衡,这些必须掌握
练。
此外,LVS+Keepalived+Nginx是主流的高可用高性能的集群负载均衡解决方案,搭建这样的架构需要用到多台服务器,所以我们并没有在生产环境上去配置,一
成本比较大,另一方面VIP也是要额外付费的,不过我们在虚拟机上也是手把手的演示了,大家一定要跟着做。
当一个企业业务发展到需要使用LVS的时候,这个一般都会有运维团队去把控,架构师负责监督,但是作为架构师需要懂原理,因为你要和各团队去沟通的。


搭建LVS-DR模式- 配置LVS节点与ipvsadm

前期准备

  1. 服务器与ip规划:
  • LVS - 1台
    • VIP(虚拟IP):192.168.1.150
    • DIP(转发者IP/内网IP):192.168.1.151
  • Nginx - 2台(RealServer)
    • RIP(真实IP/内网IP):192.168.1.171
    • RIP(真实IP/内网IP):192.168.1.172
  1. 所有计算机节点关闭网络配置管理器,因为有可能会和网络接口冲突:
  • systemctl stop NetworkManager
  • systemctl disable NetworkManager
创建子接口
  1. 进入到网卡配置目录,找到咱们的ens33:


    image.png
  2. 拷贝并且创建子接口:

拷贝并且创建子接口:

  • 注:数字1为别名,可以任取其他数字都行
  1. 修改子接口配置: vim ifcfg-ens33:1
  2. 配置参考如下:


    image.png
  • 注:配置中的 192.168.1.150 就是咱们的vip,是提供给外网用户访问的ip地址,道理和nginx+keepalived那时讲的vip是一样的。
  1. 重启网络服务,或者重启linux:


    image.png
  2. 重启成功后,ip addr 查看一下,你会发现多了一个ip,也就是虚拟ip(vip)


    image.png

创建子接口 - 方式2(不推荐)

  1. 创建网络接口并且绑定虚拟ip:

ifconfig ens33:1 192.168.1.150/24


image.png

配置成功后,查看ip会发现新增一个192.168.1.150:


image.png

通过此方式创建的虚拟ip在重启后会自动消失

安装ipvsadm

现如今的centos都是集成了LVS,所以ipvs是自带的,相当于苹果手机自带ios,我们只需要安装ipvsadm即可(ipvsadm是管理集群的工具,通过ipvs可以管理集群,查看集群等操作),命令如下:

yum install ipvsadm

  • 安装成功后,可以检测一下:


    image.png

注:关于虚拟ip在云上的事儿
阿里云不支持虚拟IP,需要购买他的负载均衡服务
腾讯云支持虚拟IP,但是需要额外购买,一台节点最大支持10个虚拟ip

搭建LVS-DR模式- 为两台RS配置虚拟IP

配置虚拟网络子接口(回环接口)

  1. 进入到网卡配置目录,找到lo(本地环回接口,用户构建虚拟网络子接口),拷贝一份新的随后进行修改


    image.png
  2. 修改内容如下


    image.png
  1. 重启后通过ip addr 查看如下,表示ok


    image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350