电影订票系统后台开发(5)Nginx 实现反向代理和负载均衡

电影订票系统后台开发(5)Nginx 实现反向代理和负载均衡
完整项目请戳 猿眼电影订票系统

Let’s go

项目开发环境

  • Deepin-Linux 15.4
  • Python 2.7.12
  • PyCharm
  • Flask
  • Nginx

代理

代理分为正向代理和反向代理,两者的区别在于代理的对象不一样:正向代理代理的对象是客户端,反向代理代理的对象是服务端

正向代理

这里先讲一下正向代理(Forward),正向代理就是我们常说的代理,正向代理是一个位于客户端和目标服务器之间的服务器(代理服务器),为了从目标服务器取得内容,客户端向代理服务器发送一个请求,然后代理服务器向目标服务器转交请求并将获得的内容返回给客户端。
正向代理的过程,它隐藏了真实的请求客户端,目标服务端不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替来请求,某些科学上网工具扮演的就是典型的正向代理角色。用浏览器访问Google被墙,可以在国外搭建一台代理服务器,让代理帮我们去请求google.com,代理把请求返回的相应结构再返回给我。
正向代理
正向代理的主要作用:

  • 访问本无法访问的目标服务器
  • 加速访问目标服务器
  • 缓存
  • 客户端访问授权
  • 隐藏客户端

反向代理

反向代理(Reverse Proxy)是指以代理服务器来接受互联网上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给互联网上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
对于客户端而言反向代理服务器它就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理服务器发送请求,接着反向代理服务器将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,反向代理隐藏了真实的服务端,当我们访问百度的时候,背后可能有很多台服务器在提供服务,但是我们无需知道这些服务器,反向代理服务器会讲请求分发到各个服务器去,并返回我们要的数据。
反向代理
反向代理的主要作用:

  • 保护网站安全:任何来自互联网的请求都必须先经过代理服务器;
  • 通过配置缓存功能加速Web请求:可以缓存真实Web服务器上的某些静态资源,减轻真实Web服务器的负载压力;
  • 实现负载均衡:充当负载均衡服务器均衡地分发请求,平衡集群中各个服务器的负载压力;

反向代理服务器不止一个的时候,我们可以把它们做成集群,当更多的用户访问资源服务器的时候,让不同的代理服务器去应答不同的用户,然后发送不同用户需要的资源。反向代理服务器像正向代理服务器一样拥有缓存的作用,它可以缓存原始资源服务器的资源,而不是每次都要向原始资源服务器请求数据,特别是一些静态文件。

Nginx

Nginx(“engine x”)是一个轻量级高性能的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,其特点是占有内存少,并发能力强, 可实现负载均衡,拦截静态请求, 伪静态化并缓存,减少动态请求数量, 访问控制,限速,限连接数等等。

安装

使用命令sudo apt-get install nginx即可进行安装。在该项目中使用 Nginx 来代理静态文件并进行负载均衡,将客户端的请求分发到不同的服务器上。Nginx 官方文档

调度算法

upstream是 Nginx 的 HTTP Upstream 模块,这个模块通过一个简单的调度算法来实现客户端IP地址到后端服务器的负载均衡。在 Nginx 的配置文件中,可以通过 upstream 指令指定一个负载均衡器的名称。这个名称可以任意指定,在后面需要用到的地方直接调用即可。Nginx的负载均衡模块目前支持5种调度算法:

  • 轮询(默认)。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。
1
2
3
4
upstream backserver {
server 192.168.0.14;
server 192.168.0.15;
}
  • 指定权重。指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
1
2
3
4
upstream backserver {
server 192.168.0.14 weight=1;
server 192.168.0.15 weight=2;
}
  • ip_hash。每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题。
1
2
3
4
5
upstream backserver {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
  • fair(第三方)。这是比上面两个更加智能的负载均衡算法。这种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块。
1
2
3
4
5
upstream backserver {
server server1;
server server2;
fair;
}
  • url_hash(第三方)。此方法按访问url的hash结果来分配请求,使每个url重定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx的hash软件包。
1
2
3
4
5
6
upstream backserver {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}

upstream支持的状态参数

在HTTP Upstream模块中,可以通过server指令指定后端服务器的IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。常用的状态有:

  • down,表示当前的server暂时不参与负载均衡。
  • backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
  • max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream模块定义的错误。
  • fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。

注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。

最后附上该项目的 Nginx 配置文件,更多详细设置请点击 很详细的Nginx配置说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
user root;
worker_processes 4; # 工作进程数目,通常为CPU数量的两倍
pid /run/nginx.pid; # 存储进程号的文件

events {
# 每个工作进程允许的最大连接数量,理论上每台Nginx服务器的最大连接数为worker_processes * worker_connections。
worker_connections 768;
}

http {
# 通过IP哈希的方式将请求分配至相应的服务器
upstream static {
ip_hash;
server 118.89.35.155:8080 max_fails=3 fail_timeout=1000;
server 127.0.0.1:5001 max_fails=3 fail_timeout=1000;
}

# 通过指定权重的方式将请求分配至相应的服务器
upstream backend {
server 127.0.0.1:5000 weight=2 max_fails=3 fail_timeout=1000;
server 123.207.233.226:1234 weight=1 max_fails=3 fail_timeout=1000;
server 119.29.238.202:5000 weight=1 max_fails=3 fail_timeout=1000;
server 118.89.44.14:5000 weight=1 max_fails=3 fail_timeout=1000;
}

server {
listen 8080; # 配置监听端口
server_name localhost; # 配置访问域名

# 配置静态文件(用户头像和电影海报)代理
location ^~ /static/images {
root /root/Desktop/MonkeyEye-Server/Flask-Server/app;
expires max;
}

location ^~ /api/users {
proxy_pass http://127.0.0.1:5000/api/users;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header Set-Cookie; # 传递HTTP头部Set-Cookie字段
proxy_buffering off; # 禁止缓存
}

location ^~ /api/ {
# 请求转向backend定义的服务器列表,即反向代理,对应upstream负载均衡器,也可以proxy_pass http://ip:port。
proxy_pass http://backend/api/;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header Set-Cookie;
proxy_buffering off;
}

location / {
proxy_pass http://static;

proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_redirect off;
# 缓冲区代理缓冲用户端请求的最大字节数。
client_body_buffer_size 128k;
# 设置代理服务器(Nginx)从后端服务器读取并保存用户头信息的缓冲区大小,默认与proxy_buffers大小相同,其实可以将这个指令值设的小一点。
proxy_buffer_size 4k;
# proxy_buffers缓冲区,Nginx针对单个连接缓存来自后端服务器的响应。
proxy_buffers 4 128k;
# 当 proxy_buffers 放不下后端服务器的响应内容时,会将一部分保存到硬盘的临时文件中,这个值用来设置最大临时文件大小,默认1024M,它与 proxy_cache 没有关系。大于这个值,将从upstream服务器传回。
proxy_temp_file_write_size 256m;
}
}

# 开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,减少用户空间到内核空间的上下文切换。
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65; # 长连接超时时间,单位是秒。
types_hash_max_size 2048;

include /etc/nginx/mime.types;
default_type application/octet-stream;

# 日志存放路径
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

# 开启gzip压缩输出,减少网络传输。
gzip on;
gzip_disable "msie6";

# gzip压缩比,1~9,压缩比越大处理速度越慢
gzip_comp_level 6;
# 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。
gzip_buffers 16 8k;
gzip_http_version 1.1;
# 匹配mime类型进行压缩。
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png image/jpg;
}

参考链接

文章目录
  1. Let’s go
    1. 项目开发环境
    2. 代理
      1. 正向代理
      2. 反向代理
    3. Nginx
      1. 安装
      2. 调度算法
      3. upstream支持的状态参数
  2. 参考链接
|
-->