利用 NGINX 最大化 Python 性能,第一部分:Web 服务和缓存

简介: 本文主要介绍 nginx 的主要功能以及如何通过 NGINX 优化 Python 应用性能。本文系国内 ITOM 管理平台 OneAPM 编译呈现。

【编者按】本文主要介绍 nginx 的主要功能以及如何通过 NGINX 优化 Python 应用性能。本文系国内 ITOM 管理平台 OneAPM 编译呈现。

Python 的著名之处在于使用简单方便,软件开发简单,而且据说运行性能优于其它脚本语言。(虽然最新版本的 PHP、PHP 7 可能会与它展开激烈竞争。)

所有人都希望自己的网站和应用程序运行得更快一些。但是,每个网站在流量增长或骤然出现流量峰值时都很容易发生性能问题、甚至宕机(这一般会在服务器最繁忙的时候发生)。此外在运行期间,无论是流量稳步增长还是使用量急速飞涨,几乎所有的网站都会经历性能问题。

而关于网站性能问题,那就到了 NGINX 和 NGINX Plus 发挥作用的时候。一般可以通过以下三种方式改善网站性能:

作 web 服务器,NGINX 最开始的设计初衷就是解决 C10K 问题,也就是能够轻松支持1万以上的同时访问。NGINX 作为 Python web 服务器,可以保证网站在流量较低时依然能够快速运行。当拥有上千名用户同时访问时,你就必须提供更高性能、更少崩溃和更短停机时间的 web 服务器。你也可以在 NGINX 服务器上进行静态文件缓存或微程序缓存,不过这两者在单独的 NGINX 反向代理服务器(见下段)上运行表现更佳。

做反向代理服务器---你可以在当前应用程序服务器上把 NGINX 设置为反向代理服务器。NGINX 会将网络请求发送到应用程序服务器。这种古怪招数可以提高网站运行速度,减少停机时间,减少服务器资源占用,并且提高网站安全。你还可以在反向代理服务器上缓存静态数据(非常高效),增加动态数据的微程序缓存,从而减少应用程序本身的负担。

做多个应用程序服务器的负载均衡器---首先要部署反向代理服务器,然后同时运行多个应用程序服务器,并使用 NGINX 或 NGINX Plus 来均衡经过它们传送的流量,进行扩展。通过这种部署,你可以轻松的根据流量需求来衡量网站性能,增加可靠度和正常运行时间。如果你需要既定的用户会话保存在同一个服务器上,配置负载均衡器还可以支持会话持久性。

无论是将其用作 Python 的 web 服务器、反向代理服务器、负载均衡器,还是同时使用以上三种功能,NGINX 和 NGINX Plus 都能带来很大好处。

下面介绍改善 Python 应用程序性能的5个技巧,本文会分多个章节进行介绍,包括把 NGINX 和 NGINX Plus 作为 web 服务器,如何实施静态文件缓存,以及微程序缓存应用程序生成文件。

再就是下篇文章会介绍如何把 NGINX 和 NGINX Plus 当作反向代理服务器和多个应用程序服务器的负载均衡器。

技巧1---找出 Python 性能瓶颈

检验 Python 应用程序的性能分有两种不同情况。

第一种是在日常合理用户数量的情况下;第二种则是负载很大的情况下。

很多站长毫不关心轻负载时网站性能,然而残酷的现实经验告诉我们,响应时间的每一秒钟都应该为之捏一把汗。虽然将响应时间缩短几毫秒是个苦差事,但却会带来更好的用户体验和更好的运营成果。

另一个就是所有人都担心的情境:网站繁忙时出现的性能问题,例如运行严重减缓和崩溃。此外,很多黑客攻击也会表现为用户数量急剧增长,所以改善网站性能也是解决攻击问题的重要一步。

服务器会为每位用户分配一定数量的内存,例如 Apache HTTP 服务器,随着用户数量的增长,物理内存就会出现超负载,服务器开始将数据交换到磁盘上,性能骤降,随之产生性能不良和崩溃。而使用 NGINX 将会有助于解决这一问题。

Python 尤其容易发生内存相关的性能问题,因为它在执行任务时一般比其它脚本语言占用更多的内存(因此它的执行速度更高)。因此,在同等条件下,基于 Python 的应用程序可能比其他语言的应用程序能承受的用户负载量更小。

优化应用程序或多或少会有帮助,但是这通常不是流量相关网站性能问题的最佳或最快解决方案。本文后续会列出解决流量相关问题的最佳/最快解决方案。当你看完本文后,无论如何都要回去优化你的应用程序,或者使用微服务架构重写。

技巧2---选择单一服务器或多个服务器配置

小网站只要配置单一服务器就可以运行良好,大网站则需要有多个服务器。而如果你处于中间地带,或者你的网站正在由小网站发展壮大起来,那你就要做些有意思的选择了。

如果你只具配置有单一服务器的能力,那么在流量峰值或整体流量迅速增长时,你会面临极大风险。因为此时你的扩展性会受限,此时解决问题的方法可以包括优化应用程序、把网络服务器改成 NGINX、换一个更大更快的服务器,或者把存储任务转移到内容分发网络(CDN)等。这其中每一个选项都需要耗费时间、成本,并且在实施过程中都可能会引入错误和问题。

此外,配置单一服务器的情况下,你的网站就有一个单一的失败节点,会有很多问题造成你的网站下线而且没有很快很简捷的解决方法。

利用 NGINX 最大化 Python 性能,第一部分:Web 服务和缓存

如果把配置单一服务器改成使用 NGINX,可以自由选择开源 NGINX 软件或 NGINX Plus。NGINX Plus 包含企业级支持及额外功能。有些额外功能可以在单一服务器配置状况下实现,例如实时活动监控,而有些功能只有在把 NGINX Plus 作为多个服务器配置下的反向代理服务器时才会出现,例如负载均衡和会话持久性。

综合以上所有考虑,除非你确信你的网站在接下来很长时间都不会扩大规模,停止运行也不会有大麻烦,可以抵抗一些其他的风险,那可以配置单一服务器。但别忘了配置多个服务器几乎可以随意扩展---单次失败完全可以处理,能迅速扩充容量,总之你应用的性能由你来定。
Tip 3 – Change Your Web Server to NGINX

技巧3---把你的 web 服务器改成 NGINX

在网络发展早期,Apache等同于web 服务器。但是21世纪初 NGINX 诞生之后使用越来越广泛,它已经成为世界上流量前1000、10000和100000的公司的 web 服务器首选。

NGINX 的设计初衷是解决 C10K 问题,也就是在给定内存预算的范围内能支持10000以上的同时访问。其它 web 服务器需要给每个访问分配一部分内存,但当几千名用户同时访问网站时,它们会面临物理内存不足、运行缓慢或崩溃的问题。NGINX 分别处理每个请求,并且能优雅地应对更多用户。(如上文所述,它在其它功能方面也有优异表现。)

以下为 NGINX 架构的概述。

利用 NGINX 最大化 Python 性能,第一部分:Web 服务和缓存

在本图中,是一个 Python 应用程序服务器的后台应用程序块,需要通过 FastCGI 来访问。NGINX 并不知道如何运行 Python,因此它需要关口来进入一个能够运行 Python 的环境。FastCGI 是 PHP、Python 等语言广泛使用的用户界面。

不过,Python 和 NGINX 之间的沟通更常用的备选是服务网关接口(WSGI)。WSGI 可以在多线程、多进程环境下运行,因此它可以在本文提到的所有配置选择下运行。

如果你要把 NGINX 作成你的 web 服务器,网上有很多操作帮助信息:

  • 配置 gunicorn---绿色独角兽,一个很有名的 WSGI 服务器,以便使用 NGINX。
  • 配置 uWSGI---另外一个有名的 WSGI 服务器,以便使用 NGINX。uWSGI 能够直接支持 NGINX。
  • 使用 uWSGI、NGINX 和 Django---一个很常用的 Python 网站框架。

以下片段展示了如何配置 NGINX 来与 uWSGI 一起运行(给出的实例是使用 Python 框架 Django 的一个项目):

http {
    ...
    upstream django {
       server 127.0.0.1:29000;
    }

    server {
        listen 80;
        server_name myapp.example.com;

        root /var/www/myapp/html;

        location / {
            index index.html;
        }

        location /static/  {
            alias /var/django/projects/myapp/static/;
        }

        location /main {
            include /etc/nginx/uwsgi_params;
            uwsgi_pass django;

            uwsgi_param Host $host;
            uwsgi_param X-Real-IP $remote_addr;
            uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
            uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
        }
    }
}

技巧4——实施静态数据缓存

静态数据缓存包括把那些不经常变更的文件(也许是几个小时,也许是永远不变)存在一个应用程序服务器之外的地方。静态文件的典型例子就是作为网页内容一部分展示的 JPEG 图像。

静态文件缓存是增强应用程序性能的常见方法,而且实际上会在下面几个层面发生:

  • 在用户的浏览器
  • 多个层级的网络提供者---从一家公司的内网,到互联网服务供应商(ISP)
  • web 服务器上,正如本文所述

在 web 服务器上实施静态数据缓存有两个好处:

  • 更快传送到用户---NGINX 针对静态数据缓存做了优化,执行静态内容的请求的速度比应用程序服务器快得多。
  • 减轻应用服务器的负担---应用服务器甚至不会收到缓存静态数据的请求,因为网络服务器已经实现这些请求。

静态文件缓存在单个服务器执行时运行良好,但其实硬件方面依然由 web 服务器和应用程序服务器共享。如果 web 服务器使用硬件找回缓存的文件(及时非常高效)应用程序将无法使用这些硬件,运行速度可能会受到影响。

要支持浏览器缓存,就要为静态文件正确设置 HTTP 标头。需要考虑 HTTP 缓存控制标头(尤其是它的 max‑age 设置)、Expires 标头和实体标签。如想了解更多这方面的介绍,可以参考 Using NGINX as an Application Gateway with uWSGI and Django

下面的代码配置 NGINX,用于缓存包括 JPEG 文件、GIF、PNG文件、MP4 视频文件、ppt等多种类型的静态文件(用你的网址来替代 www.example.com ):

server {
    # substitute your web server's URL for "www.example.com"
    server_name www.example.com;
    root /var/www/example.com/htdocs;
    index index.php;
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;

   location / {
        try_files $uri $uri/ /index.php?$args;
    }

   location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;
        # substitute the socket, or address and port, of your Python server
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        #fastcgi_pass 127.0.0.1:9000;
    }  

   location ~* .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg
                  |jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid
                  |midi|wav|bmp|rtf)$ {
        expires max;
        log_not_found off;
        access_log off;
    }
}

技巧5---实施微程序缓存

微程序缓存给了那些运行 Python、PHP 和其它语言的应用程序服务器提升性能的大好机会。可缓存的网页有以下3种类型:

  • 静态文件---可缓存,见技巧4。
  • 应用程序生成的、非个人化页面---一般来说,缓存这些没有意义,因为这些内容需要不断更新。举个例子,用户登录电商网站时看到的页面(见下段)---在售商品、同类商品推荐等等可能会不断更新,因此提供最新的网页非常重要。不过,如果另一个用户在十分之一秒之后登录,向他们展示前一位用户看到的同样页面也没有什么问题。
  • 应用程序生成的、个人化页面---这些通常不会被缓存,因为它们是单个用户所属,而且同一个用户也不会再次看到相同的页面。举个例子,用户登录电商网站后看到的页面,同样的页面不能向其他用户展示。

利用 NGINX 最大化 Python 性能,第一部分:Web 服务和缓存

微程序缓存对上述第二种网页类型很有用---应用程序生成的、非个人化页面。微是一个概括的时间范围。如果你的网站一秒之内数次生成同样的页面,缓存一秒钟就不会影响网页的新鲜度。不过这个概括的缓存时间期限会极大地减轻应用程序服务器的负担,尤其是流程峰值期间。在缓存逾时期限内,不用生成10次、20次、100次(相同的内容),而是生成既定的网页一次,然后这个网页就会被缓存,并且通过缓存向多个用户展示。

而这产生的效果却不可思议,服务器一秒钟处理大量请求运行缓慢,但在只处理一个请求时速度是极快的。(当然,还有任何个人化的页面)。设置一秒超时的代理服务器这样的核心变化只需要几行配置代码。

proxy_cache_path /tmp/cache keys_zon\=cache:10m levels=1:2 inactive=600s max_size=100m;
server {
    proxy_cache cache;
    proxy_cache_valid 200 1s;
    ...
}

更多配置范例,请参考 Tyler Hicks‑Wright 的博客 Python and uWSGI with NGINX.

结论

在这部分,本文介绍了提升单一服务器提升 Python 应用性能的解决方案,可以在单一服务器上配置,也可在反向代理服务器或单独的缓存服务器上实现。(缓存在单独的服务器上运行更好。)接下来的第二部分介绍需要两个或更多服务器才能实现的性能提升方案。

当然如果你想了解 NGINX Plus 适用于你的应用程序的高级功能,例如支持、实时活动监控、运行时同时配置,可以去 NGINX 官网查看。

本文转自 OneAPM 官方博客

原文地址:Maximizing Python Performance with NGINX, Part I: Web Serving and Caching

相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
13天前
|
缓存 自然语言处理 数据库
构建高效Python Web应用:异步编程与Tornado框架
【5月更文挑战第30天】在追求高性能Web应用开发的时代,异步编程已成为提升响应速度和处理并发请求的关键手段。本文将深入探讨Python世界中的异步编程技术,特别是Tornado框架如何利用非阻塞I/O和事件循环机制来优化Web服务的性能。我们将剖析Tornado的核心组件,并通过实例演示如何构建一个高效的Web服务。
|
1天前
|
开发框架 数据库 开发者
Web开发新境界:用Python玩转Django和Flask!
【6月更文挑战第12天】Python的Web开发框架Django和Flask各有千秋。Django是全能型框架,适合快速开发大型应用,提供ORM、模板引擎、URL路由和后台管理等全面功能。Flask则轻量级且灵活,适用于小型到中型应用,以其简单易用、高度可扩展和灵活路由著称。两者结合使用,能应对各种Web开发需求。
|
1天前
|
机器学习/深度学习 人工智能 前端开发
WebAssembly:浏览器中的新语言,引领Web性能革命
【6月更文挑战第12天】WebAssembly,简称Wasm,是浏览器中的新语言,旨在带来近乎原生的性能,引领Web性能革命。它具有高效、可移植、安全和多语言支持的特点,适用于游戏开发、图形处理、计算机视觉等领域。随着浏览器支持增强,Wasm将在跨平台应用、AI、机器学习、云计算和边缘计算中发挥更大作用,推动Web应用的发展。
|
2天前
|
Java Serverless 应用服务中间件
Serverless 应用引擎产品使用合集之Web函数启动的Spring Boot项目可以通过什么方式配置Nginx
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
6天前
|
tengine 安全 应用服务中间件
修改Nginx/Tengine版本名称伪装任意WEB SERVER
修改Nginx/Tengine版本名称伪装任意WEB SERVER
|
6天前
|
Rust JavaScript 前端开发
WebAssembly初探:提升Web应用性能的关键
WebAssembly(WASM)是一种低级的二进制格式,它允许开发者使用C、C++、Rust等语言编写的代码在Web浏览器中运行,从而实现接近原生的性能。WASM的目标是成为Web平台的一个标准组成部分,提供一个安全、高效的环境来运行高性能的应用程序。
11 0
|
6天前
|
Web App开发 JavaScript 前端开发
Web 页面性能衡量指标-以用户为中心的性能指标
Web 页面性能衡量指标-以用户为中心的性能指标 以用户为中心的性能指标是理解和改进站点体验的关键点 一、以用户为中心的性能指标 1. 指标是用来干啥的? 指标是用来衡量性能和用户体验的 2. 指标类型 • 感知加载速度:网页可以多快地加载网页中的所有视觉元素并将其渲染到屏幕上 • 加载响应速度:页面加载和执行组件快速响应用户互动所需的 JavaScript 代码的速度 • 运行时响应速度:网页在加载后对用户互动的响应速度 • 视觉稳定性:页面上的元素是否会以用户意想不到的方式发生偏移,是否可能会干扰用户的互动? • 流畅性:过渡和动画是否以一致的帧速率渲染,并在一种状态之间流畅地流动
17 1
|
6天前
|
缓存 前端开发 JavaScript
Web 网页性能及性能优化
Web 性能是 Web 开发的一个重要方面,侧重于网页加载速度以及对用户输入的响应速度 通过优化网站来改善性能,可以在为用户提供更好的体验 网页性能既广泛又非常深入 1. 为什么性能这么重要? 1. 性能关乎留住用户 性能对于任何在线业务都至关重要 与加载速度缓慢、让人感觉运行缓慢的网站相比,加载速度快并能及时响应用户输入的网站能更好地吸引并留住用户 2. 性能能提高转化次数 性能会对网站用户是否会浏览应用产生重大影响 3. 性能关乎用户体验 随着网页开始加载,用户会等待一段时间,等待内容显示。在此之前,就谈不上用户体验 快速连接会让这种体验一闪而过。而如果连接速度较慢,用户就不得不等待
16 0
|
8天前
|
SQL 前端开发 关系型数据库
28. Python Web 编程:Django 基础教程
28. Python Web 编程:Django 基础教程
17 2
|
13天前
|
缓存 JavaScript 前端开发
Vue 3的事件监听缓存如何优化性能?
【5月更文挑战第31天】Vue 3的事件监听缓存如何优化性能?
9 1