haproxy的简介就不说了,网上很详细,直接google。
一、配置
代码语言:javascript复制# this config needs haproxy-1.5.x
global
daemon
nbproc 1
maxconn 4096
log 127.0.0.1 local1 info
tune.bufsize 1000000
tune.ssl.default-dh-param 2048
ssl-default-bind-options no-sslv3 no-tlsv10
ssl-default-bind-ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256
stats timeout 2m
defaults
log global
maxconn 2000
option redispatch
retries 3
mode http
option httplog
option splice-auto
option httpclose
option forwardfor
option log-health-checks
stats hide-version
timeout http-request 30s
timeout queue 1m
timeout connect 5s
timeout client 1h
timeout server 1h
frontend ts_8081
bind 30.7.3.124:8081
mode http
option httpclose
default_backend b_def_ts_8081
backend b_def_ts_8081
mode http
balance roundrobin
option tcpka
stats hide-version
option httpchk
option httplog
server controller1 30.7.3.126:28081 check inter 30s fastinter 30s downinter 30s rise 2 fall 4
二、客户端
代码语言:javascript复制# coding: utf-8
import json
import sys
import threading
import requests
def test_haproxy(concurrent_num):
threads = []
results = []
for i in range(concurrent_num):
th = threading.Thread(target=send_req, args=(results,))
th.start()
threads.append(th)
for i in threads:
i.join()
print("test finished")
success_times = 0
failed_times = 0
for result in results:
if result is True:
success_times = 1
elif result is False:
failed_times = 1
print("success times: %s, failed times: %s" % (success_times,
failed_times))
def send_req(results=list()):
url = "http://30.7.3.124:8081/test_haproxy"
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
}
body = {"ts": "hhhh"}
kwargs = {
"headers": headers,
"data": json.dumps(body),
"verify": False,
"timeout": 60
}
try:
response = requests.request('POST', url, **kwargs)
if response.status_code == 200:
print("recv server data: %s" % response.content)
results.append(True)
return True
print("delete request failed, code: %s, msg: %s" %
(response.status_code, response.content))
results.append(False)
return False
except Exception as err:
print("send request occur exc, msg: %s" % err.message)
results.append(False)
return False
if __name__ == "__main__":
args = sys.argv
if not args or len(args) != 2:
print("Usage: python xx.py [concurrent_num]")
exit(1)
test_haproxy(int(args[1]))
三、服务端
代码语言:javascript复制# coding: utf-8
import random
import eventlet
from eventlet import wsgi
from webob import Request, Response
class ResponseBuilder(object):
def __init__(self):
super(ResponseBuilder, self).__init__()
@classmethod
def success(cls, body=None):
res = Response()
res.status = "200 OK"
res.content_type = "application/json"
res.body = body
return res
class TestApp(object):
def __call__(self, environ, start_response):
req = Request(environ)
req.charset = "utf-8"
req.decode("utf-8")
url = req.url
params = req.params
body = req.body
client_addr = req.client_addr
print("recv client req, {url: %(url)s, params: %(params)s, "
"body: %(body)s, client_addr: %(client_addr)s}" % {
"url": url, "params": params, "body": body,
"client_addr": client_addr
})
if req.path.startswith("/test_haproxy"):
eventlet.sleep(random.randint(0, 60))
response = ResponseBuilder.success(body="server response")
return response(environ, start_response)
def start():
socket = eventlet.listen(("30.7.3.126", 28081))
app = TestApp()
wsgi.server(socket, app)
if __name__ == "__main__":
start()
四、启动server
在命令行执行命令:
代码语言:javascript复制python socket_server.py
可以看到控制台在周期性的打印如下日志
代码语言:javascript复制(19761) accepted ('30.7.3.126', 53202)
recv client req, {url: http://30.7.3.126:28081/, params: NestedMultiDict([]), body: , client_addr: 30.7.3.126}
30.7.3.126 - - [20/Jun/2019 15:27:57] "OPTIONS / HTTP/1.0" 200 142 0.000472
(19761) accepted ('30.7.3.126', 53214)
recv client req, {url: http://30.7.3.126:28081/, params: NestedMultiDict([]), body: , client_addr: 30.7.3.126}
30.7.3.126 - - [20/Jun/2019 15:27:59] "OPTIONS / HTTP/1.0" 200 142 0.000567
这就是我们在配置文件中设置的check inter 30s
参数,表示haproxy每隔30s使用tcp连接后台服务器端口,如果能建立连接,就认为存活且马上关闭连接。
服务端在成功启动后,haproxy检查日志如下:
代码语言:javascript复制2019-06-20 15:35:59.228 localhost haproxy [pid:19047]notice Health check for server b_def_ts_8081/controller1 succeeded, reason: Layer7 check passed, code: 200, info: "OK", check duration: 1ms, status: 4/4 UP.
2019-06-20 15:35:59.228 localhost haproxy [pid:19047]notice Server b_def_ts_8081/controller1 is UP. 1 active and 0 backup servers online. 0 sessions requeued, 0 total in queue.
五、启动client
在命令行执行命令:
代码语言:javascript复制python socket_client.py 1
haproxy的日志如下:
代码语言:javascript复制2019-06-20 02:39:18.371 localhost haproxy [pid:17464]info 30.7.3.126:51921 [20/Jun/2019:02:38:13.367] ts_8081 b_def_ts_8081/controller1 0/0/0/65002/65003 200 142 - - ---- 3/3/3/3/0 0/0 "POST /test_haproxy HTTP/1.1"
2019-06-20 02:39:18.373 localhost haproxy [pid:17464]info 30.7.3.126:51925 [20/Jun/2019:02:38:13.369] ts_8081 b_def_ts_8081/controller1 0/0/0/65002/65003 200 142 - - ---- 2/2/2/2/0 0/0 "POST /test_haproxy HTTP/1.1"
2019-06-20 02:39:18.376 localhost haproxy [pid:13414]info 30.7.3.126:51929 [20/Jun/2019:02:38:13.371] ts_8081 b_def_ts_8081/controller1 0/0/0/65002/65003 200 142 - - ---- 0/0/0/0/0 0/0 "POST /test_haproxy HTTP/1.1"
2019-06-20 02:39:18.387 localhost haproxy [pid:19047]info 30.7.3.126:51933 [20/Jun/2019:02:38:13.383] ts_8081 b_def_ts_8081/controller1 0/0/0/65003/65003 200 142 - - ---- 1/1/1/1/0 0/0 "POST /test_haproxy HTTP/1.1"
2019-06-20 02:39:18.387 localhost haproxy [pid:19047]info 30.7.3.126:51939 [20/Jun/2019:02:38:13.383] ts_8081 b_def_ts_8081/controller1 0/0/0/65003/65003 200 142 - - ---- 0/0/0/0/0 0/0 "POST /test_haproxy HTTP/1.1"
2019-06-20 02:39:18.389 localhost haproxy [pid:17464]info 30.7.3.126:51937 [20/Jun/2019:02:38:13.386] ts_8081 b_def_ts_8081/controller1 0/0/0/65002/65002 200 142 - - ---- 1/1/1/1/0 0/0 "POST /test_haproxy HTTP/1.1"
2019-06-20 02:39:18.395 localhost haproxy [pid:17464]info 30.7.3.126:51945 [20/Jun/2019:02:38:13.391] ts_8081 b_def_ts_8081/controller1 0/0/0/65002/65004 200 142 - - ---- 0/0/0/0/0 0/0 "POST /test_haproxy HTTP/1.1"
说明haproxy手动了请求并成功进行了转发。
server也成功收到了请求并回应。
代码语言:javascript复制(24134) accepted ('30.7.3.126', 56130)
recv client req, {url: http://30.7.3.124:8081/test_haproxy, params: NestedMultiDict([]), body: {"ts": "hhhh"}, client_addr: 30.7.3.126}
client收到的信息:
代码语言:javascript复制recv server data: server response
test finished
success times: 1, failed times: 0
六、启停haproxy
- 启动haproxy
# /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg
- 重启haproxy
# /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg -st
cat /usr/local/haproxy/haproxy.pid - 停止haproxy
# killall haproxy