Nginx入门
Nginx版本
- —->>Nginx开源版:赤裸裸的一个反向代理服务器,负载均衡器;
- —->>Nginx Plus商业版:全家桶,什么都有;
- —->>openresty:以Lua脚本形式扩展的Nginx;
- —->>Tengine:以C语言的形式,以模块化的开发丰富增强了Nginx的原始功能;
Nginx开源版安装
1、将Nginx安装包上传到服务器:
2、解压到指定目录:
命令:tar -zxvf nginx-1.21.6.tar.gz -C /opt/module/
3、进入到nginx-1.21.6
目录里面,进行编译安装
命令:./configure --prefix=/usr/local/nginx
(装在/usr/local/nginx
目录下)
如果出现错误1:checking for OS
- Linux 3.10.0-693.el7.x86_64 x86_64 checking for C compiler … not found ./configure: error: C compiler cc is not found
安装gcc:yum install -y gcc
如果出现错误2:
./configure: error: the HTTP rewrite module requires the PCRE library. You can either disable the module by using —without-http_rewrite_module option, or install the PCRE library into the system, or build the PCRE library statically from the source with nginx by using —with-pcre=
option.
安装perl库:yum install -y pcre pcre-devel
如果出现错误3:
./configure: error: the HTTP gzip module requires the zlib library. You can either disable the module by using —without-http_gzip_module option, or install the zlib library into the system, or build the zlib library statically from the source with nginx by using —with-zlib=
option.
安装zlib库:yum install -y zlib zlib-devel
成功安装如下:
4、接下来进行编译并编译安装
命令1:make
命令2:make install
Nginx启动关闭等
启动
在nginx安装目录里面的sbin
目录执行启动命令:./nginx
在浏览器可以访问即证nginx开启成功(不写端口号默认是80)
关闭
进入安装好的目录/usr/local/nginx/sbin
命令1:./nginx -s stop
:快速停止;
命令2:./nginx -s quit
:优雅关闭,在退出前完成已经接受的连接请求(不会接受新请求,只是把原来没干完的活干完);
重新加载配置
命令:./nginx -s reload
:更改完配置文件之后立即生效而无需重启nginx服务器,机制就是把原来执行任务的线程暂时停掉,重新开启一个线程去读取最新的配置文件;
安装成系统服务
1、创建服务脚本
vim /usr/lib/systemd/system/nginx.service
2、服务脚本内容
[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
3、重新加载系统服务
4、系统服务方式启动
命令:systemctl start nginx.service
也可以设置为开机自启动:systemctl enable nginx.service
Nginx的目录结构和基本运行原理
目录结构
基本运行原理
Nginx基础配置与应用场景
Nginx.conf
主配置文件
去除原本自带的注释后的最简化配置
worker_processes 1; #开启的工作的进程个数,即子进程的个数
events { #事件驱动模块
worker_connections 1024; #每个worker进程创建多少连接
}
http {
include mime.types; #引入其他的配置文件mime.types
#mime.types配置文件记录所有请求的头,头里面标明当前我给你返回文件是什么类型的
default_type application/octet-stream;
#如果文件类型不包含在mime.types中,
#那么就以application/octet-stream流的这种方式传输给客户端
sendfile on;
#数据零拷贝
keepalive_timeout 65; #保持连接的超时时间
server { #虚拟主机vhost,可以配置多个虚拟主机
listen 80; #监听的端口号,来分辨不同的主机
server_name localhost; #域名,主机名
location / { #URI,讲解如下:
#http://atguigu.com/xx/yy...这个完整的是一个URL
#URI指的就是http://atguigu.com/后面的资源的路径
root html; #相对路径,指的就是Nginx目录下的html目录
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
#发生服务器端错误时展示的页面
location = /50x.html {
root html;
}
}
}
mime.types配置文件
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
...
sendfile关闭off的情况
sendfile开启on的情况
虚拟主机与域名解析
浏览器、Nginx与http协议
虚拟主机原理
产生的原因:一台主机公布一个公网ip就可以提供访问了,但是如果绑定到这1个IP地址上这一台主机不是时时都有很充足的访问量,这样这台主机上的资源(cpu、内存…)就浪费了,虚拟主机就可以把1台主机虚拟出来很多主机,原来是通过域名来访问这台主机,1个域名对应1个ip地址
,现在是多个域名对应1个ip地址上
,由Nginx服务器判断访问的是哪个域名,然后指向不同站点的目录就可以了;
域名解析与泛域名解析实战
本机hosts解析域名模仿域名解析
win10系统,目录:C:\Windows\System32\drivers\etc\
修改hosts文件,比如添加si.com 124.70.84.192
,这样访问si.com
就相当于访问124.70.84.192
了(域名与ip前后位置可以调换)
泛域名解析
配置多个站点
1、首先在/home/www/www
目录下和/home/www/vod
目录下分别创建一个index.html文件;
2、nginx主配置文件nginx.conf
修改原虚拟主机,添加多个虚拟主机;
#虚拟主机Vhost1
server {
listen 80; #监听的端口号还是默认的80
server_name localhost; #域名,主机名,如果购买了域名也可以在这里写购买的域名
location / {
root /home/www/www; #绝对路径/home/www/www
index index.html index.htm; #上面绝对路径下的访问文件
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
#虚拟主机Vhost2
server {
listen 88; #监听的端口号为88
server_name localhost;
location / {
root /home/www/vod; #绝对路径/home/www/vod
index index.html index.htm; #上面绝对路径下的访问文件
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
由于将nginx配置为了系统服务,所以可以直接使用命令systemctl reload nginx
来重新加载配置文件;
3、测试:访问80端口和88端口可以访问到配置的html文件;
servername匹配规则
对于购买了域名的服务器,匹配时会根据**nginx.conf**
配置文件的前后配置顺序来进行匹配,如果前面的虚拟主机匹配上了就不会再考虑后面的虚拟主机【先写哪个先匹配哪个】,如果都没有匹配上就会采用第一个虚拟主机;
完整匹配
例如服务器的域名是java.com
,而配置的虚拟主机1的server_name
是www.java.com
,虚拟主机2的server_name
是vod.java.com
,此时如果访问的是vod1.java.com
的话两个都不匹配那就会访问第一个虚拟主机;如下:
#虚拟主机Vhost1
server {
listen 80; #监听的端口号还是默认的80
server_name www.java.com; #域名,主机名,如果购买了域名也可以在这里写购买的域名
location / {
root /home/www/www; #绝对路径/home/www/www
index index.html index.htm; #上面绝对路径下的访问文件
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
#虚拟主机Vhost2
server {
listen 80;
server_name vod.java.com;
location / {
root /home/www/vod; #绝对路径/home/www/vod
index index.html index.htm; #上面绝对路径下的访问文件
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
nginx也可以同时配置两个域名指向同一主机,如下:
#虚拟主机Vhost2
server {
listen 80;
server_name vod.java.com vod1.java.com;
#同时配置两个域名指向同一主机,中间以空格分隔
location / {
root /home/www/vod;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
通配符匹配
配置为:
server_name *.java.com;
以通配符来进行匹配,表示以任意前缀访问,比如xxx.java.com
,yyy.java.com
….都可以与此虚拟主机进行匹配;
通配符结束匹配
配置为:
server_name www.java.*;
以通配符结束来进行匹配,表示以任意后缀访问,比如www.java.ccm
,www.java.ppp
….都可以与此虚拟主机进行匹配;
正则匹配
server_name ~^[0-9]+\.mmban\.com$;
以通正则匹配来进行匹配,表示任意以数字开头(可以有多个),以.com
为结束,域名为mmban
都可以与此主机匹配;
域名解析相关企业项目实战技术架构
多用户二级域名
短网址
httpdns
dns服务器走UDP协议,httpdns走的是http协议;
反向代理系列
介绍
Nginx起到代理服务器的作用;
网关:指的就是代理服务器,即访问互联网的入口,可以有多个。网关起到中转作用,用户需要将请求发送到网关,网关再将请求发送给特定的服务器,收到返回数据时同样也要经过网关,而不能直接放回数据给用户;
DR模型:
- 隧道式代理就是上面的方向代理,即请求和返回数据都需要经过Nginx服务器;
- 而DR模型就是请求经过代理服务器,而数据返回时直接返回给用户,不经过代理服务器;
- DR模型是lvs提供的功能,lvs是一个更高性能的负载均衡器,性能比Nginx更高,但功能不如Nginx丰富;
反向代理服务器在系统架构中的应用场景
Nginx还可以伪装真实的访问地址,比如把.../itemService?id=100
伪装为.../item/100
基于反向代理的负载均衡器
反向代理配置
实现通过自己的nginx服务器反向代理到尚硅谷官网: ```nginx …虚拟主机2
server { listen 88; server_name localhost;
location / {
proxy_pass http://www.atguigu.com; #使用proxy_pass关键字代理到尚硅谷的官网
#root /home/www/vod; #使用代理的话就需要将nginx中指向的特定路径下的文件注掉
#index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
} …
此时再访问自己nginx服务器的88号端口:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/23158036/1649923596146-bacee05f-ee03-400d-ba79-3a8331eb6b74.png#clientId=ufe3047c8-04d3-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=386&id=u31921861&margin=%5Bobject%20Object%5D&name=image.png&originHeight=434&originWidth=576&originalType=binary&ratio=1&rotation=0&showTitle=false&size=149590&status=done&style=none&taskId=ue9dc3119-9733-4c94-884a-75a717c5355&title=&width=512)<br />**注意:**
1. 只能代理http协议的服务器,不支持反向代理到https服务器,https服务器需要和域名证书对应上;
1. 真正的反向代理上面的地址栏里仍然还是nginx服务器的地址,如果上面地址栏里面是被代理服务器的地址就不是反向代理,因为里面执行了重定向操作,这样请求就不会在经过nginx服务器了;
1. 同样也可以直接代理本地的服务器,直接`proxy_pass http://ip号/;`即可。
<a name="HoXM7"></a>
## 负载均衡配置
首先准备三台nginx服务器虚拟机,分别是`192.168.80.130`,`192.168.80.131`,`192.168.80.131`;其中`192.168.80.130`服务器通过hosts文件模拟绑定了域名`www.mmban.com`;<br />这里把`192.168.80.130`服务器只作为负载均衡器使用,真正访问的机器是`192.168.80.131`和`192.168.80.131`;
```nginx
#配置负载均衡,和server一个级别
upstream httpdns{
server 192.168.80.131;
server 192.168.80.132;
}
#虚拟主机vhost1
server {
listen 80;
server_name www.mmban.com;
location / {
proxy_pass http://httpdns; #"http://"后面的名字httpdns可以随意写,上面有配置
#root /home/www/vod;
#index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
这样的话访问负载均衡器的地址www.mmban.com
的话就会显示192.168.80.131
和192.168.80.131
两台机器的内容,每刷新一下换一台机器,也就是说,这样配置默认的负载均衡策略是轮询,雨露均沾,每台机器一次轮着来;
负载均衡策略
权重weight、down、backup
【权重的具体概念dubbo笔记中有记】
配置权重weight:
#配置负载均衡,和server一个级别
upstream httpdns{
server 192.168.80.131 weight=1;
server 192.168.80.132 weight=3;
}
每访问4次中,1次访问192.168.80.131
,3次访问192.168.80.132
;
如果某台机器出现故障,可以让它先down下线。如下:
#配置负载均衡,和server一个级别
upstream httpdns{
server 192.168.80.131 weight=1 down;
#如果在后面down的话那这台主机就不参与负载均衡了,就下线了
....
}
backup表示备用机,即当所有机器都出故障都down或者都宕机了的时候它再上:
#配置负载均衡,和server一个级别
upstream httpdns{
server 192.168.80.131 weight=1 backup;
#只有没有机器可以用了才用这台机器
....
}
其余负载均衡策略
默认情况下使用轮询方式,逐一转发,这种方式适用于无状态请求。但它无法保持会话,比如访问tomcat服务器,通常是需要登陆的,登陆后会生成特定的cookie和session,但是如果轮询到另一台
tomcat服务器的话,那么此时的cookie和session就对不上或者根本就没有session,这时就需要再次登录;
ip_hash
least_conn
url_hash
fair
需要第三方插件,根据后端服务器响应时间转发请求
这些负载均衡策略都不常用,因为都无法实现动态上下线服务;
动静分离
使用动静分离的场景
原理
适用于中小新网站,因为中小新网站的并发量并不高,并且静态资源并不多,可以把静态资源上传到Nginx服务器上,
最简单的Nginx动静分离配置
首先准备两台服务器192.168.80.132
和124.70.84.192
,其中124.70.84.192
作为tomcat服务器,并放上项目;192.168.80.132
用来做Nginx服务器,起到反向代理的作用,并用来做动静分离;
①原来的项目页面如下:
②先将页面文件传到tomcat服务器:
③再将静态文件传到Nginx服务器:
④并在Nginx服务器的主配置文件中配置路径:
....
server {
listen 80;
server_name localhost;
location / { #直接一个斜杠“/”这个是默认的匹配规则,优先级最低
proxy_pass http://124.70.84.192:8080/TestWork/pages/index.html;
}
location /css {
root html; #root目录在前,location目录在后,两者拼接成为静态资源最完整的路径;
} #例如这里静态资源的路径是“nginx安装目录/html/css”,这就是配置的此静态资源的路径;
location /js {
root html;
}
location /img {
root html;
}
location /fonts {
root html;
}
....
}
...
⑤由于tomcat服务器没有静态页面,直接访问页面如下,没有任何格式:
⑥此时做完了最简单的动静分离,通过Nginx服务器采用反向代理访问如下:
使用正则配置动静分离
当我们的静态资源过多时,直接这样一个个配置location
是不现实的,于是我们可以用正则配置静态资源,将多个静态资源配置合并成为1个
...
location ~*/(js|img|css|fonts) { #“~”表示要开始正则了,“*”表示不区分大小写
root html; #“(js|img|css|fonts)”表示可以是js|img|css|fonts中的任意一个
}
...
补充:nginx和tomcat处理静态资源的能力相差并没有那么大;
URLRewrite
URLRewrite的配置
location / { #正则表达式:^表示以什么开始,$表示以什么结尾
rewrite ^/2.html$ /index.jsp?pageNum=2 break;
#首先写隐藏地址,然后写真实的地址,最后写flag标记比如break
#这样浏览器访问虚拟地址的时候服务器就会访问真实地址并返回页面给浏览器
proxy_pass http://124.70.84.192:8080/TestWork/pages/index.html;
}
flag标记说明:
- last:本条规则匹配完成后,继续向下匹配新的location URI规则;
- break:本条规则匹配完成即终止,不再匹配后面的任何规则;
- redirect:返回302临时重定向,浏览器地址会显示跳转后的URL地址(显示真实地址);
permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址(显示真实地址);
URLRewrite+负载均衡+反向代理
192.168.80.132
为nginx反向代理服务器;192.168.80.130
,192.168.80.131
,124.70.84.192
为应用服务器;架构
nginx网关服务器配置
此时nginx有反向代理,负载均衡,动静分离,URLRewrite的功能,就不能单纯称它为反向代理服务器,称它为网关服务器; ```nginx worker_processes 1; events { worker_connections 1024; }
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream mydns{ #负载均衡配置(server后面只能配置ip+端口号,不能跟真实路劲) server 124.70.84.192:8080 weight=3; server 192.168.80.130 weight=1; server 192.168.80.131 weight=1; } server { listen 80; server_name localhost; location / { proxy_pass http://mydns; #实现反向代理 rewrite ^/([0-9]+).html$ /?pageNumber=$1 break;
#URLRewrite隐藏真实访问路径
}
location ~*/(js|img|css|fonts) { #正则表达式方式便捷实现动静分离
root html;
}
#location /css {
# root html;
#}
#location /js {
# root html;
#}
#location /img {
# root html;
#}
#location /fonts {
# root html;
#}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
- `$1,$2...`是表示的小括号里的内容;
- `$1`是第一个小括号里的,`$2`是第2个小括号里的;
- `([0-9]+)`:表示多个0-9之间的数字;
<a name="nc3on"></a>
### 测试
![image.png](https://cdn.nlark.com/yuque/0/2022/png/23158036/1649991571168-1d62a4df-1b94-466c-a7ec-51a5afd3afb0.png#clientId=u080254f6-336b-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=393&id=u736edb41&margin=%5Bobject%20Object%5D&name=image.png&originHeight=393&originWidth=1058&originalType=binary&ratio=1&rotation=0&showTitle=false&size=89959&status=done&style=none&taskId=u7abd1d16-1019-4249-b688-469fb11b0ec&title=&width=1058)
<a name="CLLQE"></a>
## 防盗链
【防盗链就是存在我们自己服务器上的资源只能由我们自己服务器访问,其他引用的不能访问】
<a name="YMmnF"></a>
### 原理
当我们访问一个页面时,这个页面会引用一些css静态文件等,它还会多次请求当前这个站点,再次请求时,它会在请求头里面有一个`Referer`属性,比如`Referer: http://192.168.80.132/888.html`,表示是从这个页面被引用来的;
- 注意这个`Referer`属性只有在二次访问或多次访问才有,也就是说为访问**内联的资源**再次访问服务器时会在请求头上加上`Referer`表示是从哪个页面来的;
- 这些是浏览器完成的;
同样我们用反向代理访问时如果访问内联资源同样会带这个`Referer`属性,此时我们就可以根据这个`Referer`判断是否合法,可以防止其他网站访问我们的内联资源;
<a name="M5ob6"></a>
### 防盗链基本配置与none
首先准备三台服务器:
- `124.70.84.192`**tomcat**服务器,存放页面资源;
- `192.168.80.132`**nginx**反向代理服务器,同时存放静态资源;
- `proxy_pass http://124.70.84.192:8080/TestWork/pages/index.html;`
- `192.168.80.130`盗链服务器,用来盗链反向代理服务器的资源,同时为盗链服务器配置一个域名`www.mmban.com`;
- `proxy_pass http://192.168.80.132;`
刚开始是完全能够盗掉的:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/23158036/1649995960740-937d901e-10aa-4e2d-8191-d2e9055fa14d.png#clientId=u080254f6-336b-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=210&id=u72e91a40&margin=%5Bobject%20Object%5D&name=image.png&originHeight=263&originWidth=1229&originalType=binary&ratio=1&rotation=0&showTitle=false&size=269367&status=done&style=none&taskId=u0bfc17ae-028b-4bbd-8420-3ff8130c5c3&title=&width=983.2)<br />此时要防止`192.168.80.130`这台服务器盗链资源;<br />1、首先在反向代理服务器配置文件配置相关内容:
```nginx
...
location ~*/(js|img|css|fonts) { #防盗链这些资源
valid_referers none 192.168.80.132;
#指的是来源的网址是否包含192.168.80.132;
#生产环境这里一般是配置域名的;
#参数none表示二次转发时有Refer检测访问地址是否有这个ip然后再根据情况拦截,
#如果是直接访问的话没有Refer是可以访问到的;
if ($invalid_referer) {
return 403; #检测之后无效的引用(即检测不到)返回403
}
root html;
}
...
2、通过反向代理服务器可以正常访问如下:
通过盗链服务器则访问不到静态资源如下:
但是直接访问静态资源是可以访问到的因为配置了参数none
,如下:
其余还有以下参数:
- blocked:检测
Referer
头域的值被防火墙或者代理服务器删除或伪装的情况。这种情况该头域的值不以http://
或https://
开头也可以访问。curl测试防盗链
用浏览器测试的话浏览器为了访问观感更好会在各个地方设置缓存,有时候刷新缓存会很不方便,而curl则是更纯粹的测试;
1、安装Curl
命令:yum install -y curl
;
2、使用curl测试
命令:curl -I http://xxxx
:不展示内容,只是返回响应头信息
3、带引用
命令:curl -e "http://baidu.com" -I http://xxx
:测试二次引用的地址,即Refer,同样也是返回响应头信息;例如这里的Refer是http://baidu.com
;
测试如下:[root@lemon-02 ~]# curl -I http://192.168.80.130/img/SiLie04.jpg HTTP/1.1 200 OK Server: nginx/1.21.6 Date: Fri, 15 Apr 2022 08:03:19 GMT Content-Type: image/jpeg Content-Length: 50400 Connection: keep-alive Last-Modified: Thu, 14 Apr 2022 11:56:55 GMT ETag: “62580c07-c4e0” Accept-Ranges: bytes [root@lemon-02 ~]# curl -e “http://192.168.80.130/“ -I http://192.168.80.130/img/SiLie04.jpg HTTP/1.1 403 Forbidden Server: nginx/1.21.6 Date: Fri, 15 Apr 2022 08:06:23 GMT Content-Type: text/html Content-Length: 153 Connection: keep-alive
盗链资源返回页面或图片
页面
...
location ~*/(js|img|css|fonts) {
valid_referers none 192.168.80.132;#值的是来源的网址是否包含192.168.80.132
if ($invalid_referer) {
return 403; #检测之后无效的引用(即检测不到)返回403
}
root html;
}
error_page 403 /403.html;
location = /403.html {
root html;
}
...
如果盗链资源返回的就是html
目录下的403.html
页面;
图片
如果盗链的是图片,那么是以图片的形式显示,盗链返回页面就显示不出来了,这时可以返回防盗链图片:
location ~*/(js|img|css|fonts) {
valid_referers none 192.168.80.132;#值的是来源的网址是否包含192.168.80.132
if ($invalid_referer) {
#return 403; #检测之后无效的引用(即检测不到)返回403
rewrite ^/ /403.jpg break;
#“^/”:使用正则表达式,表示以“/”开头的路径;
}
root html;
}
直接用URLRewrite的方式实现地址转换来实现显示盗链图片;
高可用配置
安装keepalived
yum安装:yum install -y keepalived