配置文件

位置:/usr/local/nginx/conf/nginx.conf

nginx配置文件由3部分组成:

  • 全局块
    从配置文件开头到evens块之间的内容,主要会设置一些影响nginx服务器整体运行的配置指令,主要包括配置运行Nginx服务器的用户(组)、允许生成的Worker Process数、进程PID存放路径、日志存放路径和类型以及配置文件的引入等 ```nginx

    user nobody;

这是Nginx服务器并发处理服务的关键配置,worker_processes值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约。

worker_processes 1;

error_log logs/error.log;

error_log logs/error.log notice;

error_log logs/error.log info;

pid logs/nginx.pid;

  1. -
  2. events
  3. <br />events块设计的指令主要影响Nginx服务器与用户的网络连接,常用的设置包括是否开启对多work process下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,没有work process可以同时支持的最大连接数等。
  4. <br />该部分配置对Nginx的性能影响较大,实际中应该灵活配置
  5. ```nginx
  6. events {
  7. # 每个work process支持的最大连接数为1024
  8. worker_connections 1024;
  9. }
  • http块
    这是Nginx服务器配置中最频繁的部分:代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。

http块又分为:

  • http全局块
    http全局块配置的指令包括文件引入、MIME-TYPE定义、日志自定义、连接超时时间、单链接请求数上限等 ```nginx 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;

    ……….

}

  1. -
  2. 多个server
  3. <br />这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
  4. <br />每个http块可以包含**多个**server块,而每个server块就相当于一个虚拟主机,
  5. <br />每个server块也分为:全局server块,多个location块。
  6. ```nginx
  7. http {
  8. # ......
  9. server {
  10. # ......
  11. }
  12. server {
  13. # ......
  14. }
  15. server {
  16. # ......
  17. }
  18. }

http块下的server块分为:

  • 全局server块
    最常见的配置是本虚拟主机的监听配置和本虚拟机的名称或IP配置

    1. http {
    2. # ......
    3. server {
    4. listen 80;
    5. server_name localhost;
    6. #charset koi8-r;
    7. #access_log logs/host.access.log main;
    8. # .........
    9. }
    10. }
  • 多个location块
    一个server块可以配置多个location块。
    这块的主要作用是基于nginx服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称(也可以是IP别名)之外的字符串(例如/uri-string)进行匹配,对特定的请求进行处理。
    地址走向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

    1. http {
    2. # ......
    3. server {
    4. # .........
    5. location / {
    6. root html;
    7. index index.html index.htm;
    8. }
    9. location = /50x.html {
    10. root html;
    11. }
    12. }
    13. }

Nginx配置实例

反向代理实例一

目标:使用Nginx代理tomcat,在访问Nginx的8888端口时,转发到tomcat的8080端口。

环境准备:安装tomcat并启动

  1. # 安装JDK
  2. rpm -ivh jdk-8u181-linux-x64.rpm
  3. # 解压tomcat
  4. tar -zxvf apache-tomcat-8.5.65.tar.gz
  5. # 启动tomcat
  6. cd apache-tomcat-8.5.65
  7. ./startup.sh

配置Nginx:

  1. # 配置http块中的server块,或者增加一个server块
  2. server {
  3. listen 8888;
  4. server_name localhost;
  5. location / {
  6. root html;
  7. proxy_pass http://127.0.0.1:8080; # 配置代理tomcat的8080(最后面有分号)
  8. index index.html index.htm;
  9. }
  10. }

反向代理实例二

目标:使用Nginx反向代理,根部访问的路径跳转到不同端口的服务中。

nginx监听端口9001;

访问 http://192.168.29.143:9001/nacos/ 跳转到 http://192.168.xxx.xxx:8848/nacos/

访问 http://192.168.29.143:9001/edu/ 跳转到 127.0.0.1:8080/edu/

准备环境:

启动nacos;

在tomcat中的webapps中创建文件夹 edu,在edu文件夹中创建一个html文件,启动tomcat:

  1. mkdir edu
  2. cd edu
  3. echo "<h1>testEdu</h1>" >a.html

配置nginx:

  1. # 在http块中增加一个server块:
  2. server {
  3. listen 9001; # 监听9001端口
  4. server_name localhost;
  5. location ~ /nacos/ { # 波浪线表示后面的内容为一个正则表达式,根据正则表达式进行匹配
  6. proxy_pass http://192.168.xxx.xxx:8848; # 此处路径不能再加/nacos/,否则会报错:使用了正则表达式或者判断条件的location代理的proxy_pass不能带有URI
  7. }
  8. location ~ /edu/ {
  9. proxy_pass http://127.0.0.1:8080; # 此处路径不能再加/edu/
  10. }
  11. }

访问:http://192.168.29.143:9001/nacos/ 即可访问nacos

访问:http://192.168.29.143:/edu/a.html 即可正常看到a.html的内容

location指令说明:

该指令用于匹配URL

  1. # 命令格式
  2. location [ = | ~ | ~* | ^~] uri {
  3. }
  • = : 用于不含正则表达式的uri前,要求请求字符串与 uri 严格匹配,如果匹配成功, 就停止继续向下搜索并立即处理该请求。
  • ~ :用于表示 uri 包含正则表达式,并且区分大小写
  • ~* :用于表示 uri 包含正则表达式,不区分大小写
  • ^~ : 用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location块中的正则 uri 和请求字符串做匹配

如果 uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识。

负载均衡

负载均衡:增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器。

目标:在浏览器访问a.html,使用Nginx进行负载均衡,将请求平均到8080的tomcat和8081的tomcat中。

准备环境:

两台tomcat服务器,一台使用默认8080端口,另一台修改server.xml中的server port为9005、connect port为8081;

两台服务器的webapps中都创建 edu文件夹,都带有a.html文件,文件内容不同,用于测试。

配置nginx:

  1. # 定义一个upstream
  2. upstream myserver {
  3. server 127.0.0.1:8080 weight=1;
  4. server 127.0.0.1:8081 weight=1;
  5. }
  6. # 配置server
  7. server {
  8. listen 9002;
  9. location / {
  10. proxy_pass http://myserver; # 代理upstream定义的服务
  11. }
  12. }

Linux下有 Nginx、LVS、Haproxy等服务都可以提供负载均衡服务。

Nginx负载均衡的不同策略:

  • 轮询(默认)
    每个请求按时间顺序逐一分配到不同的后端服务器,如果厚度那服务器宕机,就自动剔除

  • weight
    指定轮询几率,weight和访问比率成正比,用于厚度那服务器性能不均的情况。
    weight代表权重,默认是1。权重越高被分配的客户端就越多。

    1. # weight配置示例
    2. upstream myserver {
    3. server 127.0.0.1:8080 weight=10;
    4. server 127.0.0.1:8081 weight=5;
    5. }
  • ip_hash
    每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session问题。
    1. # ip_hash配置示例
    2. upstream myserver {
    3. ip_hash;
    4. server 127.0.0.1:8080;
    5. server 127.0.0.1:8081;
    6. }
  • fair(第三方)
    按后端服务器的响应时间来分配请求,响应时间短的优先分配。
    1. # fair配置示例
    2. upstream myserver {
    3. server 127.0.0.1:8080;
    4. server 127.0.0.1:8081;
    5. fair;
    6. }

动静分离

代理服务器上的文件夹

把动态和静态请求分开,不是单纯的吧动态页面和静态页面物理隔离。可以理解成 Nginx处理静态页面,Tomcat处理动态页面。

动静分离从实现角度大致分为两种:

  • 纯粹把静态文件独立成单独的域名,放在单独的服务器上,也是目前主流推崇的方案。
  • 动态和静态文件混合在一起,通过Nginx来分开

通过 location指定不同的后缀名实现不同的请求转发。

通过expires参数设置浏览器缓存过期时间,减少与服务器之间的请求和流量。此种方法适合不经常变动的资源

expires:是给一个资源设定一个过期时间,也就是说无需去服务器验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。

例如设置 3d,表示在3天内访问这个URL,发送一个请求,比对服务器该文件最后更新时间没有变化,则不会从服务器抓取,返回状态码304,。如果有修改,则直接从服务器重新下载,返回状态码200.······

目标:访问nginx服务器上的静态资源

不允许访问 http://192.168.29.143:9003/www/

访问 http://192.168.29.143:9003/www/a.html 可以获取到服务器上的 /home/nginx/data/www/a.html

访问 http://192.168.29.143:9003/image/ 可以列出到服务器上的 /home/nginx/data/image文件夹下所有文件

访问 http://192.168.29.143:9003/image/a.jpg 可以获取到服务器上的 /home/nginx/data/image/a.jpg 文件

准备环境:

在Nginx上创建文件 /home/nginx/data/www/a.html/home/nginx/data/image/a.jpg

配置nginx:

  1. server {
  2. listen 9003;
  3. location /www/ {
  4. root /home/nginx/data/; # 浏览器访问 /www/+文件名 即可访问到nginx服务器的 /home/nginx/data/www/下的文件
  5. }
  6. location /image/ {
  7. root /home/nginx/data/;
  8. autoindex on; # 浏览器访问 /image/ , 可以列出nginx服务器的 /home/nginx/data/image/下的所有文件。不配置该项时,访问 /image/ 会报404错误
  9. }
  10. }

keepalived + Nginx高可用

部署两台Nginx,一台为主,一台为备份。使用 keepalived 进行管理。主nginx宕机后,keepalived自动切换到备份的nginx。

准备环境:

在两台服务器上部署Nginx:192.168.29.143/192.168.29.144

安装 keepalived:

使用yum安装:

  1. # 安装
  2. yum install -y keepalived
  3. # 验证
  4. rpm -qa keepalived

安装的 keepalived 1.3.5版本。

yum 自动安装的依赖:

  • lm_sensors-libs 3.4.0
  • net-snmp-agent-libs 5.7.2
  • net-snmp-libs 5.7.2

yum 自动更新的依赖

  • ipset 7.1
  • ipset-libs 7.1

keepalived安装之后,创建一个配置文件: /etc/keepalived/keepalived.conf

配置 /etc/keepalived/keepalived.conf:

  1. ! Configuration File for keepalived
  2. # 全局配置
  3. global_defs {
  4. notification_email {
  5. acassen@firewall.loc
  6. failover@firewall.loc
  7. sysadmin@firewall.loc
  8. }
  9. notification_email_from Alexandre.Cassen@firewall.loc
  10. smtp_server 192.168.29.143
  11. smtp_connect_timeout 30
  12. router_id LVS_DEVEL # 主机名
  13. }
  14. # 脚本配置
  15. vrrp_script chk_http_port {
  16. script "/home/nginx/keepalived/shell/nginx_check.sh" # 编写的检测nginx是否宕机的脚本
  17. interval 2 # 检测脚本执行的间隔(2表示每隔2秒执行一次)
  18. weight 2 # 权重(2表示:当脚本执行成立,就把权重加2),可以为负值(表示每次把权重减多少)
  19. }
  20. # 虚拟IP配置
  21. vrrp_instance VI_1 {
  22. state MASTER # 主服务器为MASTER,备服务器为BACKUP
  23. interface ens33 # 虚拟IP绑定的网卡
  24. virtual_router_id 51 # 唯一标识。主、备机的virtual_router_id必须相同
  25. priority 100 # 优先级,主机值较大,备份机值较小
  26. advert_int 1 # 心跳时间间隔(单位秒),用于检测主服务器是否存活
  27. # 权限校验饭食
  28. authentication {
  29. auth_type PASS # 密码方式校验
  30. auth_pass 1111 # 密码为1111
  31. }
  32. virtual_ipaddress {
  33. 192.168.29.145 # VRRP H虚拟地址,(需要和主机对应网卡的地址在同一个网段内)
  34. # 此处可以绑定多个虚拟IP
  35. }
  36. }

检测nginx的脚本:

该脚本文件权限可以配置为744或755,如果配置成777则keepalived会报错

  1. #!/bin/bash
  2. A=`ps -C nginx -no-header | wc -l`
  3. if [ $A -eq 0 ];then
  4. nginx # 如果当前没有nginx进程,则启动nginx
  5. sleep 2
  6. if [ $A -eq 0 ];then
  7. killall keepalived # 如果启动nginx失败,则关掉keepalived进程
  8. fi
  9. fi

在主从机器上都启动keepalived:

  1. systemctl start keepalived.service

启动后,主服务器上,查看 ens33绑定的IP,可以发现多出来一个虚拟IP:192.168.29.145

  1. ip a # 查看网卡绑定的IP

此时,在浏览器访问:http://192.168.29.145:8888,和直接访问 http://192.168.29.143:8888(主服务器上的nginx) 效果一样。

将主服务器上的 nginx、keepalived关闭:(模拟主服务器宕机的情况)

  1. nginx -s stop
  2. systemctl stop keepalived.service

此时,备服务器上的keepalived会自动生效。

在浏览器访问: http://192.168.29.145:8888, 会直接访问到 http://192.168.29.143:8888(备服务器上的nginx)效果一样。

在备服务器上使用 ip a可以看到 ens33网卡上绑定了192.168.29.145虚拟IP。

Nginx原理

Nginx启动后,默认会有两个进程:master进程、worker进程。

可以有多个worker。worker进程的数量可以在nginx的配置文件中进行配置。

master对worker起到管理、监控的作用。

流转图:

Master & Worker

客户端发送一个请求到master,master通知给所有的worker进程,worker进程进行争抢。抢到的worker执行后续的反向代理或者其他操作。

master-worker机制的优点:

对于每个worker进程来说,独立的进程不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时也会方便很多。

其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其他进程还在工作,服务不会中断,master 进程则很快启动新的worker进程。

worker进程的异常退出,肯定是程序有bug了,会导致当前worker上的所有请求失败。但是不会影响到所有的请求,降低了风险。

需要设置的worker数量:

Nginx同redis类似,都采用了io多路复用机制,每个worker都是一个独立的进程,但是每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求。

Windows系统中的Nginx没有多路复用机制

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

worker配置:

  1. # 设置worker数量
  2. worker_processes 4
  3. # worker绑定cpu(4worker绑定4cpu)
  4. worker_cpu_affinity 0001 0010 0100 1000

连接数:worker_connection:

这个值是表示每个worker进程所能建立连接的最大值,所以,一个nginx能建立的最大连接数,应该是:worker_connections * worker_processes。这里指的是最大连接数。

对于 http 请求本地资源来说,能够支持的最大并发数量是:worker_connections * worker_processes。

如果是支持 http1.1 的浏览器每次访问需要占用两个连接,代理服务器上的静态页面时,访问最大并发数是: worker_connections * worker_processes / 2。(一次请求中,客户端连接占用worker两个连接,所以最大并发数应该是连接数除以2)

而如果是 HTTP 作为反向代理来说,最大并发数量应该是 worker_connectionx * worker_processes / 4。(一次请求中,客户端连接worker占用2个,worker连接后端服务器占用2个,所以最大支持的并发数应该是连接数除以4)