python之web server搭建:Gunicorn、flask及tornado

利用Gunicorn和flask搭建web-server

之前用tornado搭服务器,但是tornado只支持多线程。众所周知python的多线程性能是很差的。

要上多进程,Gunicorn加flask这个组合刚好满足需求。而且Gunicorn支持进程意外退出后重启,还支持很多灵活的配置,综合来看是很不错的组合方案。

安装

需要安装Gunicorn和flask,另外还有gevent,具体方案可以百度。

配置

Gunicorn启动flask典型的例子需要两个文件:一个配置文件和一个python文件。配置文件定义给Gunicorn的参数(实际上这些参数也可通过命令行传入),python文件定义flask服务。

我写了个例子,我的配置文件如下:

# 监听IP和端口,也可以写'0.0.0.0:port',则在所有网卡上监听
bind = '192.168.74.205:9999'
# 服务无响应(不返回)被重启的时间阈值
timeout = 30
worker_class = 'gevent'

# This refers to the number of clients that can be waiting to be served.
backlog = 512

# 工作目录
chdir = './'

# 并行工作进程数,默认 1
workers = 5
# 指定每个进程的线程数, 默认 1
threads = 2

# 检测到代码改动是否重启服务
reload = True
# 将服务放入后台不受终端的影响
daemon = False

# stdout/stderr 是否重定向到错误日志
capture_output = False

# 日志相关
loglevel = 'info' 
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'
# 连接的IP等信息会记入accesslog日志
accesslog = "./gunicorn_access.log"
# 包括重启在内的一些信息会记录在错误日志
errorlog = "./gunicorn_error.log"

用flask实现server端业务

from flask import Flask
from flask import request
import os

app = Flask(__name__)

@app.route('/', methods=['POST'])
def fp_check():
    try:
        post_data = request.data
        
        input_dict = eval(post_data)
        print('------in server------')
        print( 'input_dict:{}'.format(input_dict) )
        '''
        # do something here
        '''
        result = { "result": 0, "msg": 'ok'}
        print('out result:{}'.format(result))
        return str(result)
    except Exception as e:
        logger.error("Error in fp_check: " + str(e))

测试代码

# -*- coding: utf-8 -*-
import json
import base64
import requests
import time
import os

url = "http://192.168.74.205:9999/"

headers = {"appId":"001", "token":"D6A7", "requestId":"789", "requestTime":"2018-03-15 15:37:54"}

def get():
    #print image_base64_data
    body = {"comments":"XXXX"}
    response = requests.post(url=url, data=json.dumps(body), headers=headers)
    print('-----in test------')
    print(response.text)


if __name__ == '__main__':
    get()
    

启动服务

现在我有三个文件:配置文件名为my.conf,服务端代码文件为mymain.py测试代码文件为test.py

启动服务命令

# gunicorn -c my.conf mymain:app &

这样所有的服务就都起在后台了,使用ps命令查看,结果如下:

在这里插入图片描述

刚好5个进程,和配置文件里一致。想杀掉进程的话,直接杀父进程22179就行。

我配置文件里配置了检测到代码改动自动重启,我试了下确实有用,调试的时候很方便呀,可以边改边测,不用手动去启停服务了。

测试

启动test.py测试,结果如下:

# python3 test.py 
------in server------
input_dict:{'comments': 'XXXX'}
out result:{'result': 0, 'msg': 'ok'}
-----in test------
{'result': 0, 'msg': 'ok'}

这只是一个例子,实际生产中可以用jason传递base64等复杂的数据。

用tornado实现web-server

功能基本一样。我这里没做实际有意义的事,仅仅在这里示意用法。实际上flask可以做和tornado同样的事情。

import tornado.web
import tornado.httpserver
import tornado.ioloop
import os

class MyHandler( tornado.web.RequestHandler ):
    executor = ThreadPoolExecutor( 10 )  # max 20 thread pool
    
    @run_on_executor
    def post(self):

        print("============in server=================")
        if 1:
            jason_dict = eval(str(self.request.body))
            print('jason_dict:{}'.format(jason_dict))
            
            resultDic = {}
            resultDic["result_code"] = 0
            resultDic["msg"] = "ok"
            self.write(resultDic)
            print('resultDic:{}'.format(resultDic))

            return


def main_start():
    try:
    
        # tornado.options.parse_command_line()
        app = tornado.web.Application(
            handlers=[
                (r"/", MyHandler),
            ]
        )
        http_server = tornado.httpserver.HTTPServer( app )
        port = 9999
        http_server.listen( port )
        tornado.ioloop.IOLoop.instance().start()
    except Exception as e:
        logger.exception( "Stop the service:{}".format(e) )

if __name__ == "__main__":
    main_start()

总结

WSGI的功能类似于CGI,CGI是通用的,WSGI仅仅是python语言的一个web调用规范。

来自《web服务器、WSGI跟Flask(等框架)之间的关系》
flask是一个支持WSGI的web框架

gunicorn是一个独立的WSGI server(其他的都是模块)。可以支持gevent的woker模式。

tornado是python的非阻塞异步框架,包含了WSGI server和web框架。

也就是说tornado是一个比较大的概念,它自己可以做“gunicorn+flask”做的事。但是tornado缺少进程管理功能。tornado也可以作为WSGI server调用flask的。

综合来说,“gunicorn+flask”(实际上还有gevent)性能很好,又支持进程管理(特别是进程意外退出后的重启),非常值得使用。

参考资料

Gunicorn 简明教程

Gunicorn Settings说明文档

优雅的退出/关闭/重启gunicorn进程

gunicorn 基础配置使用

用gunicorn+gevent启动Flask项目

gunicorn部署Flask服务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值