Nginx
(读作:恩静 X)是一个高性能的HTTP
和反向代理服务器,一个邮件代理以及通用的TCP/ UDP
代理服务器。本篇文章是我最近使用Nginx
的记录。你发现本站已经是全站https
了,而本站的图片是放在七牛云的。之所以可以使用https://www.yukun.com/qiniu/xxx
访问到存放在七牛的图片,是因为使用了nginx
的反向代理。
安装
我们使用Docker
启动一个ubuntu
容器来演示安装过程:
$ sudo docker run -t -i -p 80:80 ubuntu:16.04 /bin/bash
root@bbf4a330635d:/# cd root
root@bbf4a330635d:~#
进入容器后,开始安装nginx:
apt-get安装
$ apt-get update // 更新软件源
$ apt-get install nginx // 更新软件源
$ nginx // 启动
$ ps -ef // 显示所有进程信息
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 08:26 pts/0 00:00:00 /bin/bash
root 3757 1 0 08:58 ? 00:00:00 nginx: master process nginx
www-data 3758 3757 0 08:58 ? 00:00:00 nginx: worker process
root 3759 1 0 08:58 pts/0 00:00:00 ps -ef
源码编译安装
上一种的安装方式,在生产环境下可能会显得自定义性不强,或者安装包比较老。更多的时候我们需要下载源码编译安装。
$ wget http://nginx.org/download/nginx-1.14.0.tar.gz // 目前最新稳定版
$ tar -zxvf nginx-1.14.0.tar.gz //解压
$ cd nginx-1.14.0.tar.gz
$ apt-get install libpcre3 libpcre3-dev zlib1g-dev build-essential libtool // 编译前安装依赖包
$ ./configure // 可以在后面定制安装
$ make
$ sudo make install
这样我们就安装成功了,默认情况nginx
会安装在/usr/local/nginx
目录中启动:
$ /usr/local/nginx/sbin/nginx // 启动
$ /usr/local/nginx/sbin/nginx -s reload // 重启
$ /usr/local/nginx/sbin/nginx -s stop // 关闭进程
$ /usr/local/nginx/sbin/nginx -s quit // 平滑关闭nginx
反向代理
假如用户 A 要得到网站 C 的内容,而用户 A 因为网络原因又不能直接访问到,而服务器 B 可以访问到网站 C,那服务器可以得到网站 C 的内容再存起来发给用户 A,这整个过程用户 A 是直接和服务器 B 交互的,用户 A 不知道网站 C 的存在。那web服务器 B 就是一台反向代理服务器,C 是上游服务器。
nginx
的反向代理是依赖于ngx_http_proxy_module这个自带module
来实现的。我们以本站图片请求反向代理为例:
由于本站用的是https
协议,在浏览器的地址栏可以看到绿色的锁。而如果图片不是存储在本地服务器,而是放在七牛,又拍云这样的地方,图片的外链是http
协议的(当然七牛本身是可以开启https
协议的,只是并非免费)。那么在浏览器的地址栏,虽然显示的是https
协议,却没有绿色安全锁。
所以我们要把https
协议请求的图片地址反向代理到http
协议的真实图片上。事实上https
协议请求的图片是不存在,而如果使用反向代理,它就有一个指向http协议图片的实际地址。
server {
server_name www.yukunweb.com;
listen 443; # 443端口用于HTTPS服务
location /qiniu/post36_0.jpg {
proxy_pass http://opxib6gmc.bkt.clouddn.com/post36_0.jpg;
proxy_set_header Host opxib6gmc.bkt.clouddn.com;
}
location /example.jpg {
proxy_pass http://example.com/example.jpg;
}
}
这样我们就可以通过访问https://www.yukunweb.com/qiniu/post36_0.jpg
来请求到http://opxib6gmc.bkt.clouddn.com/post36_0.jpg
的图片。
Nginx
的sever
块主要是服务器的配置(域名,IP,端口等),在一个Nginx
的配置文件里面,我们可以有多个sever
块配置。而location
块则是在sever
块里面,对不同请求路径进行的配置。因为一个站点中的URI
通常会非常多,所以在location
块设置这部分,同样可以写多个location
的配置。当然我们不能为每一个URI
都进行配置,我们来看一些动态匹配语法:
location语法说明
syntax: location [=|~|~*|^~|@] /uri/ { ... }
default: no
context: server
语法 | 说明 |
---|---|
= | 表示精确匹配,不支持正则 |
^~ | 表示uri以某个常规字符串开头,不支持正则,理解为匹配uri路径即可 |
表示区分大小写的和不区分大小写的正则匹配 | |
! |
表示区分大小写不匹配和不区分大小写不匹配的正则匹配 |
/ | 通用匹配,任何请求都会匹配 |
匹配优先级 :=
> ^~
> ~/~*/!~/!~*
> /
。优先级的意思是当以~/~*/!~/!~*
和/
匹配到符合结果路径后,会继续往下判断其他配置项的匹配,如果^~
语法也匹配到符合的则使用^~
匹配到的结果,而^~
匹配到结果后就不会再往下判断其他配置项是否满足。
proxy_set_header
配置重写请求上游服务器头的内容,我们这里设置了请求头Host
参数。
现在我们重新写上面的配置:
server {
server_name www.yukunweb.com;
listen 443; # 443端口用于HTTPS服务
location ^~ /qiniu/ {
proxy_pass http://opxib6gmc.bkt.clouddn.com/;
proxy_set_header Host opxib6gmc.bkt.clouddn.com;
}
# 反向代理avatar.com的头像
location ^~ /avatar/ {
proxy_pass http://www.avatar.com/;
proxy_set_header Host www.avatar.com;
}
}
静态文件缓存
以本战flask
程序为例,由于静态文件(比如css/js/图片等),都是不经常更新的。可以使用nginx
的proxy_cache
将这些静态文件的响应结果缓存到本地一个目录。这样不仅可以减少服务器处理请求的压力,还有一定程度上提高程序响应速度。
下面是本站缓存配置:
# nginx.conf
http{
...
proxy_temp_path /tmp/temp_dir; # 从后端服务器接收的临时文件的存放路径
# 设置缓存的路径和其他参数
# levels 设置缓存文件目录层次;levels=1:2 表示两级目录
# keys_zone 设置缓存名字和共享内存大小
# inactive 在指定时间内没人访问则被删除
# max_size 最大缓存空间,如果缓存空间满,默认覆盖掉缓存时间最长的资源。
proxy_cache_path /tmp/cache levels=1:2 keys_zone=tmp_cache:100m inactive=1d max_size=10g;
...
server {
...
}
}
本站程序的sever
块配置在sites-available/default
中:
# default
# 缓存 flask 的static文件夹下所有静态文件
server ^~ /static/ {
root /root/project/YuBlog/app/; # 指定文件路径,root不需要在后面加static,alias需要
proxy_set_header Host $host;
proxy_cache tmp_cache; # 使用名为tmp_cache的对应与http中的缓存配置
expires 30d; # 缓存时间
}
配置完我们需要重启nginx
:/usr/local/sbin/nginx -s reload
如果没有报错就说明成功了,如果有错误可以使用/usr/local/sbin/nginx -t
查看错误原因。这是打开浏览器可以查看静态文件是否进行缓存了,看响应头中Expires
的时间。如果响应头中没有expires
信息,而 nginx 也没有出错,那么可能是 nginx 的缓存没有写入权限。这是要在nginx.conf
顶部配置有写入权限的用户。
当然,上面反向代理的图片也是可以缓存的,只需要在他们的location
配置中加入对应配置就可以了。
最后
参考文章:nginx proxy_cache 缓存配置{:target="_blank"}
推荐教程:从入门到放弃{:target="_blank"}