[译]用NGINX最大化发挥PYTHON性能

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

介绍NGINX和Python如何配合使用

Python以易用,有趣而出名,它让软件开发变得简单,据说运行性能也高于其他脚本语言(PHP最新版本PHP 7的性能好像可以与Python一较高下)

每一个人都希望自己的网站或应用可以运行得更快。但是每一个网站在大流量和流量激增时都容易遇到性能问题,甚至当机,业务繁忙时,这种情况会更加糟糕。其实无论流量是稳定增长,还是陡峭增长,所有网站都面临性能和当机的困扰。

NGINX和NGINX插件的出现就是为了解决这个问题。他们通过三种不同的方式来改善网站性能:

1、web服务 – 最初开发NGINX是为了解决 C10K 问题 – 可以轻松支撑10,000或更多的并发连接。使用NGINX为你的Python应用提供web服务,可以让你的网站运行更快,即便在小流量的情况下也有效果。当你的用户成千上万时,确定无疑,它可以提供更高的性能,更少的崩溃,以及更少的当机时间。你也可以使用NGINX提供静态文件缓存或者微缓存服务,一个独立的NGINX反向代理也是很好的选择(见下一段)。

2、反向代理– 你可以在应用服务的前端用NGINX做反向代理。NGINX接收Web请求并分发到你的应用服务。这个“怪招”可以让你的网站运行得更快,减少当机,消费更少的服务资源,而且可以提高安全性。你也可以在反向代理服务器上缓存静态资源(非常高效),添加静态内容的微缓存,以减少应用自身的负载,等等。

3、为多个应用服务提供动态均衡 – 通过布署反向代理服务。通过多应用服务并行运行和NGINX或者NGINX插件来做流量负载均衡。通过这种布署,根据流量需要,增长稳定性和运行时间需要,你可以很轻松地在线扩展网站性能。如果你需要让给定用户的会话在同一个服务上,你只需要配置负载均衡以支持会话持久化。

不管是为你的Python应用提供网站服务,还是做反向代理服务,还是做负载均衡,或者三者都用,NGINX和NGINX插件都会给你带来优势。

这是本系列(由两部分组成)中的第一篇文章,将会介绍五个提升Python应用性能的技巧,包括如何使用NGINX或NGINX插件提供web服务,如何实现静态文件的缓存,如何为动态内容做微缓存。在第二部分,我们将介绍如果用NGINX或NGINX插件提供反向代理服务,以及如何为多个应用服务提供负载均衡。

技巧 1– 定位Python性能瓶颈

有两种截然不同的情况会让你的Python应用遇到性能问题– 第一,每天有海量用户;第二,高负载。大部分网站长都不需要担心性能问题,因为他们的负载很小,根据我们的拙见,他们应该努力降低响应时间。将响应时间控制在毫秒级是一个非常困难且不被关注的工作。但可以让我们的用户体验更好,业绩更优秀。

但是这篇博文和剩下的第二部分,将关注每个人都确实关注的场景:当网站繁忙时可能会出现的性能问题,如性能大幅下降和当机。还有黑客模拟大量用户攻击造成的流量激增,同时提高网站性能也是处理攻击的重要步骤。

像Apache HTTP Server这样的系统会为每个用户分配一定数量的内存,随着用户的不断增加,物理内存不堪重负。服务器开始使用磁盘的交换分区,性能直线下降,性能问题和当机接踵而至。这篇博文中所介绍的迁移到NGINX,有助于解决这一问题。

Python特别容易出现内存相关的性能问题,因为与其他脚本语言相比,Python通常是使用更多的内存来执行任务(所以执行速度快)。所以在相同条件下,与用其他语言写的应用相比,你的Python应用更容易在少量用户的情况下而“绊倒”。

优化你的应用对解决问题会有所帮助,但要解决流量相关的性能问题,这通常不是最好最快的方式。这篇博文及剩下的第二部分,将介绍一种最好并且最快的方式。在实施这些措施之后,再采取一切方法优化你的应用,或者使用微服务架构重写。

技巧 2 – 选择单服务或者微服务布署

小网站在单个服务器上就可以运行得很好。大的网站需要多个服务器。但如果你处于中间地带–或者你的网站从一个小网站变成一个大网站– 你可以做一些有趣的选择。

如果你使用单机布署,大流量和浏览激增会给你带来很大的风险。你的扩展手段非常有限,无外乎优化你的应用,把web服务切换到NGINX,使用一个更大更快的服务器,或者使用内容分发网络(CDN)。所有这些可选项的实施都耗时耗钱,而且在实施过程中还有引入bug的风险。

另外一个很显然的风险是单机布署存在单点故障问题 – 很多问题可以导致你的站点挂掉,而且没有快速简单的解决方案。

使用NGINX做为应用的代理服务

如果你把服务切换成NGINX并且使用单机布署,你可以自由地选择使用开源的NGINX或者NGINX插件。NGINX包括企业级支持和一些扩展功能。像实时活动监测这样的扩展功能是支持单机布署的。如果做为反向代理,采用分布式布署,你可以使用其他NGINX插件,如负载均衡和会话持久化。

有很多事情都要考虑周详,除非你确定你的网站在未来很长时间内都是一个小网站,不需要关心当机问题,否则,你要明白,单机布署存在很多风险。分布式布署比较易于扩展 – 单点故障可以通过工程解决,性能可以按需调整,可以快速扩充服务器能力。

技巧 3 – 使用NGINX替换你的Web服务

在Web时代的早期,Apache就是web服务的同义词。但NGINX自2000年出现以来,迅速流行开来;现在已经是排名第一的web服务,被1,000, 10,000多个网站和世界上最繁忙的100,000多个网站使用。

NGINX最初是为了解决C10K问题而开发 – 在给定内存预算下支持10,000+并发。其他web服务需要为每个连接分配内存块,所以他们会耗尽物理内存,当数以千记的用户在同一时间访问一个网站,它会变慢甚至崩溃。NGINX处理器可以单独处理一个请求,也可以优雅地扩展,同时处理多个用户。(这可以很好地解决额外问题,后面会详述。)

一个高层NGINX架构图如下所示。

NGINX 架构, 选自开源应用架构第二卷

在上图,一个Python应用服务被布署在后端的应用服务块中,如图所示,它通过FastCGI被访问。NGINX不“知道”怎么运行Python,所以它需要一个网关连结需要的环境。FastCGI是一个被PHP,Pyhton和其他语言广泛使用的接口。

但是,连结Python和NGINX的流行方案是网络服务网关接口(WSGI)。WSGI工作在多线程和多进程环境下,所以他兼容本文所提到的所有布署选项。

如果你将web服务迁移到NGINX,这里有一些有用的软件:

Configuring
gunicorn
– “Green Unicorn”是一个流行的WSGI服务,配合NGINX使用。

Configuring
uWSGI
– 另一个流行的WSGI服务,配合NGINX使用. uWSGI包含NGINX指令支持。

Using
uWSGI, NGINX, and Django
– 一个流行的Python web框架。

下面的代码片断将向你展示如何配置NGINX和uWSGI – 这个案例中的工程使用Python框架Django。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

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图片。

缓存静态文件是提升应用性能的常用手段,经常被用到:

1、用户浏览器

2、互联网提供商 – 从公司网络到互联网提供商(ISP)

3、web服务, 也就是本文所讲的

在web服务端实现静态文件缓存有两个好处:

1、为用户提供快速服务 – NGINX 专门为静态文件缓存做过优化,对静态内容请求的处理比应用服务要快。

2、减少应用服务负载– 应用服务不需要处理已经缓存的静态文件,已经由web服务接管。

缓存静态文件在单服务器上也可以很好的实现,但底层硬件资源仍然是由web服务和应用服务所共享。如果web服务要处理频率的静态文件访问 – 甚至是海量 – 应用服务可以使用的硬件资源就会变少,一些功能可能就会变慢。

如果要支持浏览器缓存,需要正确设置静态文件的头部信息。如HTTPCache Control(特别是它的max age设置),Expires,和Entity标记。如果想深入了解,参见NGINX Plus的管理员指南:使用NGINX为uWSGI和Django提供应用网关

下面的NGINX配置代码用来缓存静态文件,包括JPEG文件,GIF文件,PNG文件,MP4文件,Powerpoint文件,和一些其他文件,请把www.example.com替换成你自己的网址。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

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和一些其他语言开发的应用服务性能,根据是否适合缓存,可以把网页分成三类:

静态文件 – 这类文件适合缓存,见技巧4所述。

动态,非个性化页面 – 因为它们需要刷新,这些文件通常不适合做缓存。例如未登录前的电商用户所看到的页面(见下一点) – 可用商品和推荐相似商品经常要发生改变,所以必须生成新页面。但是,如果有另外一个用户,在10毫秒之后发送同样请求,将前一用户看到的网页缓存并发送给后一用户就变得合情合理。

动态,个性化页面 –这些不适合缓存,因为它们是针对具体用户的,同一个用户不希望两次看到同一个个性化页面。例如一个电商用户登录后的页面不应该展示给另外一个用户。

静态文件和非个化性动态内容可以缓存

微缓存适用于上面提到的第二类页面–动态,非个性化页面。“微”是指很短的时间。如果你的网站在一秒内要多次生成同一个页面,如果你把这个页面只缓存一秒,并不影响该页面的刷新。但这个短暂的缓存可以极大的降低应用服务的负载,特别是流量较大时。将原来在一个缓存区间内,同一内容生成10,或者20,甚至100次,调整为只生成一次并缓存,为其他用户提供缓存内容。

这个效果是很神奇的。一个服务如果一秒钟要处理大量请求会变得很慢,但如果只处理一个请求,就会变得很快。(包括任何个性化页面)。我们自己的Owen Garrett有一篇博客对微服务的优势做了详情介绍,里面还有配置代码。主要要修改的地方是把代理缓存过期时间设为一秒,只需要几行配置代码就可以搞定。


1

2

3

4

5

6

proxy_cache_path
/tmp/cache keys_zone=cache:10m levels=
1:2

inactive=600s max_size=100m;

server
{

    proxy_cache
cache;

    proxy_cache_valid
200

1s;

    ...

}

更多配置样例,参见Tyler
Hicks Wright关于Python和uWSGI如何使用NGINX的博客

总结

在第一部分,我们回顾了一下在单机环境下提高Python应用性能的解决方案,还有缓存的使用,在单机情况下缓存可以应用于反向代理服务器或者独立缓存服务(缓存比独立服务性能更好)。在下一部分,我们将会介绍分布式环境下的性能提升方案。

如果你想在应用中使用更多的NGINX Plus特性,如实时事件监测,在线修改配置,你可以马上开通30天免费试用,或者联系我们,可以获得一个真实例子。

时间: 2024-07-29 11:27:12

[译]用NGINX最大化发挥PYTHON性能的相关文章

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

[编者按]本文主要介绍 nginx 的主要功能以及如何通过 NGINX 优化 Python 应用性能.本文系国内 ITOM 管理平台 OneAPM 编译呈现. Python 的著名之处在于使用简单方便,软件开发简单,而且据说运行性能优于其它脚本语言.(虽然最新版本的 PHP.PHP 7 可能会与它展开激烈竞争.) 所有人都希望自己的网站和应用程序运行得更快一些.但是,每个网站在流量增长或骤然出现流量峰值时都很容易发生性能问题.甚至宕机(这一般会在服务器最繁忙的时候发生).此外在运行期间,无论是流

让CPU充分发挥出性能

让CPU充分发挥出性能 现在我们在尝试抓包,如何发挥服务器最大化性能成为摆在我们面前的一个问题.今天给大家介绍一下CPU性能的配置项. 1.首先在Linux系统内查看一下目前的CPU物理频率和工作频率,在下面你会发现,我们的CPU是E5-2620 2.0GHz,但是CPU工作在1200MHz下. cat /proc/cpuinfo processor : 0vendor_id : GenuineIntelcpu family : 6model : 45model name : Intel(R) 

谷歌推出 Python 性能加速方案

https://codingpy.com/article/grumpy-boosts-python-with-go/ 昨天,谷歌发布了一个 Python 性能加速方案 —— Grumpy,可以将 Python 代码转译(transcompile)为 Go 源代码. 昨天,谷歌发布了一个 Python 性能加速方案 —— Grumpy,可以将 Python 代码转译(transcompile)为 Go 源代码,然后再编译为 Native Code.目前在 Github 上已经获得了 3000+ s

Python性能鸡汤(转)

英文原文:http://blog.monitis.com/index.php/2012/02/13/python-performance-tips-part-1/ 英文原文:http://blog.monitis.com/index.php/2012/03/21/python-performance-tips-part-2/ 译文:http://www.oschina.net/question/1579_45822 Python是解释型语言,因此它的执行效率不高 [1] ,但这并不影响它的流行.

Python性能(转)

第一部分 阅读 Zen of Python,在Python解析器中输入 import this. 一个犀利的Python新手可能会注意到"解析"一词, 认为Python不过是另一门脚本语言. "它肯定很慢!" 毫无疑问:Python程序没有编译型语言高效快速. 甚至Python拥护者们会告诉你Python不适合这些领域. 然而,YouTube已用Python服务于每小时4千万视频的请求. 你所要做的就是编写高效的代码和需要时使用外部实现(C/C++)代码. 这里有一

提高Python性能的一些建议(一)

最近换住的地方,网费到期,有两个星期没更新博客了,博客还是要坚持写的,有时候工作时遇到了相关问题,查看相关博客,还是能够得到一些思路或者灵感.虽然写篇博客要话费不少时间(我一般要花一个半小时到两个小时之间),但是这中间码字呀.归纳总结的过程还是让我受益匪浅的,温故而知新!当然分享自己的学习心得,也会让自己认识一些志同道合的朋友,也挺好.不说许多,今天讲讲如何提高Python性能的问题. python的性能相对c语言等还是有一定的劣势,但是如果能掌握一些优化性能的技巧,不仅能够提高代码的运行效率,

Python应用攻略 ---- Mac环境下Flask+Nginx+FastCGI实现Python应用部署

对于一个iOS开发者来说,会写后台应用并非必要的技能,然而掌握一门后台语言却无疑可以锦上添花,不仅可以对前后台架构有更加全面的了解,同时在实际开发工作中也可以自己写一些后台应用. flask框架本身集成了一个简单的服务器,可以在本机调用,然而在这种情况下要调用Python应用接口就只能使用模拟器调试,若想要使用真机调试,我们还是需要正儿八经地部署服务器. 在这里,我们介绍一种Nginx搭配FastCGI实现Mac环境下的本地服务器部署. Nginx配置 a. 安装HomeBrew ruby -e

Python性能鸡汤

第一部分 阅读 Zen of Python,在Python解析器中输入 import this. 一个犀利的Python新手可能会注意到"解析"一词, 认为Python不过是另一门脚本语言. "它肯定很慢!" 毫无疑问:Python程序没有编译型语言高效快速. 甚至Python拥护者们会告诉你Python不适合这些领域. 然而,YouTube已用Python服务于每小时4千万视频的请求. 你所要做的就是编写高效的代码和需要时使用外部实现(C/C++)代码. 这里有一

分析python性能

python性能分析 阅读目录 调优简介 Python基于事件的性能分析器的简单示例代码 Linux统计式性能分析器OProfile(http://oprofile.sourceforge.net/news/)的分析结果: 性能分析的重要性 性能分析的内容 内存消耗和内存泄漏 过早优化的风险 运行时间复杂度 性能分析最佳实践 回到顶部 调优简介 什么是性能分析 没有优化过的程序通常会在某些子程序(subroutine)上消耗大部分的CPU指令周期(CPU cycle).性能分析就是分析代码和它正