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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
|
一、部署HAProxy(2台)
1、安装
yum
install
HAProxy
2、配置
vim
/etc/haproxy/haproxy
.cfg
global
#全局配置
log 127.0.0.1 local3
#日志纪录位置
chroot
/var/lib/haproxy
#haproxy的工作目录
pidfile
/var/run/haproxy
.pid
#pid文件位置
maxconn 4000
#最大连接数
user haproxy
#运行时使用的用户身份
group haproxy
#运行时使用的组身份
daemon
#启动为守护进程,不加此处运行在前台
stats socket
/var/lib/haproxy/stats
#本地访问stats统计信息时以套接字方式通信
defaults
#默认配置
mode http
#已http模式运行
log global
#默认日志为全局配置中日志的设置
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0
/8
#除本机外所有发往服务器的请求首部中加入“X-Forwarded-For”首部
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#前端最大并发连接数
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend web *:80
#acl url_static path_beg -i /static /images /javascript /stylesheets
#acl url_static path_end -i .jpg .gif .png .css .js .html .txt .htm
#acl url_dynamic path_begin -i .php .jsp
#default_backend static_srv if url_static
#use_backend dynamic_srv if url_dynamic
use_backend varnish_srv
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend varnish_srv
balance uri
#使用基于URL的一致性哈希调度算法
hash
-
type
consistent
server varnish1 192.168.50.56:9527 check
server varnish2 192.168.50.57:9527 check
listen stats
#开启HAProxy图形化Web管理功能
bind :9091
stats
enable
stats uri
/simpletime
?admin
stats hide-version
stats auth admin:hequan.123
stats admin
if
TRUE
3、启动
systemctl start haproxy
systemctl status haproxy
systemctl
enable
haproxy
netstat
-lntup
二、在haproxy部署keepalived
1、安装
yum
install
-y keepalived
2、配置
vim
/etc/keepalived/keepalived
.conf
! Configuration File
for
keepalived
global_defs {
router_id proxy1
}
vrrp_script chk_haproxy {
script
"killall -0 haproxy"
interval 1
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 100
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.50.200
/24
}
track_script {
chk_down
chk_haproxy
}
notify_master
"/etc/keepalived/changemail.py master"
notify_backup
"/etc/keepalived/changemail.py backup"
notify_fault
"/etc/keepalived/changemail.py fault"
}
3、启动
systemctl start keepalived.service
systemctl
enable
keepalived.service
systemctl status keepalived.service
报警邮件设置
vim
/etc/keepalived/changemail
.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import
smtplib
import
socket
import
time
from email.MIMEText
import
MIMEText
from email.Utils
import
formatdate
from email.Header
import
Header
import
sys
#发送邮件的相关信息,根据实际情况填写
smtpHost =
'XXXXXXXXXXXXXXXXXXX'
smtpPort =
'25'
sslPort =
'110'
fromMail =
'XXXXXXXXXXXXXXXXX'
toMail =
'XXXXXXXXXXXX'
username =
'XXXXXXXXXX'
password =
'XXXXXXX'
#解决中文问题
reload(sys)
sys.setdefaultencoding(
'utf8'
)
#邮件标题和内容
subject = socket.gethostname() +
" HA status has changed"
body = (
time
.strftime(
"%Y-%m-%d %H:%M:%S"
)) +
" vrrp transition, "
+ socket.gethostname() +
" changed to be "
+ sys.argv[1]
#初始化邮件
encoding =
'utf-8'
mail = MIMEText(body.encode(encoding),
'plain'
,encoding)
mail[
'Subject'
] = Header(subject,encoding)
mail[
'From'
] = fromMail
mail[
'To'
] = toMail
mail[
'Date'
] = formatdate()
try:
#连接smtp服务器,明文/SSL/TLS三种方式,根据你使用的SMTP支持情况选择一种
#普通方式,通信过程不加密
smtp = smtplib.SMTP(smtpHost,smtpPort)
smtp.ehlo()
smtp.login(username,password)
#tls加密方式,通信过程加密,邮件数据安全,使用正常的smtp端口
#smtp = smtplib.SMTP(smtpHost,smtpPort)
#smtp.ehlo()
#smtp.starttls()
#smtp.ehlo()
#smtp.login(username,password)
#纯粹的ssl加密方式,通信过程加密,邮件数据安全
#smtp = smtplib.SMTP_SSL(smtpHost,sslPort)
#smtp.ehlo()
#smtp.login(username,password)
#发送邮件
smtp.sendmail(fromMail,toMail,mail.as_string())
smtp.close()
print
'OK'
except Exception:
print
'Error: unable to send email'
chmod
+x
/etc/keepalived/changemail
.py
三、部署varnsh(2台)
1、安装
yum
install
varnish -y
2、配置
vim
/etc/varnish/varnish
.params
VARNISH_LISTEN_PORT=9527
#更改默认端口
vim
/etc/varnish/default
.vcl
#修改配置文件
vcl 4.0;
##############启用负载均衡模块###############
import
directors;
################定义Purge-ACL控制#######################
acl purgers {
"127.0.0.1"
;
"192.168.50.0"
/24
;
}
# Default backend definition. Set this to point to your content server.
##############配置健康状态探测##############
probe HE {
#静态检测
.url =
"/health.html"
;
#指定检测URL
.timeout = 2s;
#探测超时时长
.window = 5;
#探测次数
.threshold = 2;
#探测次数成功多少次才算健康
.initial = 2;
#Varnish启动探测后端主机2次健康后加入主机
.interval = 2s;
#探测间隔时长
.expected_response = 200;
#期望状态响应码
}
probe HC {
#动态监测
.url =
"/health.php"
;
.timeout = 2s;
.window = 5;
.threshold = 2;
.initial = 2;
.interval = 2s;
.expected_response = 200;
}
#############添加后端主机################
backend web1 {
.host =
"192.168.50.58:80"
;
.port =
"80"
;
.probe = HC;
}
backend web2 {
.host =
"192.168.50.59:80"
;
.port =
"80"
;
.probe = HC;
}
backend app1 {
.host =
"192.168.50.60:80"
;
.port =
"80"
;
.probe = HE;
}
backend app2 {
.host =
"192.168.50.61:80"
;
.port =
"80"
;
.probe = HE;
}
#############定义负载均衡及算法###############
sub vcl_init {
new webcluster = directors.round_robin();
webcluster.add_backend(web1);
webcluster.add_backend(web2);
new appcluster = directors.round_robin();
appcluster.add_backend(app1);
appcluster.add_backend(app2);
}
################定义vcl_recv函数段######################
sub vcl_recv {
#####ACL未授权,不允许PURGE,并返回405#####
if
(req.method ==
"PURGE"
) {
if
(!client.ip ~ purgers){
return
(synth(405,
"Purging not allowed for"
+ client.ip));
}
return
(purge);
}
#####添加首部信息,使后端服务记录访问者的真实IP
# if (req.restarts == 0) {
# set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
# } else {
# set req.http.X-Forwarded-For = client.ip;
# }
# set req.backend_hint = webcluster.backend();
# set req.backend_hint = appcluster.backend();
#注:因为Varnish不是一级代理,配置forward只能取到上级代理IP,而上级代理IP,本身就包含在HAProxy发送过来的Forward里,所以没必要配置,而后端服务器只要日志格式有启用记录Forward信息,并且上级代理没有做限制,那么,就能获取到客户端真实IP;
#####动静分离#####
if
(req.url ~
"(?i)\.(php|asp|aspx|jsp|do|ashx|shtml)($|\?)"
) {
set
req.backend_hint = webcluster.backend();
}
else
{
set
req.backend_hint = appcluster.backend();
}
#####不正常的请求不缓存#####
if
(req.method !=
"GET"
&&
req.method !=
"HEAD"
&&
req.method !=
"PUT"
&&
req.method !=
"POST"
&&
req.method !=
"TRACE"
&&
req.method !=
"OPTIONS"
&&
req.method !=
"PATCH"
&&
req.method !=
"DELETE"
) {
return
(pipe);
}
#####如果请求不是GET或者HEAD,不缓存#####
if
(req.method !=
"GET"
&& req.method !=
"HEAD"
) {
return
(pass);
}
#####如果请求包含Authorization授权或Cookie认证,不缓存#####
if
(req.http.Authorization || req.http.Cookie) {
return
(pass);
}
#####启用压缩,但排除一些流文件压缩#####
if
(req.http.Accept-Encoding) {
if
(req.url ~
"\.(bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)$"
) {
unset
req.http.Accept-Encoding;
} 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
{
unset
req.http.Accept-Encoding;
}
}
return
(
hash
);
}
####################定义vcl_pipe函数段#################
sub vcl_pipe {
return
(pipe);
}
sub vcl_miss {
return
(fetch);
}
####################定义vcl_hash函数段#################
sub vcl_hash {
hash_data(req.url);
if
(req.http.host) {
hash_data(req.http.host);
}
else
{
hash_data(server.ip);
}
if
(req.http.Accept-Encoding ~
"gzip"
) {
hash_data (
"gzip"
);
} elseif (req.http.Accept-Encoding ~
"deflate"
) {
hash_data (
"deflate"
);
}
}
##############设置资源缓存时长#################
sub vcl_backend_response {
if
(beresp.http.cache-control !~
"s-maxage"
) {
if
(bereq.url ~
"(?i)\.(jpg|jpeg|png|gif|css|js|html|htm)$"
) {
unset
beresp.http.Set-Cookie;
set
beresp.ttl = 3600s;
}
}
}
################启用Purge#####################
sub vcl_purge {
return
(synth(200,
"Purged"
));
}
###############记录缓存命中状态##############
sub vcl_deliver {
if
(obj.hits > 0) {
set
resp.http.X-Cache =
"HIT from "
+ req.http.host;
set
resp.http.X-Cache-Hits = obj.hits;
}
else
{
set
resp.http.X-Cache =
"MISS from "
+ req.http.host;
}
unset
resp.http.X-Powered-By;
unset
resp.http.Server;
unset
resp.http.Via;
unset
resp.http.X-Varnish;
unset
resp.http.Age;
}
3、启动
systemctl start varnish.service
systemctl
enable
varnish.service
systemctl status varnish.service
4、查看,加载配置,因为还没有配置后端应用服务器,可以看到后端主机健康检测全部处于Sick状态
#varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
200
varnish> vcl.load conf1 default.vcl
200
VCL compiled.
varnish> vcl.use conf1
200
VCL
'conf1'
now active
varnish> backend.list
200
Backend name Refs Admin Probe
web1(192.168.50.58,,80) 2 probe Sick 0
/5
web2(192.168.50.59,,80) 2 probe Sick 0
/5
app1(192.168.50.60,,80) 2 probe Sick 0
/5
app2(192.168.50.61,,80) 2 probe Sick 0
/5
|
本文转自 295631788 51CTO博客,原文链接:http://blog.51cto.com/hequan/1886307,如需转载请自行联系原作者