# CentOS 安装 Nginx
# 下载安装包
wget https://nginx.org/download/nginx-1.16.1.tar.gz |
# 解压缩
tar zxvf nginx-1.16.1.tar.gz -C ../module/ |
# 进入目录
cd nginx-1.16.1/ |
# 安装 nginx
# 安装 gcc | |
yum install -y gcc | |
# 安装 perl | |
yum install -y pcre pcre-devel | |
# 安装 zlib | |
yum install -y zlib zlib-devel |
make | |
make install |
安装到指定目录
./configure --prefix=/usr/local/nginx |
# 启动 Nginx
进入 /usr/local/nginx/sbin
目录
# 启动 | |
./nginx | |
# 快速停止 | |
./nginx -s stop | |
# 优雅关闭,在退出前完成已经接受的连续请求 | |
./nginx -s quit | |
# 重新加载配置 | |
./nginx -s reload |
# 关闭防火墙
systemctl stop firewalld.service |
# 禁止防火墙开机启动
systemctl disable firewalld.service |
# 放行端口
firewall-cmd --zone=public --add-port=80/tcp --permanent |
# 重启防火墙
firewall-cmd --reload |
# 查看 nginx 状态
ps -ef | grep nginx |
# 安装成系统服务
创建服务脚本
vi /usr/lib/systemd/system/nginx.service |
复制,路径请对应
[Unit] | |
Description=nginx - web server | |
After=network.target remote-fs.target nss-lookup.target | |
[Service] | |
Type=forking | |
PIDFile=/usr/local/nginx/logs/nginx.pid | |
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf | |
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf | |
ExecReload=/usr/local/nginx/sbin/nginx -s reload | |
ExecStop=/usr/local/nginx/sbin/nginx -s stop | |
ExecQuit=/usr/local/nginx/sbin/nginx -s quit | |
PrivateTmp=true | |
[Install] | |
WantedBy=multi-user.target |
重新加载系统服务
systemctl daemon-reload |
关闭服务
# 见上 |
启动服务
systemctl start nginx |
开机启动
systemctl enable nginx.service |
# 基本配置文件
# nginx.conf | |
worker_processes 1; #允许进程数量,建议设置为 cpu 核心数或者 auto 自动检测,注意 Windows 服务器上虽然可以启动多个 processes,但是实际只会用其中一个 | |
events { | |
#单个进程最大连接数(最大连接数 = 连接数 * 进程数) | |
#根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把 cpu 跑到 100% 就行。 | |
worker_connections 1024; | |
} | |
http { | |
#文件扩展名与文件类型映射表 (是 conf 目录下的一个文件) | |
include mime.types; | |
#默认文件类型,如果 mime.types 预先定义的类型没匹配上,默认使用二进制流的方式传输 | |
default_type application/octet-stream; | |
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为 on。如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,以平衡磁盘与网络 IO 处理速度。 | |
sendfile on; | |
#长连接超时时间,单位是秒 | |
keepalive_timeout 65; | |
#虚拟主机的配置 | |
server { | |
#监听端口 | |
listen 80; | |
#域名,可以有多个,用空格隔开 | |
server_name localhost; | |
#配置根目录以及默认页面 | |
location / { | |
root html; | |
index index.html index.htm; | |
} | |
#出错页面配置 | |
error_page 500 502 503 504 /50x.html; | |
#/50x.html 文件所在位置 | |
location = /50x.html { | |
root html; | |
} | |
} | |
} |
# 虚拟主机与域名解析
虚拟主机使用特殊的软硬件技术,把一台运行在因特网上的服务器主机分成一台台 “虚拟” 的主机,每一台虚拟主机都具有独立的域名,具有完整的 Internet 服务器(WWW、FTP、Email 等)功能,虚拟主机之间完全独立,并可由用户自行管理,在外界看来,每一台虚拟主机和一台独立的主机完全一样。
域名解析就是域名到 IP 地址的转换过程,IP 地址是网路上标识站点的数字地址,为了简单好记,采用域名来代替 ip 地址标识站点地址。域名的解析工作由 DNS 服务器完成。
# 域名、dns、ip 地址的关系
域名是相对网站来说的,IP 是相对网络来说的。当输入一个域名的时候,网页是如何做出反应的?
输入域名 ----> 域名解析服务器(dns)解析成 ip 地址 —> 访问 IP 地址 —> 完成访问的内容 —> 返回信息。
Internet 上的计算机 IP 是唯一的,一个 IP 地址对应一个计算机。
一台计算机上面可以有很多个服务,也就是一个 ip 地址对应了很多个域名,即一个计算机上有很多网站。
# IP 地址和 DNS 地址的区别
IP 地址是指单个主机的唯一 IP 地址,而 DNS 服务器地址是用于域名解析的地址。
一个是私网地址,一个是公网地址;
一个作为主机的逻辑标志,一个作为域名解析服务器的访问地址。
# IP 地址
IP,就是 Internet Protocol 的缩写,是一种通信协议,我们用的因特网基本是 IP 网组成的。
IP 地址就是因特网上的某个设备的一个编号。
IP 地址一般由网络号,主机号,掩码来组成。
IP 网络上有很多路由器,路由器之间转发、通信都是只认这个 IP 地址,类似什么哪?就好像你寄包裹,你的写上发件人地址,你的姓名,收件人地址,收件人姓名。
这个发件人地址就是你电脑的 IP 的网络号,你的姓名就是你的主机号。
收件人的地址就是你要访问的 IP 的网络号,收件人的姓名就是访问 IP 的主机号。
现在还有了更复杂的 IPV6, 还有 IPV9。
# DNS 是什么?
我们访问因特网必须知道对端的 IP 地址,可是我们访问网站一般只知道域名啊,怎么办?
这时候 DNS 就有用处了,电脑先访问 DNS 服务器,查找域名对应的 IP, 于是,你的电脑就知道要发包到 IP 地址了。
# ServerName 匹配规则
我们可以在同一个 servername 中配置多个域名
# 完整匹配
server 中可以配置多个域名,例如:
server_name test81.xzj520520.cn test82.xzj520520.cn; |
# 通配符匹配
使用通配符的方式如下:
server_name *.xzj520520.cn; |
需要注意的是精确匹配的优先级大于通配符匹配和正则匹配。
# 通配符结束匹配
使用通配符结束匹配的方式如下:
server_name www.xzj520520.*; |
# 正则匹配
正则匹配格式,必须以~开头,比如: server_name~^www\d+\.example\.net$;
。如果开头没有~,则 nginx 认为是精确匹配。在逻辑上,需要添加 ^
和 $
锚定符号。注意,正则匹配格式中。为正则元字符,如果需要匹配,则需要反斜线转义。如果正则匹配中含有 {
和 }
则需要双引号引用起来,避免 nginx 报错,如果没有加双引号,则 nginx 会报如下错误: directive "server_name" is not terminated by ";" in ...
。
# 特殊匹配格式
server_name "";
匹配 Host 请求头不存在的情况。
# 匹配顺序
- 精确的名字
- 以 * 号开头的最长通配符名称,例如 *.example.org
- 以号结尾的最长通配符名称,例如 mail
- 第一个匹配的正则表达式(在配置文件中出现的顺序)
# 优化
- 尽量使用精确匹配;
- 当定义大量
server_name
时或特别长的server_name
时,需要在http
级别调整server_names_hash_max_size
和server_names_hash_bucket_size
,否则nginx
将无法启动。
# 附录
~ 为区分大小写的匹配
~* 不区分大小写的匹配(匹配 firefox 的正则同时匹配 FireFox)
!~ 区分大小写不匹配
!~* 不区分大小写不匹配
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
* 重复零次或更多次前面一个字符
+ 重复一次或更多次前面一个字符
? 重复零次或一次前面一个字符
{n} 重复 n 次前面一个字符 {n,} 重复 n 次或更多次
{n,m} 重复 n 到 m 次
*? 重复任意次,但尽可能少重复
+? 重复 1 次或更多次,但尽可能少重复
?? 重复 0 次或 1 次,但尽可能少重复
{n,m}? 重复 n 到 m 次,但尽可能少重复
{n,}? 重复 n 次以上,但尽可能少重复
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了 x 以外的任意字符
[^abc] 匹配除了 abc 这几个字母以外的任意字符
(exp) 匹配 exp, 并捕获文本到 0…9
(?exp) 匹配 exp, 并捕获文本到名称为 name 的组里,也可以写成 (?'name’exp)
(?:exp) 匹配 exp, 不捕获匹配的文本,也不给此分组分配组号
(?=exp) 零宽断言,匹配 exp 前面的位置
(?<=exp) 匹配 exp 后面的位置
(?!exp) 匹配后面跟的不是 exp 的位置
(?<!exp) 匹配前面不是 exp 的位置
(?#comment) 注释,这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读
# 反向代理在系统结构中的应用场景
反向代理方式是指以代理服务器来接受 Internet 上的连接请求,然后将请求转发给内部网络上的服务器;并将从服务器上得到的结果返回给 Internet 上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
反向代理服务器通常有两种模型,一种是作为内容服务器的替身,另一种作为内容服务器集群的负载均衡器。
- 作内容服务器的替身
如果您的内容服务器具有必须保持安全的敏感信息,如信用卡号数据库,可在防火墙外部设置一个代理服务器作为内容服务器的替身。当外部客户机尝试访问内容服务器时,会将其送到代理服务器。实际内容位于内容服务器上,在防火墙内部受到安全保护。代理服务器位于防火墙外部,在客户机看来就像是内容服务器。
当客户机向站点提出请求时,请求将转到代理服务器。然后,代理服务器通过防火墙中的特定通路,将客户机的请求发送到内容服务器。内容服务器再通过该通道将结果回传给代理服务器。代理服务器将检索到的信息发送给客户机,好像代理服务器就是实际的内容服务器。如果内容服务器返回错误消息,代理服务器会先行截取该消息并更改标头中列出的任何 URL,然后再将消息发送给客户机。如此可防止外部客户机获取内部内容服务器的重定向 URL。
这样,代理服务器就在安全数据库和可能的恶意攻击之间提供了又一道屏障。与有权访问整个数据库的情况相对比,就算是侥幸攻击成功,作恶者充其量也仅限于访问单个事务中所涉及的信息。未经授权的用户无法访问到真正的内容服务器,因为防火墙通路只允许代理服务器有权进行访问。
- 作为内容服务器的负载均衡器
可以在一个组织内使用多个代理服务器来平衡各 Web 服务器间的网络负载。在此模型中,可以利用代理服务器的高速缓存特性,创建一个用于负载平衡的服务器池。此时,代理服务器可以位于防火墙的任意一侧。如果 Web 服务器每天都会接收大量的请求,则可以使用代理服务器分担 Web 服务器的负载并提高网络访问效率。
对于客户机发往真正服务器的请求,代理服务器起着中间调停者的作用。代理服务器会将所请求的文档存入高速缓存。如果有不止一个代理服务器,DNS 可以采用 “轮询法” 选择其 IP 地址,随机地为请求选择路由。客户机每次都使用同一个 URL,但请求所采取的路由每次都可能经过不同的代理服务器。
可以使用多个代理服务器来处理对一个高用量内容服务器的请求,这样做的好处是内容服务器可以处理更高的负载,并且比其独自工作时更有效率。在初始启动期间,代理服务器首次从内容服务器检索文档,此后,对内容服务器的请求数会大大下降。
# 反向代理
# 示例
#虚拟主机的配置 | |
server { | |
#监听端口 | |
listen 80; | |
#域名,可以有多个,用空格隔开 | |
server_name test80.xzj520520.cn; | |
#配置根目录以及默认页面 | |
location / { | |
proxy_pass http://192.168.8.102; | |
# root /www/test80; | |
# index index.html index.htm; | |
} | |
#出错页面配置 | |
error_page 500 502 503 504 /50x.html; | |
#/50x.html 文件所在位置 | |
location = /50x.html { | |
root html; | |
} | |
} |
proxy_pass
后接要代理到的 url
# location 配置规则
- 匹配模式及顺序举例
location | 说明 |
---|---|
location = /url | = 开头表示精确匹配,只有完全匹配上才能生效 |
location ^~ /url | ^~ 开头对 URL 路径进行前缀匹配,并且在正则之前 |
location ~ pattern | ~ 开头表示区分大小写的正则匹配 |
location /url | 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后,如果没有正则命中,命中最长的规则 |
location / | 通用匹配,任何未匹配到其它 location 的请求都会匹配到,相当于 switch 中的 default |
- location 是否以 “/” 结尾
在 ngnix
中 location
进行的是模糊匹配
没有 “/” 结尾时,location /abc/def 可以匹配 /abc/defghi 请求,也可以匹配 /abc/def/ghi 等
而有 “/” 结尾时,location /abc/def/ 不能匹配 /abc/defghi 请求,只能匹配 /abc/def/anything 这样的请求
# proxy_pass 配置规则
配置 proxy_pass 时,当在后面的 url 加上了 /,相当于是绝对路径,则 Nginx 不会把 location 中匹配的路径部分加入代理 url。
如果配置 proxy_pass 时,后面没有 /,Nginx 则会把匹配的路径部分加入代理 uri。
server { | |
listen 8081; | |
server_name localhost; | |
location / { | |
root html; | |
index index.html index.htm; | |
} | |
#情景 1:proxy_pass 后有 / ,表绝对路径,不把匹配部分加入最终代理路径(location 和 proxy_pass 结尾一致) | |
#访问地址:http://localhost:8081/WCP.Service/wcp/modeladapter/download/asc.shtml | |
#最终代理:http://10.194.171.7:13082/modeladapter/download/asc.shtml | |
location /WCP.Service/wcp/modeladapter/download/ { | |
proxy_pass http://10.194.171.7:13082/modeladapter/download/; | |
} | |
#访问地址:http://localhost:8081/model/asc.shtml | |
#最终代理:http://127.0.0.1:8082/model/asc.shtml | |
location /model/ { | |
proxy_pass http://127.0.0.1:8082/model/; | |
} | |
#情景 2:proxy_pass 后有 / ,表绝对路径,不把匹配部分加入最终代理路径(location 和 proxy_pass 结尾不一致) | |
#访问地址:http://localhost:8081/model/asc.shtml | |
#最终代理:http://127.0.0.1:8082/asc.shtml | |
location /model/ { | |
proxy_pass http://127.0.0.1:8082/; | |
} | |
#情景 3:proxy_pass 后没有 / ,Nginx 会把匹配部分带到代理的 url | |
#访问地址:http://localhost:8081/model/asc.shtml | |
#最终代理:http://127.0.0.1:8082/model/asc.shtml | |
location /model/ { | |
proxy_pass http://127.0.0.1:8082; | |
} | |
#情景 4 | |
#访问地址:http://localhost:8081/model/asc.shtml | |
#最终代理:http://127.0.0.1:8082/AAAmodel/asc.shtml | |
location /model/ { | |
proxy_pass http://127.0.0.1:8082/AAA; | |
} | |
#情景 5 | |
#访问地址:http://localhost:8081/model/asc.shtml | |
#最终代理:http://127.0.0.1:8082/asc.shtml | |
location /model { | |
proxy_pass http://127.0.0.1:8082/; | |
} | |
#情景 6 | |
#访问地址:http://localhost:8081/modelBBB/asc.shtml | |
#最终代理:http://127.0.0.1:8082/asc.shtml | |
location /model { | |
proxy_pass http://127.0.0.1:8082/; | |
} | |
location /opus-front-sso { | |
proxy_pass http://10.194.170.94/opus-front-sso; | |
} | |
location /awater { | |
proxy_pass http://10.194.170.94/awater; | |
} | |
} |
# 负载均衡
# 轮询模式
#定义一组服务器 | |
upstream httpds{ | |
server 192.168.8.102:80; | |
server 192.168.8.103:80; | |
} | |
#虚拟主机的配置 | |
server { | |
#监听端口 | |
listen 80; | |
#域名,可以有多个,用空格隔开 | |
server_name test80.xzj520520.cn; | |
#配置根目录以及默认页面 | |
location / { | |
proxy_pass http://httpds; | |
# root /www/test80; | |
# index index.html index.htm; | |
} | |
#出错页面配置 | |
error_page 500 502 503 504 /50x.html; | |
#/50x.html 文件所在位置 | |
location = /50x.html { | |
root html; | |
} | |
} |
# 权重模式
#定义一组服务器 | |
upstream httpds{ | |
server 192.168.8.102 weight=10; | |
server 192.168.8.103 weight=1; | |
# server 192.168.8.102 weight=10 down; #down 表示不参与负载均衡 | |
# server 192.168.8.102 weight=10 backup; #backup 表示是备用服务器,没有服务器可用的时候使用 | |
} | |
#虚拟主机的配置 | |
server { | |
#监听端口 | |
listen 80; | |
#域名,可以有多个,用空格隔开 | |
server_name test80.xzj520520.cn; | |
#配置根目录以及默认页面 | |
location / { | |
proxy_pass http://httpds; | |
# root /www/test80; | |
# index index.html index.htm; | |
} | |
#出错页面配置 | |
error_page 500 502 503 504 /50x.html; | |
#/50x.html 文件所在位置 | |
location = /50x.html { | |
root html; | |
} | |
} |
# 其他策略
- ip_hash
根据客户端的 ip 地址转发同一台服务器,可以保持会话,但是很少用这种方式去保持会话,例如我们当前正在使用 wifi 访问,当切换成手机信号访问时,会话就不保持了。
- least_conn
最少连接访问,优先访问连接最少的那一台服务器,这种方式也很少使用,因为连接少,可能是由于该服务器配置较低,刚开始赋予的权重较低。
- url_hash(需要第三方插件)
根据用户访问的 url 定向转发请求,不同的 url 转发到不同的服务器进行处理(定向流量转发)。
- fair(需要第三方插件)
根据后端服务器响应时间转发请求,这种方式也很少使用,因为容易造成流量倾斜,给某一台服务器压垮。
# 使用阿里云配置 https
使用阿里云配置 https
# 参考链接
参考链接