本文内容有转载自技术胖的内容
0. 简介
本文针对 Nginx 的配置进行了简单的分析,我是看完了视频进行的总结,希望大家谅解。而且,视频教程中许多知识需要自己购买服务器和域名进行练习,如果需要可以按视频中教程进行购买。我是在阿里云购买了服务器和域名并配置了博客,因此在本文中也会穿插说明我在搭建服务时遇到的问题。
1. 部署
作为一个想着全栈开发前进的码农使用 Nginx 的开始其实是因为我在部署网站的时候,搜索服务的时候全部都是 Nginx 的教程,因此就有了想深入学习的想法,至于 Nginx到底是什么?的介绍如下:
「Nginx是一款轻量级的HTTP服务器,采用事件驱动的异步非阻塞处理方式框架,这让其具有极好的IO性能,时常用于服务端的反向代理和负载均衡。」
在这个网站中,服务器的占比中 Nginx 是排第二位的(如下图),第一位的份额大部分都是老服务器,更换技术不变,而新型的创业公司大部分都会选择 Nginx 。理由我觉得很简单就是内存消耗少。其它的优点也许可能不足以让公司选择它,但是内存少不一样,它是可以明显减少公司服务器开支的,选它也是因为我没钱。
部署方法
基于 yum 的方式安装 Nginx(Linux 熟悉的话可以跳过)
注意:如果你的镜像没有完成网络配置和安装 yum 的话可以先搜索一下配置方法,而如果在阿里云上购买的镜像默认是已经配置好的状态
首先可以先来查看一下 yum 中的 nginx 是否已经存在,输入如下指令
yum list | grep nginx
输出如下
「可以发现系统原来的源只支持1.1.16版本,这版本有些低」
如果不存在,或者不是你需要的版本,那我们可以自行配置yum源,下面是官网提供的源,我们可以放心大胆的使用。注意修改一下对应的操作系统和版本号
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/
gpgcheck=0
enabled=1
例如:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
将上述代码复制到如下文件「使用 vim 直接创建即可」(vim 的使用方法不在本文讨论范围之内)
vim /etc/yum.repos.d/nginx.repo
运行安装命令如下
yum install nginx
安装完成后可以使用命令,来检测 Nginx 的版本
nginx -v
如果出现下面图片的内容,说明 Nginx 就安装成功了
2. 配置文件详解
进入 nginx 的目录查看,如下
# 如果你不知道你的路径可以运行着一行代码
rpm -ql nginx # 如果你知道安装路径不用运行
cd /usr/local/nginx # 这是我的安装目录
vim nginx.conf # 使用 vim 打开配置文件
下面是文件的详细注释:
# 运行用户,默认即是nginx,可以不进行设置
user nginx;
# Nginx进程,一般设置为和CPU核数一样
worker_processes 1;
# 错误日志存放目录
error_log /home/wwwlogs/nginx_error.log crit;
# 进程pid存放位置
pid /usr/local/nginx/logs/nginx.pid;
events {
worker_connections 51200; # 单个后台进程的最大并发数
}
http {
include mime.types; # 文件扩展名与类型映射表
default_type application/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 off; # nginx访问日志存放位置
sendfile on; # 开启高效传输模式
#tcp_nopush on; # 减少网络报文段的数量
keepalive_timeout 65; # 保持连接的时间,也叫超时时间
#gzip on; # 开启gzip压缩
include vhost/*.conf; # 包含的子配置项位置和文件
...
}
我们看到最后有一个子文件的配置项,那我们打开这个 include 子文件配置项看一下里边都有些什么内容。
进入 vhost 目录,然后使用 vim default.conf
进行查看。
我的是已经配置好的 zhuhe.site.conf
文件,如果你不知道文件夹里有什么文件,可以尝试用 ls
命令查看,方便起见我用一个简单的版本查看。
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; # 配置404页面
# 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;
#}
}
明白了这些配置项,我们知道我们的服务目录放在了/usr/share/nginx/html
下,这是 nginx 默认生成的配置,可以直接访问自己的 ip 查看一下效果。
3. Nginx 服务的启动、停止、重启
启动
- 直接启动
nginx
- systemctl命令启动
systemctl start nginx.service
可以输入这个命令查看是否启动成功
ps aux | grep nginx
有这三条记录,说明我们Nginx被正常开启了。
停止
- 立即停止服务
nginx -s stop
这种方法比较强硬,无论进程是否在工作,都直接停止进程。
- 从容停止服务
nginx -s quit
这种方法较stop相比就比较温和一些了,需要进程完成当前工作后再停止。
- killall 方法杀死进程
killall nginx
这种方法也是比较野蛮的,我们直接杀死进程,但是在上面使用没有效果时,我们用这种方法还是比较好的。
- systemctl 停止
systemctl stop nginx.service
重启
有时候我们需要重启 Nginx 服务,这时候可以使用下面的命令。
systemctl restart nginx.service
重新载入配置文件
在重新编写或者修改 Nginx 的配置文件后,都需要作一下重新载入,这时候可以用 Nginx 给的命令。
nginx -s reload
在默认情况下,Nginx 启动后会监听80端口,从而提供 HTTP 访问,如果 80 端口已经被占用则会启动失败。我么可以使用 netstat -tlnp
命令查看端口号的占用情况。
4. 自定义错误页面
本节内容我以前写过,可以结合观看
单页面配置
其实基本都是如下方式实现的
error_page 500 502 503 504 /50x.html;
error_page 404 /404_error.html;
这种方式只要主要实现了 50x.html
和404_error.html
页面的配置即可
简单实现访问控制
有时候我们的服务器只允许特定主机访问,比如内部OA系统,或者应用的管理后台系统,更或者是某些应用接口,这时候我们就需要控制一些IP访问,我们可以直接在location
块里进行配置。
location / {
deny 123.9.51.42;
allow 45.76.202.231;
}
配置完成后,重启一下服务器就可以实现限制和允许访问了,这在工作中非常常用。
本站的实现
本来是没有这一项内容的,但是我在配置中发现了一个问题,由于在更换了网站框架之后改为 php 的一个现实即「typecho」。为了域名的简洁,我设置了伪静态。但是如果配置后,会发现由于 nginx 的转发设置无法在此域名下在挂载其它页面,即:
server {
...
location /update {
alias /home/blog/update;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 @tempdown;
location @tempdown {
rewrite ^(.*)$ /update break;
}
...
}
上述代码部分会无法工作,原因似乎是由于在伪静态实现会在内部转发时在域名后加index.php
,即https://ip/index.php/...
的样子,导致即使转发也会变成https://ip/index.php/update/...
触发 typecho 内部的错误页面,不清楚我的分析对不对,希望有了解的可以留言
5. 访问权限
上节我们已经简单接触了 Nginx 访问简单用法,简单的知道了,deny是禁止访问,allow是允许访问。
指令优先级
location / {
allow 45.76.202.231;
deny all;
}
上面的配置表示只允许45.76.202.231
进行访问,其他的IP是禁止访问的。但是如果我们把deny all
指令,移动到allow 45.76.202.231
之前,会发生什么那?会发现所有的IP都不允许访问了。这说明了一个问题:就是在同一个块下的两个权限指令,先出现的设置会覆盖后出现的设置(也就是谁先触发,谁起作用)。
复杂访问控制权限匹配
在工作中,访问权限的控制需求更加复杂,例如,对于网站下的 img(图片目录)是运行所有用户访问,但对于网站下的 admin 目录则只允许公司内部固定 IP 访问。这时候仅靠 deny 和 allow 这两个指令,是无法实现的。我们需要 location 块来完成相关的需求匹配。
location =/img{
allow all;
}
location =/admin{
deny all;
}
=
号代表精确匹配,使用了=
后是根据其后的模式进行精确匹配。这个直接关系到我们网站的安全。
使用正则表达式设置访问权限
正则表达式的使用规则不在本文的讨论范围之内。
只有精确匹配有时是完不成我们的工作任务的,比如现在我们要禁止访问所有 php 的页面,php 的页面大多是后台的管理或者接口代码,所以为了安全我们经常要禁止所有用户访问,而只开放公司内部访问的。
location ~\.php$ {
deny all;
}
这样我们再访问的时候就不能访问以php结尾的文件了。
6. 设置虚拟主机
基于端口号
原理就是 Nginx 监听多个端口,根据不同的端口号,来区分不同的网站。
例如:
server{
listen 8001;
server_name localhost;
root /usr/share/nginx/html/html8001;
index index.html;
}
基于IP
基于IP和基于端口的配置几乎一样,只是把server_name
选项,配置成IP就可以了。例如:
server{
listen 80;
server_name 112.74.164.244;
root /usr/share/nginx/html/html8001;
index index.html;
}
使用域名
例如,我的顶级域名是zhuhe.site
,那么可以设置以下两个子域名:
- nginx.zhuhe.site :这个域名映射到默认的 Nginx 首页位置。
- nginx2.zhuhe.site : 这个域名映射到原来的8001端口的位置。
将原来的配置文件改为:
server {
listen 80;
server_name nginx.zhuhe.site;
...
}
新建配置文件为:
server{
listen 80;
server_name nginx2.zhuhe.site;
location / {
root /usr/share/nginx/html/html8001;
index index.html index.htm;
}
}
然后我们用平滑重启的方式,进行重启,这时候我们在浏览器中访问这两个网页。
7. 反向代理
先简单说明两个概念:
- 正向代理:简单来说就是你想访问目标服务器的权限,但是没有权限。这时候代理服务器有权限访问服务器,并且你有访问代理服务器的权限,这时候你就可以通过访问代理服务器,代理服务器访问真实服务器,把内容给你呈现出来。
- 反向代理:反向代理跟代理正好相反(需要说明的是,现在基本所有的大型网站的页面都是用了反向代理),客户端发送的请求,想要访问server服务器上的内容。发送的内容被发送到代理服务器上,这个代理服务器再把请求发送到自己设置好的内部服务器上,而用户真实想获得的内容就在这些设置好的服务器上。
如下图:
最简单的反向代理:
现在我们要访问 http://nginx2.zhuhe.site
然后反向代理到 https://blog.zhuhe.site
这个网站。我们直接在配置文件中进行修改。
server{
listen 80;
server_name nginx2.zhuhe.site;
location / {
proxy_pass https://blog.zhuhe.site;
}
}
一般我们反向代理的都是一个IP,但是我这里代理了一个域名也是可以的。其实这时候我们反向代理就算成功了,访问 http://nginx2.zhuhe.site
会显示 https://blog.zhuhe.site
的内容,但是浏览器地址栏的地址不会改变。
8. 适配移动端
看起来有点奇怪,因为现在自适应的网页那么多,而且框架也一大堆,为什么会出现 Nginx 的适配。
其实,这和一些网页的特性有关,有的网页例如淘宝,在手机端访问网页会出现信息过多,字体过小不容易点击的问题,这时候移动端和电脑端分开适配就显得很有必要。
如果你还不知道如何分辨自适应和代理适配,可以做一个简单的实验,用手机访问网页如果手机端和电脑端的域名有明显区别,那么就是服务器做的适配。
Nginx 通过内置变量$http_user_agent
,可以获取到请求客户端的userAgen
,就可以用户目前处于移动端还是PC端,进而展示不同的页面给用户。
配置如下:
server{
listen 80;
server_name nginx2.zhuhe.site;
location / {
root /usr/share/nginx/pc; # PC 网页所在文件夹
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
root /usr/share/nginx/mobile; # 移动端所在文件夹
}
index index.html;
}
}
9. Gzip 压缩
Gzip 是网页的一种网页压缩技术,经过 gzip 压缩后,页面大小可以变为原来的 30% 甚至更小。更小的网页会让用户浏览的体验更好,速度更快。gzip 网页压缩的实现需要浏览器和服务器的支持。
gzip最简单的配置如下:
http {
.....
gzip on;
gzip_types text/plain application/javascript text/css;
.....
}
你也可以在网页搜索「gzip 检测」来查看自己的网站是否支持和是否开启
10. root 和 alias
nginx指定文件路径有两种方式root和alias,指令的使用方法和作用域:
[root]
语法:root path
默认值:root html
配置段:http、server、location、if
[alias]
语法:alias path
配置段:location
root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上。
root的处理结果是:root路径+location路径
alias的处理结果是:使用alias路径替换location路径
注意:
假如server 中声明
root /usr/share;
那么此时声明
location / {
root /usr/html/www
}
此时就会覆盖掉server root
中的路径
假如此时声明
location /app {
}
那么此时所有的操作就是基于路径/usr/share/app
11. 简述本站的升级
由于之前的网站是前后端分离的,本来好几个组件应该放在不同的服务器上,但是我仅仅是想尝试一下就部署了,事实证明我的服务器确实带不起来,因此换用了现在的框架「typecho」比较轻量级。
部署过程其实比较简单,先用一键安装包安装 LNMP 环境,别说我为什么不一个一个装,我之前的服务在部署的时候就是被环境弄疯的。
本部分不是那么详细,如需详细资料可以看这里
在 SSH 里面,我们输入:
wget http://soft.vpser.net/lnmp/lnmp1.6.tar.gz -cO lnmp1.6.tar.gz && tar zxf lnmp1.6.tar.gz && cd lnmp1.6 && ./install.sh lnmp
一路 Default 和 yes 在中间要设置 mysql 的 root 密码,要记牢
提示 "Press any key to install...or Press Ctrl+c to cancel" 后,按回车键确认开始安装。
LNMP 脚本就会自动安装编译 Nginx、MySQL、PHP、phpMyAdmin 等软件及相关的组件
搭建完成你会看到下图:
添加域名:
lnmp vhost add
按提示完成初始化即可
之后上传 typecho 的安装文件即可在网页上实现图形化操作。
12. 小结
nginx 是属于运维的工作,但是好歹还是要了解的,毕竟作为一个程序猿还是希望有一个自己的网站的 ^_^