• 使用uwsgi 部署python web服务


    uwsgi, wsgi协议的一个很好的实现,源码在这里:https://github.com/unbit/uwsgi

    c语言编写,有兴趣可以研究下。

    DEMO

    wsgi_server.py

    def application(env, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        return 'hello world'

    应用:

    使用uwsgi部署以上应用:

    uwsgi --http 0.0.0.0:9090 -p 4 -l 100 -M -R 100000  -z30 -L --wsgi-file  wsgi_server.py --max-apps 65535 --stats 127.0.0.1:1717 --post-buffering 100M --cpu-affinity --buffer-size 65535 --daemonize /tmp/uwsgi --pidfile /tmp/uwsgi.pid  --memory-report --threads 4

    然后浏览器访问: http://localhost:9090/ 即可。

    优势:

    提高并发访问支持(-p 进程数, --threads  线程数)

    提高服务运行稳定性(--daemonize)

    安装

    pip install uwsgi
    pip install uwsgitop

    uwsgi--uwsgi服务器

    uwsgitop--uwsgi服务器性能查看工具,用法:

    配合以上例子

    uwsgitop 127.0.0.1:1717

    参数详细说明

    官方文档:http://uwsgi-docs.readthedocs.io/en/latest/Options.html

    不错的中文文档:http://www.cnblogs.com/zhouej/archive/2012/03/25/2379646.html

    挑几个重点:

    --wsgi-file , 指定wsgi入口文件

    -p  , workers个数,也是进程数, 按照惯例可默认设为核数,但是不是最优配置需要通过 uwsgitop来查看(个人觉得uwsgitop没啥用)。

    --threads , 线程数, 每个进程的线程数,进程的任务用线程的模式完成。由于用c编写,因此不用担心GIL的问题, 但linux上不存在线程,线程本质来讲是伪进程(且存在上下文切换成本),因此不建议使用。

    (用了后,再用uwsgitop监控时,可通过键盘的“A”键查看线程的资源占用情况)

    --listen (-l), 内核监听(listen)网络队列的长度,受文件操作系统最大的网络连接数(net.core.somaxconn) 的限制, 长度越大意味着在高并发的环境下,丢失请求越少。

    --cpu-affinity, cpu友好,即进程在运行时不切换核(切换意味着时间成本)

    --stats,  监控程序的url,只有设置了这个参数以后才能用 uwsgitop 1717来观看监控

    --memory-report, 开启内存占用报告(uwsgitop中可以看到) 

    --master(-M), 启动主进程,方便管理所有进程, 可以配合--pidfie 使用。方便停止(uwsgi --stop /tmp/uwsgi.pid)/重启uwsgi ( uwsgi --reload /tmp/uwsgi.pid)

    --daemonize, 增加守护进程,使web服务更加稳定。参数为日志文件的路径。

    --disable-loggin, 不记录请求信息的日志。只记录错误以及uWSGI内部消息到日志中。

    其他略,可以自己逐一尝试。

    用途

    flask必需搭配使用咯。

    django建议使用,默认支持,有默认的wsgi.py文件生成。

    1. flask 

    uwsgi -s /tmp/uwsgi.sock --manage-script-name --mount /=xxx_project:app --http 0.0.0.0:9091

    xxx_project换为具体的项目文件顶层文件夹。

    2. django

     django官方介绍

    uwsgi --chdir=/path/to/project/site_app  --module=site_app.wsgi:application  --env DJANGO_SETTINGS_MODULE=site_app.settings

     uwsgi官方介绍:http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html#test-your-django-project。

    uwsgi --http :8000 --module web_app.wsgi

    相对来说后者简单粗暴。

    进一步的并发提升

    +nginx,

    为啥呢?看这里:http://www.oschina.net/translate/serving-python-web-applications?lang=eng

    即:

    I was pretty proud when we got API response times down to 40ms on average. When I say API I’m only talking about the time it takes from it hitting the Python server, to the server returning it’s response to the proxy.
    Unfortunately, it quickly became apparent that there were capacity issues when we started getting more traffic for larger spikes. We’d hit bumpy response times that were no longer consistent, but we still had about 30% memory and 60% cpu to spare on the web nodes.

    即:实测发现,uwsgi似乎不能充分的利用cpu和内存来达到无上限的并发。有一定瓶颈,并且到达瓶颈后,cpu和内存还剩下很多!

    那为了充分利用资源不妨多开几个uwsgi服务咯。

    老外实测发现: 与其让一个uwsgi服务跑10个进程,不如开10个uwsgi服务,然后用nginx做负载均衡!

    After quite a few tweaks, what we eventually settled on was managing a larger amount of uwsgi processes, and letting nginx load balance them (vs letting uwsgi itself load balance).
    
    What this means, is that instead of doing uwsgi –processes=10, we ran 10 separate uwsgi processes.
    
    The result was a beautiful, consistent 20ms average response time.

    当然这个有待验证。

    简单说,就是uwsgi本身的负载均衡没有nginx牛逼。所以阉割掉不用。

    因此uwsgi退化成了wsgi服务器。

    nginx 咋配置,略。

    转载请注明来自:http://www.cnblogs.com/Tommy-Yu/p/5647730.html,谢谢!

  • 相关阅读:
    Go从入门到精通——结构体——构造函数——结构体和类型的一系列初始化操作的函数封装
    Go从入门到精通——接口(interfce)——实现接口的条件
    Go从入门到精通——结构体(struct)——示例:使用匿名结构体分离 JSON 数据
    通过goaccess分析出nginx的访问量保存到数据库
    linux清理buffer缓存脚本
    nginx为什么配置了路径后还去/etc/nginx/html下面找静态资源
    加密算法RSA和Base64的关系
    vue 小插件记录 nanoid
    记录:uniapp 开发原生组件视频通话的总结
    makefile
  • 原文地址:https://www.cnblogs.com/Tommy-Yu/p/5647730.html
Copyright © 2020-2023  润新知