1. 简介
1.1 定义
Nginx(发音同 engine x)是一款基于异步框架的轻量级/高性能的Web 服务器/反向代理负载均衡服务器/缓存服务器/电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。由俄罗斯的程序设计师Igor Sysoev(伊戈尔·赛索耶夫)所开发,最初供俄国大型网站Rambler.ru及搜寻引擎Rambler使用。
1.2 特点
- 优点
- 缺点
1.3 作用
- 静态文件展示、动静分离
2. 使用
2.1 安装
- 命令行安装:
apt install nginx -y
- 检查nginx运行端口:
netstat -tnulp | grep nginx
- nginx服务操作指令(使用
systemctl
指令操作,当使用apt标准化安装nginx才有的操作指令):
# start:启动;stop:关闭;reload:重启
systemctl [start|stop|reload] nginx
- nginx服务操作指令(使用
nginx
可执行程序操作):
nginx -V|v # 查看版本
nginx -c /etc/nginx/nginx.conf
nginx -s [stop|reload] # [关闭|重启]
nginx -t
2.2 配置
- nginx软件默认目录
- nginx默认配置文件
- 文件结构
2.3 访问原理
server {
listen 80 default_server;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
# 根据请求路径,按照指定的规则去处理
# 路由配置
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# Nginx访问原理:
# 1、$uri变量指的是请求的路径,和root目录拼接得出静态文件绝对路径;如果文件存在则返回;如果没有走第2步;
# 2、$uri/ 把请求路径尾部拼接一个/,意味把请求路径理解成一个文件夹,把该文件夹和root拼接,在该目录下查找index指定的索引文件;
# 3、如果前1,2都找不到静态资源则返回404;
try_files $uri $uri/ =404;
}
}
2.4 其他配置
1. Server配置
1.1 配置样式
# 一个server就是一个http服务器
server {
listen 端口;
server_name 主机名;
...
}
server配置段最重要的属性是listen和server_name。它们都是用于匹配并处理请求的
1.2 属性详解
- listen属性
作用:定义Server监听的ip和port,当ip/port匹配时候才进行下一步匹配。
- server_name属性
作用:当A主机只有一个开发的端口80,但是却存在多个网站,可以通过Server_name指定的域名,进行匹配后的下一步操作
server_name www.example.com;
- root属性
作用:定义Server相应请求的html文件所在路径
root /var/www/html;
- index属性
作用:定义响应请求后返回的文件名称或格式
index index.html index.htm index.nginx-debian.html;
2. Location配置
2.1 配置样式
location主要是根据Server匹配到的请求路径和关键字去响应和处理。
语法:
location optional_modifier location_match { ... }
# 如果请求路径按照既定选项,和匹配字符成功匹配了,那么就按照当前规则去处理此次请求
location 选项 匹配的字符 { 当前规则 }
其中:
optional_modifier是匹配条件(条件)
location_match是匹配的样式(字符)
{}是要执行的操作(规则)
匹配条件主要有两种:正则/前缀字符。
2.2 匹配规则
- 正则匹配
- 普通匹配
- 匹配示例
常见示例:
location = / { location ~ \.(gif|jpg|png|js|css)$ { location !~* \.xhtml$ {
#精确规则A #正则规则D #正则规则G
} } }
location = /login { location ~* \.png$ { location / {
#精确规则B #正则规则E #通用规则H
} } }
location ^~ /static/ { location !~ \.xhtml$ {
#优先规则C #正则规则F
} }
访问效果如下:
访问根目录/, 比如http://a.com/ 将匹配规则A
访问 http://a.com/login 将匹配规则B
访问 http://a.com/static/a.html 将匹配规则C
访问 http://a.com/a.gif, http://a.com/b.png 规则D和E均适合,按顺序优先使用规则D
访问 http://a.com/static/c.png 则优先匹配到规则C
访问 http://a.com/a.PNG 则匹配规则E,因为规则E不区分大小写。
访问 http://a.com/a.XHTML 使用规则F。
访问 http://a.com/category/id/1111 则最终匹配到规则H。
2.3 应用
在location内部常用的功能属性非常多,常见的基本属性、访问控制、目录列表等。
location / {
root /var/www/html; # 指定响应请求的文件所在路径
index index.php index.html index.htm; # 指定响应请求的默认文件名称
try_files $uri $uri/ =404; # 如果root指定的路径下有查找的文件,就返回,否则报错
}
重点理解:location匹配规律
- (1)、多个location匹配字符都能匹配成功的情况下,选择优先级最高的location规则去处理!
- (2)、多个locaiton匹配字符都能匹配成功,且他们的优先级一样的情况下,选择先定义的location规则去处理!
3. 应用
3.1 应用目录
root 和 alias 所起的作用都是指定响应请求所用文件的路径,只是他们有些许的区别。
root 表示 location 匹配内容的相对路径
alias 表示 一个绝对路径,而且必须以"/"结尾
root标志的绝对路径,不要"/"结尾
规律:
- (1)、
alias
指定目录的时候,是把alias目录
和剩余未匹配路径
拼接,得出静态文件绝对路径; - (2)、
root
指定目录的时候,是把root目录
和完整的请求路径
拼接,得出静态文件绝对路径;
效果一: 效果二:
location /img/ { location /img/ {
alias /var/www/image/; root /var/www/image;
} }
效果一:访问http://localhost/img/,nginx找/var/www/image/目录下的文件
效果二:访问http://localhost/img/,nginx找/var/www/image/img/目录下的文件
注意:
一般情况下,在location /中配置root,在location /other中配置alias
配置的目录必须有nginx的访问权限,否则全部失效,不要设置为X用户的家目录。
3.2 项目整合
1、准备工作
这里以 192.168.203.153 主机作为项目的部署主机,准备好代码目录 /data/
其中:
/data/front_end_pc/
目录是商城页面静态文件根目录/data/meiduo_mall_admin/
目录是管理后台静态文件根目录/data/meiduo_mall/
目录是Django动态服务器根目录
-
(1)、修改商城工程配置
-
(2)、编译生成商城管理站点静态文件
- 进入管理站点前端工程目录:
cd meiduo_mall_admin
- 安装依赖包(如果安装过则无需重复安装):
npm install
- 编译生成静态文件**(静态文件存储在
meiduo_mall_admin/dist
文件夹中)**:npm run build
- 进入管理站点前端工程目录:
-
(3)、上传静态文件和商城的代码到部署主机指定目录
front_end_pc
文件夹里面的所有文件发送到部署主机/data/front_end_pc
目录下:scp -r front_end_pc/* <部署主机用户名>@<部署主机ip>:/data/front_end_pc/
meiduo_mall_admin/dist/
文件夹里面的所有文件发送到部署主机/data/meiduo_mall_admin
目录下:scp -r meiduo_mall_admin/dist/* <部署主机用户名>@<部署主机ip>:/data/meiduo_mall_admin/
-
(4)、清空nginx无效配置(可做可不做)
rm /etc/nginx/conf.d/*
rm /etc/nginx/sites-enabled/*
rm /etc/nginx/sites-available/*
2、商城静态nginx配置文件
新建/etc/nginx/conf.d/8080.conf
并编辑如下:
server {
listen 8080;
server_name www.meiduo.site;
location / {
root /data/front_end_pc/;
index index.html;
try_files $uri $uri/ =404;
}
}
新建/etc/nginx/conf.d/8081.conf
并编辑如下:
server {
listen 8081;
server_name www.meiduo.site;
location / {
root /data/meiduo_mall_admin/;
index index.html;
try_files $uri $uri/ =404;
}
}
3、启动服务
-
(1)、检查nginx配置文件
nginx -t
-
(2)、启动nginx
systemctl restart nginx
3. 反向代理
3.1 简介
1. 代理定义
- 简单来说,我找一个中间人,代替我去做一件事情,只要他给我结果就可以。
- 在nginx中,我们一般用的就是 “反向代理”
- 反向代理
2. 代理模块
官方介绍
-
官方资料:http://www.nginx.cn/doc/standard/httpproxy.html
-
官方的代理属性很多,我们主要介绍proxy_pass
-
官方代码示例
location / {
proxy_pass http://localhost:8000; # 设定请求跳转后的地址,可以使用hostname或IP:Port
}
属性详解:
proxy_pass 指 令设置被代理服务器的地址和被映射的URI,地址可以使用主机名或IP加端口号的形式
proxy_pass关键点
proxy_pass后面的路径最后的/作用很重要!!!
示例代码:
location /html/ {
proxy_pass http://proxy.com;
proxy_pass http://proxy.com/;
}
假设访问的url是 http://domain.com/html/test.js,如何理解上述两种proxy_pass的区别呢?
对于 1 来说 proxy.com后面没有"/",表示"/html/" 请求(包括自己)后续的路径及其参数等关键字都由http://a.com/来处理,代理后的样式如下: http://proxy.com/html/test.js
对于 2 来所 proxy.com后面有"/",表示"/html/" 请求后续的路径及其参数等关键字都由http://a.com/来处理,代理后的样式如下: http://proxy.com/test.js
uwsgi模块
功能简介
nginx善于做静态文件相关的代理,而不擅长动态相关的代理,所以nginx的uwsgi模块就出现了,它主要做动态相关的代理工作
代码示例:
include uwsgi_params;
uwsgi_pass uwsgi_server_address;
3.2 应用
将192.168.203.153
主机作为了商城的代码部署主机。
-
(1)、新建
/etc/nginx/conf.d/8000.conf
编辑如下# 新增8000反向代理服务器 server { listen 8000; # 把匹配到的所有的请求,转发 location / { # 七层协议请求转发 # proxy_pass定义出请求转发的目标服务器(被反向代理的服务器) # proxy_pass http://127.0.0.1:8001; # 四层协议转发 include uwsgi_params; uwsgi_pass 127.0.0.1:8001; } }
-
(2)、检查nginx配置文件并重启
nginx -t
systemctl restart nginx
-
(3)、(七层代理转发动态服务器启动方式)启动Django开发服务器(HTTP服务)的方法
- 切换到root用户
- 进入虚拟环境:
source /home/python/.virtualenvs/django_env/bin/activate
- 启动Django(开发服务器):
python3 manage.py runserver 0.0.0.0:8001
-
(4)、(四层代理转发动态服务器启动方式)使用
uwsgi
调用django-
安装
uwsgi
:pip3 install uwsgi
-
修改
meiduo_mall/wsgi.py
import os from django.core.wsgi import get_wsgi_application # 指定我们的配置文件 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'meiduo_mall.settings.dev') application = get_wsgi_application()
-
新建
meiduo_mall/uwsgi.ini
编辑如下:[uwsgi] # 使用Nginx连接时使用,Django程序所在服务器地址 socket=127.0.0.1:8001 # 直接做web服务器使用,Django程序所在服务器地址 # http=127.0.0.1:8001 # 项目目录 # chdir=项目路径/meiduo_project/meiduo_mall chdir=/data/meiduo_mall # 项目中wsgi.py文件的目录,相对于项目目录 wsgi-file=meiduo_mall/wsgi.py # 进程数 processes=1 # 线程数 threads=2 # uwsgi服务器的角色 master=True # 存放进程编号的文件 pidfile=uwsgi.pid # 日志文件 daemonize=uwsgi.log # 指定依赖的虚拟环境 # 方式一:使用python用户的虚拟环境 # virtualenv=/home/python/.virtualenvs/django_env # 方式二:使用root用户的虚拟环境; # 前提把python用户虚拟环境拷贝到root用户虚拟环境目录下, 命令如下: # cp -r /home/python/.virtualenvs/django_env /root/.virtualenvs/ # 然后就可以指定root下的django_env虚拟环境了 virtualenv=/root/.virtualenvs/django_env
-
启动uwsgi:
uwsgi --ini uwsgi.ini
-
关闭uwsgi:
uwsgi --stop uwsgi.pid
-
4. 负载均衡
4.1 简介
1. 应用场景
- 使用
proxy_pass
的方式实现了nginx
代理请求到后端的效果,随着我们的网站访问量越来越多,一个后端就不现实了,在访问量日渐增大的情况下需要负载均衡满足线上业务的稳定 - 负载均衡简单说来人多力量大,打群架
2. 模块简介
官方资料:http://www.nginx.cn/doc/standard/httpupstream.html
官方的负载属性很多,常用的有upstream和ip_hash等属性
官方代码示例
upstream backend {
server backend2.example.com:8080;
}
server {
location / {
proxy_pass http://backend;
}
}
属性详解:
upstream 主要是定义一个后端服务地址的集合列表,每个后端服务使用一个server命令表示
upstream {} 和 Server {} 两部分内容属于平级关系。
4.2 调度策略(均衡策略)
-
官方资料:http://nginx.org/en/docs/http/ngx_http_upstream_module.html#example
-
Nginx提供的负载均衡策略有两种:内置策略 和 扩展策略
-
内置策略:nginx自带的算法
常用算法简介:
轮询(默认):请求按顺序逐一分配到不同的后端服务器。
weight:指定轮询权重,值越大,分配到的几率就越高,适用于后端服务器性能不均衡情况。
ip_hash:按访问IP的哈希结果分配请求,分配后访客访问固定后端服务器,有效的解决动态网页会话共享问题。
fair:基于后端服务器的响应时间来分配请求,响应时间短的优先分配。
url_hash:按访问URL的哈希结果分配请求,使同URL定
-
轮训
-
加权轮训
upstream meiduo_backend {
server 192.168.8.14:10086 weight=20;
server 192.168.8.14:10087 weight=80;
}
server {
listen 80;
location / {
proxy_pass http://meiduo_backend/;
}
}
- ip哈希
upstream meiduo_backend {
ip_hash;
server 127.0.0.1:10086;
server 127.0.0.1:10087;
}
server {
listen 80;
location / {
proxy_pass http://meiduo_backend/;
}
}
- uri哈希(路径哈希)
upstream meiduo_backend {
hash $request_uri;
server 127.0.0.1:10086;
server 127.0.0.1:10087;
}
server {
listen 80;
location / {
proxy_pass http://meiduo_backend/;
}
}
4.3 部署
- 新建/修改
/etc/nginx/conf.d/8000.conf
upstream backend.meiduo.site {
server 127.0.0.1:8001;
# server 127.0.0.1:8002;
}
server {
listen 8000;
location / {
# 使用4层负载(传输层)
include uwsgi_params;
uwsgi_pass backend.meiduo.site;
}
}
-
重启nginx
nginx -t
systemctl restart nginx
-
把
uwsgi.ini
配置文件中设置socket=127.0.0.1:8001
模式
[uwsgi]
# 使用Nginx连接时使用,Django程序所在服务器地址
socket=127.0.0.1:8001
# 直接做web服务器使用,Django程序所在服务器地址
# http=127.0.0.1:8001
# 项目目录
# chdir=项目路径/meiduo_project/meiduo_mall
chdir=/data/meiduo_mall
# 项目中wsgi.py文件的目录,相对于项目目录
wsgi-file=meiduo_mall/wsgi.py
# 进程数
processes=1
# 线程数
threads=2
# uwsgi服务器的角色
master=True
# 存放进程编号的文件
pidfile=uwsgi.pid
# 日志文件
daemonize=uwsgi.log
# 指定依赖的虚拟环境
# 方式一:使用python用户的虚拟环境
# virtualenv=/home/python/.virtualenvs/django_env
# 方式二:使用root用户的虚拟环境;
# 前提把python用户虚拟环境拷贝到root用户虚拟环境目录下, 命令如下:
# cp -r /home/python/.virtualenvs/django_env /root/.virtualenvs/
# 然后就可以指定root下的django_env虚拟环境了
virtualenv=/root/.virtualenvs/django_env
- 修改
meiduo_mall/wsgi.py
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'meiduo_mall.settings.dev')
application = get_wsgi_application()
- 使用
uwsgi
运行django
uwsgi --ini uwsgi.ini
- 关闭
uwsgi
uwsgi --stop uwsgi.pid
5. 日志解析
5.1 简介
- Nginx默认提供了两个日志文件 access.log和error.log,通过access.log可以得到用户请求的相关信息;通过error.log可以获取某个web服务故障或其性能瓶颈等信息
- 而且nginx的日志支持定制化格式,这样就可以根据实际的业务情况更好的高效工作。最常见的场景就是获取客户端的IP,记录用户访问量。
- 官方介绍:http://nginx.org/en/docs/http/ngx_http_log_module.html
5.2 配置
# cat /etc/nginx/nginx.conf -n
40 access_log /var/log/nginx/access.log;
41 error_log /var/log/nginx/error.log;
注意: nginx日志属性设置的完整格式是:
属性名称 access_log
存储位置 /var/log/nginx/access.log
日志格式 位置为空表示使用默认的combined 日志格式。它是通过log_format设置的
5.3 默认日志格式
结论:nginx记录的日志,就是其内置变量信息;
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
注意:log_format是有一批nginx内置变量组合而成的。
日志样式:
# tail /var/log/nginx/access.log
192.168.8.14 - - [12/Nov/2018:08:24:18 -0800] "GET /favicon.ico HTTP/1.0" 404 580 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"
5.4 内置变量
- nginx常用的内置变量主要是用来分析日志中的http记录的,可以根据内置的变量精确的获取相关的信息 默认变量
- 其他常用变量
5.5 自定义日志记录代理ip
需求
- 基于代理方式访问app1应用,日志存放在/var/logs/nginx/app1/access.log,要求能从日志中获取客户端的IP地址;
定制日志
- 设置日志格式
# vim /etc/nginx/nginx.conf
# Logging Settings
log_format proxy_format '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent "$http_referer"'
'"$http_user_agent" "$http_x_forwarded_for" "$http_x_real_ip"';
-
注意:这个格式,仅仅需要在真正的web应用server上设置。
-
使用日志格式:
access_log /var/log/nginx/access.log proxy_format;
代理配置文件
# log_format 日志格式名称 "内置变量"
log_format proxy_format '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent "$http_referer"'
'"$http_user_agent" "$http_x_forwarded_for" "$http_x_real_ip"';
server {
listen 10086;
location / {
# 协议转发的时候设置头信息X-Real-IP, 记录请求10086的源地址
proxy_set_header X-Real-IP $remote_addr;
# 协议转发的时候设置头信息X-Forwarded-For,记录请求10086的前序地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:10087;
}
}
server {
listen 10087;
location / {
# 协议转发的时候设置头信息X-Forwarded-For,记录请求10087的前序地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:10088;
}
}
server {
listen 10088;
# access_log 日志文件绝对路径 日志格式名称
access_log /data/logs/access.log proxy_format;
error_log /data/logs/error.log;
root /home/python/Desktop/data/10088_html;
}