nginx之反向代理实现

前言:我们从事web开发,在项目上线以后我们大部分都需要在服务器上面使用nginx做反向代理或者负载均衡来提高我们项目的并发量,本人我只是针对于反向代理这一块来做之前一些项目使用总结

一.关于正反向代理

我们使用nginx做反向代理的时候,我们首先要要知道什么是代理,通俗点代理其实就是一个中介,A和B本来可以直接连接,这个时候中间插入一个C,C就是中介 刚开始的时候,代理多数是帮助内网客户端访问外网服务端 后来出现了反向代理,'反向'这个词语在这里的意思是指方向相反,即代理将来自外网客户端的请求转发到内网服务器,从内到外,所以现在就有了正反向代理

正向代理

首先要明白正向代理代理的是客户端,我们客户端通过vpn访问,实际上服务端并不知道访问他的客户端的具体地址,只知道的是vpn的地址

用途:

1.访问原来无法访问的资源,如google

2.可以做缓存,加速访问资源

3.对客户端访问授权,上网进行认证

4.代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息

反向代理

反向代理代理的是我们的服务端,正常的客户端请求通过http或者https发送过来,会直接访问到我们的服务端,在python中我们会使用web服务器网关比如uwsgi做请求的处理,再经过我们的中间件,最终抵达我们的路由层,而当我们使用了反向代理以后,客户端并不会直接访问到我们的服务端,而是访问的是nginx服务器,由nginx做请求的转发,转发给我们web服务器

用途:

1.保证内网的安全,阻止web攻击,大型网站,通常会将反向代理作为公网访问地址,web服务器是内网 2.负载均衡,通过反向代理服务器来优化网站的负载

总结:

正向代理是客户端代理,代理客户端,服务端不知道实际发起请求的客户端

反向代理是服务端代理,代理服务端,客户端不知道实际提供服务的服务端

二.nginx基本了解

nginx是一款轻量级的web服务器,他可以做反向代理也可以实现负载均衡,而且nginx的负载均衡是七层的负载均衡他可以识别ip、端口、应用层的协议以及域名,我们想要使用nginx做反向代理,首先大概了解一下nginx的运行,当一个nginx运行以后他会有一个master进程以及多个worker进程,master主要负责读取nginx.conf配置文件以及管理worker进程,真正做请求转发的是worker进程,当nginx运行起来以后就可以看到有master进程和worker进程了,worker进程默认配置是1个,我们可以在配置文件中进行修改,注意,我们之前说的都是进程,那当我们想要开启多个worker进程的时候,就要注意我们的cpu核数是否足够,否则开启多个worker进程会造成我们cpu的使用率过高影响服务器性能

上面就是我们启动的一个nginx服务,我们可以看到其中PID 为30665的是nginx的master进程,而PID为30667的是worker进程,这里为什么只有一个worker进程,我们可以查看nginx的配置文件,就明白了

worker_processes  1;

# 我们可以看到配置文件中有这么一句话,这句话就表示的是worker进程的个数,如果我们将这个数量进行改变,那么worker进程的数量也会发生改变

现在我们可以尝试改变worker进程的数量,来看看是否会发生改变

 vim nginx.conf
 # 进入配置文件进行修改
worker_processes  2;
# 这个时候我们将worker进程数量改为了2

这个时候我们要进行nginx的重新加载:sudo /usr/local/nginx/sbin/nginx -s reload

我们再去查看nginx的启动以后得进程:


root      1562  1545  0 8月02 ?       00:00:00 runsv nginx
root      1573  1562  0 8月02 ?       00:00:00 svlogd -tt /var/log/gitlab/nginx
nobody   13347 30665  0 15:33 ?        00:00:00 nginx: worker process
nobody   13348 30665  0 15:33 ?        00:00:00 nginx: worker process
root     30665     1  0 14:50 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx

这个时候我们可以看到我们的master进程不变,由于重新启动了他的所以PID发生了改变,但是我们可以明显的看到worker进程数量变成了两一个,一个PID为13347另一个PID为13348,所以我们可以通过配置文件来改变worker进程的数量

总结:

master进程的作用:
  1. 启动和停止工作进程:当你启动 Nginx 时,主进程会负责创建工作进程,并将请求分配给它们。当你停止 Nginx 时,主进程会关闭所有工作进程。

  2. 监控工作进程的状态:主进程会监控工作进程的健康状况。如果某个工作进程意外终止或停止响应,主进程会重新启动新的工作进程来替代它,以确保服务的可用性和稳定性。

  3. 处理信号:主进程会接收操作系统发送的信号,并根据信号执行相应的操作。例如,当你向 Nginx 发送 HUP 信号时,主进程会重新加载配置文件,以便动态更新配置而无需停止整个服务。

  4. 管理日志和子进程:主进程会处理日志记录和子进程的管理。例如,主进程可以设置工作进程将日志信息写入指定的日志文件中。

因此,主进程在 Nginx 中是至关重要的组成部分,它起着协调和管理工作进程的作用,确保服务器的正常运行。工作进程则负责处理客户端请求,并执行实际的请求处理逻辑

worker进程的作用:

它的主要作用是接收和处理客户端请求。

具体来说,工作进程的功能包括:

  1. 处理客户端请求:工作进程负责接收来自客户端的HTTP请求,并根据配置文件中的规则进行处理。它可以执行各种操作,如代理请求到上游服务器、提供静态文件、执行缓存等。

  2. 并发处理:由于每个工作进程独立运行,Nginx 可以在并发请求上实现高性能和高吞吐量。每个工作进程可以同时处理多个客户端请求,从而有效地利用系统资源。

  3. 负载均衡:工作进程还可以配合负载均衡算法,将请求分发给多个上游服务器,实现负载均衡和高可用性。通过使用多个工作进程,Nginx 可以同时处理多个请求,并将它们分配给各个上游服务器,降低单个服务器的压力。

  4. 缓存功能:工作进程可以使用内存缓存或磁盘缓存,提供高效的静态内容访问。通过将经常请求的静态内容缓存在工作进程中,可以减轻上游服务器的负载,提高响应速度。

总之,工作进程是 Nginx 的核心组件之一,它负责接收和处理客户端请求,实现高性能、高并发、负载均衡和缓存等功能

三.nginx的配置文件

我们想要使用nginx,就绕不开nginx得配置文件,全名是nginx.conf,我们想要实现反向代理,就需要去改配置文件,所以我们需要去看一下nginx的配置文件里面是什么

命令:cat nginx.conf

因为配置文件比较长,所以我们分段进行了解

#user  nobody;
worker_processes  2;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}

user: 该指令指定了Nginx运行的用户和用户组。在这里,用户被设置为“nobody”,表示以非特权用户身份运行,并降低了可能面临的安全风险

 worker_processes:就是我们的进程数,刚才被我们修改为了2

error_log: 这个指令定义了错误日志的路径和级别。在这里,Nginx 错误日志被设置为 logs/error.log,并且可以通过使用 notice 或 info 级别来记录不同类型的错误信息。如果你需要调试或查看 Nginx 运行时的错误,请查看这个日志文件

events: 这个块定义了 Nginx 如何处理事件,如连接、关闭等。在这里,worker_connections 指令指定了每个工作进程可同时处理的最大连接数

pid: 这个指令定义了包含主进程PID的文件路径。在这里,PID 文件被设置为 logs/nginx.pid。 如果需要管理或关掉 Nginx 进程,可以使用这个文件

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 {
        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;
    #    }
    #}
 

这么长一段他都属于nginx对于http请求做转发的配置

  1. include: 该指令用于引入其他的配置文件。在这里,Nginx 包含了一个名为 mime.types 的文件,用于定义 MIME 类型和文件扩展名的映射关系。

  2. default_type: 这个指令定义了默认的 MIME 类型。在这里,所有未知类型的文件都会按照二进制流(application/octet-stream)的方式进行处理。

  3. sendfile: 这个指令指定是否启用零拷贝技术来传输文件。在这里,被设置为 on,表示启用了零拷贝技术来提高文件传输效率。

  4. keepalive_timeout: 这个指令定义了客户端和服务器之间保持连接的超时时间。在这里,被设置为 65 秒。如果客户端在 keepalive_timeout 时间内没有发起新的请求,连接就会被关闭。

  5. server: 这个指令定义了一个虚拟主机的配置信息。在这里,监听地址为 80 端口,服务名称为 localhost。

  6. location: 这个指令用于配置不同路径下的不同行为。在这里,Nginx 在根目录下的 / 路径下提供了一个文件静态服务器。当请求以 / 开头时,Nginx 会在 html 目录下查找对应的文件。

  7. error_page: 这个指令用于定义错误页面和错误码。在这里,Nginx 会在返回 500、502、503 或 504 错误时,重定向到 /50x.html 页面,该页面也在 html 目录下。

总之,这个配置文件定义了 Nginx 的基本参数和一个简单的文件静态服务器,为 Web 应用提供了必要的支持。

1.我们可以看到server这个大配置里面,listen后面紧跟着80,也就是意味着我们现在启动的nginx他监听我们这台服务器端的80端口,也就意味着我们现在可以通过访问服务器的80端口访问到我们的nginx,尝试访问可以看到这样一段话

证明我们的nginx服务是正常启动的,也是可以访问到的 

 2. location

这个是非常重要的,我们要配置http的反向代理,就需要再location这里进行配置,配置我们项目的IP和端口,如下:

server {
         listen 80;
         servser_name:  # 这里修改为网站的域名,没有域名就使用服务器IP地址和端到
         charset utf-8;
            location / {
               include uwsgi_params;
               uwsgi_pass ;  # 端口要和uwsgi里配置的一样
               uwsgi_param ;  #wsgi.py所在的目录名+.wsgi
               uwsgi_param ; # 项目路径
            }
            # 新增的配置静态文件
            location /static {
                
            }
        }

这样就是一个简单的nginx.conf反向代理的配置了,我们可以看一眼我们nginx服务器监听着80端口,

server_name为我们网站的ip地址+端口,当通过80端口发送请求,就会被我们的nginx服务器转发给我们的uwsgi跑的ip地址和端口,将请求转发给我们的后端,但是一般我们的项目肯定不止后端,我们一个项目运行在服务器上面有前段和后端两个,下面就是一个简单的前后端一起被nginx代理

http {     
    include          mime.types;
    default_type     application/octet-stream;
    sendfile          on;
    # 前段部分
    server {
         listen 80;
         servser_name:  # 这里修改为网站的域名,没有域名就使用服务器IP地址:80
         charset utf-8;
            location / {
               root /home/html    # 这里表示我们html访问的路径,所以我们要将编译后的Vue静态              资源放在这个目录下面
               index index.html   # 表示访问跟会访问index.html页面
               try_filed $uri $uri/index.html   # 这个是Vue必须配置的,解决单页面刷新404问题
            }
        }

     server {
         listen 8000;
         servser_name:  # 这里修改为网站的域名,没有域名就使用服务器IP地址和端到
         charset utf-8;
            location / {
               include uwsgi_params;
               uwsgi_pass ;  # 端口要和uwsgi里配置的一样
               uwsgi_param ;  #wsgi.py所在的目录名+.wsgi
               uwsgi_param ; # 项目路径
            }
            # 新增的配置静态文件
            location /static {
                
            }
        }
}

上面这个配置就是我们比较常见的配置了,他在http请求中配置了前端和后端,当我们想服务器地址80端口发送请求,nginx会从/home/html目录下找到index.html静态资源返回到前端,当我们前端加载完毕以后ajax请求会向我们服务器的8000端口发送请求,这个请求会被nginx转发给我们的uwsgi服务,然后从后端成功拿到数据资源,再返回到前端加载页面,最终让用户看到我们正常的页面,可以画一个简单的结构图让我们理解

上面就算简单的一个架构图,我们可以从图中可以看到实际上我们客户端所有的请求都被我们的nginx服务器所接收转发,ajax发送8000端口请求被nginx转发给我们的uwsgi服务器,处理过后的http请求才由我们的django后端真正的做处理,最终将数据返回给我们的前端,页面加载成功

继续读配置文件,下面是关于hppts请求的代理

 # 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;
    #    }

这段代码是一个注释块,意味着它被用于说明 HTTPS 服务器的配置方式,但在实际配置中被禁用了。

HTTPS 是 HTTP 协议的安全版本,其使用了 SSL/TLS 加密协议来保护数据传输的安全性。在 Nginx 的配置文件中,可以通过 server 块来配置 HTTPS 服务器。这个注释块给出了一个示例 HTTPS 服务器的配置方式,包括监听端口、域名、SSL/TLS 证书的路径和缓存设置等。除此之外,还有一个 location 块,用于配置请求路径的处理方式。

如果需要启用这个 HTTPS 服务器,可以将这个注释块中的内容取消注释,并根据需要进行适当的修改。例如:

  • 修改 listen 配置项来设置 HTTPS 服务器监听的端口号和 IP 地址;
  • 修改 server_name 配置项来设置主机名,匹配客户端请求的域名;
  • 设置正确的 SSL/TLS 证书路径和私钥路径,以便 Nginx 可以加载它们;
  • 根据需要修改缓存设置和加密算法。

最后,记得重新加载或重启 Nginx 服务器,以使 HTTPS 服务器的配置生效。

通过nginx.conf文件我们就可以实现我们的反向代理,只需要配置我们的location选项就可以了

三.nginx的高级

 现在有一个场景,我们想要对nginx进行平滑的修改,不停掉nginx的服务,但是可以改变了nginx的配置文件,想要如何实现:

思路:我们知道nginx的master进程负责的内容有读取nginx.conf内容,worker进程负责处理请求,那么我们是不是可以在不停机的情况下让master进程主动去读取nginx.conf得内容,这个时候我们再主动的产生worker进程,由新的进程来进行配置修改后的处理,而旧的进程在处理完请求以后直接干掉,那怎么实现呢?

要实现在不停机的情况下对 Nginx 进行平滑修改,你可以按照以下步骤进行操作:

  1. 修改 Nginx 配置文件(nginx.conf)中的相应配置项,例如 server 块、location 块等。确保新的配置文件内容已经准备好。

  2. /usr/local/nginx/sbin/nginx -s reload这个命令会通知 Nginx 的主进程重新读取配置文件并启动新的 worker 进程。

  3. 此时,Nginx 主进程会开始读取新的配置文件,并创建新的 worker 进程来处理新的请求。旧的 worker 进程会继续处理完当前正在进行的请求,并在处理完成后被停止。

通过这种方式,Nginx 实现了平滑的配置文件修改。旧的 worker 进程会在处理完请求后停止,而新的 worker 进程会根据新的配置文件重新启动。

需要注意的是,这种平滑修改配置的方式并不是完全零停机,因为会有一小段时间的过渡期。在过渡期间,旧的和新的 worker 进程可能同时存在,但这个过程对于大多数请求来说是无感知的。

我们能实现这样的操作,其实根源于nginx的信号

在 Nginx 中,可以使用不同的信号与主进程进行通信,以控制其行为。以下是常用的 Nginx 信号:

  • reload:重新加载配置文件,并启动新的 worker 进程,平滑地将新配置应用到服务器。可以使用命令 nginx -s reload 发送该信号给主进程。

  • stop:停止 Nginx 服务器的运行,发送该信号给主进程即可,命令为 nginx -s stop

  • quit:优雅地关闭 Nginx 服务器,在处理完当前请求后停止进程。发送该信号给主进程,命令为 nginx -s quit

  • reopen:重新打开日志文件,发送该信号给主进程,命令为 nginx -s reopen。通常用于将日志文件切割归档时使用。

  • reload/upgrad:升级 Nginx 执行文件。首先,通过重新编译或替换 Nginx 可执行文件。然后,向主进程发送 nginx -s reload 信号,重新加载配置文件和启动新的 worker 进程。

这些信号是通过向 Nginx 主进程发送操作系统级别的信号来实现的。可以使用操作系统提供的工具(如 kill 命令)或其他脚本来发送这些信号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值