一般不会直接使用flask进行部署,因为扛不住高并发
一般需要wsgi
这里我是使用的gunicorn
使用之前需要安装gunicorn
pip install gunicorn
然后就可以试一下:
root@zl:/opt# gunicorn -h
usage: gunicorn [OPTIONS] [APP_MODULE]
optional arguments:
-h, --help show this help message and exit
-v, --version show program's version number and exit
-c CONFIG, --config CONFIG
The Gunicorn config file. [None]
-b ADDRESS, --bind ADDRESS
The socket to bind. [['127.0.0.1:8000']]
--backlog INT The maximum number of pending connections. [2048]
-w INT, --workers INT
The number of worker processes for handling requests.
[1]
-k STRING, --worker-class STRING
The type of workers to use. [sync]
--threads INT The number of worker threads for handling requests.
[1]
--worker-connections INT
The maximum number of simultaneous clients. [1000]
--max-requests INT The maximum number of requests a worker will process
before restarting. [0]
--max-requests-jitter INT
The maximum jitter to add to the *max_requests*
setting. [0]
-t INT, --timeout INT
Workers silent for more than this many seconds are
killed and restarted. [30]
--graceful-timeout INT
Timeout for graceful workers restart. [30]
--keep-alive INT The number of seconds to wait for requests on a Keep-
Alive connection. [2]
--limit-request-line INT
The maximum size of HTTP request line in bytes. [4094]
--limit-request-fields INT
Limit the number of HTTP headers fields in a request.
[100]
--limit-request-field_size INT
Limit the allowed size of an HTTP request header
field. [8190]
--reload Restart workers when code changes. [False]
--reload-engine STRING
The implementation that should be used to power
:ref:`reload`. [auto]
--reload-extra-file FILES
Extends :ref:`reload` option to also watch and reload
on additional files [[]]
--spew Install a trace function that spews every line
executed by the server. [False]
--check-config Check the configuration. [False]
--preload Load application code before the worker processes are
forked. [False]
--no-sendfile Disables the use of ``sendfile()``. [None]
--reuse-port Set the ``SO_REUSEPORT`` flag on the listening socket.
[False]
--chdir CHDIR Chdir to specified directory before apps loading.
[/opt]
-D, --daemon Daemonize the Gunicorn process. [False]
-e ENV, --env ENV Set environment variable (key=value). [[]]
-p FILE, --pid FILE A filename to use for the PID file. [None]
--worker-tmp-dir DIR A directory to use for the worker heartbeat temporary
file. [None]
-u USER, --user USER Switch worker processes to run as this user. [0]
-g GROUP, --group GROUP
Switch worker process to run as this group. [0]
-m INT, --umask INT A bit mask for the file mode on files written by
Gunicorn. [0]
--initgroups If true, set the worker process's group access list
with all of the [False]
--forwarded-allow-ips STRING
Front-end's IPs from which allowed to handle set
secure headers. [127.0.0.1]
--access-logfile FILE
The Access log file to write to. [None]
--disable-redirect-access-to-syslog
Disable redirect access logs to syslog. [False]
--access-logformat STRING
The access log format. [%(h)s %(l)s %(u)s %(t)s
"%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"]
--error-logfile FILE, --log-file FILE
The Error log file to write to. [-]
--log-level LEVEL The granularity of Error log outputs. [info]
--capture-output Redirect stdout/stderr to specified file in
:ref:`errorlog`. [False]
--logger-class STRING
The logger you want to use to log events in Gunicorn.
[gunicorn.glogging.Logger]
--log-config FILE The log config file to use. [None]
--log-config-dict LOGCONFIG_DICT
The log config dictionary to use, using the standard
Python [{}]
--log-syslog-to SYSLOG_ADDR
Address to send syslog messages. [udp://localhost:514]
--log-syslog Send *Gunicorn* logs to syslog. [False]
--log-syslog-prefix SYSLOG_PREFIX
Makes Gunicorn use the parameter as program-name in
the syslog entries. [None]
--log-syslog-facility SYSLOG_FACILITY
Syslog facility name [user]
-R, --enable-stdio-inheritance
Enable stdio inheritance. [False]
--statsd-host STATSD_ADDR
``host:port`` of the statsd server to log to. [None]
--dogstatsd-tags DOGSTATSD_TAGS
A comma-delimited list of datadog statsd (dogstatsd)
tags to append to statsd metrics. []
--statsd-prefix STATSD_PREFIX
Prefix to use when emitting statsd metrics (a trailing
``.`` is added, []
-n STRING, --name STRING
A base to use with setproctitle for process naming.
[None]
--pythonpath STRING A comma-separated list of directories to add to the
Python path. [None]
--paste STRING, --paster STRING
Load a PasteDeploy config file. The argument may
contain a ``#`` [None]
--proxy-protocol Enable detect PROXY protocol (PROXY mode). [False]
--proxy-allow-from PROXY_ALLOW_IPS
Front-end's IPs from which allowed accept proxy
requests (comma separate). [127.0.0.1]
--keyfile FILE SSL key file [None]
--certfile FILE SSL certificate file [None]
--ssl-version SSL_VERSION
SSL version to use. [_SSLMethod.PROTOCOL_TLS]
--cert-reqs CERT_REQS
Whether client certificate is required (see stdlib ssl
module's) [VerifyMode.CERT_NONE]
--ca-certs FILE CA certificates file [None]
--suppress-ragged-eofs
Suppress ragged EOFs (see stdlib ssl module's) [True]
--do-handshake-on-connect
Whether to perform SSL handshake on socket connect
(see stdlib ssl module's) [False]
--ciphers CIPHERS SSL Cipher suite to use, in the format of an OpenSSL
cipher list. [None]
--paste-global CONF Set a PasteDeploy global config variable in
``key=value`` form. [[]]
--strip-header-spaces
Strip spaces present between the header name and the
the ``:``. [False]
事先建立一个名为test.py的flask文件:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "ok"
if __name__=='__main__':
app.run(host='0.0.0.0',port=9000)
为了使用工作模式为gevent,需要手动安装
pip install gevent==1.4
需要使用1.4以上的版本才能使用
准备就绪,现在可以运行一下服务了:
root@zl:/opt# gunicorn test:app -b 0.0.0.0:9000 -k gevent -w 4 --log-level debug
[2021-03-24 17:29:42 +0800] [23684] [DEBUG] Current configuration:
config: None
bind: ['0.0.0.0:9000']
backlog: 2048
workers: 4
worker_class: gevent
threads: 1
worker_connections: 1000
max_requests: 0
max_requests_jitter: 0
timeout: 30
graceful_timeout: 30
keepalive: 2
limit_request_line: 4094
limit_request_fields: 100
limit_request_field_size: 8190
reload: False
reload_engine: auto
reload_extra_files: []
spew: False
check_config: False
preload_app: False
sendfile: None
reuse_port: False
chdir: /opt
daemon: False
raw_env: []
pidfile: None
worker_tmp_dir: None
user: 0
group: 0
umask: 0
initgroups: False
tmp_upload_dir: None
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
forwarded_allow_ips: ['127.0.0.1']
accesslog: None
disable_redirect_access_to_syslog: False
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
errorlog: -
loglevel: debug
capture_output: False
logger_class: gunicorn.glogging.Logger
logconfig: None
logconfig_dict: {}
syslog_addr: udp://localhost:514
syslog: False
syslog_prefix: None
syslog_facility: user
enable_stdio_inheritance: False
statsd_host: None
dogstatsd_tags:
statsd_prefix:
proc_name: None
default_proc_name: test:app
pythonpath: None
paste: None
on_starting: <function OnStarting.on_starting at 0x7f729a6ed1e0>
on_reload: <function OnReload.on_reload at 0x7f729a6ed2f0>
when_ready: <function WhenReady.when_ready at 0x7f729a6ed400>
pre_fork: <function Prefork.pre_fork at 0x7f729a6ed510>
post_fork: <function Postfork.post_fork at 0x7f729a6ed620>
post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f729a6ed730>
worker_int: <function WorkerInt.worker_int at 0x7f729a6ed840>
worker_abort: <function WorkerAbort.worker_abort at 0x7f729a6ed950>
pre_exec: <function PreExec.pre_exec at 0x7f729a6eda60>
pre_request: <function PreRequest.pre_request at 0x7f729a6edb70>
post_request: <function PostRequest.post_request at 0x7f729a6edbf8>
child_exit: <function ChildExit.child_exit at 0x7f729a6edd08>
worker_exit: <function WorkerExit.worker_exit at 0x7f729a6ede18>
nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f729a6edf28>
on_exit: <function OnExit.on_exit at 0x7f729a1e40d0>
proxy_protocol: False
proxy_allow_ips: ['127.0.0.1']
keyfile: None
certfile: None
ssl_version: 2
cert_reqs: 0
ca_certs: None
suppress_ragged_eofs: True
do_handshake_on_connect: False
ciphers: None
raw_paste_global_conf: []
strip_header_spaces: False
[2021-03-24 17:29:42 +0800] [23684] [INFO] Starting gunicorn 20.0.4
[2021-03-24 17:29:42 +0800] [23684] [DEBUG] Arbiter booted
[2021-03-24 17:29:42 +0800] [23684] [INFO] Listening at: http://0.0.0.0:9000 (23684)
[2021-03-24 17:29:42 +0800] [23684] [INFO] Using worker: gevent
[2021-03-24 17:29:42 +0800] [23687] [INFO] Booting worker with pid: 23687
[2021-03-24 17:29:42 +0800] [23688] [INFO] Booting worker with pid: 23688
[2021-03-24 17:29:42 +0800] [23689] [INFO] Booting worker with pid: 23689
[2021-03-24 17:29:42 +0800] [23690] [INFO] Booting worker with pid: 23690
[2021-03-24 17:29:42 +0800] [23684] [DEBUG] 4 workers
可以测试一下请求:
我们也可以看一下进程:
root@zl:/opt# ps -ef|grep python
root 727 1 0 13:52 ? 00:00:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
root 799 1 0 13:52 ? 00:00:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
root 2014 1992 0 13:52 pts/0 00:00:00 python
zl 11792 1 0 13:57 tty2 00:00:03 /usr/bin/python3 /usr/bin/update-manager --no-update --no-focus-on-map
zl 23338 3204 0 17:12 pts/1 00:00:00 /opt/AN/bin/python /opt/AN/bin/ipython
root 23624 1992 0 17:19 pts/0 00:00:00 /opt/AN/bin/python /opt/AN/bin/gunicorn test:app -b 0.0.0.0:9000 -k gevent -w 4 --log-level debug
root 23627 23624 0 17:19 pts/0 00:00:00 /opt/AN/bin/python /opt/AN/bin/gunicorn test:app -b 0.0.0.0:9000 -k gevent -w 4 --log-level debug
root 23628 23624 0 17:19 pts/0 00:00:00 /opt/AN/bin/python /opt/AN/bin/gunicorn test:app -b 0.0.0.0:9000 -k gevent -w 4 --log-level debug
root 23629 23624 0 17:19 pts/0 00:00:00 /opt/AN/bin/python /opt/AN/bin/gunicorn test:app -b 0.0.0.0:9000 -k gevent -w 4 --log-level debug
root 23630 23624 0 17:19 pts/0 00:00:00 /opt/AN/bin/python /opt/AN/bin/gunicorn test:app -b 0.0.0.0:9000 -k gevent -w 4 --log-level debug
root 23664 23405 0 17:21 pts/2 00:00:00 grep --color=auto python
可以发现有5个进程,1个是主进程+4个工作进程
具体使用参数可以参考:https://www.itnotebooks.com/?p=531