flask框架使用uWSGI部署服务

前言:由于工作需要使用flask写了一个简易的http服务用来提供接口,按照接口文档demo写好以后本地测试一切正常,但是发布到服务器以后有一串警告:WARNING:This is a developnent server. Do not use it in a production deploynent,如下图:

意思是我的这个启动方式不能在生产环境上使用,然后带着疑问上网查了一下,我的启动方式是app.run(host="0.0.0.0", port=80) 只适用于开发模式,因为它是单线程的,生产环境影响性能,替代方案是可以用uWSGI或者pywsgi

三者的区别如下:

1.app.run 启动的是单线程服务,性能很低

2.pywsgi服务器使用的是gevent的pywsgi模块,性能不错,配置也很简单,但是它只是把单线程改造成了单线程异步方式

3.uWSGI性能最好,配置稍微比上面难一点,但是它是支持多进程、多线程、和多协程的方式,简直就是完美,所以我选择尝试使用uWSGI服务器来替代

一、pywsgi方式实现简单,下面我也一下步骤,非常简单

1.安装gevent模块
pip install gevent

2.在启动类里引入模块
from gevent import pywsgi

3.main方法里将app.run替换
server = pywsgi.WSGIServer(('0.0.0.0', 80), app)
server.serve_forever()
复制代码

二、uWSGI实现方式以前需要引入nginx,现在也不需要了,很简单的实现,如下

1.安装uWSGI模块

pip install uwsgi
复制代码

2.在根目录下创建uWSGI配置文件 【uwsgi.ini】

[uwsgi]
# 地址端口
http = 0.0.0.0:80
# 项目路径
chdir = /root/projectname
# 项目启动文件
wsgi-file = manage.py
# 项目需要调用的启动类
callable = app
# 进程线程设置
processes = 4
threads = 10
# 日志文件
daemonize = /app/logs/uwsgi.log
# 保存主进程pid文件
pidfile = uwsgi.pid
# 是否需要主进程
master = true
复制代码

3.相关指令

#启动
uwsgi --ini uwsgi.ini

#重新加载
uwsgi --reload uwsgi.pid

#停止
uwsgi --stop uwsgi.pid
复制代码

4.附代码

manage.py

# coding:utf-8
from app import create_app
app = create_app()

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=80)
复制代码

app/__init__.py

# coding:utf-8
import os
import sys

from apscheduler.schedulers.background import BackgroundScheduler
from flask import Flask as _Flask, request, jsonify
from flask_apscheduler import APScheduler

from app.extensions import *
from app import config
from app.api import api
import fcntl
import atexit


class Flask(_Flask):
    def wsgi_app(self, environ, start_response):
        ctx = self.request_context(environ)
        ctx.push()
        error = None
        try:
            try:
                response = self.full_dispatch_request()
            except Exception as e:
                error = e
                response = self.handle_exception(e)
            except:
                error = sys.exc_info()[1]
                raise
            return response(environ, start_response)
        finally:
            if self.should_ignore_error(error):
                error = None
            ctx.auto_pop(error)


def create_app():
    app = Flask(__name__, static_folder=os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'static'))
    app.config.from_object(config)
    blueprints_fabric(app)
    run_task(app)
    extensions_fabric(app)
    process_request(app)
    app.json_encoder = CustomJSONEncoder
    return app
	
class CustomJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, bytearray):
            return str(obj, encoding='utf-8')
        if isinstance(obj, datetime):
            return obj.strftime('%Y-%m-%dT%H:%M:%S')
        else:
            return JSONEncoder.default(self, obj)

def job1():
	print("job1")

def run_task(app):
    # 执行一次
    """Configure Scheduler"""
    f = open("scheduler.lock", "wb")
    try:
        fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
        print("********************************run_task**********************************")
        scheduler = APScheduler(scheduler=BackgroundScheduler(timezone='Asia/Shanghai'))
        scheduler.init_app(app)
        scheduler.start()

        @scheduler.task('interval', id='do_job_1', seconds=10, misfire_grace_time=900)
        def do_job_1():
            job1()

    except:
        pass

    def unlock():
        fcntl.flock(f, fcntl.LOCK_UN)
        f.close()
    atexit.register(unlock)


def blueprints_fabric(app):
    blueprints = [api]
    for blueprint in blueprints:
        app.register_blueprint(blueprint)


def extensions_fabric(app):
    csrf.init_app(app)
    cors.init_app(app, origins=config.CORS_ORIGINS, supports_credentials=True)


def process_request(app):

    @app.before_request
    def test():
        if request.path == '/test':
            return jsonify({"code": 200, "message": "success"})
复制代码

app/extensions.py

from flask_wtf.csrf import CSRFProtect

cors = CORS()
csrf = CSRFProtect()
复制代码
  • 8
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
nginx和uwsgi是常用的部署flask应用的工具。首先,需要配置nginx将请求转发给uwsgi处理。在nginx的配置文件中,可以使用类似以下的配置来实现转发: ``` location / { include uwsgi_params; uwsgi_pass 127.0.0.1:3031; } ``` 这样配置后,nginx会将所有的请求转发给uwsgi处理。\[1\] 启动nginx可以使用以下命令: ``` service nginx start ``` 可以使用以下命令查看nginx的状态: ``` service nginx status ``` 重启nginx可以使用以下命令: ``` service nginx restart ``` 可以使用以下命令查看nginx是否已经启动: ``` ps -ef | grep nginx ``` 如果需要强制停止nginx,可以使用以下命令: ``` kill -9 nginx ``` 可以使用以下命令查看nginx的错误日志: ``` tail -f error.log ``` 在后端代码中,可以使用`@app.route('/info', methods=\['GET', 'POST'\])`来定义路由。当使用flask自带的web服务器进行测试时,访问`xxxx:xx/info`可以正常访问界面。但是通过nginx访问时,nginx会将末尾不带斜杠的非文件类请求加上斜杠,并给出301回应,然后重定向到有斜杠的URL下。这是因为在一些经典的WEB开发语言中,请求通常是一个文件,如.php,.aspx,.html等。而python框架实际上将一个“目录”节点作为一个html文件给出。因此,末尾需要加上斜杠,以便让nginx知道这是一个指向目录的请求。\[3\] #### 引用[.reference_title] - *1* [部署Flask应用:nginx+uwsgi+flask](https://blog.csdn.net/qq_33411065/article/details/90410667)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Nginx+uWSGI+Flask服务部署](https://blog.csdn.net/baidu_24752135/article/details/123726280)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值