前言
使用集群是网站解决高并发、海量数据问题的经常使用手段。当一台服务器的处理能力、存储空间不足时,不要企图去换更强大的服务器,对大型网站而言,无论多么强大的服务器,都知足不了网站持续增加的业务需求。这种状况下,更恰当的作法是增长一台服务器分担原有服务器的访问及存储压力。经过负载均衡调度服务器,未来自浏览器的访问请求分发到应用服务器集群中的任何一台服务器上,若是有更多的用户,就在集群中加入更多的应用服务器,使应用服务器的负载压力再也不成为整个网站的瓶颈。css
摘自《大型网站技术架构_核心原理与案例分析》html
环境准备
server1 192.168.200.111:nginx + keepalived masternginx
server2 192.168.200.112:nginx + keepalived backupcentos
server3 192.168.200.113:tomcat浏览器
server4 192.168.200.114:tomcattomcat
虚拟ip(VIP):192.168.200.254,对外提供服务的ip,也可称做浮动ipbash
各个组件之间的关系图以下:服务器
tomcat作应用服务器
nginx作负载均衡
nginx.conf内容以下网络
user nginx nginx; worker_processes 2;
worker_cpu_affinity 01 10;
worker_rlimit_nofile 102400;
error_log logs/error.log; pid logs/nginx.pid; events { use epoll; worker_connections 4096; }
http { include 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 logs/access.log main;
sendfile on;
keepalive_timeout 65;
upstream tomcat_pool {
server 192.168.200.112:8080 weight=4 max_fails=2 fail_timeout=30s; server 192.168.200.113:8080 weight=4 max_fails=2 fail_timeout=30s; } server { listen 80; server_name localhost; charset utf-8; location / { proxy_pass http://tomcat_pool;
proxy_set_header Host $http_host; } location ~ \.(jsp|jspx|dp)$ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://tomcat_pool; } location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ { expires 30d; }
location ~ .*\.(js|css)${ expires 1h; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
配置好后,启动nginx,路径要写本身的
/usr/local/nginx/sbin/nginx
keepalived实现nginx高可用(HA)
keepalived主要起到两个做用:实现VIP到本地ip的映射; 以及检测nginx状态。
master上的keepalived.conf内容以下:
global_defs { notification_email { 997914490@qq.com } notification_email_from sns-lvs@gmail.com smtp_server smtp.hysec.com smtp_connection_timeout 30 router_id nginx_master # 设置nginx master的id,在一个网络应该是惟一的 } vrrp_script chk_http_port { #引用脚本文件 script "/usr/local/check_nginx_pid.sh" #脚本文件绝对路径 interval 2 #(检测脚本执行的间隔,单位是秒) weight -20 # 权重要比 BACKUP 小 } vrrp_instance VI_1 { state MASTER # 指定keepalived的角色,MASTER为主,BACKUP为备 interface ens32 # 当前进行vrrp通信的网络接口卡(当前centos的网卡) virtual_router_id 66 # 虚拟路由编号,主从要相同 priority 100 # 优先级,数值越大,获取处理请求的优先级越高 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数) authentication { auth_type PASS auth_pass 1111 } track_script { chk_http_port #(调用检测脚本) } virtual_ipaddress { 192.168.200.254 # 定义虚拟ip(VIP),可多设,每行一个 } }
backup上的keepalived.conf内容以下:
global_defs { notification_email { 997914490@qq.com } notification_email_from sns-lvs@gmail.com smtp_server smtp.hysec.com smtp_connection_timeout 30 router_id nginx_backup # 设置nginx backup的id,在一个网络应该是惟一的 } vrrp_script chk_http_port { script "/usr/local/check_nginx_pid.sh" interval 2 #(检测脚本执行的间隔) weight -20 } vrrp_instance VI_1 { state BACKUP # 指定keepalived的角色,MASTER为主,BACKUP为备 interface ens32 # 当前进行vrrp通信的网络接口卡(当前centos的网卡) virtual_router_id 66 # 虚拟路由编号,主从要相同 priority 90 # 优先级,数值越大,获取处理请求的优先级越高 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数) authentication { auth_type PASS auth_pass 1111 } track_script { chk_http_port #(调用检测脚本) } virtual_ipaddress { 192.168.200.254 # 定义虚拟ip(VIP),可多设,每行一个 } }
nginx检测脚本check_nginx_pid.sh内容以下:
#!/bin/bash count=$(ps -C nginx --no-header |wc -l) if [ $count -eq 0 ];then /usr/local/nginx/sbin/nginx #重启nginx if [ $(ps -C nginx --no-header |wc -l) -eq 0 ];then #nginx重启失败 systemctl stop keepalived fi fi
脚本加权限
chmod +x /usr/local/check_nginx_pid.sh
启动keepalived
systemctl start keepalived