Nginx——配置文件实战

配置文件结构

Nginx 配置文件由三部分组成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
...              #全局块

events { #events块
...
}

http #http块
{
... #http全局块
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局块
}
  1. 全局块

    主要设置一些影响 nginx 服务器整体运行的配置指令。
    比如: worker_processes 1; , worker_processes 值越大,可以支持的并发处理量就越多。

  2. events块

    events 块涉及的指令主要影响Nginx服务器与用户的网络连接。
    比如: worker_connections 1024; ,支持的最大连接数。

  3. http块

    http 块又包括 http 全局块和 server 块,是服务器配置中最频繁的部分,包括配置代理、缓存、日志定义等绝大多数功能。
    server块:配置虚拟主机的相关参数。
    location块:配置请求路由,以及各种页面的处理情况。

配置文件样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
########### 每个指令必须有分号结束。#################
#user administrator administrators; #配置用户或者组,默认为nobody nobody。
#worker_processes 2; #允许生成的进程数,默认为1
#pid /nginx/pid/nginx.pid; #指定nginx进程运行文件存放地址
error_log log/error.log debug; #制定日志路径,级别。这个设置可以放入全局块,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块。

upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备
}
error_page 404 https://www.baidu.com; #错误页
server {
keepalive_requests 120; #单连接请求上限次数。
listen 4545; #监听端口
server_name 127.0.0.1; #监听地址
location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
#root path; #根目录
#index vv.txt; #设置默认页
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip
}
}
}

实战

反向代理

  1. 浏览器输入监听地址端口,跳转到tomcat主界面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    server {
    listen 8888;
    server_name 127.0.0.1; #监听地址

    location / {
    root html; #/html目录
    proxy_pass http://127.0.0.1:8080; #请求转向
    index index.html index.htm; #设置默认页
    }
    }
  2. 根据在浏览器输入的路径不同,跳转到不同端口的服务中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    server {
    listen 8888;
    server_name 127.0.0.1; #监听地址

    location ~ /example1/ {
    proxy_pass http://127.0.0.1:8080;
    }

    location ~ /example2/ {
    proxy_pass http://127.0.0.1:8081;
    }
    }

location 指令说明:

  • ~ : 表示uri包含正则表达式,且区分大小写。
  • ~* : 表示uri包含正则表达式,且不区分大小写。
  • = : 表示uri不含正则表达式,要求严格匹配。

负载均衡

浏览器输入监听地址端口,平均跳转到tomcat不同端口主界面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
upstream myserver {
server 127.0.0.1:8081;
server 127.0.0.1:8080;
}


server {
listen 8888; #监听端口
server_name 127.0.0.1; #监听地址

location / {
root html; #html目录
index index.html index.htm; #设置默认页
proxy_pass http://myserver; #请求转向 myserver 定义的服务器列表
}
}

负载均衡策略

轮询(默认)

按请求的时间顺序依次逐一分配,如果服务器down掉,能自动剔除。

权重

weight 越高,被分配的客户端越多,默认为 1。比如:

1
2
3
4
upstream myserver {
server 127.0.0.1:8081 weight=10;
server 127.0.0.1:8080 weight=5;
}

ip

按请求 ip 的 hash 值分配,每个访客固定访问一个后端服务器。比如:

1
2
3
4
5
upstream myserver {
ip_hash;
server 127.0.0.1:8081;
server 127.0.0.1:8080;
}

fair

按后端服务器的响应时间来分配,响应时间短的优先分配到请求。比如:

1
2
3
4
upstream myserver {
server 127.0.0.1:8081;
server 127.0.0.1:8080;
}

正向代理

我们需要通过能连接到具体网址的代理服务器,来完成正向代理。

nginx配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
server {  
resolver 114.114.114.114; #指定DNS服务器IP地址
listen 8080;
location / {
proxy_pass http://$http_host$request_uri; #设定代理服务器的协议和地址
}
}

以上的配置只能访问80 端口的网站,而不能访问https443端口的网站,现在的网站基本上都是https的要解决技能访问http80端口也能访问https443端口的网站,需要置两个SERVER节点,一个处理HTTP转发,另一个处理HTTPS转发。

```properties
server {
resolver 114.114.114.114; #指定DNS服务器IP地址
listen 80;
location / {
proxy_pass http://$http_host$request_uri; #设定代理服务器的协议和地址
proxy_set_header HOST $http_host;
proxy_buffers 256 4k;
proxy_max_temp_file_size 0k;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_next_upstream error timeout invalid_header http_502;
}
}
server {
resolver 114.114.114.114; #指定DNS服务器IP地址
listen 443;
location / {
proxy_pass https://$host$request_uri; #设定代理服务器的协议和地址
proxy_buffers 256 4k;
proxy_max_temp_file_size 0k;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_next_upstream error timeout invalid_header http_502;
}
}

客户端使用:

client端:
一次代理,直接在shell执行:

#export http_proxy=http://192.168.1.9:8080

永久使用:

#vim .bashrc export http_proxy=http://192.168.1.9:8080
#source  .bashrc

Nginx缓存

在3天内,通过浏览器地址栏访问 http://192.168.4.32/a.jpg ,不会从服务器抓取资源,3天后(过期)则从服务器重新下载。

1
2
3
4
5
6
7
8
9
10
11
12
13
# http 区域下添加缓存区配置 
proxy_cache_path /tmp/nginx_proxy_cache levels=1 keys_zone=cache_one:512m inactive=60s max_size=1000m;

# server 区域下添加缓存配置
location ~ \.(gif|jpg|png|htm|html|css|js)(.*) {
proxy_pass http://192.168.4.32:5000;#如果没有缓存则转向请求
proxy_redirect off;
proxy_cache cache_one;
proxy_cache_valid 200 1h; #对不同的 HTTP 状态码设置不同的缓存时间
proxy_cache_valid 500 1d;
proxy_cache_valid any 1m;
expires 3d;
}

expires 是给一个资源设定一个过期时间,通过 expires 参数设置,可以使浏览器缓存过期时间之前的内容,减少与服务器之间的请求和流量。也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。此种方法非常适合不经常变动的资源。

动静分离

通过浏览器地址栏访问 www.abc.com/a.html ,访问静态资源服务器的静态资源内容。通过浏览器地址栏访问 www.abc.com/a.jsp ,访问动态资源服务器的动态资源内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
upstream static {   
server 192.167.4.31:80;
}

upstream dynamic {
server 192.167.4.32:8080;
}

server {
listen 80; #监听端口
server_name www.abc.com; 监听地址

# 拦截动态资源
location ~ .*\.(php|jsp)$ {
proxy_pass http://dynamic;
}

# 拦截静态资源
location ~ .*\.(jpg|png|htm|html|css|js)$ {
root /data/; #html目录
proxy_pass http://static;
autoindex on;; #自动打开文件列表
}
}

高可用

一般情况下,通过 nginx 主服务器访问后台目标服务集群,当主服务器挂掉后,自动切换至备份服务器,此时由备份服务器充当主服务器的角色,访问后端目标服务器。

准备两台nginx服务器,在两台 nginx 服务器上安 keepalived。

keepalived 相当于一个路由,它通过一个脚本来检测当前服务器是否还活着,如果还活着则继续访问,否则就切换到另一台备份服务器。

//安装 keepalived
yum install keepalived -y  

//检查版本 
rpm -q -a keepalived 
keepalived-1.3.5-16.el7.x86_64

修改主备服务器 /etc/keepalived/keepalivec.conf 配置文件(可直接替换),完成高可用主从配置。

keepalived 将 nginx 服务器绑定到一个虚拟 ip , nginx 高可用集群对外统一暴露这个虚拟 ip,客户端都是通过访问这个虚拟 ip 来访问 nginx 服务器 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}

notification_email_from_Alexandre.Cassen@firewall.loc
smtp_server 192.168.4.32
smtp_connect_timeout 30
router_id LVS_DEVEL # 在 /etc/hosts 文件中配置,通过它能访问到我们的主机
}

vrrp_script_chk_http_port {
script "/usr/local/src/nginx_check.sh"
interval 2 # 检测脚本执行的时间间隔
weight 2 # 权重每次加2
}

vrrp_instance VI_1 {
interface ens7f0 # 网卡,需根据情况修改
state MASTER # 备份服务器上将 MASTER 改为 BACKUP
virtual_router_id 51 # 主备机的 virtual_router_id 必须相同
priority 100 # 主备机取不同的优先级,主机值较大,备份机值较小
advert_int 1 # 每隔多长时间(默认1s)发送一次心跳,检测服务器是否还活着

authentication {
auth_type PASS
auth_pass 1111
}

virtual_ipaddress {
192.168.1.100 # VRRP H 虚拟地址,可以绑定多个
}
}

router_id: 在 /etc/hosts 文件中配置,通过它能访问到我们的主机。

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4   
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6   
127.0.0.1   LVS_DEVEL

interval: 设置脚本执行的间隔时间

weight: 当脚本执行失败即 keepalived 或 nginx 挂掉时,权重增加的值(可为负数)。

interface: 输入 ifconfig 命令查看当前的网卡名是什么。

ens7f0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500           
        inet 192.168.4.32  netmask 255.255.252.0  broadcast 192.168.7.255           
        inet6 fe80::e273:9c3c:e675:7c60  prefixlen 64  scopeid 0x20<link>           
        ... ... 
 ... ...

在 /usr/local/src 目录下添加检测脚本 nginx_check.sh

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash 
A=`ps -C nginx -no-header |wc -l`

if [ $A -eq 0 ];then
/usr/local/nginx/sbin/nginx
sleep 2

if [ ps -C nginx -no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi

启动两台服务器的 nginx 和 keepalived。

//启动 nginx 
./nginx  

//启动 keepalived 
systemctl start keepalived.service

查看虚拟 ip 地址 ip a 。把主服务器 192.168.4.32 nginx 和 keepalived停止,再访问虚拟 ip 查看高可用效果。

原理解析

Nginx——配置文件实战_2020-07-27-15-14-39.png

Nginx 启动之后,在 Linux 系统中有两个进程,一个为 master,一个为 worker。master 作为管理员不参与任何工作,只负责给多个 worker 分配不同的任务(worker 一般有多个)。

客户端发送一个请求首先要经过 master,管理员收到请求后会将请求通知给 worker,多个 worker 以争抢的机制来抢夺任务,得到任务的 worker 会将请求经由 tomcat 等做请求转发、反向代理、访问数据库等(nginx 本身是不直接支持 java 的)。

Nginx 和 redis 类似,都采用了 io 多路复用机制,每个 worker 都是一个独立的进程,每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求,每个 worker 的线程可以把一个 cpu 的性能发挥到极致,因此,worker 数和服务器的 cpu 数相等是最为适宜的。

文章目录
  1. 1. 配置文件结构
  2. 2. 配置文件样例
  3. 3. 实战
    1. 3.1. 反向代理
    2. 3.2. 负载均衡
    3. 3.3. 正向代理
    4. 3.4. Nginx缓存
    5. 3.5. 动静分离
    6. 3.6. 高可用
  4. 4. 原理解析
|