欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

爬梯:Nginx全解析

程序员文章站 2022-03-20 11:39:08
...

学习整理自:B站尚硅谷

系统平台:centos 7

Nginx

1、基本概念

百科:

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。

Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强。

正向代理

客户端通过配置代理服务器的信息,访问国外的网站。

对于客户端来说他访问的是代理服务器,而代理服务器再访问国外的网站

反向代理

客户端不需要配置代理服务器直接访问访问代理服务器,而代理服务器将请求引导至真实的应用服务器。

反向的意思是,代理服务器代理了应用服务器,而非常理中的客户端。

图解:

爬梯:Nginx全解析

负载均衡

将大量的请求分发到各台服务器上,将访问负担均衡开来

图解:

爬梯:Nginx全解析

动静分离

为了加快网站的解析速度,把动态页面和静态页面由不同的服务器来解析,加快客户端的解析速度

图解:

爬梯:Nginx全解析

2、安装、常用命令及配置文件

安装

Nginx需要PCRE运行环境

  1. 安装PCRE

PCRE官方下载地址:https://sourceforge.net/projects/pcre/files/pcre/8.44/pcre-8.44.tar.gz/download

[aaa@qq.com opt]# wget http://downloads.sourceforge.net/project/pcre/pcre/8.44/pcre-8.44.tar.gz
# ...
[aaa@qq.com opt]# tar zxvf pcre-8.44.tar.gz
# ...
[aaa@qq.com pcre-8.44]# ./configure
# ...
[aaa@qq.com pcre-8.44]# make && make install
# ...
[aaa@qq.com opt]# pcre-config --version
8.44

如果configure失败的话可以尝试以下命令:

yum install gcc gcc-c++ autoconf automake
  1. 安装Nginx

我从win下载了压缩包拖进去的

[aaa@qq.com opt]# tar zxvf nginx-1.18.0.tar.gz
# ...
[aaa@qq.com nginx-1.18.0]# ./configure
# ...
[aaa@qq.com nginx-1.18.0]# make && make install
# ...
[aaa@qq.com nginx-1.18.0]# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.18.0

如果configure失败的话可以尝试以下命令:

yum install -y zlib-devel

安装完成~

启动并访问:

[aaa@qq.com nginx-1.18.0]# /usr/local/nginx/sbin/nginx
[aaa@qq.com nginx-1.18.0]# ps -ef|grep nginx
root      38148      1  0 05:07 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody    38149  38148  0 05:07 ?        00:00:00 nginx: worker process
root      38162   3793  0 05:09 pts/0    00:00:00 grep --color=auto nginx
[aaa@qq.com nginx-1.18.0]#

nginx默认监听80端口

爬梯:Nginx全解析

常用命令

# 查看版本
[aaa@qq.com ~]# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.18.0

# 启动
[aaa@qq.com ~]# /usr/local/nginx/sbin/nginx

# 关闭
[aaa@qq.com ~]# /usr/local/nginx/sbin/nginx -s stop

# 重新加载,平滑重启
[aaa@qq.com ~]# /usr/local/nginx/sbin/nginx -s reload

# 测试配置文件是否正确
[aaa@qq.com ~]# /usr/local/nginx/sbin/nginx -t [config name]

配置文件

/usr/local/nginx/cinf/nginx.conf

全局块

从配置文件开始到events块之间的内容,主要是设置nginx服务器整体运行,主要包括:

  • 配置运行Nginx服务器的用户(组)
  • 允许生成的worker process数
  • 进程PID存放路径
  • 日志存放路径、类型以及配置文件的引入等

Nginx.cof

#user  nobody; # 配置运行Nginx服务器的用户(组)
worker_processes  1; # 进程数,并发量

#error_log  logs/error.log;  # 日志存放路径
#error_log  logs/error.log  notice; # 日志类型
#error_log  logs/error.log  info; # 日志类型

#pid        logs/nginx.pid; # 进程PID存放路径

events{ }

主要配置Nginx服务器与用户的网络连接,常用设置包括:

  • 是否开启对多work process下的网络连接进行序列化
  • 是否允许同事接收多个网络连接
  • 选取事件驱动模型来处理连接请求
  • 每个word process可以同时支持的最大连接数等

这部分配置对Nginx的性能影响较大,在实际中应灵活配置

Nginx.cof

events {
	# 表示每个work process支持的最大连接数为 1024个
    worker_connections  1024;
}

http{ }

可以配置Nginx的代理、缓存和日志定义等大多数功能和第三方模块

包括两部分:http全局快、server块

  • http 全局块

http全局快配置的指令包括文件引入、MIME-TYPE定义、日志自定义、链接超时时间、单链接请求数上限等

nginx.conf

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  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    
    
    
}

  • server 块

这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一*立的硬件主机完全相同,该技术的产生是为了节省互联网服务器硬件成本。

每个http块可以包含多个server块,而每个server块就相当于一个虚拟主机。

而每个server块也分为全局server块,及同时包含多个location块

  1. 全局server块

最常见的配置是本虚拟机的监听配置和本虚拟机的名称或IP配置

  1. location块

一个server块可以配置多个location块。

这块的主要作用是基于Nginx服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称(IP别名)之外的字符串(如:/uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存或应答控制等功能,还有许多第三方模块的配置也在这里配置。

location [ = | ~ | ~* | ^~ ] uri {

}

  1. = :全值严格匹配,如果匹配成功则停止继续向下搜索并立即处理该请求;
  2. ~ : 用于匹配uri中正则表达式,区分大小写;
  3. ~* :用于匹配uri中正则表达式,不区分大小写;
  4. ^~ :用匹配uri中不包含的正则表达式,nginx服务器找到匹配度最高的location后,才会使用对应的规则来处理此请求。(也就是可能要全部location都匹配一遍才处理的意思)

nginx.conf

http{


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

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

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

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   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;
        #}
    }
    
	# another virtual host using mix of IP-, name-, and 	port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

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


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

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

}

3、反向代理

准备工作

安装启动Tomcat

# ...检查jdk
[aaa@qq.com logs]# java -version
# ...解压tomcat
[aaa@qq.com opt]# tar -vxf apache-tomcat-8.5.58.tar.gz
# ...启动tomcat
[aaa@qq.com opt]# /opt/apache-tomcat-8.5.58/bin/startup.sh
# ...查看tomcat日志
[aaa@qq.com opt]# tail -f /opt/apache-tomcat-8.5.58/log/catalina.out

启动防火墙,添加80端口和8080端口协议

[aaa@qq.com opt]# systemctl enable firewalld.service
Created symlink from /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service to /usr/lib/systemd/system/firewalld.service.
Created symlink from /etc/systemd/system/basic.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service.
[aaa@qq.com opt]# systemctl start firewalld.service
[aaa@qq.com opt]# firewall-cmd --state
running
[aaa@qq.com opt]# firewall-cmd --zone=public --permanent --add-port=8080/tcp
success
[aaa@qq.com opt]# firewall-cmd --zone=public --permanent --add-port=80/tcp
success
[aaa@qq.com opt]# systemctl-cmd --reload
success
[aaa@qq.com opt]# firewall-cmd --list-all
public (default, active)
  interfaces: eno16777736
  sources: 
  services: dhcpv6-client ssh
  ports: 15672/tcp 80/tcp 6379/tcp 5672/tcp 8080/tcp
  masquerade: no
  forward-ports: 
  icmp-blocks: 
  rich rules: 
[aaa@qq.com opt]# 

反向代理实例(一)

简单IP转发

修改Nginx.conf

爬梯:Nginx全解析

到这一步,已经完成了对8080的转发配置爬梯:Nginx全解析

反向代理实例(二)

使用正则判断更精细的uri进行分发

准备工作

启动两个tomcat,分别监听8080、8081

# ...创建两个文件夹
[aaa@qq.com opt]# mkdir tomcat8080
[aaa@qq.com opt]# mkdir tomcat8081

# ...先停止tomcat
[aaa@qq.com opt]# /opt/apache-tomcat-8.5.58/bin/shutdown.sh

# ...拷贝两份tomcat
[aaa@qq.com opt]# cp -r apache-tomcat-8.5.58/. tomcat8080
[aaa@qq.com opt]# cp -r apache-tomcat-8.5.58/. tomcat8081

# ...修改tomcat8081端口
[aaa@qq.com opt]# vi tomcat8081/conf/server.xml

<Server port="8006" shutdown="SHUTDOWN">
<Connector port="8081" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
               
# ...启动
[aaa@qq.com opt]# tomcat8080/bin/startup.sh 
[aaa@qq.com opt]# tomcat8081/bin/startup.sh 
      
# ...防火墙
[aaa@qq.com opt]# firewall-cmd --zone=public --permanent --add-port=8081/tcp
success
[aaa@qq.com opt]# systemctl-cmd --reload
success

加入静态页面到 webapps/

8080

爬梯:Nginx全解析

8081

爬梯:Nginx全解析

正式修改nginx.conf

# 在http块中加入
# 监听9001端口,转发到location。“~”表示正则匹配
# 当连接中含有hello则转发到8080
# 如:http://192.168.0.106:9001/hello/a.html
# 转发到:http://127.0.0.1:8080/hello/a.html

   server {
        listen       9001; 
        server_name  192.168.0.106;

        location ~ /hello/ {
              proxy_pass      http://127.0.0.1:8080;
        }
        location ~ /hi/ {
              proxy_pass        http://127.0.0.1:8081;
        }

   }

# ...测试配置文件是否编写正确
[aaa@qq.com opt]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
# ...平滑重启,重新加载配置文件信息
[aaa@qq.com opt]# /usr/local/nginx/sbin/nginx -s reload
# ...防火墙
[aaa@qq.com opt]# firewall-cmd --zone=public --permanent --add-port=9001/tcp
success
[aaa@qq.com opt]# firewall-cmd --reload
success

开放9001端口后测试:

hello

爬梯:Nginx全解析

hi

爬梯:Nginx全解析

4、负载均衡

将请求按一定规则分发到不同的应用服务器,实现负载的均衡

准备工作

准备两台tomcat,分别监听8080、8081,并放入一个路径相同的静态页面

…/webapps/ssx/stone.html

爬梯:Nginx全解析

爬梯:Nginx全解析

正式配置 nginx.conf

在http块中,加入upstream块,并将server块代理到这个upstream块

	upstream mystream{
        server 127.0.0.1:8080; # 负载的服务器1地址
        server 127.0.0.1:8081; # 负载的服务器2地址
    }

    server {
        listen       80;
        server_name  192.168.1.106;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            proxy_pass http://mystream;  # 使用多个server处理请求
            index  index.html index.htm;
        }
        
        ......
     }
     
     
# 测试 重启
[aaa@qq.com ssx]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[aaa@qq.com ssx]# /usr/local/nginx/sbin/nginx -s reload

测试

将会在8080、8081间选择

爬梯:Nginx全解析

负载规则

负载均衡既是将负载分摊到不同的服务单元,既保证服务器的可用性,有保证用户体验。

  1. 轮询(默认)

每个请求按先后顺序逐一分配到不同的应用服务器上,如果应用服务器宕机,能自动剔除。

  1. weight

weight代表权重,默认为1,权重越高被分配请求的几率就越大。

upstream server_pool{
	server 192.168.0.106 weight=2;
	server 192.168.0.107 weight=3;
	server 192.168.0.108 weight=5;
}
  1. ip_hash

每个请求按照访问ip(即Nginx的前置服务器或者客户端IP)的hash结果分配,即某个访客的后续的请求都访问这一个server,从而解决应用session不一致的问题。

upstream server_pool{
	ip_hash;
	server 192.168.0.106;
	server 192.168.0.107;
	server 192.168.0.108;
}
  1. fair(第三方)

按后端服务器的响应时间来分配请求,相应时间短的优先分配

upstream server_pool{
	server 192.168.0.106;
	server 192.168.0.107;
	server 192.168.0.108;
	fair;
}

5、动静分离

基本概念

动静分离指的是,匹配判断动态请求和静态请求,然后区别对待,分开处理,目的还是为了提高服务的响应速度、用户的体验。

现在比较主流的分离方式是,将动态请求放在一台服务器上,静态请求放在另一台服务器上。

  • location 指定不同的后缀名实现请求类型的判断,转发请求;
  • expires 设置浏览器缓存过期时间。使用浏览器缓存可以加快响应速度,降低请求流量。这个过期时间,无需到应用服务端验证,浏览器自身确认是否过期。

准备工作

在服务器放一张图

/opt/images/sailboat.png

正式配置 nginx.conf

没有匹配到png的请求正常访问tomcat

匹配到 .png的请求访问目录

爬梯:Nginx全解析

测试

爬梯:Nginx全解析

6、高可用集群

基础概念

应用服务器可能会宕机,所以配置了多台,那么nginx也可能会宕机,所以也有一定的需要配置高可用集群。

集群结构图:

爬梯:Nginx全解析

集群配置

  1. 两台nginx服务器 192.168.0.106、192.168.0.107
  2. keepalived软件
# 安装keepalived
[aaa@qq.com opt]# yum install keepalived -y
[aaa@qq.com opt]# rpm -q -a keepalived
keepalived-1.3.5-16.el7.x86_64

keepalived配置文件

[aaa@qq.com opt]# ls /etc/keepalived/
keepalived.conf
! Configuration File for keepalived

global_defs {			# 全局配置
   notification_email {
     aaa@qq.com
     aaa@qq.com
     aaa@qq.com
   }
   notification_email_from aaa@qq.com
   smtp_server 192.168.0.106 
   smtp_connect_timeout 30
   router_id LVS_DEVEL	# 路由ID,服务器名。/etc/hosts
}

# 脚本
vrrp_script chk_http_port {
	script "/usr/local/src/nginx_check.sh"
	interval 2			# 检测脚本执行的间隔	
	weight 2			# 权重。意思是当脚本执行成立,则此服务的权重 +2 。若配置的是负数,则减2
}

# 虚拟机配置
vrrp_instance VI_1 {
    state MASTER		# MASTER:主服务器  BACKUP:备用服务器
    interface eno16777736		# 网卡  ifconfig查看
    virtual_router_id 51	#主、备机的virtual_router_id必须相同
    priority 100		# 主、备机取不同的优先级,主机取较大值,备机取较小值。一般主机配置100
    advert_int 1		# 时间间隔、心跳。每隔1s发送一个心跳包,检测服务器是否存活
    authentication {	# 校验权限的方式
        auth_type PASS	# 密码方式
        auth_pass 1111	# 密码是 1111
    }
    virtual_ipaddress {
        192.168.0.110	# VRRP H虚拟地址。可绑定多个。
    }
}

检测脚本

检测nginx是否存活,如果死掉则关闭keepalived。目的是让另一台keepalived检测到。

#!/bin/bash
A='ps -C nginx -no-header |wc -1'
if [ $A -eq 0 ];then
	/usr/local/nginx/sbin/nginx
	sleep 2
	if [ 'ps -C nginx --no-header |wc -1' -eq 0 ];then
		killall keepalived
	fi
fi

两台机器都要修改keepalived.conf、添加脚本文件。

脚本文件不用改,配置文件需要修改网卡和priority。

启动和测试

1. 启动

[aaa@qq.com src]# /usr/local/nginx/sbin/nginx 
[aaa@qq.com src]# systemctl start keepalived.service
[aaa@qq.com src]# ps -ef|grep keepalived
root      18055      1  0 10:06 ?        00:00:00 /usr/sbin/keepalived -D
root      18057  18055  0 10:06 ?        00:00:00 /usr/sbin/keepalived -D
root      18058  18055  0 10:06 ?        00:00:00 /usr/sbin/keepalived -D
root      18148   2665  0 10:06 pts/0    00:00:00 grep --color=auto keepalived

爬梯:Nginx全解析

2. 测试-访问虚拟主机 192.168.0.110

爬梯:Nginx全解析

成功进入主Nginx配置的tomcat!

3. 测试-停掉主Nginx,再访问110

爬梯:Nginx全解析

请求正常访问,进入了备机nginx,没有配置转发端口,所以不跳tomcat

此时备机上的绑定了虚拟ip 192.168.0.110

爬梯:Nginx全解析

至此,Nginx的集群已经全部完成。

撒花~~

7、Nginx工作原理(性能调优)

Master&Worker

[aaa@qq.com src]# ps -ef|grep nginx
root      18485      1  0 10:35 ?        00:00:00 nginx: master process /usr/local/nginx/sbin//nginx
nobody    18486  18485  0 10:35 ?        00:00:00 nginx: worker process
root      18488  14574  0 10:35 pts/0    00:00:00 grep --color=auto nginx

Nginx启动之后,可以看到是有两个进程的。

Marster:分配任务;

Worker:接收命令,具体执行任务,可以有多个。每个woker是一个独立的进程

工作原理图:

爬梯:Nginx全解析

当有新的请求到来时,Master得到新任务,由多个Woker进行争抢执行新任务。

Nginx热部署原理:

修改nginx配置文件平滑加载的命令:

./nginx -s reload

原理是:比如此时有个四个woker存活,而worker1正在执行请求任务,另外三个woker空闲,执行了 reload之后,三个空闲的woker去加载了新的nginx.conf,当有新的任务进来时,三个空闲的woker使用的是新nginx.conf去执行任务。而当woker1执行完任务后,会自行去加载新配置文件,再参与争抢下一个任务。

性能调优

因为每个woker是一个独立的进程,所以当一个woker进程销往并不会对nginx的服务造成影响!

同redis类似都采用io多路复用机制,每个woker进程都只有一个主线程,通过异步非阻塞的方式来处理请求,即使成千上万个请求也可支持。所以关键点在于设置多少个woker进程数,才能充分发挥cpu资源。

1. worker_processes

通常cpu有多少核就配置多少个进程

2. worker_cpu_affinity

开启cpu多核配置:

  • 2核cpu,开启两个进程

    worker_processes	2;
    worker_cpu_affinity 01 10;	
    

    解释:01表示启用第一个cpu内核、10表示启用第二个cpu内核。意思是第一个进程对应第一个cpu内核,第二个进程表示第二个内核。

  • 2核cpu,开启四个进程

    worker_processes	4;
    worker_cpu_affinity 01 10 01 10;	
    
  • 4核cpu,开启两个进程

    worker_processes	2;
    worker_cpu_affinity 0101 1010;	
    

    解释:0101表示开启第一个和第三个内核,1010表示开启第二个和第四个内核。

  • 4核cpu,开启四个进程

    worker_processes	4;
    worker_cpu_affinity 0001 0010 0100 1000;	
    
  • 8核cpu,开启8个进程

    worker_processes	8;
    worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;	
    

worker_processes最多开启8个,8个以上性能提升不会再提升了,而且稳定性变得更低,所以8个进程够用了。

规律:2核是 01,四核是0001,8核是00000001,有多少个核,就有几位数,1表示该内核开启,0表示该内核关闭。

配置完之后可以重启nginx,用ab工具或者wrk工具,可以进行性能测试,在服务器上执行top,然后按1,就可以看到cpu工作情况,如果多个cpu内核的利用率差不多,就证明nginx已经成功利用了多核cpu,测试结束后,cpu内核的负载都同时降低。

3. worker_connection

连接数考题:客户端发送一条请求,占用了worker的几个连接数?

答案:2或4个;

解释:1:客户端链接到nginx服务器的请求;2、nginx返回客户端的请求;3:nginx服务器访问tomcat服务器的请求;4、tomcat服务器返回nginx服务器的请求;当访问的内容在nginx服务器上则答案是2条,当访问的内容在外部服务器上则答案是4条;

并发数考题:当前Nginx有一个Master,有四个Worker,每个Worker支持最大连接数是1024,那么当前Nginx支持的最大并发数是多少?

答案:2048或1024个;

解释:当前最大请求数:4个woker * 1024连接数 / ( 2|4 ) = 2048 | 1024

至此可以按照实际情况,计算调试出最合适的连接数配置。

相关标签: Nginx nginx