企业web高可用集群实战之haproxy篇
By:opsren
本实验环境所用域名:www.opsren.com
! Configuration File for keepalived
global_defs {
notification_email {
}
notification_email_from [email protected]
smtp_server smtp.163.com
# smtp_connect_timeout 30
router_id LVS_DEVEL
}
# VIP1
vrrp_instance VI_1 {
state MASTER #备份服务器上将MASTER改为BACKUP
interface eth0
lvs_sync_daemon_inteface eth0
virtual_router_id 51
priority 100 # 备份服务上将100改为90
advert_int 5
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.8.12
}
}
virtual_server 192.168.8.12 80 {
delay_loop 6 #(每隔10秒查询realserver状态)
lb_algo wlc #(lvs 算法)
lb_kind DR #(Direct Route)
persistence_timeout 60 #(同一IP的连接60秒内被分配到同一台realserver)
protocol TCP #(用TCP协议检查realserver状态)
real_server 192.168.8.20 80 {
weight 100 #(权重)
TCP_CHECK {
connect_timeout 10 #(10秒无响应超时)
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
real_server 192.168.8.21 80 {
weight 100
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
global
maxconn 4096
chroot /usr/local/haproxy
uid 188
gid 188
daemon
quiet
nbproc 2
pidfile /usr/local/haproxy/haproxy.pid
defaults
log global
mode http
option httplog
option dontlognull
log 127.0.0.1 local3
retries 3
option redispatch
maxconn 20000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen www.opsren.com 0.0.0.0:80
stats uri /status
stats realm Haproxy\ statistics
stats auth admin:admin
balance source
option httpclose
option forwardfor
#option httpchk HEAD /index.php HTTP/1.0
server cache1_192.168.8.20 192.168.8.20:80 cookie app1inst1 check inter 2000 rise 2 fall 5
server cache2_192.168.8.21 192.168.8.21:80 cookie app1inst2 check inter 2000 rise 2 fall 5
global
log 127.0.0.1 local3
maxconn 4096
chroot /usr/local/haproxy
uid 188
gid 188
daemon
quiet
nbproc 2
pidfile /usr/local/haproxy/haproxy.pid
defaults
log global
mode http
retries 3
option redispatch
maxconn 20000
stats enable
stats hide-version
stats uri /status
contimeout 5000
clitimeout 50000
srvtimeout 50000
frontend www.opsren.com
bind *:80
mode http
option httplog
log global
default_backend php_opsren
backend php_opsren
balance source
#option httpclose
#option forwardfor
server cache1_192.168.8.20 192.168.8.20:80 cookie app1inst1 check inter 2000 rise 2 fall 5
server cache2_192.168.8.21 192.168.8.21:80 cookie app1inst2 check inter 2000 rise 2 fall 5
#!/bin/bash
# chkconfig 35 on
# description: HAProxy is a TCP/HTTP reverse proxy which is particularly suited for high availability environments.
# Source function library.
if [ -f /etc/init.d/functions ]; then
. /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
. /etc/rc.d/init.d/functions
else
exit 0
fi
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
[ -f /usr/local/haproxy/haproxy.conf ] || exit 1
RETVAL=0
start() {
/usr/local/haproxy/sbin/haproxy -c -q -f /usr/local/haproxy/haproxy.conf
if [ $? -ne 0 ]; then
echo "Errors found in configuration file."
return 1
fi
echo -n "Starting HAproxy: "
daemon /usr/local/haproxy/sbin/haproxy -D -f /usr/local/haproxy/haproxy.conf -p /var/run/haproxy.pid
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/haproxy
return $RETVAL
}
stop() {
echo -n "Shutting down HAproxy: "
killproc haproxy -USR1
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/haproxy
[ $RETVAL -eq 0 ] && rm -f /var/run/haproxy.pid
return $RETVAL
}
restart() {
/usr/local/haproxy/sbin/haproxy -c -q -f /usr/local/haproxy/haproxy.conf
if [ $? -ne 0 ]; then
echo "Errors found in configuration file, check it with 'haproxy check'."
return 1
fi
stop
start
}
check() {
/usr/local/haproxy/sbin/haproxy -c -q -V -f /usr/local/haproxy/haproxy.conf
}
rhstatus() {
status haproxy
}
condrestart() {
[ -e /var/lock/subsys/haproxy ] && restart || :
}
# See how we were called.
case"$1"in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
reload)
restart
;;
condrestart)
condrestart
;;
status)
rhstatus
;;
check)
check
;;
*)
echo $"Usage: haproxy {start|stop|restart|reload|condrestart|status|check}"
RETVAL=1
esac
exit $RETVAL
#Cache for opsren sites
#backend vhost
backend opsren1 {
.host = "192.168.8.30";
.port = "80";
}
backend opsren2 {
.host = "192.168.8.31";
.port = "80";
}
director webserver random {
{.backend = opsren1; .weight = 5; }
{.backend = opsren2; .weight = 8; }
}
#acl
acl purge {
"localhost";
"127.0.0.1";
"192.168.0.0"/24;
}
sub vcl_recv {
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|jpeg|flv)$" ) {
remove req.http.Accept-Encoding;
remove req.http.Cookie;
} elseif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elseif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
remove req.http.Accept-Encoding;
}
}
if (req.http.host ~ "(.*)opsren.com") {
set req.backend = webserver;
}
else {
error 404 "This website is maintaining or not exist!";
}
if (req.request == "PURGE") {
if (!client.ip ~purge) {
error 405 "Not Allowed";
}
return(lookup);
}
if (req.request == "GET"&& req.url ~ "\.(png|gif|jpeg|jpg|ico|swf|css|js|html|htm|gz|tgz|bz2|tbz|mp3|ogg|mp4|flv|f4v|pdf)$") {
unset req.http.cookie;
}
if (req.request =="GET"&&req.url ~ "\.php($|\?)"){
return (pass);
}
# if (req.restarts == 0) {
if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For =
req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
# }
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
return (pipe);
}
if (req.request != "GET" && req.request != "HEAD") {
return (pass);
}
if (req.http.Authorization) {
return (pass);
}
return (lookup);
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return (hash);
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged";
}
return (deliver);
}
sub vcl_fetch {
if (req.url ~ "\.(jpeg|jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|ico|swf|flv|dmg|js|css|html|htm)$") {
set beresp.ttl = 2d;
set beresp.http.expires = beresp.ttl;
set beresp.http.Cache-Control = "max-age=172800";
unset beresp.http.set-cookie;
}
if (req.url ~ "\.(dmg|js|css|html|htm)$") {
set beresp.do_gzip = true;
}
if (beresp.status == 503) {
set beresp.saintmode = 15s;
}
}
sub vcl_deliver {
set resp.http.x-hits = obj.hits ;
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT You!";
} else {
set resp.http.X-Cache = "MISS Me!";
}
}
# varnish Control the varnish HTTP accelerator
# chkconfig: - 90 10
# description: Varnish is a high-perfomance HTTP accelerator
# processname: varnishd
# config: /usr/local/varnish/etc/varnish.conf
# pidfile: /var/run/varnishd.pid
### BEGIN INIT INFO
# Provides: varnish
# Required-Start: $network $local_fs $remote_fs
# Required-Stop: $network $local_fs $remote_fs
# Should-Start: $syslog
# Short-Description: start and stop varnishd
# Description: Varnish is a high-perfomance HTTP accelerator
### END INIT INFO
# Source function library.
start() {
echo -n "Starting varnish HTTP accelerator: "
# Open files (usually 1024, which is way too small for varnish)
ulimit -n ${NFILES:-131072}
# Varnish wants to lock shared memory log in memory.
ulimit -l ${MEMLOCK:-82000}
usr/local/varnish/sbin/varnishd -u www -g www -f /usr/local/varnish/etc/varnish/vcl.conf -a 192.168.8.20:80 -s file,/data/varnish/cache/varnish_cache.data,1G -w 1024,51200,10 -t 3600 -T 192.168.8.20:3000 &
sleep 15
/usr/local/varnish/bin/varnishncsa -w /data/varnish/logs/varnish.log &
}
stop() {
echo -n "Stopping varnish HTTP accelerator: "
pkill -9 varnish
}
restart() {
stop
start
}
reload() {
/etc/init.d/varnish_reload.sh
}
# See how we were called.
case"$1"in
start)
start && exit 0
;;
stop)
stop || exit 0
;;
restart)
restart
;;
reload)
reload || exit 0
;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 2
esac
exit $?
# Configuration file for varnish
# /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this
# shell script fragment.
# Maximum number of open files (for ulimit -n)
NFILES=131072
# Locked shared memory (for ulimit -l)
# Default log size is 82MB + header
MEMLOCK=1000000
## Alternative 2, Configuration with VCL
DAEMON_OPTS="-a 192.168.8.20:80 \
-f /usr/local/varnish/etc/varnish/vcl.conf \
-T 192.168.9.20:3000 \
-u www -g www \
-n /data/varnish/cache \
-s file,/data/varnish/cache/varnish_cache.data,1G"
#!/bin/bash
#Reload a varnish config
FILE="/usr/local/varnish/etc/varnish/vcl.conf"
#Hostname and management port
#(defined in /etc/default/varnish or on startup) HOSTPORT="IP:6082"
NOW=`date +%s`
BIN_DIR=/usr/local/varnish/bin
error()
{
echo 1>&2 "Failed to reload $FILE."
exit 1
}
$BIN_DIR/varnishadm -T $HOSTPORT vcl.load reload$NOW $FILE || error
sleep 0.1
$BIN_DIR/varnishadm -T $HOSTPORT vcl.use reload$NOW || error
sleep 0.1
echo Current configs:
$BIN_DIR/varnishadm -T $HOSTPORT vcl.list
#!/bin/bash
logs_path=/data/varnish/logs
date=$(date -d "yesterday" +"%Y-%m-%d")
pkill -9 varnishncsa
mkdir -p ${logs_path}/$(date -d "yesterday" +"%Y")/$(date -d "yesterday" +"%m")/
mv /data/varnish/logs/varnish.log ${logs_path}/$(date -d "yesterday" +"%Y")/$(date -d "yesterday" +"%m")/varnish-${date}.log
/usr/local/varnish/bin/varnishncsa -w /data/varnish/logs/varnish.log &
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
#net.ipv4.tcp_fin_timeout = 30
#net.ipv4.tcp_keepalive_time = 300
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_tw_recycle = 1
#net.ipv4.tcp_tw_len = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800