本篇整理一下Nginx常用的配置,并使用测试案例说明配置文件用法。

注意事项

  • 文中①②…对应问题出现的位置
  • nginx修改或添加配置文件需要使用/usr/local/nginx/sbin/nginx -s reload 命令重新加载配置文件才能生效
  • 修改主配置文件运行用户需要重启nginx,停止命令/usr/local/nginx/sbin/nginx -s stop,启动命令/usr/local/nginx/sbin/nginx -s
  • 本篇除nginx配置文件(nginx.conf、server/*.conf)以外,其他均为测试需要

Nginx主配置

主配置文件中只是加入一些通用配置,详细设置区分管理至单独文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 指定运行用户
user root; # ①
# 工作进程数量
worker_processes 1;
events {
# 每个进程的连接数
worker_connections 1024;
}
http {
# 引入mime.types 文件
include mime.types;
# 默认类型为二进制流
default_type application/octet-stream;
#sendfile参数用于开启高效文件传输模式
sendfile on;
# keepalive_timeout设置客户端连接保持活动的超时时间
keepalive_timeout 65;
# 引入当前文件相对路径 server 文件夹下所有已conf 结尾的文件,方便区分管理
include server/*.conf;
}

前端

站点访问

为方便测试,需要完成以下几点

  1. 在hosts中添加 本机ip www.test.com(将www.test.com 解析到本地)

  2. /root/www/www.test.com文件夹下添加index.html文件

  3. index.html文件内容<html><head><meta charset="utf-8"></head><body><h2>这里是www.test.com</h2></body></html>

  4. 在server文件夹下添加www.test.com.conf(文件名可任意设置)配置文件,内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 虚拟主机
    server {
    listen 80;
    server_name www.test.com; # 浏览器访问域名
    charset utf-8; # 指定字符集
    root /root/www/www.test.com; # 访问根目录
    # 路由
    location / {
    index index.html; # 入口文件
    try_files $uri $uri/ /index.html; / 默认访问文件夹下的index.html , 例如访问/user 会自动尝试访问/user/index.html
    }
    }
  5. 访问www.test.com测试是否可以访问页面

静态资源缓存

  1. 在hosts中添加 本机ip cache.test.com(将cache.test.com 解析到本地)

  2. /root/www/cache.test.com文件夹下添加index.html文件,内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <html>
    <head>
    <meta charset="utf-8">
    <script src="index.js"></script>
    </head>
    <body>
    <h2>这里是www.test.com</h2>
    </body>
    </html>
  3. 同路径下添加index.js文件测试js缓存,内容如下

    1
    2
    3
    function a(){
    alert("a")
    }
  4. 在server文件夹下添加cache.test.com.conf(文件名可任意设置)配置文件,内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # 虚拟主机
    server {
    listen 80;
    server_name cache.test.com; # 浏览器访问域名
    charset utf-8;
    root /root/www/cache.test.com; # 访问根目录
    # 路由
    location / {
    index index.html index.htm; # 入口文件
    # try_files $uri $uri/ /index.html;
    }
    # 设置js缓存为30天
    location ~ .*\.js$ {
    expires 30d;
    break;
    }
    }
  5. 访问cache.test.com,查看F12中js文件的请求信息,出现(memory cache)为成功,如下图

    image-20200618111751768

防盗链

防止其他ip请求资源

1
2
3
4
5
6
7
location ~* \.(gif|jpg|png)$ {
# 只允许 192.168.0.1 请求资源
valid_referers none blocked 192.168.0.1;
if ($invalid_referer) {
rewrite ^/ http://$host/logo.png;
}
}

静态文件压缩

1
2
3
4
5
6
7
8
9
10
11
12
server {
# 开启gzip 压缩
gzip on;
# 设置gzip所需的http协议最低版本 (HTTP/1.1, HTTP/1.0)
gzip_http_version 1.1;
# 设置压缩级别,压缩级别越高压缩时间越长 (1-9)
gzip_comp_level 4;
# 设置压缩的最小字节数, 页面Content-Length获取
gzip_min_length 1000;
# 设置压缩文件的类型 (text/html)
gzip_types text/plain application/javascript text/css;
}

禁止文件缓存

1
2
3
location ~* \.(js|css|png|jpg|gif)$ {
add_header Cache-Control no-store;
}

后端

反向代理

为方便测试,需要完成以下几点

  1. 在hosts中添加 本机ip api.test.com(将api.test.com 解析到本地)

  2. 添加/root/www/api.test.com/test.py 文件用来测试,内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # -*- coding: UTF-8 -*-

    # 引入框架
    import flask,json
    # 将本文件当做一个服务
    server = flask.Flask(__name__)
    # 制定一个测试接口
    @server.route('/index',methods=['get'])
    def index():
    res = {'msg':'测试接口','code':0}
    return json.dumps(res,ensure_ascii=False) # json转换并取消ascii转码
    # 运行并监听8000端口
    server.run(port=8000)
  3. 在server文件夹下添加api.test.com.conf(文件名可任意设置)配置文件,内容如下

    1
    2
    3
    4
    5
    6
    7
    server {
    listen 80;
    server_name api.test.com; # 域名
    location / {
    proxy_pass http://localhost:8000; # 代理地址
    }
    }
  4. 使用python test.py 命令运行python并监听8000端口 ②

  5. 访问api.test.com/index测试

负载均衡

  1. 在hosts中添加 本机ip load.test.com(将load.test.com 解析到本地)

  2. 添加/root/www/load.test.com/test_8100.py 文件用来测试,内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # -*- coding: UTF-8 -*-

    # 引入框架
    import flask,json
    # 将本文件当做一个服务
    server = flask.Flask(__name__)
    # 制定一个测试接口
    @server.route('/index',methods=['get'])
    def index():
    res = {'msg':'测试接口,端口为8100','code':0}
    return json.dumps(res,ensure_ascii=False)
    # 运行并监听8000端口
    server.run(port=8100)
  3. 添加/root/www/load.test.com/test_8101.py 文件用来测试,内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # -*- coding: UTF-8 -*-

    # 引入框架
    import flask,json
    # 将本文件当做一个服务
    server = flask.Flask(__name__)
    # 制定一个测试接口
    @server.route('/index',methods=['get'])
    def index():
    res = {'msg':'测试接口,端口为8101','code':0}
    return json.dumps(res,ensure_ascii=False)
    # 运行并监听8000端口
    server.run(port=8101)
  4. 在server文件夹下添加load.test.com.conf(文件名可任意设置)配置文件,内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    upstream loadapi {
    # 负载均衡,配置权重
    server localhost:8100 weight=1 max_fails=2 fail_timeout=3s;
    server localhost:8101 weight=3 max_fails=2 fail_timeout=3s;
    }
    server {
    listen 80;
    server_name load.test.com;
    location / {
    proxy_pass http://loadapi; # 这里对应上面的 upstream loadapi
    }
    }
  5. 使用python test_8100.pypython test_8101.py 运行两个python文件

  6. 访问load.test.com/index , 多次访问会出现{"msg": "测试接口,端口为8100", "code": 0}{"msg": "测试接口,端口为8101", "code": 0}结果。

代理Nexus

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
listen 10100;
server_name nexus.kthirty.top; # 域名
location / {
proxy_pass http://localhost:10103; # 代理地址
proxy_redirect off;
proxy_set_header Host $host:10100; # 如果nginx不是80端口这里需要添加nginx端口号
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
}
}

HTTPS

  1. 在hosts中添加 本机ip ssl.test.com(将ssl.test.com 解析到本地)

  2. 使用keymanager 生成一个测试证书(已有证书请忽略)

  3. 上传证书文件至 /etc/ssl/ssl.test.com,路径可以自定义

  4. 在server文件夹下添加ssl.test.com.conf(文件名可任意设置)配置文件,内容如下 ③

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    server {
    listen 80;
    #ssl参数
    listen 443 ssl;
    server_name ssl.test.com;
    root /root/www/www.test.com; # 访问根目录(这里主要测试https复用www的文件)
    #证书文件路径
    ssl_certificate /etc/ssl/ssl.test.com/ssl.test.com_chain.crt;
    #私钥文件路径
    ssl_certificate_key /etc/ssl/ssl.test.com/ssl.test.com_key.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;
    # 路由
    location / {
    index index.html index.htm; # 入口文件
    # try_files $uri $uri/ /index.html;
    }
    }
  5. 浏览器访问 https://ssl.test.com 可以正常访问就是成功,出现不安全是以为测试证书浏览器不信任。

遇到的问题

  • 对应①,可能会出现403 forbidden 错误,原因是未指定运行用户,主配置文件添加 user root即可。保证nginx的运行用户有权限访问文件路径即可

  • 对应②,使用Python监听测试接口出现Python“Non-ASCII character 'xe5' in file”错误,原因为Python文件未指定字符集,文件第一行添加*# -\*- coding: UTF-8 -\*-*即可。

  • 对应②,python运行时出现ImportError: No module named flask , 缺少flask,运行yum install python-flask即可

  • 对应③,the "ssl" parameter requires ngx_http_ssl_module,原因是因为源码编译安装为开启ngx_http_ssl_module,解决步骤如下

    • 进入nginx源码目录 cd /root/soft/nginx/nginx-1.18.0 根据自己的情况进入

    • 运行/usr/local/nginx/sbin/nginx -V查看并复制configure arguments:后面的值(路径可能不一致,未安装插件的情况下后面一般为空

    • 运行/usr/local/nginx/sbin/nginx -s stop停止当前nginx,如果出现the "ssl" parameter requires ngx_http_ssl_module,暂时把包含的配置文件删除即可。

    • nginx源码目录下运行./configure --原来有的模块(如果有的话) --with-http_ssl_module

      这里可能会出现/configure: error: SSL modules require the OpenSSL library

      Centos需要安装openssl-devel yum install openssl openssl-devel

      Ubuntu则需要安装:sudo apt-get install libssl-dev

    • 编译make

    • 备份原有nginx cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak

    • 复制新编译的nginx cp ./objs/nginx /usr/local/nginx/sbin/

    • 启动Nginx /usr/local/nginx/sbin/nginx

    • 验证查看/usr/local/nginx/sbin/nginx -V 出现with-http_ssl_module为成功

附录