nginx 和 uwsgi 实现简易负载均衡

nginx+uwsgi 实现简易负载均衡

之前使用django+nginx+uwsgi开发部署的博客,只使用了一台uwsgi内部服务器,对于博客网站访问量不是特别大的时候其实够用了。但是,如果对于高并发的应用来说,一台服务器肯定不够,这样不仅会导致一台服务器压力过大,严重的话,会产生单点故障,唯一的一台服务器挂了,那么整个应用也就game over了,这是就需要多台服务器实现负载均衡,一台挂了,另一台接着顶上去,这样几乎使用户察觉不到有台服务器挂了。


简单介绍下nginx和uwsgi

nginx:是一个反向代理服务器。反向代理的好处是外网客户端如果要访问内部服务器(uwsgi,tomcat,文件服务器等),客户端是不知道真正的内部服务器是谁,在哪,它只知道用来做反向代理的服务器—nginx,通过向nginx发出请求,nginx再将请求分发给内部服务器,内部服务器处理请求,再将响应返回给nginx,nginx最后将响应结果返回给客户端。

或许看到这里,你可能有点迷糊,为什么需要nginx作为中间人呢?

原因如下:

① nginx自身具备一定的缓存能力。它对静态资源的处理性能特别高,因此当某个用户发送多次同样的请求,如果nginx中存了之前相应的结果缓存,就直接将响应的缓存发送给客户端。减少了访问服务器的次数,降低服务器处理的压力。

注:nginx对静态资源处理性能很高,但是对于动态资源,很难处理,还是要发送给内部服务器进行处理响应返回结果。

② 有了nginx,就可以对不同的请求分发到不同的内部服务器中,因而内部服务器就可以组件一个集群。至于讲请求转发到集群中的哪个服务器,就需要看nginx.conf中配置的各个内部服务器权重了。

我用nginx,uwsgi,client举个例子:

1.client发送给nginx一个请求:”hey boy~,what’s your name?”

2.nginx收到请求,思考:”i have a mass of sons? who is client asking?”,(如果内部服务器是集群的话),就会按照各个服务器的weigth来发送给weight最高的服务器。

3.某个uwsgi收到了请求,回答道:”my name is syz”,并将它响应给nginx,nginx接收到响应,将响应发送给client。

4.紧接着,client又来发送请求了”hey boy~,what’s your name?”

5.此时nginx收到请求,哟嚯,我知道答案(缓存数据尚未过期),于是将缓存数据发送个client,而不用去请求内部服务器,使得内部服务器性能更加稳定。

注:实现负载均衡可以有效的增加并发量,假如一台uwsgi服务器1000个并发,那么5个uwsgi组成的集群,就可以达到5000个并发量。


nginx+uwsgi实现负载均衡

之前我是用了nginx+1个uwsgi部署项目,现在我多增加1个uwsgi,实现负载均衡。


具体步骤如下:

1.配置第二个uwsgi服务器的配置文件uwsgi2.ini

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[uwsgi]
chdir = /home/admin/mblog
# wsgi应用
module = mblog.wsgi:application
#使用nginx做反向代理的服务器地址
socket = 127.0.0.1:8004
# 使用主线程
master = true
# 分4条进程
processes = 4
threads = 2
# 运行日志
daemonize = /home/admin/mblog/run2.log
# 只记录发生错误的日志
disable-logging = true
wsgi-file = /home/admin/mblog/mblog/wsgi.py
# 记录进程pid
pidfile = /home/admin/mblog/uwsgi2.pid

注:

① 指令前后不能有空格

② 不同uwsgi服务器之间只需要修改socket,daemonize,pidfile就可以了,还有一些配置我没有使用。

配置完后,sudo uwsgi --ini uwsgi.ini启动服务器。

到此为止,2个服务器组件的集群就创建好并启动好了,接下来是配置nginx,使得进入nginx的请求进行反向代理到集群中的不同服务器上。


配置nginx反向代理


具体步骤如下:

1.进入etc/nginx/nginx.conf,增加内部服务器集群。

1
2
3
4
5
6
7
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
# 在这里添加 服务器集群,集群名字叫做SYZ,weight表示每个服务器的接收请求所占的权重,权重高的一般为主服务器。
upstream SYZ{
server 127.0.0.1:8002 weight=10;
server 127.0.0.1:8004 weight=10;
}

2.进入sites-availabledefault配置文件中,

1
2
3
4
5
6
7
8
9
10
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
# 包含uwsgi的参数
include uwsgi_params; #
# uwsgi_pass 127.0.0.1:8002;
# 反向代理到uwsgi的集群上
uwsgi_pass SYZ;
}

配置完毕后,重启nginx服务器,sudo service nginx restart


说个题外话

阿里的学生机其实是带不动2个uwsgi组成的集群的,我用我的博客做实验,2G的云服务器上跑了redis,nginx,supervisord管理的celery,mysql,2个uwsgi,会导致mysql被挤掉。

跑mysql所占的内存至少在512M(官网给出的解释),1个uwsgi占了600+M内存,2个就是1200+M内存,nginx估摸着也要500+M,redis+celery估摸着300+M,这样算来已经超过了2G。

我跑了一个uwsgi+redis+celery+mysql+nginx,就花费了约1.8G。所以要想玩集群有两种建议:

① 买一个内存大点的服务器。

② 将mysql分出去,单独买一个云数据库。

这样就可以开心的玩集群了。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!