什么是Nginx

  • Nginx是一个高性能的HTTP的反向代理web服务器,同时也提供IMAP/POP3/SMTP服务 -引用百度百科
  • 主要功能是反向代理
  • 通过配置文件实现集群负载均衡
  • 静态资源虚拟化

常见服务器

MS IIS asp.net
Weblogic、Jboss 传统行业 ERP/物流/电信/金融
Tomcat、Jetty J2EE
Apache、Nginx 静态服务、反向代理
Netty 高性能服务器编程

什么是正向代理

客户端请求目标服务器之间的一个代理服务器
请求会先经过代理服务器,然后转发给到目标服务器,获取到内容后最后响应到客户端

安装Nginx与运行

1、去官网 http://nginx.org/ 下载对应 nginx,推荐使用稳定版本

2、上传 nginx 到 Linux 版本

3、安装依赖环境

(1)安装 gcc 环境
  1. yum install gcc-c++

(2)安装 pcre 库,用于解析正则表达式
  1. yum install -y pcre pcre-devel

(3)zlib 库和解压缩依赖
  1. yum install -y zlib zlib-devel

(4)SSL 安全的加密的套接字协议层,用于 HTTP 安全传输,也就是 https
  1. yum install -y openssl openss-devel

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

  1. tar -zxvf nginx-1.16.1.tar.gz

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

  1. nkdir /var/temp/nginx -p

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

  1. ./configure \
  2. --prefix=/usr/local/nginx \
  3. --pid-path=/var/run/nginx/nginx.pid \
  4. --lock-path=/var/lock/nginx.lock \
  5. --error-log-path=/var/log/nginx/error.log \
  6. --http-log-path=/var/log/nginx/access.log \
  7. --with-http_gzip_static_module \
  8. --http-client-body-temp-path=/var/temp/nginx/client \
  9. --http-proxy-temp-path=/var/temp/nginx/proxy \
  10. --http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
  11. --http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
  12. --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临时目录

7、make 编译

  1. make

8、安装

  1. make install

9、进入 sbin 目录启动 nginx

  1. ./nginx
  • 停止: ./nginx -s stop
  • 重新加载: ./nginx -s -reload

    10、打开浏览器,访问虚拟机所处内网 ip 即可打开 nginx 默认页面,显示如下便表示安装成功

    image.png

    注意事项:

  1. 如果在云服务器安装,需要开启默认的 nginx 端口:80
    2. 如果在虚拟机安装,需要关闭防火墙
    3. 本地 win 或 mac 需要关闭防火墙

Nginx 默认首页解析过程


Nginx 进程模型解析

master 进程:主进程

worker 进程:工作进程

例子:管理者和员工
信号:

  1. ./nginx -s stop # 停止 nginx
  2. ./nginx -s quit # 退出 nginx
  3. ./nginx -s reload # 重新加载 nginx.conf 并启动
  4. ./nginx -t # 检查 nginx.conf 配置文件是否正确

image.png
每个进程相互独立,相互之间安全

Nginx 处理 Web 请求机制解析

worker 抢占机制

image.png

传统服务器事件处理

一个请求被阻塞后,就无法接收新的请求
image.png

Nginx 事件处理

一个 worker 被阻塞后,立马去处理另一个请求
image.png

为什么能达到这么高并发

1、抢占机制
2、模型 异步非阻塞 一个 worker 可以处理多个请求
3、多路复用器


nginx.conf 配置结构

image.png
nginx.conf

  1. #user nobody;
  2. # 当 worker 进程执行时,他是又操作系统的每个用户区执行的,默认就是 nobody 使用 ps -ef | grep nginx 查看 nginx 进程
  3. # 可以将 user 修改为 root 为 root 用户运行
  4. worker_processes 1;
  5. # worker 进程数量 cpu 有几个就设置几个,如果还有其他中间件在运行的话,可以设置为 n-1 8个cpu减一个,worker 设置为7个
  6. # ==========================================================================================
  7. # error_log 错误日志
  8. # 日志级别 debug[最低] info notice warn error crit[最严重]
  9. # 在安装 nginx 时就制定了对应的日志文件夹
  10. #error_log logs/error.log;
  11. #error_log logs/error.log notice;
  12. #error_log logs/error.log info;
  13. #===========================================================================================
  14. # pid nginx 进程号,默认安装时就指定了
  15. #pid logs/nginx.pid;
  16. pid /usr/local/nginx/logs/nginx.pid;
  17. # events 事件
  18. events {
  19. # 默认使用 epoll
  20. use epoll;
  21. # 每个worker允许连接的客户端最大连接数,根据自身硬件进行配置
  22. worker_connections 1024;
  23. }
  24. # 网络传输模块
  25. http {
  26. # 导入外部文件,提高可读性 types 非常多
  27. include mime.types;
  28. # 默认的 type 类型
  29. default_type application/octet-stream;
  30. #设置body请求大小
  31. client_max_body_size 1024m;
  32. # 日志格式
  33. #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  34. # '$status $body_bytes_sent "$http_referer" '
  35. # '"$http_user_agent" "$http_x_forwarded_for"';
  36. # 用户发起请求,都会记录在日志里头
  37. #access_log logs/access.log main;
  38. # 文件高效传输
  39. sendfile on;
  40. # 数据包达到一定大小,在进行发送,
  41. #tcp_nopush on;
  42. # 客户端链接服务器超时时间 默认0,这里设置的是65秒,防止占用链接过长,影响资源
  43. #keepalive_timeout 0;
  44. keepalive_timeout 65;
  45. # 压缩 html css 资源
  46. #gzip on;
  47. # server 服务也可以通过配置文件进行导入
  48. # 服务
  49. server {
  50. # 监听端口号
  51. listen 80;
  52. # 服务器名称 127.0.0.1 或者域名
  53. server_name localhost;
  54. # 编码
  55. #charset koi8-r;
  56. #access_log logs/host.access.log main;
  57. # 默认访问根目录
  58. location / {
  59. root html;
  60. index index.html index.htm;
  61. }
  62. # 错误页面
  63. #error_page 404 /404.html;
  64. # redirect server error pages to the static page /50x.html
  65. #
  66. # 匹配相应规则,符合打开对应页面
  67. error_page 500 502 503 504 /50x.html;
  68. location = /50x.html {
  69. root html;
  70. }
  71. }
  72. # 单独引入配置文件
  73. include imooc.conf;
  74. }

Nginx日志切割

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

  1. #!/bin/bash
  2. LOG_PATH="/var/log/nginx/"
  3. RECORD_TIME=$(date -d "yesterday" +%Y-%m-%d+%H:%M)
  4. PID=/var/run/nginx/nginx.pid
  5. mv ${LOG_PATH}/access.log ${LOG_PATH}/access.${RECORD_TIME}.log
  6. mv ${LOG_PATH}/error.log ${LOG_PATH}/error.${RECORD_TIME}.log
  7. #向Nginx主进程发送信号,用于重新打开日志文件 kill -USR1 `cat $PID`

2、为 cut_my_log.sh 文件创建权限

  1. chmod +x cut_my_log.sh

3、测试日志切割后的结果

  1. ./cut_my_log

对 access.log 进行切割,这里是切割到对应分钟,方便排查线上错误

  1. [root@localhost nginx]# /usr/local/nginx/sbin/cut_my_log.sh
  2. [root@localhost nginx]# ll
  3. 总用量 4
  4. -rw-r--r--. 1 nobody root 0 3 6 11:09 access.2022-03-05+11:10.log
  5. -rw-r--r--. 1 nobody root 2660 3 6 11:12 access.2022-03-05+11:13.log
  6. -rw-r--r--. 1 nobody root 0 3 6 11:13 access.log
  7. -rw-r--r--. 1 nobody root 0 3 6 11:09 error.2022-03-05+11:10.log
  8. -rw-r--r--. 1 nobody root 0 3 6 11:10 error.2022-03-05+11:13.log
  9. -rw-r--r--. 1 nobody root 0 3 6 11:13 error.log
  10. [root@localhost nginx]#

Nginx 日志切割(定时)

使用定时任务

1、安装定时任务

  1. yum install crontabs

2、crontab -e 编辑并添加一行新的任务

  1. */1 * * * * /usr/local/nginx/sbin/cut_my_log.sh

3、重启定时任务

  1. service crond restart

附:常见定时任务命令

  1. service crond start //启动服务
  2. service crond stop //关闭服务
  3. service crond restart //重启服务
  4. service crond reload //重新载入配置
  5. crontab -e // 编辑任务
  6. crontab -l // 查看任务列表

定时任务表达式
Cron表达式是,分为5或6个域,每个域代表一个含义,如下所示:

星期几 年可选
取值范围 0-59 0-23 1-31 1-12 1-7 2019/2020

常用表达式

每分钟执行:

  1. */1 * * * *

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

  1. 59 23 * * *

每日凌晨1点执行:

  1. 0 1 * * *

Nginx 为静态资源提供服务

Nginx 开启 gzip 压缩

  1. # 开启 gzip 压缩功能,目的,提高传输效率,节约带宽
  2. gzip on;
  3. # 限制最小压缩,小于1字节文件不会压缩
  4. gzip_min_length 1;
  5. # 定义压缩的级别 压缩比 文件越大 压缩越多 但是cpu使用的会越多 1-9
  6. gzip_comp_level 3;
  7. # 定义压缩文件的类型
  8. gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/json;

Nginx 中 location 匹配规则

空格 :默认匹配,普通匹配

  1. location / {
  2. root /home;
  3. }

= :精确匹配

  1. # 只能通过这个路径来访问
  2. location = /imooc/img/face1.png {
  3. root /home;
  4. }

~* :匹配正则表达式,不区分大小写

  1. location ~ \.(GIF|jpg|png|jpeg) {
  2. root /home;
  3. }

~ :匹配正则表达式,区分大小写

  1. # GIF 必须大写才能匹配到
  2. location ~ \.(GIF|jpg|png|jpeg) {
  3. root /home;
  4. }

^~ :以某个字符路径开头

  1. # 当访问其他目录下就访问不到
  2. location ^~ /imooc/img {
  3. root /home;
  4. }


DNS解析域名

image.png
image.png

Nginx 请求文件设置

设置请求最大大小

  1. http {
  2. include mime.types;
  3. default_type application/octet-stream;
  4. client_max_body_size 1024m; #设置body请求大小
  5. #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  6. # '$status $body_bytes_sent "$http_referer" '
  7. # '"$http_user_agent" "$http_x_forwarded_for" "$host" - $http_referer';
  8. #access_log logs/access.log main;

Nginx 的跨越

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

Nginx 中配置静态资源防盗链

  1. #对源站点验证 必须通过对应的域名来进行访问
  2. valid_referers *.imooc.com;
  3. #非法引入会进入下方判断
  4. if ($invalid_referer) {
  5. return 404;
  6. }

Nginx 模块化设计

image.png
image.png


Nginx 的集群负载均衡解析

什么是单节点?

缺点:只要一个人累了、或者说生病了,那么他就不能进行搬砖·
image.png

什么是集群

image.png

Nginx集群负载均衡

请求转发给到上游服务器
image.png
单台Tomcat和两台Tomcat对比

image.png


Nginx搭建3台Tomcat集群

www.tomcats.com 接受到请求后,通过 proxy_pass 代理 tomcats 又 tomcats 来处理请求,如果z多个他会轮训的方式将请求分发到对应的服务器上

  1. # 配置上游服务器
  2. upstream tomcats {
  3. # 单独的一个服务用来部署Tomcat
  4. server 192.168.128.129:8080;
  5. server 192.168.128.130:8080;
  6. }
  7. server {
  8. listen 94;
  9. server_name www.tomcats.com;
  10. location / {
  11. proxy_pass http://tomcats;
  12. }
  13. }

负载均衡之轮训

例子:


image.png


权重
  1. upstream tomcats {
  2. # weight 默认权重是1,设置的越大,请求接收的就越多
  3. # 例如一共有3个请求,就会根据权重进行分类,两个给到129 一个给到130,权重需要根据服务器的性能进行判断,性能好,那么权重就可以设置的高
  4. server 192.168.128.129:8080 weight 2;
  5. server 192.168.128.130:8080 weight 1;
  6. }

负载均衡之 upstream 指令参数

max_conns 请求最大连接数

官网文档:https://nginx.org/en/docs/http/ngx_http_upstream_module.html
limits the maximum number of simultaneous active connections to the proxied server (1.11.5). Default value is zero, meaning there is no limit. If the server group does not reside in the shared memory, the limitation works per each worker process.
限制与代理服务器 (1.11.5) 的同时活动连接的最大数量。 默认值为零,表示没有限制。 如果服务器组不驻留在共享内存中,则限制适用于每个工作进程。

限制每台server的连接数,用于保护避免过载,可起到限流作用。

  1. # max_conns 最大连接数,请求执行完以后才能执行其他请求,未被处理到的请求返回502 例如 129 最大只能处理两个,超出的请求就会返回502
  2. server 192.168.128.129:8080 weight=2 max_conns=2;

slot_start 慢启动

商业版本才有 设置多少秒后,才开始加入集群中


down 服务器状态 表示为不可用

用于标记服务节点不可用:


backup 备用机

backup 表示当前服务器节点是备用机,只有在其他的服务器都宕机以后,自己才会加入到集群中,被用户访问到
注意:
backup 参数不能使用在 hash 和 random load balancing 中。


max_fails 最大失败次数

表示失败几次,则标记server已宕机,剔出上游服务。


fail_timeout 失败时间段

表示失败的重试时间

  1. max_fails=2 fail_timeout=15s

代表在15秒内请求某一server失败达到2次后,则认为该server已经挂了或者宕机了,随后再过15秒,这15秒内不会有新的请求到达刚刚挂掉的节点上,而是会将请求给到其他运作的server,15秒后会再有新请求尝试连接挂掉的server,如果还是失败,重复上一过程,直到恢复。


keepalived

未设置之前
image.png
设置之后
image.png
keepalived : 设置长连接处理的数量
proxy_http_version :设置长连接http版本为1.1
proxy_set_header :清除connection header 信息

  1. # 配置上游服务器
  2. upstream tomcats {
  3. server 192.168.128.128:8080;
  4. keepalive 32;
  5. }
  6. server {
  7. listen 94;
  8. server_name www.tomcats.com;
  9. location / {
  10. proxy_pass http://tomcats;
  11. # 代理http版本设置为1.1
  12. proxy_http_version 1.1;
  13. # 连接报头字段应该被清除
  14. proxy_set_header Connection "";
  15. }
  16. }

ip_hash

ip_hash 可以保证用户访问可以请求到上游服务中的固定的服务器,前提是用户ip没有发生更改。
使用ip_hash的注意点:
不能把后台服务器直接移除,只能标记 down

hash 算法

取余算出应该访问那台服务器
image.png

hash 算法带来的问题

原本三台服务器正常请求
image.png
挂掉一台后,需要重新计算hash
image.png

一致性hash算法

hash计算出来后,只访问hash附近的服务器
image.png
例子:学区房 就近原则
image.png

  1. upstream tomcats {
  2. ip_hash;
  3. server 192.168.1.173:8080;
  4. server 192.168.1.174:8080 down;
  5. server 192.168.1.175:8080;
  6. }

url_hash

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

  1. upstream tomcats {
  2. # url hash
  3. hash $request_uri;
  4. # 最少连接数
  5. # least_conn
  6. server 192.168.1.173:8080;
  7. server 192.168.1.174:8080;
  8. server 192.168.1.175:8080;
  9. }
  10. server {
  11. listen 80;
  12. server_name www.tomcats.com;
  13. location / {
  14. proxy_pass http://tomcats;
  15. }
  16. }

Nginx 控制浏览器缓存

1. 浏览器缓存:

加速用户访问,提升单个用户(浏览器访问者)体验,缓存在本地

2. Nginx缓存

  • 缓存在nginx端,提升所有访问到nginx这一端的用户
  • 提升访问上游(upstream)服务器的速度
  • 用户访问仍然会产生请求流量

控制浏览器缓存:

  1. location /files {
  2. alias /home/imooc;
  3. # expires 10s; 缓存10秒后过期
  4. # expires @22h30m; 缓存在10点30分过期
  5. # expires -1h; 缓存一小时后过期
  6. # expires epoch; 不缺设置
  7. # expires off; 默认
  8. expires max; # 缓存永不过期
  9. }

image.png

反向代理缓存

  1. # proxy_cache_path 设置缓存保存的目录
  2. # keys_zone 设置共享内存以及占用的空间大小
  3. # max_size 设置缓存大小
  4. # inactive 超过此时间 则缓存自动清理
  5. # use_temp_path 关闭临时目录
  6. proxy_cache_path /usr/local/nginx/upstream_cache keys_zone=mycache:5m max_size=1g inactive=30s use_temp_path=off;
  7. server {
  8. listen 94;
  9. server_name www.tomcats.com;
  10. # 开启并使用缓存
  11. proxy_cache mycache;
  12. # 针对200和304状态码的缓存设置过期时间
  13. proxy_cache_valid 200 304 8h;
  14. location / {
  15. proxy_pass http://tomcats;
  16. }
  17. }

缓存目录
image.png
到达时间后自动删除
image.png


使用Nginx配置SSL证书提供Https访问

以http进行访问的网站,那么这个网站他是安全的
image.png
没有以https进行访问的网站,那么他是不安全的
image.png

前提域名需要自己单独去购买

小程序开发、安卓开发都是需要https

1、nginx中安装安装 SSL 模块

要在nginx中配置https,就必须安装ssl模块,也就是: http_ssl_module

  • 进入到nginx的解压目录: /home/software/nginx-1.16.1
  • 新增ssl模块(原来的那些模块需要保留) ```bash ./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 # 新增了一个ssl模块,需要重新进行安装、编译

编译、安装 make make install

  1. <a name="RyG08"></a>
  2. #### 2、配置 HTTPS
  3. - 把ssl证书 *.crt 和 私钥 *.key 拷贝到 /usr/local/nginx/conf 目录中
  4. - 新增 server 监听 443 端口
  5. ```shell
  6. server {
  7. listen 443;
  8. server_name www.imoocdsp.com;
  9. # 需要参考腾讯云、阿里云域名官方文档,改配置都是从文档拷贝过来
  10. # 开启ssl
  11. ssl on;
  12. # 配置ssl证书
  13. ssl_certificate 1_www.imoocdsp.com_bundle.crt;
  14. # 配置证书秘钥
  15. ssl_certificate_key 2_www.imoocdsp.com.key;
  16. # ssl会话cache
  17. ssl_session_cache shared:SSL:1m;
  18. # ssl会话超时时间
  19. ssl_session_timeout 5m;
  20. # 配置加密套件,写法遵循 openssl 标准
  21. ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  22. ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  23. ssl_prefer_server_ciphers on;
  24. location / {
  25. proxy_pass http://tomcats/;
  26. }

配置后就可以通过 https 进行访问


动态分离的那些事儿

动静分类的特点

  • 分布式
  • 前后端解耦
    • 前后端分开部署,发布快速便捷
  • 静态归 nginx
  • 接口服务化
    • 单独进行部署,安卓、小程序

静态数据

  • css/html/images/audios

    动态数据

  • 得到的数据可能会和上一次不一样

动态分离方式

内容分发 CDN

根据用户地址,访问就近的服务器
image.png
例如:
image.png

动态分离方式 Nginx

使用ngxin存放静态资源
image.png

动静分离带来的问题

image.png


KeepAlived 安装

工作中暂时用不到,待需要用到的时候在进行学习

Nginx 双机备份

前提条件

1、当前服务【jar包】准备两份,一份作主服务,一份作为从服务,默认情况下请求都是访问主服务
2、nginx中请求转发配置

  1. upstream pt_project-management_pool{
  2. server 172.18.101.77:9001 ;
  3. server 172.18.101.77:9002 backup;
  4. }
  5. // backup 作为备用机,如果9001服务挂掉,请求就会打到 9002 服务上,如果不标识 backup ,请求会随机打到两个中的一个
  6. // backup 表示当前服务器节点是备用机,只有在其他的服务器都宕机以后,自己才能被用户访问到

操作步骤

先将备份服务【9002】进行更新,然后重启【默认都是访问的主服务,备用服务是没人访问的】
调整nginx中配置,将 9002【备份服务】服务作为主服务,9001 设置为备用机,此时请求就会打到 9002 上

  1. upstream pt_project-management_pool{
  2. server 172.18.101.77:9001 backup; // 当前服务作为备用服务
  3. server 172.18.101.77:9002; // 请求到打到该服务上
  4. }

更新 9001【主服务】内容,然后重启
更改nginx中配置,将 9001 作为主服务,9002 作为备用服务,此时请求就会打到 9001 上

  1. upstream pt_project-management_pool{
  2. server 172.18.101.77:9001 ; // 请求打到当前服务上
  3. server 172.18.101.77:9002 backup; // 备份服务
  4. }

此过程中,用户都能调用接口,不会出现调用不了对应接口的情况

总结

切换nginx配置,先将请求打到从服务,更新主服务内容,主服务内容更新后,更改 nginx 配置转发到主服务,从服务作为备份