Ari的小跟班

  :: :: 博问 :: 闪存 :: :: :: :: 管理 ::

参考Nginx学习 | 何叨叨的个人博客 (heyingjiee.github.io)尚硅谷Nginx教程-bilibili,感谢作者和尚硅谷。

Nginx介绍

​ 虚拟机安装就略过了。

  • Nginx开源版 http://nginx.org/en/

    官方原始的Nginx版本

  • Nginx plus商业版

    开箱即用,集成了大量功能

  • Open Resty https://openresty.org/cn/

    OpenResty是一个基于Nginx与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。更适用于需要大量二次开发的场景,有极强的扩展性

  • Tengine https://tengine.taobao.org/

    由淘宝网发起的Web服务器项目。它在Nginx 的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网 天猫商城 等得到了很好的检验。相比于Open Resty,扩展性不够强,但是能够满足绝多数使用场景

Nginx安装

​ 下载Nginx官方安装包http://nginx.org/en/download.html

1.解压安装包

​ 上传到虚拟机目录里,我将安装包解压到了/usr/software/下,使用命令tar -zxvf进行解压,得到/usr/software/nginx-1.23.3

2.安装依赖库

#安装C编译器
yum install -y gcc

#安装pcre库
yum install -y pcre pcre-devel

#安装zlib
yum install -y zlib zlib-devel

3.安装

./configure --prefix=/usr/local/nginx #使用prefix选项指定安装的目录
make
make install

4.启动

cd /usr/local/nginx/sbin

ls # 里面是一个nginx的可执行文件

./nginx # 启动这个可执行

5.关闭防火墙

systemctl stop firewalld

6.补充Nginx命令

./nginx -s stop #快速停止
./nginx -s quit #完成已接受的请求后,停止
./nginx -s reload #重新加载配置
./nginx -t #检查nginx配置是否正确

7.查看nginx状态

ps -ef | grep nginx

启动时:

​ 可以看到master进程和worker进程都存在。如果nginx处在停止状态,则只会有最下面一个的进程,masterworker进程都不会存在。

8.注册系统服务,通过系统服务的方式启动nginx

(1)创建服务脚本:vim /usr/lib/systemd/system/nginx.service

(2)其中的内容为:

​ 如果安装的目录不是在/usr/local/nginx下的话,需要修改目录地址。

[Unit] 
Description=nginx
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)重新加载系统服务:systemctl daemon-reload

​ 之后启动nginx服务就可以使用systemctl start nginx,我们可以用systemctl status nginx查看nginx状态。

​ 设置成开机启动,使用命令systemctl enable nginx.service

Nginx目录

​ Nginx一般安装在/usr/local/nginx目录下(安装时--prefix可指定安装目录),目录结构如下。

conf #配置文件
	|-nginx.conf # 主配置文件
	|-其他配置文件 # 可通过那个include关键字,引入到了nginx.conf生效
	
html #静态页面

logs
	|-access.log #访问日志(每次访问都会记录)
	|-error.log #错误日志
	|-nginx.pid #进程号,会标记出当前nginx进程的进程号
	
sbin
	|-nginx #主进程文件
	
*_temp #运行时,生成临时文件

Nginx运行流程

1.首先启动/sbin/nginx进程,开启master进程。

2.master进程会读取并校验配置文件,检查配置文件是否正确。

3.启动worker子进程,此时worker已经获取到了配置文件(conf文件)

4.请求过来之后,worker会根据请求的路径以及配置文件去找对应的响应信息。

​ worker是进程,会有多个,master进程只有一个用于协调各个worker之间的工作。

Nginx配置文件

​ 后面学习Nginx配置,每次修改配置文件,一定要重载才能生效。systemctl reload nginx

​ 将配置文件的注释部分去掉之后,配置文件如下所示:

worker_processes  1; # 启动的worker进程数

events {
    worker_connections  1024; #每个worker进程的连接数
}


http {
    include  mime.types; #include是引入关键字,这里引入了mime.types这个配置文件(同在conf目录下,mime.types是用来定义,请求返回的content-type)
    default_type  application/octet-stream; #mime.types未定义的,使用默认格式application/octet-stream

    sendfile   on; #详情,见下文
    keepalive_timeout  65; #长链接超时时间
	
	#一个nginx可以启用多个server(虚拟服务器 vhost),每个server就是一个主机
    server {
        listen       80;#监听端口80
        server_name  localhost;  #接收的域名 或者 主机名

        location / { 
            root   html; #根目录指向html目录
            index  index.html index.htm; #域名/index 指向 index.html index.htm文件
        }

        error_page   500 502 503 504  /50x.html; # 服务器错误码为500 502 503 504,转到"域名/50x.html"
        location = /50x.html {# 指定到html文件夹下找/50x.htm
            root   html;
        }

    }
}

核心配置

1.worker_processes:启动的worker子进程的数量,基本是对应到CPU物理的内核数量。

2.events

3.http

(1)include表示引入文件,这里引入了同目录下的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;
    application/rss+xml                              rss;

    text/mathml                                      mml;
    text/plain                                       txt;
    text/vnd.sun.j2me.app-descriptor                 jad;
    text/vnd.wap.wml                                 wml;
    text/x-component                                 htc;

    image/avif                                       avif;
    image/png                                        png;
    image/svg+xml                                    svg svgz;
    image/tiff                                       tif tiff;
    image/vnd.wap.wbmp                               wbmp;
    image/webp                                       webp;
    image/x-icon                                     ico;
    image/x-jng                                      jng;
    image/x-ms-bmp                                   bmp;

    font/woff                                        woff;
    font/woff2                                       woff2;

    application/java-archive                         jar war ear;
    application/json                                 json;
    application/mac-binhex40                         hqx;
    application/msword                               doc;
    application/pdf                                  pdf;
    application/postscript                           ps eps ai;
    application/rtf                                  rtf;
    application/vnd.apple.mpegurl                    m3u8;
    application/vnd.google-earth.kml+xml             kml;
    application/vnd.google-earth.kmz                 kmz;
    application/vnd.ms-excel                         xls;
    application/vnd.ms-fontobject                    eot;
    application/vnd.ms-powerpoint                    ppt;
    application/vnd.oasis.opendocument.graphics      odg;
    application/vnd.oasis.opendocument.presentation  odp;
    application/vnd.oasis.opendocument.spreadsheet   ods;
    application/vnd.oasis.opendocument.text          odt;
    application/vnd.openxmlformats-officedocument.presentationml.presentation
                                                     pptx;
    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
                                                     xlsx;
    application/vnd.openxmlformats-officedocument.wordprocessingml.document
                                                     docx;
    application/vnd.wap.wmlc                         wmlc;
    application/wasm                                 wasm;
    application/x-7z-compressed                      7z;
    application/x-cocoa                              cco;
    application/x-java-archive-diff                  jardiff;
    application/x-java-jnlp-file                     jnlp;
    application/x-makeself                           run;
    application/x-perl                               pl pm;
    application/x-pilot                              prc pdb;
    application/x-rar-compressed                     rar;
    application/x-redhat-package-manager             rpm;
    application/x-sea                                sea;
    application/x-shockwave-flash                    swf;
    application/x-stuffit                            sit;
    application/x-tcl                                tcl tk;
    application/x-x509-ca-cert                       der pem crt;
    application/x-xpinstall                          xpi;
    application/xhtml+xml                            xhtml;
    application/xspf+xml                             xspf;
    application/zip                                  zip;

    application/octet-stream                         bin exe dll;
    application/octet-stream                         deb;
    application/octet-stream                         dmg;
    application/octet-stream                         iso img;
    application/octet-stream                         msi msp msm;

    audio/midi                                       mid midi kar;
    audio/mpeg                                       mp3;
    audio/ogg                                        ogg;
    audio/x-m4a                                      m4a;
    audio/x-realaudio                                ra;

    video/3gpp                                       3gpp 3gp;
    video/mp2t                                       ts;
    video/mp4                                        mp4;
    video/mpeg                                       mpeg mpg;
    video/quicktime                                  mov;
    video/webm                                       webm;
    video/x-flv                                      flv;
    video/x-m4v                                      m4v;
    video/x-mng                                      mng;
    video/x-ms-asf                                   asx asf;
    video/x-ms-wmv                                   wmv;
    video/x-msvideo                                  avi;
}

​ 对应的分别是类型以及文件后缀名。default_type application/octet-stream; mime.types未定义的,使用默认格式application/octet-stream,即以数据流的方式进行下载,比如exe文件,浏览器是无法加载exe文件的,这个时候就会显示下载。

(2)snedfile表示数据零拷贝,打开sendfile,用户请求的数据不用再加载到nginx的内存中,而是直接发送

​ 若没有开启零拷贝,则是会先拷贝到nginx应用程序的内存中:

​ nginx将文件读到自己的应用程序内存后,再从自己的应用程序内存里读取文件到网络接口缓存,再由OS调度读取网络接口缓存从而返回给用户。


​ 若开启了零拷贝,则流程为:

​ nginx直接发送一个带有套接字或者文件地址的信号sendfile()给系统内核,系统内核直接读取文件到网络接口缓存中后返回给用户。

虚拟主机

​ 一台主机可以绑定多个域名,这样可以节省服务器资源,nginx可以根据域名来区分访问的内容,从而到对应的文件夹中寻找响应文件。

​ 为了模拟域名的效果,我们可以先修改本机host,写一些域名绑定到虚拟机上:

​ 为了模拟出多站点的情况,我们可以先创建对应的文件夹,比如在根目录下创建/www文件夹,其下再创建vod和www文件夹来模拟多站点的情况,每个单独的文件夹下都有一个index.html:

​ 接下来编辑nginx的配置文件(nginx自己有一个nginx.conf.default文件,如果有写错了的情况,可以用默认的配置文件代替):

worker_processes  1; # 启动的worker进程数
events {
    worker_connections  1024; #每个worker进程的连接数
}
http {
    include  mime.types; 
    default_type  application/octet-stream; 
    sendfile   on; 
    keepalive_timeout  65; 
	#一个nginx可以启用多个server(虚拟服务器 vhost),每个server就是一个主机
    server {
        listen       80;#监听端口80
        server_name  localhost;
        location / { 
            root   /www/www;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html; 
        location = /50x.html {# 指定到html文件夹下找/50x.htm
            root   html;
        }
    }
    server {
        listen       88;#监听端口88
        server_name  localhost;
        location / { 
            root   /www/vod;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html; 
        location = /50x.html {# 指定到html文件夹下找/50x.htm
            root   html;
        }
    }
}

​ 比如80端口监听主站点的,88端口监听的是vod站点的。

​ 修改配置文件后需要reload一下:systemctl reload nginx

​ 那假如说我想都用80端口,根据域名来区分返回的内容,只需要把server_name改成对应的域名即可,总之只要保证每个server的listen(端口号)+server_name(域名)保持唯一性即可。

多个域名配置到同一个文件夹

​ 可以在server_name后面加上多个域名,每个域名、主机名之间用空格区分开来。比如server_name vod1.test.com vod2.test.com;,比如这个配置就是将两个域名都配置到一个文件夹下了。

    server {
        listen       80;#监听端口80
        server_name  vod1.test.com vod2.test.com;

        location / { 
            root   /www/www;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html; 
        location = /50x.html {# 指定到html文件夹下找/50x.htm
            root   html;
        }
    }

​ 除了配置固定的主机名外,还可以使用通配符的方式进行配置,比如*.test.comwww.test.*,这个可以查看专门的文档

反向代理

​ 反向代理的概念非常简单,用户访问反向代理服务器(nginx)后,把请求转发给对应的业务服务器,随后业务服务器返回结果给nginx,nginx将结果再返回给用户,这是一种典型的隧道式代理,隧道式服务器中,用户与业务服务器不能直接产生连接。

​ 因为隧道式代理非常考验nginx的能力,所以又提出了一种LVS的代理模式,与隧道式的区别在于,nginx转发请求给业务服务器后,业务服务器直接返回结果给用户,即返回结果的时候不再经过nginx。LVS代理模式中,业务服务器只接受从nginx进入的流量,但是发出数据时不受限制,可以发给任意的一个用户。

​ 反向代理的实现方式使用proxy_pass实现,使用了proxy_pass后,rootindex就不需要再配置了。

server {
        listen       80;#监听端口80
        server_name  localhost;

        location / {
            proxy_pass http://www.atguigu.com;
            #root   /www/www;
            #index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {# 指定到html文件夹下找/50x.htm
            root   html;
        }
    }

​ 将本机反向代理至http://www.atguigu.com,这个时候访问本机地址192.168.247.128时,就会转到尚硅谷的主页并且地址栏不会变化。

​ 不过反向代理是不支持反向代理至https的,不过服务端一般都会对http请求进行重定向至https,所以这个问题不大。

负载均衡

​ 刚刚我们提到nginx作为反向代理服务器时转发请求给对应的业务服务器,这个过程中,nginx可以做负载均衡的功能。负载均衡:把请求,按照一定算法规则,分配给多台业务服务器(即使其中一个坏了/维护升级,还有其他服务器可以继续提供服务)

轮询

​ 负载均衡的配置要与proxy_pass配置项搭配的使用,我们可以定义一个地址别名,随后使用upstream来配置这个别名的负载均衡。

http{
	upstream httpds{
		server 192.168.174.133:80; #如果是80端口,可以省略不写
		server 192.168.174.134:80;
	}
	server {
        listen       80;
        server_name  localhost;

        location / { 
        		proxy_pass http://httpds;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
		}
}

​ 使用upstream定义一组地址【在server字段下】,访问localhost,访问都会代理到192.168.174.133:80192.168.174.134:80这两个地址之一,每次访问这两个地址轮着切换(后面讲到,因为默认权重相等)。

设置权重

​ 访问使用哪个地址的权重

upstream httpds{
		server 192.168.174.133:80 weight=10;
		server 192.168.174.134:80 weight=80;
}

​ 设置down后,可以让这台机器不参与负载均衡,也就是休息。(使用不多)

upstream httpds{
		server 192.168.174.133:80 weight=10 down;
		server 192.168.174.134:80 weight=80;
}

​ 备用服务器,如果192.168.174.133:80出现故障,无法提供服务,就用使用backup的这个机器。(使用不多)

upstream httpds{
		server 192.168.174.133:80 weight=10;
		server 192.168.174.134:80 weight=80 backup;
}

动静分离

​ 当用户请求时,动态请求分配到Tomcat业务服务器,静态资源请求放在Nginx服务器中。可用于中小型的应用。

例子:

  • 如果请求的资源地址是location//的优先级比较低,如果下面的location没匹配到,就会走http://xxx这个地址的机器
  • 如果请求的资源地址是location/css/*,就会被匹配到nginx的html目录下的css文件夹中(我们把css静态资源放在这个位置)
server {
        listen       80;
        server_name  localhost;
				
				location / { # /的优先级比较低,如果下面的location没匹配到,就会走http://xxx这个地址的机器
        		proxy_pass http://xxx;
        }
        
        location /css {  # root指的是html,location/css指的是root下的css,所以地址就是html/css
        		root html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}

​ 还可以使用正则表达式来进行匹配,这样把/js/css以及/img的请求都进行了反向代理。~表示开始正则,*表示任意字符。

location ~*/(js|css|img){
	root html;
  index  index.html index.htm;
}

不过现在项目基本上都是前后端分离了,前端部署到nginx上,后端再另外启动一个服务。

URLRewrite

​ 这个配置在前后端分离中可能是会用到的。rewrite是URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结尾是flag标记。

rewrite    <regex>   <replacement>  [flag];
关键字				正则				替代内容     flagt标记
正则:使用正则表达式语句进行规则匹配
替代内容:将正则匹配的内容替换成replacement

flag标记说明:
last  #本条规则匹配完成后,继续向下匹配新的1ocation URI规则
break #本条规则匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临重定向,游览器地址会显示跳转后的URL地址
permanent #返回301永久重定向,测览器地址栏会显示跳转后的URL地址

​ 浏览器地址栏访问 xxx/123.html实际上是访问xxx/index.jsp?pageNum=123

server {
        listen       80;
        server_name  localhost;
				
				location / { 
						rewrite ^/([0-9]+).html$ /index.jsp?pageNum=$1  break;
        		proxy_pass http://xxx;
        }
      

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}

网关服务器配置

​ 上图中,应用服务器,不能直接被外网访问到,只能通过Nginx服务器进行访问(使用proxy_pass),这时候这台Nginx服务器就成为了网关服务器(承担入口的功能)

​ 所以,我们启动应用服务器的防火墙,设置其只能接受这台Nginx服务器的请求

添加rich规则

firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.174.135" port protocol="tcp" port="8080" accept" 
#这里的192.168.174.135是网关 服务器地址

移除rich规则

firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.174.135" port port="8080" protocol="tcp" accept"

​ 移除和添加规则后都要重启才能生效:firewall-cmd --reload;可以使用该命令查看所有规则:firewall-cmd --list-all

防盗链

​ 当我们请求到一个页面后,这个页面一般会再去请求其中的静态资源,这时候请求头中,会有一个refer字段,表示当前这个请求的来源,我们可以限制指定来源的请求才返回,否则就不返回,这样可以节省资源。

​ 我们可以通过valid_referers none|server_name,设置有效的refer值。

  • none:检测地址没有refer,则有效;比如直接请求图片的时候(即不是在另一个页面里请求图片的情况),配置示例:valid_referes none 192.168.44.101,这种情况下资源只允许来自192.168.44.101的页面引用或者直接请求该页面。
  • server_name:检测主机地址,refer显示是从这个地址来的,则有效(server_name必须是完整的http://xxxx

注意:if ($invalid_referer)中if后有个空格,不写就会报错,报错信息如下:

nginx: [emerg] unknown directive "if($invalid_referer)" in /usr/local/nginx/conf/nginx.conf:27

​ 例子:这里设置nginx服务器中的img目录下的图片必须refer为http:192.168.174/133才能访问。

server {
        listen       80;
        server_name  localhost;
				
				location / { 
        		proxy_pass http://xxx;
        }
      
				location /img{
                valid_referers http:192.168.174/133;
                if ($invalid_referer){#无效的
                        return 403;#返回状态码403
                }
                root html;
                index  index.html index.htm;
        }
        
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}

​ 如果引用这张图片的页面且refer并没有被设置,图片无法加载出来。如果直接访问图片地址,因为没有refer字段指向来源,会直接显示Nginx的页面:

设置盗链图片

​ 将提示图片放在html/img/x.png,访问设置防盗链图片时,就返回这x.png张图,if(之间必须有一个空格。

location /img{
    valid_referers http:192.168.174/133;
    if ($invalid_referer){#无效的
    rewrite ^/  /img/x.png break;
    }
    root html;
    index  index.html index.htm;
}

高可用(High Availablity)

​ 我们之前用到的nginx的负载均衡,考虑到的场景是后端服务器如果挂掉的话,把请求转发到正常运作的服务器上,但是设想一个场景:如果nginx挂掉了,那么就没办法把请求转发给后端服务器了,自然也没法儿进行负载均衡了。

​ 那我们拓展一下,在nginx前面再放一层nginx,第一层nginx对第二层nginx做负载均衡,但是这样就会陷入到逻辑怪圈中,万一第一层nginx挂了,那第二层的nginx也访问不到了,自然也访问不到后面的应用服务器了。这个时候我们就提出了高可用的概念。

​ 用户访问时,访问的是一个虚拟IP,keepalived会选定一个主服务器使用这个虚拟IP。

​ 每台机器上的keepalived会相互通信,根据其他机器上的keepalived进程是否存在,判断服务器状态,如果默认的Master停止了,就会在剩下的Backup机器中,竞选出一台Nginx服务器作为Master

安装keepalived

​ 通过yum命令安装:

yum install -y keepalived

​ yum安装后的配置文件在/etc/keepalived/keepalived.confvrrp_instanceauthenticationvirtual_router_idvirtual_ipaddress这几个一样的机器,才算是同一个组里。这个组才会选出一个作为Master机器。

​ 这里我们设置两台机器,分别下载好keepalived,然后进行配置

机器一:

! Configuration File for keepalived

global_defs {
   router_id lb1 # 名字与其他配置了keepalive的机器不重复就行
}

vrrp_instance heyingjie {#vrrp实例名可以随意取
    state MASTER #只能有一个默认的Master,其他写BACKUP
    interface ens33 # ip addr查看下网卡名,默认时ens33
    virtual_router_id 51
    priority 100 # 多台安装了keepalived的机器竞争成为Master的优先级
    advert_int 1 #通信时间
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.16 #虚拟IP
    }
}

机器二:

! Configuration File for keepalived

global_defs {
   router_id lb2 
}

vrrp_instance heyingjie {
    state BACKUP #只能有一个默认的Master,其他写BACKUP
    interface ens33 
    virtual_router_id 51
    priority 50
    advert_int 1 
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.16 #虚拟IP
    }
}

​ 通过命令ip addr查看机器一的ip信息,可以看到虚拟IP

posted on 2022-12-28 10:11  Ari的小跟班  阅读(295)  评论(0)    收藏  举报