面对网站服务器端负载增大的问题,是“拿15万¥买一台服务器”来解决,还是靠“加三倍服务器”来解决?还是用其它一些办法?

对于一个访问量日益增加的网站架构而言,从单机到集群、从集群到分布式,架构演化是必然的。

接手环境,分析瓶颈,扩展架构

笔者现在的环境在刚接手时算是单机LAMP环境。在单机LAMP环境时,由于访问量逐渐变大,网站会经常出现打不开的情况,为了解决这个问题在LAMP前端临时加了一台vanish来缓存一些静态文件,从而减轻了web服务器的负载。再到后来为了满足业务访问需求,将架构改为CDN+Nginx负载均衡(反向代理)+LNMP+代码层缓存+MySQL主从,从而将网站整体负载性能提升15倍,且访问速度也得到很大提升。

负载均衡为什么要选择使用Nginx呢?

普通负载均衡用LVS,文艺负载均衡用Nginx/F5/HAproxy,XX负载均衡用NLB

LVS:四层负载均衡的典型代表,目前已经被添加到linux发行版的内核。LVS用于较为成熟,因此不再做类述,在此推荐一篇不错的LVS文章:《互联网运营智慧》第六章负载均衡及服务器集群(LVS)

Nginx/F5/HAproxy:均为七层负载均衡,F5为商业设备,功能强大,但价格不菲,所以在此不做讨论;HAproxy为重量级的七层负载均衡/反向代理程序,一般应用于大中型站点;而Nginx虽然属于轻量级产品,但是功能毫不逊色与HAproxy,如可以对静态文件可以实现缓存、可以通过URL、目录结构、静动分离对网站实现分流,还可以实现对后端服务器状态码健康检测、对网络依赖较小、对虚拟主机支持友好等等,这也是笔者选择Nginx来做负载均衡的原因。

NLB:windows下的东东,性能、可操作性可想而知。在此也提醒一下各位同仁,针对HTTP类的应用千万不要选择使用windows,如同样的业务放linux上只需两台服务器,而放windows上可能会需要三台甚至更多,运维/硬件采购成本也会增加,同时license也是一笔不小的费用。国内较大的一些web站点后端架构为windows的分别有京东商城、当当网、凡客诚品、麦包包。

使用Nginx构建负载均衡时需要注意的几个问题

Session同步:由于笔者所维护的架构硬件预算受限,所以在整个架构中没有共享存储,针对于session处理,笔者使用ip_hash来解决后端服务器session问题。另外,关于存储session,推荐使用redis或memcached(感谢小卫、小灰狼 两位兄弟的建议)。

网站代码存储:还是由于没有共享存储,所以笔者每台web服务器本地均存放一份代码,为了保证多台web服务器的代码数据一致性,使用rsync+inotify实现动态同步(具体实现方法会在后面的文章中介绍)。倘若硬件条件允许的情况下,推荐使用NFS来存储;若考虑到NFS无法满足性能需求,可以将NFS的硬盘换成SSD或者使用分布式文件系统来解决。

负载均衡模式选择:在不受session困扰的情况下,负载均衡模式可以使用weight,因为ip_hash会有导致后端服务器负载不均的情况出现。

开始部署Nginx和Keepalived

为了避免负载均衡出现单点故障,所以使用keepalived对Nginx负载均衡做了HA,也就是说当主负载均衡发生软硬件故障时,负载均衡服务将有备用负载均衡服务器自动接管服务,环境拓扑如下:

Vip:192.168.1.100

Nginx-proxy-master:192.168.1.101

Nginx-proxy-backup:192.168.1.102

安装Nginx与Keepalived

在Nginx-proxy-master和Nginx-proxy-backup上分别安装Nginx、Keepalived,两台主机安装步骤相同

安装Nginx

#yum -y install pcre pcre-devel
#useradd www -s /sbin/nologin
#tar zxvf nginx-0.7.62.tar.gz
#cd nginx-0.7.62
#./configure \
--prefix=/usr/local/nginx \
--user=www \
--group=www \
--with-http_stub_status_module \
--with-http_ssl_module
#make && make install

安装Keepalived

#tar zxvf keepalived-1.1.17.tar.gz
#cd cd keepalived-1.1.17
#./configure --prefix=/usr/local/keepalived
#make && make install
#rm -rf /usr/local/keepalived/etc/keepalived/keepalived.conf
#mkdir /etc/keepalived

配置Nginx

注:Nginx-proxy-master和Nginx-proxy-backup的Nginx配置相同
#more /usr/local/nginx/conf/nginx.conf
user www www;
worker_processes 4;
error_log logs/error.log crit;
pid logs/nginx.pid;
worker_rlimit_nofile 51200; events {
use epoll;
worker_connections 51200;
} http {
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 256;
client_header_buffer_size 256k;
large_client_header_buffers 4 256k;
keepalive_timeout 120;
client_max_body_size 50m;
client_body_buffer_size 256k;
server_tokens off; gzip on;
gzip_min_length 1k;
gzip_buffers 4 1024k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types text/plain application/x-javascript text/css application/xml; #gzip_vary on;
proxy_hide_header Vary; proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_buffer_size 16k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k; sendfile on;
tcp_nodelay on;
# add_header Cache-Control no-cache; upstream blog.luwenju.com { ip_hash;
server 192.168.1.201:80;
server 192.168.1.202:80;
server 192.168.1.203:80;
} server {
listen 80;
server_name blog.luwenju.com;
location / {
index index.php;
proxy_pass http://blog.luwenju.com;
proxy_set_header Host $host;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_504; proxy_set_header X-Forwarded-For $remote_addr;
}
location /NginxStatus {
stub_status on;
allow 192.168.1.0/24;
}
log_format blog.luwenju.com '$remote_addr - $remote_user [$time_local] $upstream_addr $upstream_status $request' '"$status" $body_bytes_sent "$http_referer"' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /usr/local/nginx/logs/blog.luwenju.com_access.log blog.luwenju.com;
}
}

说明:upstream为服务器池。以本配置文件为例,upstream中共包含三台web服务器,负载均衡方式为ip_hash。server为主机,用于为upstream内的三台web服务器实现反向代理,从而到达负载均衡的目的。在本配置文件中只设置了一个主机(server),如果要实现虚拟主机,将一个server分别对应一个upstream即可。

另外,还有两个关于日志设置的问题:

负载均衡上是否需要开启access_log:系统/程序刚上线时需要开启,用于Nginx调试,后期运行稳定后建议将日志打印关闭,因为对于访问量较大的网站来说大量日志写入磁盘也会导致磁盘性能下降。

如何设置日志格式:可能使用Nginx部署过负载均衡的朋友都知道,当把Nginx反向代理服务器部署在web前端时,web服务器的access_log就无法获取用户的真实ip地址了,针对这个问题的解决办法会放到后面的文章中<Nginx日志设置及日志分析>

在Nginx-proxy-master服务器上配置Keepalived

#more /etc/keepalived/keepalived.conf
! Configuration File for keepalived global_defs {
router_id nginx-proxy-ha
} vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight 2
} vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
} track_interface {
eth0 } track_script {
check_nginx
} virtual_ipaddress {
192.168.1.100
}
}

有关check_nginx.sh的说明:如果Nginx-proxy-master上的nginx进程由于某种原因停止了,但是keepalived进程还正常运行着,这时候Nginx-proxy-backup上的keepalived会认为Nginx-proxy-master是正常的(因为master检测到backup的keepalived进程还存在),所以在这种情况下当Nginx进程死亡的时候Keepalived也不会发生故障转移。那么这个脚本的作用就是让keepalived实时监控Nginx进程,当发现Nginx进程不存在的时候自动将本机的keepalived进程杀死,从而实现故障转移,脚本内容如下(注:Nginx-proxy-master和Nginx-proxy-backup上此脚本内容均一样)

#more /etc/keepalived/check_nginx.sh
#!/bin/bash
if [ "$(ps -ef | grep "nginx: master process"| grep -v grep )" == "" ] then
killall -9 keepalived fi

在Nginx-proxy-backup服务器上配置Keepalived

注:Nginx-proxy-backup上keepalived的配置与Nnginx-proxy-master只有两处不同,state为BACKUP、优先级低于master

#more /etc/keepalived/keepalived.conf
! Configuration File for keepalived global_defs {
router_id nginx-proxy-ha
} vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh" interval 2
weight 2
} vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 180
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
} track_interface {
eth0 } track_script {
check_nginx
} virtual_ipaddress {
192.168.1.100
}
}

启动Nginx和Keepalived

#/usr/local/nginx/sbin/nginx
#/usr/local/keepalived/sbin/keepalived –D #echo “/usr/local/nginx/sbin/nginx”>>/etc/rc.local
#echo “/usr/local/keepalived/sbin/keepalived –D” >>/etc/rc.local

测试负载均衡是否正常工作

1、打开浏览器,分别访问Nginx-proxy-master、Nginx-proxy-backup、vip,如都能访问到后端web内容,则说明如上所有配置正确

2、杀死Nginx-proxy-master服务器上的Nginx进程,观察keepalived进程是否自动消失、观察vip是否已经转移到了Nginx-proxy-backup服务器上,如杀死Nginx进程后,keepalived进程也随之消失,且vip已经转移到Nginx-proxy-backup服务器,则说明Nginx-proxy-master可正常实现故障转移

3、依次启动 Nginx-proxy-master的Nginx、Keepalived(必须先启动Nginx后启动Keepalived。如果先启动Keepalived,Keepalived检测到Nginx没有启动还是会执行杀死自己进程的脚本),然后将Nginx-proxy-backup的Nginx进程杀死,看vip是否会自动转移到Nginx-proxy-master服务器上,如杀死Nginx进程后,keepalived进程也随之消失,且vip已经转移到Nginx-proxy-master服务器,则说明Nginx-proxy-backup可正常实现故障转移

至此,Nginx负载均衡配置完毕。另外,Nginx非常稳定,笔者的Nginx负载均衡运行在HP DL380服务器上(一颗至强E5620CPU,16G内存,万转SAS硬盘),运行四个月以来,从未出现过任何问题。在负载性能上,2000并发情况下load average:仅为0.02, 0.01, 0.00,CPU使用率仅为3%,内存使用为1G(算上linux系统本身使用,系统为64bit)。

使用Nginx、Keepalived构建文艺负载均衡的更多相关文章

  1. Nginx+Keepalived主主负载均衡服务器

    Nginx+keepalived主主负载均衡服务器测试实验环境: 主Nginx之一:192.168.11.27主Nginx之二:192.168.11.28Web服务器一:192.168.11.37We ...

  2. 使用Ansible实现nginx+keepalived高可用负载均衡自动化部署

    本篇文章记录通过Ansible自动化部署nginx的负载均衡高可用,前端代理使用nginx+keepalived,端web server使用3台nginx用于负载效果的体现,结构图如下: 部署前准备工 ...

  3. Nginx+Keepalived高可用负载均衡

    转自 https://www.jianshu.com/p/da26df4f7d60 Keepalived+Nginx实现高可用Web负载均衡 Master backup vip(虚拟IP) 192.1 ...

  4. Nginx+Keepalived主备负载均衡

    实验环境及软件版本: CentOS版本:    6.6(2.6.32.-504.el6.x86_64) nginx版本:     nginx-1.6.2 keepalived版本:keepalived ...

  5. Nginx反向代理,负载均衡,redis session共享,keepalived高可用

    相关知识自行搜索,直接上干货... 使用的资源: nginx主服务器一台,nginx备服务器一台,使用keepalived进行宕机切换. tomcat服务器两台,由nginx进行反向代理和负载均衡,此 ...

  6. nginx实现请求的负载均衡 + keepalived实现nginx的高可用

    前言 使用集群是网站解决高并发.海量数据问题的常用手段.当一台服务器的处理能力.存储空间不足时,不要企图去换更强大的服务器,对大型网站而言,不管多么强大的服务器,都满足不了网站持续增长的业务需求.这种 ...

  7. [转]搭建Keepalived+Nginx+Tomcat高可用负载均衡架构

    [原文]https://www.toutiao.com/i6591714650205716996/ 一.概述 初期的互联网企业由于业务量较小,所以一般单机部署,实现单点访问即可满足业务的需求,这也是最 ...

  8. keepalived+nginx双机热备+负载均衡

    Reference: http://blog.csdn.net/e421083458/article/details/30092795 keepalived+nginx双机热备+负载均衡 最近因业务扩 ...

  9. keepalived+nginx+tomcat+redis实现负载均衡和session共享(原创)

    keepalived+nginx+tomcat+redis实现负载均衡和session共享 直接上链接,码了一天,就不再重写了,希望能帮到大家,有问题欢迎留言交流.

随机推荐

  1. 【转】【Android】ProgressDialog进度条对话框的使用

    Android ProgressDialog进度条对话框的使用: 转自:http://aina-hk55hk.iteye.com/blog/679134/ <?xml version=" ...

  2. 不应该使用Connected属性作为Socket是否连接上的依据

    最近在做一个接口,用到了Socket异步通信. 调试了3天了,一直将Socket的Connected属性作为客户端和服务器端是否连接上的依据.今天发现我错了. 下面是从一个csdn博友写的,很好. h ...

  3. c++位运算符 | & ^ ~ && ||,补码,反码

    一:简介 1 位逻辑运算符: & (位   “与”)  and       ^  (位   “异或”)       |   (位    “或”)   or       ~  (位   “取反” ...

  4. help手册使用

    属性的方法名的一般规律: 设置的属性名: set+属性名 获取属性值: 1.如果是bool类型,可能是 is+属性名 或者 属性名 2.不是bool类型,就是属性名

  5. Liunx基础优化配置

    1:  为系统添加操作用户,并授予sudo权限 [root@localhost ~]# groupadd cai [root@localhost ~]# useradd cai -g cai [roo ...

  6. linux硬盘IO优化相关资料整理

    内核相关参数 相关内核参数,有条件的话可以修改参数测试验证一下. 1./proc/sys/vm/dirty_ratio 这个参数则指定了当文件系统缓存脏页数量达到系统内存百分之多少时(如10%),系统 ...

  7. c++将文件之间编译关系降到最低

    类的定义式:类的定义,可以知道类的大小 类的实现: 类的声明:类的声明,表明,使用此类,编译不会出错 C++并没有把“将接口从实现中分离”做得很好.Class的定义式不只详细叙述了Class接口,还包 ...

  8. 12306 Pytho抢票代码

    1.需要先安装python环境 2.安装selenium模拟用户来操作浏览器 3.将chromedriver驱动放入chrome浏览器应用根目录 4.用文本编辑器打开脚本,编辑购票人信息 5.通过cm ...

  9. kuangbin专题七 HDU4027 Can you answer these queries? (线段树)

    A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use ...

  10. 微信小程序传数组(Json字符串)到Java后端

    一:小程序端: wxml中代码: <!--index.wxml--> <view> <view> <button bindtap="onShow&q ...