网站架构

【笔记】常用网站架构

作者 Trekerz 日期 2017-02-27
网站架构

一、 Python应用服务器

1. WSGI协议

规定了一种在Web服务器与Web应用程序/框架之间推荐的标准接口,以确保Web应用程序在不同的Web服务器之间具有可移植性,有了它Web开发者就可以任意选择适合自己的组合。

2. 常见的WSGI容器(用于生产环境中的)

WSGI是一个同步接口,所以Tornado的WSGI容器是无法实现异步的。主流的选择是Gunicorn和uWSGI。

(1) Gunicorn

易于配置,兼容性好,在豆瓣中广泛使用,支持多种Worker模式(同步Worker、异步Worker、异步IO Worker)。

Worker的个数并不是越多越好,推荐CPU数×2+1。

(2) uWSGI

用C编写,实现了自有的uWSGI协议的Web服务器。自带丰富插件,包括核心组件(进程管理、监控、IPC)和网关组件(负载均衡、代理、路由)。

二、 Web服务器Nginx

1. Web服务器与应用服务器的区别

​ (1) Web服务器负责处理HTTP协议;

​ 应用服务器既可以处理HTTP内容,也能处理其他协议,比如RPC。

​ (2) Web服务器用于处理静态页面的内容,对于脚本语言产生的动态内容要通过WSGI接口交给应用服务器。

​ (3) 一般应用服务器都集成了Web服务器,但主要是为了调试方便,处于性能和稳定性考虑,应用服务器并不能在生产环境中使用。

2. Nginx的优点

3. Nginx安装

4. 使用Nginx部署Flask应用

部署Flask应用时,通常都是使用一种WSGI应用服务器搭配Nginx作为反向代理。

(1) 反向代理和正向代理

​ a. 正向代理和反向代理的概念;

​ b. Nginx是反向代理的最佳选择。

​ c. 反向代理的优点:提高IO能力;加密加速;安全;负载均衡;缓存静态内容;支持压缩。

(2) Nginx的配置

​ a. 以块(即“{}”)的形式。

​ b. 也有Nginx和Gunicorn共用一个配置文件的情况。

(3) 负载均衡算法

Nginx支持4种调度算法:

​ a. round-robin:默认轮询算法。每个请求按时间顺序逐一分配到不同后端服务器,若有服务器宕机会被自动剔除。

​ b. least_conn:请求会被发送到活跃连接最少的服务器上。

​ c. ip_hash:按访问IP的哈希结果分配请求。即同一个IP会固定访问同一个服务器。

​ d. hash:按某个键的哈希结果分配。

(4) 负载均衡中的状态参数

Upstream模块(Nginx中关于负载均衡的配置)中支持4种状态:down、max_fails、fail_timeout、backup。

(5) 通过Gunicorn启动Flask应用
(6) 通过uWSGI启动Flask应用
(7) TCP/IP Socket和UNIX Socket区别

​ a. UNIX Socket是同一台服务器上不同进程间的通信机制;而TCP/IP是网络上不同服务器之间进程的通信机制,也可以让同一台服务器不同进程通信。

​ b. 有实验证明,UNIX Socket比TCP/IP Socket方式要快31%,所以在同一台服务器中优先使用UNIX Socket。

三、 缓存系统Memcached

通过在内存中缓存数据来减少读取数据库的次数,减轻应用服务器对于数据库大量访问造成的负担,提高Web应用的速度。

守护进程用C编写,客户端则可以使用任何语言。Python中的客户端有Python-memcached、Pymemcached(Pinterest开源客户端)、Python-Libmemcached(豆瓣曾经的开源客户端;Cython实现;豆瓣使用它的时候打过补丁)、Pylibmc、Libmc(测试对比中最;豆瓣现任;支持一致性哈希的方式一次性与多个Memcached节点交互)。

1. Libmc安装配置(首先装Memcached)

2. 使用原生SQL缓存

3. 常用缓存更新策略

a. 懒惰式加载

​ 客户端先查Memcached,若命中则返回,若没命中(没有数据或数据过期)则从数据库中获得最新数 据,并传一份给Memcached。

​ 在高并发的场景下,突然失效会让后端数据库的压力骤增。

b. 主动更新

​ 默认缓存永不失效。当有数据需要更新时,同时也会把最新数据写回到Memcached中。

​ 这种更新如果耗时过长,应该注意使用异步更新,如放在消息队列中。

4. Memcached使用的经验

​ a. 批量获取时尽可能使用“mc.get_multi”代替“mc.get”,能减少网络请求次数。

​ b. 对缓存全部更新,可以直接升级缓存键(版本号)。

​ c. 批量更新缓存的时候应该尽量少给后端数据库带来压力,需要对缓存预热。

​ d. Memcached不仅能缓存SQL查询结果,还能缓存HTML。

​ e. 不鼓励缓存的值大于1MB(Memcached协议规定大小)。

​ f. 不鼓励使用读/写/删之外的接口,会给运维带来困难。