Nginx七层(应用层)反向代理:UWSGI代理uwsgi_pass篇

news2024/11/13 9:42:43
Nginx七层(应用层)反向代理
UWSGI代理uwsgi_pass篇

- 文章信息 - Author: 李俊才 (jcLee95)
Visit me at CSDN: https://jclee95.blog.csdn.net
My WebSitehttp://thispage.tech/
Email: 291148484@163.com.
Shenzhen China
Address of this article:https://blog.csdn.net/qq_28550263/article/details/140253227
HuaWei:https://bbs.huaweicloud.com/blogs/XXXXXXXXXX

【介绍】:Nginx提供了多种应用层反向代理支持,包括proxy_pass、uwsgi_pass、fastcgi_pass和scgi_pass等。其中,proxy_pass指令可以接受一个URL参数,用于实现对HTTP/HTTPS协议的反向代理;uwsgi_pass用于代理到uWSGI应用服务器;fastcgi_pass用于代理到FastCGI服务器;而scgi_pass则用于代理到SCGI(Simple Common Gateway Interface)应用。这些指令使Nginx能够灵活地处理不同类型的后端服务和应用程序。本文介绍的重点是proxy_pass。


相关文章:
Nginx七层反向代理:HTTP反向代理proxy_pass篇

Nginx七层反向代理:UWSGI代理uwsgi_pass篇
Nginx七层反向代理:SCGI代理scgi_pass篇
Nginx七层反向代理:FastCGI代理fastcgi_pass篇

在这里插入图片描述


1. 概述

1.1 什么是反向代理

反向代理是一种常见的服务器架构模式,它位于用户和原始服务器之间,接收用户的请求并将其转发到一个或多个后端服务器。然后,反向代理将从后端服务器获取的响应返回给用户,就好像这些内容都是由代理服务器本身直接提供的一样。

在这个过程中,用户只与反向代理服务器进行直接交互,而不知道后端服务器的存在。这种架构为系统提供了额外的抽象和控制层,使得系统管理员能够灵活地部署和管理后端资源,同时为用户提供一致的访问体验。

反向代理与正向代理有所不同。正向代理主要用于帮助客户端访问其无法直接访问的资源,而反向代理则是代表服务器接收并处理来自客户端的请求。

1.2 为什么需要反向代理

反向代理通过隐藏后端服务器的IP地址和架构细节,增强了系统安全性。管理员可以在反向代理服务器上集中实施SSL/TLS加密、访问控制和防火墙规则,从而减轻后端服务器的安全管理负担。

反向代理实现负载均衡,将请求分发到多个后端服务器。这种机制提高了系统吞吐量,能够处理更高的并发请求,同时改善响应时间。

缓存功能存储静态内容和常访问的动态内容,减少后端服务器负载,加快内容交付速度。对高流量网站,缓存降低服务器压力和带宽消耗。

内容压缩减少带宽使用,加快页面加载速度。移动用户和网络条件欠佳地区的用户从中受益。

URL重写和重定向优化路由逻辑。例如,将/api/v1的请求重写到实际后端服务路径,无需修改客户端代码,简化API设计和版本管理。

系统扩展性通过添加或移除后端服务器来调整系统容量,客户端无需感知这些变化。这种透明的扩展能力应对流量波动和系统升级。

在微服务架构中,反向代理作为API网关,统一处理认证、限流、监控等横切关注点。各个微服务的实现得以简化,开发团队专注于核心业务逻辑。

A/B测试和金丝雀发布通过配置规则,将部分流量导向新版本服务,实现功能平稳迭代和风险控制。

2. UWSGI协议简介

2.1 UWSGI协议的特点

UWSGI协议是一种二进制协议,专为Web服务器和Web应用程序之间的通信而设计。它采用二进制格式传输数据,相比文本协议如HTTP,能够更高效地处理请求和响应。

UWSGI协议使用简单的数据包结构,包含头部和主体两部分。头部包含数据包长度和变量数量等信息,主体包含实际的键值对数据。这种结构使得数据解析和处理变得快速高效。

该协议支持多种数据类型,包括字符串、整数和自定义类型,允许灵活传输不同格式的信息。它还提供了丰富的环境变量支持,可以传递请求相关的详细信息。

UWSGI协议具有可扩展性,允许添加自定义头部和变量,以满足特定应用程序的需求。这种灵活性使得它能够适应各种复杂的Web应用场景。

2.2 UWSGI vs HTTP协议

UWSGI协议与HTTP协议在设计目标和应用场景上有明显区别。HTTP协议主要用于客户端和服务器之间的通信,而UWSGI协议专注于服务器内部组件之间的通信。

性能方面,UWSGI协议通常比HTTP协议更高效。它的二进制格式减少了数据传输量,降低了解析开销。相比之下,HTTP协议的文本格式虽然人类可读,但在高并发场景下可能导致更多的处理开销。

UWSGI协议的设计更加紧凑,减少了冗余信息。它省略了HTTP协议中的一些头部字段,如用户代理和接受语言等,这些信息在服务器内部通信中通常不需要。

然而,UWSGI协议的使用范围较窄,主要限于Web服务器和应用服务器之间。HTTP协议则具有更广泛的应用,包括浏览器、移动应用和API调用等各种场景。

2.3 UWSGI在Web应用中的角色

UWSGI协议在Web应用架构中充当了Web服务器和应用服务器之间的桥梁。它允许Web服务器(如Nginx)将请求高效地传递给应用服务器(如uWSGIGunicorn)。

在典型的部署中,Nginx作为前端服务器接收客户端请求,然后通过UWSGI协议将这些请求转发给后端的PythonRubyPHP应用程序。这种架构提高了整体系统的性能和可扩展性。

UWSGI协议使得Web服务器能够更好地管理连接和请求分发。它支持长连接和请求复用,减少了连接建立和断开的开销,提高了系统的并发处理能力。

对于Python Web应用,UWSGI协议与WSGIWeb服务器网关接口)标准兼容。这意味着使用UWSGI协议的服务器可以无缝地与遵循WSGI标准的Python应用程序集成。

UWSGI协议还支持进程管理和监控功能,使得应用服务器可以动态调整工作进程数量,实现负载均衡和故障恢复。这些特性增强了Web应用的稳定性和可靠性。

3. Nginx中的uwsgi_pass指令

3.1 uwsgi_pass指令的基本语法

uwsgi_pass指令在Nginx配置中用于将请求转发到运行uWSGI协议的后端服务器。其基本语法如下:

uwsgi_pass backend;

这里的backend可以是以下几种形式:

  • IP地址加端口号:uwsgi_pass 127.0.0.1:8000;
  • Unix域套接字路径:uwsgi_pass unix:/tmp/uwsgi.sock;
  • 上游服务器组名称:uwsgi_pass myapp;

uwsgi_pass指令通常放在location块内,用于指定特定URL路径的请求处理方式。例如:

location /myapp {
    uwsgi_pass 127.0.0.1:8000;
}

此配置将所有/myapp路径的请求转发到本地8000端口的uWSGI服务器。

3.2 uwsgi_pass vs proxy_pass

uwsgi_passproxy_pass都是Nginx中用于请求转发的指令,但它们针对不同的协议和应用场景。

uwsgi_pass专门用于与使用uWSGI协议的后端服务器通信。它理解并处理uWSGI协议的特定格式和头部,适用于PythonRuby等使用uWSGI服务器的应用。

proxy_pass是一个通用的反向代理指令,主要用于HTTP协议。它可以将请求转发到任何支持HTTP的后端服务器,包括其他Web服务器、应用服务器或API服务。

使用uwsgi_pass时,Nginx会自动添加必要的uWSGI协议头部,而proxy_pass则保持原始的HTTP请求格式。

在性能方面,对于支持uWSGI协议的应用,uwsgi_pass通常比proxy_pass更高效,因为它避免了HTTPuWSGI的协议转换开销。

3.3 uwsgi_pass的工作原理

Nginx接收到客户端请求后,uwsgi_pass指令触发以下处理流程:

Nginx解析客户端的HTTP请求,提取相关信息如URL、请求方法、头部等。

Nginx将这些信息转换为uWSGI协议格式,包括创建uWSGI数据包头部和正文。

Nginx通过配置的后端地址(TCP套接字或Unix域套接字)建立与uWSGI服务器的连接。

Nginx将转换后的uWSGI请求发送给后端服务器。

后端uWSGI服务器处理请求并生成响应。

Nginx接收uWSGI服务器的响应,将其转换回HTTP格式。

Nginx将转换后的HTTP响应发送给客户端。

这个过程中,Nginx充当了HTTPuWSGI协议之间的转换器,使得客户端和uWSGI应用服务器能够无缝通信。uwsgi_pass指令还处理连接池管理、超时控制、错误处理等细节,确保高效可靠的请求转发。

4. 配置Nginx使用uwsgi_pass

4.1 基本配置示例

Nginx中使用uwsgi_pass的基本配置示例展示了如何将请求转发到运行uWSGI协议的后端服务器。这个配置通常包含在Nginx的服务器块或位置块中。例如:

server {
    listen 80;
    server_name example.com;

    location / {
        uwsgi_pass 127.0.0.1:8000;
        include uwsgi_params;
    }
}

在这个例子中,server块定义了一个监听80端口的虚拟主机,域名为example.comlocation /块指定了对根路径的请求处理方式。

uwsgi_pass 127.0.0.1:8000;指令告诉Nginx将请求转发到本地运行在8000端口的uWSGI服务器。这里使用的是TCP套接字连接。

include uwsgi_params;指令包含了一个预定义的配置文件,其中包含了一系列uWSGI参数。这些参数确保Nginx正确地将HTTP请求转换为uWSGI格式。

对于使用Unix域套接字的情况,配置可以修改如下:

location / {
    uwsgi_pass unix:/tmp/uwsgi.sock;
    include uwsgi_params;
}

这里,uwsgi_pass指向一个Unix域套接字文件,通常提供比TCP套接字更好的性能,特别是在同一台机器上运行NginxuWSGI服务器时。

如果需要对静态文件进行特殊处理,可以添加额外的位置块:

location /static {
    alias /path/to/static/files;
}

location / {
    uwsgi_pass 127.0.0.1:8000;
    include uwsgi_params;
}

这个配置将/static路径下的请求直接映射到服务器上的静态文件目录,而其他请求则转发到uWSGI服务器。

对于需要设置特定uWSGI参数的情况,可以在位置块中直接指定:

location / {
    uwsgi_pass 127.0.0.1:8000;
    include uwsgi_params;
    uwsgi_param UWSGI_SCHEME $scheme;
    uwsgi_param UWSGI_CHDIR /path/to/your/project;
    uwsgi_param UWSGI_SCRIPT your_wsgi_module_name:application;
}

这里,uwsgi_param指令用于设置额外的uWSGI参数,如项目目录和WSGI脚本位置。

4.2 upstream模块的使用

Nginx的upstream模块允许定义一组服务器,可用于负载均衡和故障转移。在使用uwsgi_pass时,upstream模块特别有用,因为它可以将请求分发到多个uWSGI后端服务器。

upstream块通常定义在Nginx配置文件的http上下文中,位于server块之外。基本语法如下:

upstream backend_name {
    server backend1.example.com:8000;
    server backend2.example.com:8000;
    server backend3.example.com:8000;
}

在这个例子中,"backend_name"是自定义的上游服务器组名称,后面列出了三个后端服务器。

定义好upstream后,可以在uwsgi_pass指令中引用它:

location / {
    uwsgi_pass backend_name;
    include uwsgi_params;
}

这样,Nginx会自动在定义的后端服务器之间分发请求。

upstream模块支持多种负载均衡算法。默认情况下,Nginx使用加权轮询算法。可以通过在server指令后添加参数来调整权重:

upstream backend_name {
    server backend1.example.com:8000 weight=3;
    server backend2.example.com:8000;
    server backend3.example.com:8000;
}

在这个配置中,backend1的权重为3,而其他服务器的默认权重为1。这意味着backend1将接收大约60%的请求。

除了轮询,Nginx还支持其他负载均衡方法。例如,最少连接数方法:

upstream backend_name {
    least_conn;
    server backend1.example.com:8000;
    server backend2.example.com:8000;
    server backend3.example.com:8000;
}

least_conn指令指示Nginx将请求发送到当前活动连接数最少的服务器。

对于需要会话一致性的应用,可以使用ip_hash方法:

upstream backend_name {
    ip_hash;
    server backend1.example.com:8000;
    server backend2.example.com:8000;
    server backend3.example.com:8000;
}

ip_hash确保来自同一IP地址的请求总是被发送到同一个后端服务器,除非该服务器不可用。

upstream模块还提供了服务器健康检查和故障转移功能。可以使用max_failsfail_timeout参数来配置:

upstream backend_name {
    server backend1.example.com:8000 max_fails=3 fail_timeout=30s;
    server backend2.example.com:8000 max_fails=3 fail_timeout=30s;
    server backend3.example.com:8000 max_fails=3 fail_timeout=30s;
}

这个配置指定如果一个服务器在30秒内失败3次,它将被标记为不可用30秒。

对于需要备用服务器的情况,可以使用backup参数:

upstream backend_name {
    server backend1.example.com:8000;
    server backend2.example.com:8000;
    server backend3.example.com:8000 backup;
}

标记为backup的服务器只有在其他服务器都不可用时才会接收请求。

通过合理配置upstream模块,可以显著提高Web应用的可用性、性能和可扩展性。它使得Nginx能够智能地分发请求,处理后端服务器的故障,并优化资源利用。

4.3 Unix socket vs TCP socket

在配置Nginx使用uwsgi_pass时,我们可以选择使用Unix域套接字或TCP套接字来连接后端的uWSGI服务器。这两种方式各有优缺点,选择哪种方式取决于具体的部署环境和性能需求。

Unix域套接字是一种进程间通信机制,它使用文件系统中的特殊文件作为通信端点。在Nginx配置中,Unix域套接字的使用方式如下:

uwsgi_pass unix:/path/to/your/uwsgi.sock;

Unix域套接字的主要优势在于其性能。由于它们不需要经过网络协议栈,因此在同一台机器上的进程间通信时,Unix域套接字通常比TCP套接字更快。它们减少了数据复制和上下文切换的次数,从而降低了延迟并提高了吞吐量。

另一个优点是安全性。Unix域套接字文件可以使用文件系统权限来控制访问,这提供了一个额外的安全层。只有具有适当权限的进程才能连接到套接字。

然而,Unix域套接字也有其局限性。它们只能用于同一台机器上的进程间通信,不能跨网络使用。这意味着如果NginxuWSGI服务器需要运行在不同的机器上,就不能使用Unix域套接字。

相比之下,TCP套接字使用IP地址和端口号作为通信端点。在Nginx配置中,TCP套接字的使用方式如下:

uwsgi_pass 127.0.0.1:8000;

TCP套接字的主要优势是灵活性。它们可以用于本地和远程通信,允许NginxuWSGI服务器运行在不同的机器上。这种灵活性使得系统更容易扩展,因为可以轻松地添加更多的后端服务器。

TCP套接字还提供了更好的负载均衡能力。使用Nginx的upstream模块,可以轻松地在多个后端服务器之间分发请求,这在使用Unix域套接字时较难实现。

然而,TCP套接字的性能通常略低于Unix域套接字,特别是在高并发场景下。这是因为TCP通信涉及更多的系统调用和数据复制操作。

在选择使用哪种套接字时,需要考虑几个因素。如果NginxuWSGI服务器运行在同一台机器上,并且性能是首要考虑因素,那么Unix域套接字可能是更好的选择。如果需要跨机器通信或者系统可能需要横向扩展,那么TCP套接字会更合适。

在实际部署中,可以通过性能测试来确定哪种方式更适合特定的应用场景。有时,即使NginxuWSGI在同一台机器上,使用TCP套接字也可能更方便管理和监控。

无论选择哪种方式,都应确保正确设置权限和安全措施。对于Unix域套接字,要注意设置适当的文件权限。对于TCP套接字,考虑使用防火墙规则限制访问,并在可能的情况下使用SSL/TLS加密通信。

5. uwsgi_pass的高级配置

5.1 超时设置

Nginx中配置uwsgi_pass时,合理设置超时参数对于保证系统的稳定性和性能至关重要。超时设置可以防止长时间运行的请求占用过多资源,同时也能在后端服务器无响应时快速失败,提高用户体验。

uwsgi_read_timeout指令用于设置NginxuWSGI服务器读取响应的超时时间。默认值为60秒。如果在指定时间内Nginx没有从uWSGI服务器接收到数据,连接将被关闭,并向客户端返回错误。例如,设置5分钟的读取超时:

uwsgi_read_timeout 300s;

uwsgi_send_timeout指令控制NginxuWSGI服务器发送请求的超时时间。这个超时同样默认为60秒。如果在指定时间内Nginx无法将请求发送完毕,连接将被关闭。可以这样设置2分钟的发送超时:

uwsgi_send_timeout 120s;

uwsgi_connect_timeout指令定义了NginxuWSGI服务器建立连接的超时时间。默认值为60秒。如果在这个时间内无法建立连接,Nginx将尝试下一个服务器或返回错误。例如,设置30秒的连接超时:

uwsgi_connect_timeout 30s;

这些超时设置可以在http、server或location块中配置,根据需要选择合适的作用域。通常,在处理复杂请求或大文件上传时,可能需要增加这些超时值。例如,对于文件上传接口,可以这样配置:

location /upload {
    uwsgi_pass backend;
    uwsgi_read_timeout 300s;
    uwsgi_send_timeout 300s;
    client_max_body_size 50m;
}

这里将读取和发送超时都设置为5分钟,并允许最大50MB的上传文件大小。

对于需要长时间处理的API请求,可以单独设置更长的超时:

location /api/long-running {
    uwsgi_pass backend;
    uwsgi_read_timeout 600s;
}

这个配置为特定的API端点设置了10分钟的读取超时。

在设置超时时,需要考虑应用程序的特性和用户体验。过短的超时可能导致正常请求被中断,而过长的超时则可能造成资源浪费。理想的做法是根据应用程序的实际需求和性能特征来调整这些值。

此外,还应该考虑与uWSGI服务器端的超时设置保持一致。如果Nginx的超时设置比uWSGI服务器的短,可能会导致一些请求在uWSGI服务器处理完成前就被Nginx中断。

在生产环境中,建议监控这些超时事件的发生频率。如果发现特定类型的请求经常触发超时,可能需要优化应用程序的性能或调整超时设置。通过日志分析和性能监控,可以不断优化这些参数,以达到最佳的平衡点。

5.2 缓冲区配置

Nginx中配置uwsgi_pass时,合理设置缓冲区参数对于优化性能和资源利用至关重要。缓冲区配置允许Nginx在将响应发送给客户端之前,先从uWSGI服务器接收并存储响应内容。这种机制可以提高大型响应的处理效率,减少网络延迟对性能的影响。

uwsgi_buffering指令控制Nginx是否对uWSGI响应进行缓冲。默认情况下,该指令是启用的。可以通过以下方式显式设置:

uwsgi_buffering on;

当缓冲开启时,Nginx会尽可能快地从uWSGI服务器读取响应,并将其存储在内存或磁盘上。这允许uWSGI进程快速释放,以处理新的请求,而Nginx则负责将缓冲的响应逐步发送给客户端。

uwsgi_buffers指令用于设置用于读取uWSGI响应的缓冲区数量和大小。其语法为:

uwsgi_buffers number size;

例如,设置8个4k大小的缓冲区:

uwsgi_buffers 8 4k;

这意味着Nginx将分配8个4KB的缓冲区来存储uWSGI响应。总缓冲大小为32KB。

对于大型响应,Nginx可能需要使用更多的缓冲区。uwsgi_buffer_size指令设置用于读取uWSGI响应头的缓冲区大小:

uwsgi_buffer_size 4k;

如果响应头超过这个大小,Nginx会分配一个更大的缓冲区。

当内存中的缓冲区不足以存储整个响应时,Nginx会将部分响应写入临时文件。uwsgi_max_temp_file_size指令控制这些临时文件的最大大小:

uwsgi_max_temp_file_size 1024m;

这里设置了1GB的最大临时文件大小。如果将此值设为0,Nginx将禁用临时文件的使用,所有响应都将存储在内存中。

uwsgi_temp_file_write_size指令控制写入临时文件的数据块大小:

uwsgi_temp_file_write_size 8k;

这个设置可以影响磁盘I/O性能,特别是在处理大型响应时。

对于某些特殊情况,可能需要禁用特定位置的缓冲。例如,对于实时流媒体应用:

location /stream {
    uwsgi_pass backend;
    uwsgi_buffering off;
}

禁用缓冲后,Nginx会立即将从uWSGI服务器接收到的数据转发给客户端,这对于需要低延迟的应用很有用。

5.3 连接池管理

连接池管理是优化NginxuWSGI服务器之间通信的关键策略。通过有效管理连接池,可以显著提高系统性能,减少资源消耗,并增强整体稳定性。

Nginx提供了keepalive指令来管理与上游服务器的持久连接。这个指令通常在upstream块中配置,用于指定每个工作进程应该保持的空闲keepalive连接的最大数量。例如:

upstream backend {
    server 127.0.0.1:8000;
    keepalive 32;
}

在这个配置中,Nginx将为每个工作进程维护最多32个空闲的keepalive连接。这些连接可以被重复使用,避免了频繁建立和关闭连接的开销。

为了充分利用keepalive连接,需要在location块中设置uwsgi_keepalive_requests指令。这个指令定义了在关闭连接之前,可以通过一个keepalive连接处理的最大请求数。例如:

location / {
    uwsgi_pass backend;
    uwsgi_keepalive_requests 100;
}

这个配置允许每个keepalive连接处理最多100个请求,之后连接将被关闭,Nginx会创建一个新的连接。

uwsgi_http_version指令也在连接池管理中扮演重要角色。将其设置为1.1可以启用HTTP/1.1的持久连接特性:

uwsgi_http_version 1.1;

此外,uwsgi_next_upstream指令允许在特定条件下将请求传递给下一个服务器。这对于处理连接失败或服务器错误非常有用:

uwsgi_next_upstream error timeout invalid_header http_500;

这个配置指示Nginx在遇到错误、超时、无效头部或HTTP 500错误时尝试下一个上游服务器。

为了防止在服务器出现问题时过度重试,可以使用uwsgi_next_upstream_triesuwsgi_next_upstream_timeout指令:

uwsgi_next_upstream_tries 3;
uwsgi_next_upstream_timeout 30s;

这限制了Nginx最多尝试3次或在30秒内进行重试。

在管理连接池时,还需要考虑uwsgi_read_timeoutuwsgi_send_timeout指令。这些超时设置影响NginxuWSGI服务器之间的通信:

uwsgi_read_timeout 60s;
uwsgi_send_timeout 60s;

这些设置确保了在通信出现问题时,连接不会无限期地保持打开状态。

对于需要处理大量并发连接的高流量网站,可以考虑增加Nginx工作进程的数量。这可以通过worker_processes指令来实现:

worker_processes auto;

设置为"auto"允许Nginx根据可用的CPU核心自动调整工作进程数量。

通过精心配置这些参数,以创建一个高效的连接池管理策略。这可以提高性能,增强系统的可靠性和可扩展性。

6. 关于安全性

在配置Nginxuwsgi_pass时,合理的安全措施不仅能保护后端服务器免受潜在攻击。这章仅作为顺带提一下,关于安全性方面内容已另外独立成多篇单独的文章已经或将在后续发布于我的博客。

6.1 SSL/TLS配置

实施SSL/TLS加密是保护数据传输安全的基础。在Nginx中配置SSL/TLS需要首先获取有效的SSL证书。可以使用免费的证书或购买商业证书。获得证书后,在Nginx配置文件中添加以下内容:

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        uwsgi_pass backend;
        include uwsgi_params;
    }
}

这个配置启用了HTTPS,并指定了SSL证书和私钥的位置。ssl_protocols指令限制了允许的TLS版本,而ssl_ciphers指定了加密算法。

为了进一步增强安全性,可以添加HSTS(HTTP严格传输安全)头:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

这告诉浏览器在指定时间内(这里是一年)只使用HTTPS连接。

6.2 访问控制

访问控制是限制未授权访问的关键。Nginx提供了多种方法来实现访问控制。

IP地址限制是一种基本的访问控制方法。可以使用allowdeny指令来实现:

location /admin {
    allow 192.168.1.0/24;
    deny all;
    uwsgi_pass backend;
}

这个配置只允许来自192.168.1.0/24网段的IP访问/admin路径。

基本身份认证也是一种常用的访问控制方法:

location /private {
    auth_basic "Restricted Access";
    auth_basic_user_file /etc/nginx/.htpasswd;
    uwsgi_pass backend;
}

这里使用.htpasswd文件存储用户名和密码。可以使用htpasswd命令生成这个文件。

对于更复杂的认证需求,可以使用auth_request模块,它允许将认证委托给外部服务:

location /secure {
    auth_request /auth;
    uwsgi_pass backend;
}

location = /auth {
    internal;
    proxy_pass http://auth_service;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
}

这个配置将认证请求发送到专门的认证服务。

6.3 请求限制

请求限制是防止滥用和DDoS攻击的重要手段。Nginxlimit_req_zonelimit_req指令可以用来实现请求限制:

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    server {
        location / {
            limit_req zone=one burst=5;
            uwsgi_pass backend;
        }
    }
}

这个配置限制了每个IP地址每秒只能发送一个请求,但允许短时间的突发流量(最多5个请求)。

除了请求频率限制,还可以限制连接数:

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    server {
        location / {
            limit_conn addr 10;
            uwsgi_pass backend;
        }
    }
}

这限制了每个IP地址最多同时维持10个连接。

为了防止大文件上传导致的DoS攻击,可以限制请求体的大小:

client_max_body_size 10m;

这将限制请求体的最大大小为10MB。

此外,配置适当的超时设置也很重要:

uwsgi_read_timeout 30s;
uwsgi_send_timeout 30s;
uwsgi_connect_timeout 30s;

这些设置可以防止慢速攻击,确保资源不会被长时间占用。

7. 实际应用案例

7.1 Django应用的uwsgi_pass配置

在部署Django应用时,使用Nginx作为反向代理,配合uWSGI作为应用服务器是一种常见且高效的方案。这种配置能够充分发挥Nginx的静态文件处理能力和负载均衡特性,同时利用uWSGI高效处理Python应用的优势。

首先,确保Django项目已经正确配置并能够通过uWSGI运行。通常,uWSGI配置文件(如uwsgi.ini)可能如下所示:

[uwsgi]
chdir = /path/to/your/django/project
module = yourproject.wsgi:application
master = true
processes = 4
socket = /tmp/yourproject.sock
chmod-socket = 666
vacuum = true

这个配置指示uWSGI使用Unix套接字/tmp/yourproject.sock来通信,并运行4个工作进程。

接下来,配置Nginx以使用uwsgi_pass将请求转发到uWSGI服务器。在Nginx的配置文件中(通常位于/etc/nginx/sites-available/目录),添加以下内容:

server {
    listen 80;
    server_name example.com;

    location = /favicon.ico { access_log off; log_not_found off; }

    location /static/ {
        root /path/to/your/django/project;
    }

    location / {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/yourproject.sock;
    }
}

这个配置中,server_name指定了服务器的域名。location /static/块处理静态文件请求,直接从文件系统提供服务,无需经过uWSGI

location /块使用uwsgi_pass指令将所有其他请求转发到uWSGI服务器。unix:///tmp/yourproject.sock指定了uWSGI服务器监听的Unix套接字路径,这应与uWSGI配置文件中的socket设置相匹配。

include uwsgi_params;语句包含了一组预定义的uWSGI参数,这些参数对于NginxuWSGI之间的正确通信至关重要。

对于需要处理大文件上传的Django应用,可能需要增加客户端请求体的大小限制:

client_max_body_size 10M;

这将允许上传最大10MB的文件。

如果Django应用需要处理长时间运行的请求,可能需要调整超时设置:

uwsgi_read_timeout 300s;
uwsgi_send_timeout 300s;

这将超时时间设置为5分钟,给予长时间运行的请求更多的处理时间。

对于高流量的Django站点,可以考虑启用Nginx的缓冲功能:

uwsgi_buffering on;
uwsgi_buffer_size 8k;
uwsgi_buffers 8 8k;

这些设置启用了响应缓冲,并为每个请求配置了8个8KB的缓冲区。

如果Django应用部署在多个服务器上,可以使用Nginxupstream模块实现负载均衡:

upstream django_cluster {
    server unix:///tmp/yourproject1.sock;
    server unix:///tmp/yourproject2.sock;
    server unix:///tmp/yourproject3.sock;
}

server {
    location / {
        uwsgi_pass django_cluster;
        include uwsgi_params;
    }
}

这个配置将请求分发到三个不同的uWSGI实例,实现简单的负载均衡。

最后,为了提高安全性,建议启用HTTPS。可以使用免费的Let’s Encrypt证书:

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    # 其他SSL相关配置...

    location / {
        uwsgi_pass unix:///tmp/yourproject.sock;
        include uwsgi_params;
    }
}

这个配置启用了HTTPS,确保客户端和服务器之间的通信是加密的。

通过这些配置,Nginx能够高效地将请求转发到Django应用,同时处理静态文件、负载均衡和SSL加密。这种设置充分利用了Nginx的强大功能,为Django应用提供了一个稳定、高性能的生产环境。

7.2 Flask应用的uwsgi_pass配置

在使用Flask框架开发Web应用时,将其与NginxuWSGI结合是一种常见且高效的部署方式。这种配置能够充分发挥Nginx的反向代理和负载均衡能力,同时利用uWSGI高效处理Python应用请求的优势。下面详细介绍如何为Flask应用配置Nginxuwsgi_pass

首先,确保Flask应用已经准备就绪,并且uWSGI已正确安装和配置。典型的Flask应用入口文件"app.py"可能如下所示:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello, World!"

if __name__ == '__main__':
    app.run()

接下来,创建一个uWSGI配置文件,通常命名为"uwsgi.ini":

[uwsgi]
module = app:app
master = true
processes = 4
socket = /tmp/uwsgi.sock
chmod-socket = 660
vacuum = true
die-on-term = true

这个配置指定了Flask应用的入口模块,设置了4个工作进程,并使用Unix域套接字/tmp/uwsgi.sock进行通信。

现在,配置Nginx服务器块以使用uwsgi_pass将请求转发到Flask应用。在Nginx配置文件中添加以下内容:

server {
    listen 80;
    server_name example.com;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/tmp/uwsgi.sock;
    }

    location /static {
        alias /path/to/your/static/files;
    }
}

这个配置将所有请求通过Unix域套接字转发到uWSGI服务器,除了/static路径下的静态文件请求,这些请求将直接由Nginx处理。

为了优化性能,可以在Nginx配置中添加缓冲和超时设置:

location / {
    include uwsgi_params;
    uwsgi_pass unix:/tmp/uwsgi.sock;
    uwsgi_read_timeout 60s;
    uwsgi_send_timeout 60s;
    uwsgi_connect_timeout 60s;
    uwsgi_buffers 8 16k;
    uwsgi_buffer_size 32k;
}

这些设置增加了读取、发送和连接的超时时间,并配置了适当的缓冲区大小,有助于处理较大的请求和响应。

如果Flask应用需要处理文件上传,可能需要增加客户端请求体的大小限制:

client_max_body_size 10M;

这将允许上传最大10MB的文件。

对于需要SSL/TLS加密的生产环境,可以配置HTTPS

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/tmp/uwsgi.sock;
    }
}

这个配置启用了HTTPS,并指定了SSL证书的位置。

如果Flask应用是一个API服务,可能需要处理CORS(跨源资源共享)问题。可以在Nginx配置中添加相应的头部:

location / {
    include uwsgi_params;
    uwsgi_pass unix:/tmp/uwsgi.sock;

    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
}

这将允许来自任何源的跨域请求。在生产环境中,应该根据实际需求限制允许的源。

最后,为了提高安全性,可以添加一些基本的安全头部:

add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";

这些头部可以防止点击劫持、跨站脚本攻击和MIME类型嗅探。

通过以上配置,Nginx可以有效地作为反向代理服务器,将请求转发到运行Flask应用的uWSGI服务器。这种设置不仅提高了应用的性能和可扩展性,还增强了安全性。在实际部署中,可能还需要根据具体的应用需求和服务器环境进行进一步的优化和调整。

8. 总结

F. 参考文献

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1916685.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

攻防世界 Web_python_template_injection(flask模版注入)

学习文章:https://www.freebuf.com/column/187845.html https://blog.csdn.net/weixin_54515836/article/details/113778233 flask的渲染方法有render_template和render_template_string两种。 render_template()是用来渲染一个指定的文件的。使用如下 return re…

时序分解 | Matlab基于ESMD极点对称模态分解

时序分解 | Matlab基于ESMD极点对称模态分解 目录 时序分解 | Matlab基于ESMD极点对称模态分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 ESMD(Extreme-point Symmetric Mode Decomposition)是一种信号分解方法,用于提取信号中的模…

MVC 返回集合方法,以及分页

返回一个数据集方法 返回多个数据集方法 》》定义一个Model public class IndexMoel {public List<UserGroup> UserGroup{get;set;}public List<User> User{get;set;}}》》》控制器 //db 是 EF 中的上下文 var listnew IndexModel(); list.UserGroupdb.UserGro…

2-30 基于matlab的神经网路下身份证号码识别算法

基于matlab的神经网路下身份证号码识别算法&#xff0c;二值化、膨胀处理、边界区域划分、身份证字符分割&#xff0c;字符识别算法&#xff0c;输出识别结果。并保存识别结果。程序已调通&#xff0c;可直接运行。 2-30 神经网络 身份证识别 图像处理 - 小红书 (xiaohongshu.c…

Python强大的数据转换功能库之awswrangler使用详解

概要 在现代数据工程和数据科学领域,AWS(亚马逊云服务)是一个非常重要的平台。它提供了丰富的服务,包括S3、Glue、Redshift等,这些服务在数据存储、处理和分析中发挥了关键作用。Python的awswrangler库是一个强大的工具,旨在简化与AWS服务的交互。awswrangler库提供了一…

Python | Leetcode Python题解之第227题基本计算器II

题目&#xff1a; 题解&#xff1a; class Solution:def calculate(self, s: str) -> int:n len(s)stack []preSign num 0for i in range(n):if s[i] ! and s[i].isdigit():num num * 10 ord(s[i]) - ord(0)if i n - 1 or s[i] in -*/:if preSign :stack.append(…

机器学习笔记之监督学习

基本概念 用于训练模型的数据集称为&#xff1a;训练集 成本函数/代价函数&#xff1a;指示模型的运行情况&#xff0c;用于衡量训练数据与该直线的拟合程度。将预测值和目标值做差&#xff0c;该差值也被称为“损失值”。 例如我们需要计算平均的平方误差来衡量 成本函数/…

日常学习-20240710

1、一次一千万条数据插入和删除案例&#xff1a; 第一次&#xff1a;插入--批量插入&#xff0c;每次插入5000条数据&#xff0c;总耗时28min,数据无异常 删除--通过sql语句一次性删除&#xff0c;总耗时1h52min;一次删除的数据过多导致mysql的备份恢复文件极其庞大&#xff0…

百度搜索框制作HTML+CSS

样品图 自制效果图&#xff08;附注释&#xff09; <!DOCTYPE html> <html lang"en"><head><!-- 定义文档的字符编码为UTF-8&#xff0c;以支持中文等多语言字符 --><meta charset"UTF-8" /><!-- 设置页面在不同设备上的…

【Python 基础】控制流 - 2

程序执行 在第1篇的 hello.py 程序中,Python 开始执行程序顶部的指令,然后一条接一条往下执行。“程序执行”(或简称“执行”)这一术语是指当前被执行的指令。如果将源代码打印在纸上,在它执行时用手指指着每一行代码,你可以认为手指就是程序执行。 但是,并非所有的程…

【Linux】进程的基本概念(已经进程地址空间的初步了解)

目录 一.什么是进程 进程和程序的区别 Linux查看进程 进程的信息 fork函数 二.进程状态 操作系统上进程状态的概念 运行 阻塞 挂起 Linux中的进程状态 R状态 S状态和D状态 T状态 t状态 X状态 Z状态 三.进程的优先级 修改进程优先级 四.环境变量 常见的环境变量 PATH HOME PW…

夏日智启:我的Datawhale AI夏令营探索之旅

前言 最近几年&#xff0c;AI&#xff08;人工智能&#xff09;的发展呈现出了前所未有的迅猛势头&#xff0c;其影响力和应用范围不断扩大&#xff0c;深刻地改变着我们的生活、工作和社会结构。尤其是AI大模型技术&#xff0c;国内外可谓是“百模大战”&#xff0c;百舸争流…

【Python 基础】控制流 - 1

控制流 你已经知道了单条指令的基本知识。程序就是一系列指令。但编程真正的力量不仅在于运行&#xff08;或“执行”&#xff09;一条接一条的指令&#xff0c;就像周末的任务清单那样。根据表达式求值的结果&#xff0c;程序可以决定跳过指令&#xff0c;重复指令&#xff0…

线性代数|机器学习-P22逐步最小化一个函数

文章目录 1. 概述2. 泰勒公式3. 雅可比矩阵4. 经典牛顿法4.1 经典牛顿法理论4.2 牛顿迭代法解求方程根4.3 牛顿迭代法解求方程根 Python 5. 梯度下降和经典牛顿法5.1 线搜索方法5.2 经典牛顿法 6. 凸优化问题6.1 约束问题6.1 凸集组合 Mit麻省理工教授视频如下&#xff1a;逐步…

实验-ENSP实现防火墙区域策略与用户管理

目录 实验拓扑 自己搭建拓扑 实验要求 实验步骤 整通总公司内网 sw3配置vlan 防火墙配置IP 配置安全策略&#xff08;DMZ区内的服务器&#xff0c;办公区仅能在办公时间内&#xff08;9: 00- 18:00)可以访问&#xff0c;生产区的设备全天可以访问&#xff09; 配置nat策…

26.Labview波形图、XY图、强度图使用精讲

我们如何使用Labview显示曲线或者制作出下面这种我们想要的曲线并随着我们输入值的变化而变化呢&#xff1f; 本文详细讲解一下每种波形图的使用方式&#xff0c;帮助大家深入了解波形图的使用技巧。 文章中的所有程序已上传到下面链接中&#xff0c;下载地址(建议先转存)&am…

利用量子信息推进计算

利用量子信息推进计算 编译 李升伟 我们重点介绍 2024 年美国物理学会 3 月会议上关于量子计算和量子算法的热烈讨论&#xff0c;并邀请能够显著推动量子信息科学领域向前发展的论文提交。 美国物理学会 (APS) 三月会议可以说是世界上最大的年度物理学会议之一&#xff0c;今…

N32G45XVL-STB之lvgl的应用实例

目录 概述 1 硬件介绍 1.1 ST7796-LCD 1.2 MCU IO与LCD PIN对应关系 1.3 MCU IO与Touch PIN对应关系 2 N32G45x移植 LVGL 2.1 移植步骤 2.2 注意点 2.2.1 UI刷新函数 2.2.2 主函数中调用 3 LVGL的应用Demo 3.1 功能描述 3.2 代码实现 3.3 测试 N32G45XVL-STB之lv…

为Linux设置GRUB密码

正文共&#xff1a;999 字 11 图&#xff0c;预估阅读时间&#xff1a;1 分钟 我们前面介绍了如何恢复root密码&#xff08;CentOS 7.9遗忘了root密码怎么办&#xff1f;&#xff09;&#xff0c;虽然简单好用&#xff0c;但是可能会被不法分子利用&#xff0c;造成root密码以及…

Elasticsearch文档_id以数组方式返回

背景需求是只需要文档的_id字段&#xff0c;并且_id组装成一个数组。 在搜索请求中使用 script_fields 来整理 _id 为数组输出&#xff1a; POST goods_info/_search?size0 {"query": {"term": {"brand": {"value": "MGC"…