python的web框架比如Flask,Django自带的服务器的目的是用于开发的,那么在生产环境下我们使用什么样的服务器呢?
web框架和web服务器之间需要进行通信,WSGI规定了一种在web服务器与web应用程序/框架之间推荐的标准接口。
pip install gunicorn
gunicorn --worker=3 project.app:app -b 0.0.0.0:9000
# 这是启动应用的方式,第一个app是模块文件的名字,第二个是文件中flask实例的名字。
# 这里worker推荐值是CPUx2+1,
python -c 'import multiprocessing; print multiprocessing.cpu_count()'
# 虚拟机只有一个CPU,所以使用3
pip install uwsgi
uwsgi --http 0.0.0.0:9000 .....
uwsgi的启动命令会复杂许多,如果需要使用可以仔细的阅读官网!
上面说的就是应用服务器!!!!!
使用python开发的站点使用的主流web服务器有Nginx,Apache,Tengine。
Nginx是一个开源高性能的HTTP服务器和反向代理。
sudo apt-get install nginx -yq
安装完后就启动了
部署Flask应用,通常都是使用一种WSGI应用服务器配合Nginx作为反向代理!!!!
正向代理: 作为一个媒介在互联网上获取资源然后返回给相关联的客户端,代理和客户端在一个局域网内,对于服务器是透明的。
反向代理: 根据客户端的需求,从后端的服务器上获取资源,再将资源返回给客户端,代理和服务器在一个局域网内,对客户端是透明的。Nginx是反向代理的最佳选择,反向代理的优点有:提高动态语言的IO处理能力,加密和SSL加速,安全,负载均衡,缓存静态内容,支持压缩。
Nginx的配置文件是block形式的,主要有6个:
block | meaning |
---|---|
main | 全局设置,基本控制功能,包含events和http两个block |
events | 事件设置,控制nginx处理连接的方式 |
http | Http设置,下面包含了server和upstream两个block |
server | 主机设置 |
upstream | 负载均衡设置 |
location | URL模式设置,在server下面,可有多个 |
适用于Nginx和Gunicorn模式的Nginx配置,.conf文件
user ubuntu ubuntu;
worker_processes 1;
worker_cpu_affinity auto;
worker_rlimit_nofile 65536;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 65536;
accept_mutex off;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
keepalive_timeout 75 20;
proxy_read_timeout 200;
keepalive_requests 100000;
client_header_timeout 10m;
client_body_timeout 10m;
client_max_body_size 20m;
send_timeout 10m;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
gzip on;
gzip_min_length 1000;
gzip_proxied any;
gzip_types text/plain text/css
application/x-javascript application/xml
application/atom+xml text/javascript;
upstream frontends {
server 127.0.0.1:8000;
server 127.0.0.1:8001;
server 127.0.0.1:8002;
# server unix:/tmp/gunicorn.sock;
}
server {
listen 80;
server_name localhost;
keepalive_timeout 5;
location ^~ /static/ {
root /home/ubuntu/web_develop/static;
}
location ~* \.(woff|eot|ttf|svg|mp4|webm|jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_redirect off;
proxy_pass http://frontends;
# 如果开启keepalive需要指定如下2项
# proxy_http_version 1.1;
# proxy_set_header Connection "";
}
}
}
替换默认的Nginx配置:
sudo cp .../nginx_gunicorn.conf /etc/nginx/nginx.conf
sudo /etc/init.d/nginx reload
# 上面的重启之前是可以来验证配置文件的语法
sudo /etc/init.d/nginx configtest
Nginx的负载均衡算法:
上面的Nginx配置设置了8000-8002三个后端端口,为了演示,启动8000端口的Gunicorn实例:
gunicorn -w 3 project.app:app -b :8000
然后通过Nginx访问flask应用;
http http://localhost
频繁通过直接访问数据库获得数据的方式对数据库造成很大的负担Memcached是一个高性能的分布式内存对象缓存系统,它通过在内存中缓存数据来减少读取数据库的次数。目前最好用的Python客户端是Libmc
首先安装Memcached:
sudo apt-get install memcached
安装后就直接启动了,这是默认的启动方式
下面使用Memcached分布式处理缓存:
/usr/bin/memcached -m 64 -p 11212 -u memcache -l 127.0.0.1 -d
下面再安装libmc:
pip install libmc
Libmc的配置:
# coding=utf-8
from libmc import (
Client, MC_HASH_MD5, MC_POLL_TIMEOUT, MC_CONNECT_TIMEOUT, MC_RETRY_TIMEOUT
)
from mc_decorator import create_decorators
mc = Client(
[
'localhost', # 默认端口为11211, 所以和下面的一个是等价的
'localhost:11212',
'localhost:11213 mc_213'
], # 第一个参数为Memcached服务器列表
do_split=True, # 默认值为false, 不接受大于1MB,设置为True,小于10MB的会被切片分段,但是不能存储大于10MB的数据
comp_threshold=0,
noreply=False,
prefix=None,
hash_fn=MC_HASH_MD5,
failover=False
)
mc.config(MC_POLL_TIMEOUT, 100) # 100 ms
mc.config(MC_CONNECT_TIMEOUT, 300) # 300 ms
mc.config(MC_RETRY_TIMEOUT, 5) # 5 s
globals().update(create_decorators(mc))
使用Memcached实例:
首先实现一个装饰器,可以在方法上定义缓存键和缓存时间。
具体方法省略,网上自行查找,我们重点介绍Redis
Redis详解
缓存:
通常用户访问的热点数据只集中在一小部分数据上,这部分数据应该存储在缓存中,这样就减轻了后端应用的负担。一共有四种缓存方式:
负载均衡:
后端服务器的各种性能可能都不一样,所以较好的服务器理应负担更大的访问量,较差的服务器理应负担较小的访问量。通过负载均衡可以把用户的请求分发到多台后端设备上,这样就均衡了服务器的负担。
常见的负载均衡工具有LVS,HAProxy,Nginx:
高可用:
现在单个节点已经无法满足我们的业务要求,所以需要让服务运行在多个节点上面,系统要有可用性,即组成系统的某些设备或者组件失效或者宕机时,并不会中断服务。
集群:
使用集群时解决高并发,海量数据问题的常用手段,当单体服务器不能负担的时候,不要盲目想着提高服务器的性能,而是增加一台服务器来分担原来的压力。一般大型网站的大部分页面都不是一个单独的应用来提供服务,而是被分割成了多个部分,每个部分都由独立部署的一个服务器集群来提供服务。
不同用途的服务器对硬件资源的要求是不一样的:
应用服务器需要处理大量的业务逻辑,所以需要更快的CPU
文件服务器需要储存大量用户的文件,所以需要更大的硬盘
数据库服务器需要快速的写入数据和检索到要查询的数据缓存,所以需要更快的硬盘和更大的内存