Nginx配置与uWSGI配置详解

温馨提示:点击页面下方以展开或折叠目录

摘要:文章介绍了NginxuWSGI的知识,并依具体的例子对Web应用进行详细配置。

文章说明
文章作者:鴻塵
文章链接:https://hwame.top/20200522/configuration-of-nginx-and-uwsgi.html

一、Nginx配置文件

1.指令

Nginx配置文件包含指定指令控制的模块,指令分为 简单指令块指令 ,如果块指令大括号内有其他指令,就被称为一个 上下文 ,比如events, http, server, location等。

简单指令:由名称和参数组成,以空格分隔,并以分号结尾;
块指令:具有和简单指令相同的结构,以大括号包围的一堆附加指令结束。
指令

nginx -t不运行,仅测试配置文件;
nginx -c config_path从指定路径加载配置文件;
nginx -t -c config_path测试指定配置文件。

2.控制命令

启动Nginxnginx [-c config_path],默认配置目录为/etc/nginx/nginx.conf
查看信息nginx -v,查看版本信息;nginx -V,查看详细信息。
查看进程ps -ef | grep nginx,利用管道命令查看进程,ps命令用法参见:【Linux命令大全】
控制Nginxnginx -s signal,参数signalstop, quit, reload,分别表示快速关闭、优雅关闭、重载配置
系统管理systemctl option nginx,参数optionstatus, start, stop, enable, disable,分别表示查看状态、启动服务、关闭服务、设置开机自启、禁止开机自启

3.文件详情

nginx.conf

文件位置:默认位于/etc/nginx/nginx.conf,此乃默认配置文件,服务启动基于该文件。
原文内容

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
user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker-connections 1024 ;
}

http {
include /etc/nginx/mime.types;
default_type appplication/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 /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}

文件结构

为结构清晰,特删掉大括号,······处表示块指令。

1
2
3
4
5
6
7
8
9
10
11
main 【全局设置】
events 【指定工作模式,连接配置上限】
······
http 【http的配置】
······
upstream xxx 【负载均衡配置】
······
server 【主机设置】
······
location 【URL匹配】
······

参数详解

  • main
    • user:worker进程运行的用户和组
    • worker_processes:指定开启的子进程数,建议设置为与CPU数相等
    • error_log:用来定义全局错误日志文件,如原文中路径为/var/log/nginx/error.log,级别leveldebug, info, notice, warn, error, crit
    • pid:指定进程ID的存储文件位置
  • events
    • use:指定Nginx工作模式,①epoll=高效工作模式,Linux,默认,②kqueue=高效工作模式,BSD,③poll=标准模式,④epoll=标准模式
    • worker_connections:每个进程的最大连接数,其中$正向代理=连接数×进程数$,$反向代理=\frac{1}{4}\times\text{连接数}\times\text{进程数}$
      【Linux系统限制最多能同时打开$65535=2^{16}$个文件,亦即默认上限,能以ulimit -n 65535解除】
  • http最核心的模块,主要负责http服务器相关配置,包含serverupstream子模块,见后文
    • include:第12行include mime.types设置文件的mime类型为/etc/nginx/mime.types所定义的类型,第27行xxx.config包含其他配置文件(分开规划解耦作用)的server
    • default_type:设置默认类型,当文件类型未知时将使用默认(注:octet-stream=八进制字节流
    • log_format:设置日志格式
    • access_log:访问日志,中间为日志路径,最后main为日志格式log_format中的main
    • sendfile:设置高效文件传输模式
    • keepalive_timeout:设置客户端连接活跃超时
    • gzip:gzip压缩

核心模块http

  • upstream子模块,负载均衡,多服务器反向代理
    • server ip:port weight=1:指定反向代理服务器及分流权重
  • server子模块,用来指定虚拟主机
    • listen 80;:指定虚拟主机监听的端口,80端口表示http
    • server_name localhost;:指定ip地址或域名,多个域名以空格分隔
    • charset utf-8:指定网页的默认编码格式
    • error_page 500 502 /50x.html;:指定错误页面,见/etc/nginx/conf.d/*.confdefault.conf
    • access_log xxx main;:指定虚拟主机的访问日志存放路径
    • error_log xxx main;:指定虚拟主机的错误日志存放路径
    • root xxx;:指定虚拟主机的根目录
    • index xxx;:指定默认主页
    • location:核心【server】中的核心【location】,后面主要就是配置这里,支持正则匹配和条件,其主要功能是定位和解析URL、实现动静分离。语法格式:location [modifier] uri {指令 xxx}可选修饰符modifier表示定位URL的方式:①=,使用精确匹配并且终止搜索②~,区分大小写的正则③~*,不区分大小写的正则④^~,最佳匹配通常用来匹配目录(非正则匹配);常用指令aliasalias定义了location的别名(需要在文件系统中能够找到),如果location指定了正则表达式,alias将会应用正则表达式中的捕获,alias替代location中匹配的部分,没有匹配的部分将在文件系统中搜索
default.conf

文件位置:位于/etc/nginx/conf.d/nginx.conf,只包含一个server模块。Nginx服务启动时由nginx.conf通过include /etc/nginx/conf.d/*.conf;引用其内容(即server),从而实现解耦。
原文内容

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
40
41
42
43
44
45
server {
listen 80;
server_name localhost;

#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

二、uwsgi配置文件

1.命令

启动:uwsgi --ini uwsgi.ini,当前目录(项目目录)下新建ini文件
停止:uwsgi --stop uwsgi.pid,uWSGI服务器启动后在当前目录自动生成pid文件,无需新建

2.文件详情

文件位置:位于[Project_Dir]/uwsgi.ini,此乃用户建立的配置文件,uwsgi服务启动基于该文件。
文件内容

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
[uwsgi]
# 用于nginx与uwsgi对接时的uwsgi配置

# (1)使用nginx连接时,使用socket
socket = ip:port

# (2)直接作为web服务器使用(相当于测试,(1)(2)二选一)
#http = ip:port

# (3)配置工程目录,wsgi-file为入口文件,此用于Flask
chdir = [Project_Absolute_dir]
wsgi-file = app.py
# router
callable = app_flask_instance

# (4)配置项目的wsgi目录,相对于工程目录(3),此用于Django
#chdir = [Project_Absolute_dir]
#wsgi-file = Project_name/wsgi.py
#Note: unlike Flask, wsgi.py generated by Django automaticly

# (5)配置进程和线程信息
processes = 4
threads = 10
enable-threads = True
master = True
pidfile = uwsgi.pid
daemonize = uwsgi.log

三、项目部署

1.项目描述

项目位置:位于/usr/local/flask_covid/
项目文件:主要包括app.pyspider.pystatic/css+js/templates/main.html,以及测试静态路由的文本文件static/mmdd.md

2.配置准备

  1. 将Nginx默认的配置文件/etc/nginx/nginx.conf/etc/nginx/conf.d/default.conf复制到项目根目录下,default.conf用处不大(只需用到少量内容)
  2. 编辑配置文件/usr/local/flask_covid/nginx.conf【若因非root用户修改而出现权限问题,则需修改文件权限】,将default.conf内容去注释后复制到nginx.conf中的include /etc/nginx/conf.d/*.conf;处【由于将default配置转移过来了,所以不需要include语句来引用,删除之】,nginx.conf内容为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
···omit text above···

#include /etc/nginx/conf.d/*.conf;
#Copy "server {...}" from file="default.conf"
server {
listen 80;
server_name localhost;
#charset koi8-r;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location = /50x.html {
root /usr/share/nginx/html;
}
}
#Copy and replace over.
  1. 继续编辑配置文件/usr/local/flask_covid/nginx.conf,文件如上,修改如下:
  • (1)修改字符集:charset utf-8;
  • (2)将root移动到上一级server下,并修改路径为项目的绝对路径root /usr/local/flask_covid;
  • (3)修改URL静态路由的解析:首先将location / {···}修改为location /static {···},以便于访问./static静态资源【注:ppt18,当client请求发出请求时,由Nginx直接提供静态资源,由uwsgi通过Nginx提供动态资源,后者才是真正意义上的代理】,然后为其内容设置别名alias [Project_Absolute_dir]/static;
  • (4)由于默认用户为user nginx;时进程master_process = root, worker_process = nginx,为了避免请求静态资源时出现的因权限不够而请求失败的问题,故需修改用户:user root;
  • 此时在项目目录下执行nginx -c /usr/local/flask_covid/nginx.conf启动Nginx服务器,于是可以在浏览器中输入http://ip/static/file_name(不加端口号)访问到静态资源,就如同操作文件夹一样【实测成功,直接下载到了./static/mmdd.md文件,并且./static文件夹下的所有资源皆可访问到】。修改后nginx.conf内容为:
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 root;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker-connections 1024 ;
}

http {
include /etc/nginx/mime.types;
default_type appplication/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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;

#include /etc/nginx/conf.d/*.conf;
# ********** VERY IMPORTANT PARAGRAPH **********
#Copy "server {...}" from file="default.conf"
server {
listen 80;
server_name localhost;
charset utf-8;
root /usr/local/flask_covid;
location /static {
alias /usr/local/flask_covid/static;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
#Copy and replace over.
}
  1. 至此测试成功

3.uWSGI配置

  1. 安装uwsgi:pip install uwsgi
  2. 工程目录下创建uwsgi.ini配置文件并添加配置信息,见2.2
  3. 个性化修改如下:
  • 部署时用(1),测试时用(2),ip设置为0.0.0.0保证所有人可以访问,端口号与app.py相同;
  • Flask项目用(3),Django项目用(4),配置工程目录chdir为项目完整绝对路径,并与nginx.confserver → root相同:chdir = /usr/local/flask_covidwsgi-file为项目启动文件【注:Django项目会自动生成./[Project_Name/wsgi.py]】;
  • 配置进程和线程,其中enable-threads表示线程可用
  1. 修改完成后uwsgi.ini内容为:
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
[uwsgi]
# 用于nginx与uwsgi对接时的uwsgi配置

# (1)使用nginx连接时,使用socket
socket = 0.0.0.0:5000
# (2)直接作为web服务器使用(相当于测试,部署时与(1)二选一)
#http = 0.0.0.0:5000

# (3)配置工程目录,wsgi-file为入口文件,callable为flask实例,此用于Flask
chdir = /usr/local/flask_covid
wsgi-file = app.py
# router
callable = app
# (4)配置项目的wsgi目录,相对于工程目录(3),此用于Django
#chdir = /usr/local/flask_covid
#wsgi-file = flask_covid/wsgi.py
#Note: unlike flask, wsgi.py generated by Django automaticly

# (5)配置进程和线程信息
processes = 2
threads = 4
enable-threads = True
master = True
pidfile = uwsgi.pid
daemonize = uwsgi.log
  1. 使用uWSGI服务器:
  • 启动:uwsgi --ini uwsgi.ini,不能加sudo
  • 停止:uwsgi --stop uwsgi.pid,uWSGI服务器启动后在当前目录自动生成pid文件,无需新建
  1. 测试(打开(2)、关闭(1)):启动 Nginx和uWSGI服务器,出现[uWSGI] getting INI configuration from /usr/local/flask_covid/uwsgi.ini的信息表明 uWSGI配置成功,此时可以在浏览器中输入http://ip:port(加端口号)访问
  2. 部署(打开(1)、关闭(2)):见3.2

4.Nginx配置

  1. 首先停止3.3的测试:uwsgi --stop /usr/local/flask_covid/uwsgi.pid【注:如果无法停止并报错:signal_pidfile()/kill(): No such process [core/uwsgi.c line 1693],首先利用ps -ef | grep uwsgi查询其进程号,然后将uwsgi.pid文件修改为相应进程号,最后执行停止命令】
  2. 部署时,uWSGI与 Nginx的对接依赖于/etc/nginx/uwsgi_params文件,该文件在安装uwsgi时自动生成,其定义了一系列的uwsgi参数
  3. 编辑配置文件/usr/local/flask_covid/nginx.conf,在原来配置好了的静态文件下配置首页目录,location定位和解析的URL/就表示首页,然后利用include去对接uwsgi_params文件,uwsgi_pass去关联localhost【因为uWSGI与 服务器同属一个地方】,端口号port必须与3.3uwsgi.inisocket一致,如下所示:
1
2
3
4
5
6
7
location /static {
alias xxx/static/;
}
location / {
include /etc/nginx/uwsgi_params;
uwsgi_pass localhost:5000;
}
  1. 由于修改了Nginx配置,因此需要先关闭服务nginx -s quit,然后重新启动:nginx -c /usr/local/flask_covid/nginx.conf
  2. 启动uWSGI服务器:uwsgi --ini /usr/local/flask_covid/uwsgi.ini
  3. 此时nginx与uwsgi便对接成功,可以在浏览器中输入http://ip(不加端口号)进行访问【由于location /{...}下面有uwsgi_pass localhost:8000进行转发代理,自动加上port,因此不能加端口号】

四、总结建议

不建议改变Nginx默认的配置文件/etc/nginx/nginx.conf的位置,当部署大型项目时,或有多个服务需要同时运行,则将导致配置文件的混乱,且难以使用系统服务管理工具systemctl,建议的做法是针对具体的项目,在/etc/nginx/conf.d/目录下创建具有标识性的独用于本项目的配置文件myproject.conf,便于维护。