Using HAProxy as a reverse proxy » History » Version 5
Christian Meyer, 10/06/2015 04:50 PM
1 | 1 | Koen Deforche | h1. Using HAproxy as a reverse proxy |
---|---|---|---|
2 | |||
3 | 3 | Koen Deforche | "HAproxy":http://haproxy.1wt.eu/ has a great feature set when used in conjunction with Wt: |
4 | 1 | Koen Deforche | * Uses async I/O and thus handles thousands of connections without any problem. Just like Wt! |
5 | * Supports reverse proxying of WebSocket connections (as per draft-76). |
||
6 | * Can be configured to use session affinity without needing cookies. |
||
7 | |||
8 | 4 | Koen Deforche | You need a fairly recent of haproxy for the options 'http-server-close' and 'http-pretend-keepalive' to work, which is needed for reliable load-balancing. |
9 | |||
10 | 1 | Koen Deforche | h2. Basic setup |
11 | |||
12 | <pre> |
||
13 | global |
||
14 | log 127.0.0.1 local0 |
||
15 | log 127.0.0.1 local1 notice |
||
16 | maxconn 4096 |
||
17 | user haproxy |
||
18 | group haproxy |
||
19 | daemon |
||
20 | |||
21 | defaults |
||
22 | log global |
||
23 | mode http |
||
24 | option httplog |
||
25 | option dontlognull |
||
26 | 4 | Koen Deforche | option http-server-close |
27 | option http-pretend-keepalive |
||
28 | option forwardfor |
||
29 | option originalto |
||
30 | 1 | Koen Deforche | retries 3 |
31 | option redispatch |
||
32 | maxconn 2000 |
||
33 | contimeout 5000 |
||
34 | clitimeout 50000 |
||
35 | srvtimeout 50000 |
||
36 | |||
37 | listen 0.0.0.0:8181 |
||
38 | server srv1 0.0.0.0:9090 check |
||
39 | </pre> |
||
40 | |||
41 | h2. Using session affinity |
||
42 | |||
43 | 2 | Koen Deforche | All of the built-in mechanisms in HAproxy for session affinity using the @appsession@ option rely on cookies, but cookies are not our preferred method since this does not give an intuitive user experience (e.g. a user cannot open multiple sessions), are not entirely reliable (a user can disable cookies) and a source of security risks (CSRF). |
44 | 1 | Koen Deforche | |
45 | Luckily there is a work-around: using Wt's ability to generate session-id's that have a prefix which identifies the back-end, we can have HAproxy match on this prefix in the request URL and send the requests to the correct server. |
||
46 | |||
47 | Below is an example configuration for two back-end servers. |
||
48 | |||
49 | <pre> |
||
50 | global |
||
51 | log 127.0.0.1 local0 |
||
52 | log 127.0.0.1 local1 notice |
||
53 | maxconn 4096 |
||
54 | user haproxy |
||
55 | group haproxy |
||
56 | daemon |
||
57 | |||
58 | defaults |
||
59 | log global |
||
60 | mode http |
||
61 | option httplog |
||
62 | option dontlognull |
||
63 | 4 | Koen Deforche | option http-server-close |
64 | option http-pretend-keepalive |
||
65 | option forwardfor |
||
66 | option originalto |
||
67 | 1 | Koen Deforche | retries 3 |
68 | option redispatch |
||
69 | maxconn 2000 |
||
70 | contimeout 5000 |
||
71 | clitimeout 50000 |
||
72 | srvtimeout 50000 |
||
73 | |||
74 | frontend wt |
||
75 | bind 0.0.0.0:80 |
||
76 | acl srv1 url_sub wtd=wt1 |
||
77 | acl srv2 url_sub wtd=wt2 |
||
78 | acl srv1_up nbsrv(bck1) gt 0 |
||
79 | acl srv2_up nbsrv(bck2) gt 0 |
||
80 | use_backend bck1 if srv1_up srv1 |
||
81 | use_backend bck2 if srv2_up srv2 |
||
82 | default_backend bck_lb |
||
83 | |||
84 | backend bck_lb |
||
85 | balance roundrobin |
||
86 | server srv1 0.0.0.0:9090 track bck1/srv1 |
||
87 | server srv2 0.0.0.0:9091 track bck2/srv2 |
||
88 | |||
89 | backend bck1 |
||
90 | balance roundrobin |
||
91 | server srv1 0.0.0.0:9090 check |
||
92 | |||
93 | backend bck2 |
||
94 | balance roundrobin |
||
95 | server srv2 0.0.0.0:9091 check |
||
96 | |||
97 | </pre> |
||
98 | |||
99 | And start the two Wt httpd servers using: |
||
100 | |||
101 | <pre> |
||
102 | $ app.wt --session-id-prefix=wt1 --http-port 9090 ... |
||
103 | $ app.wt --session-id-prefix=wt2 --http-port 9091 ... |
||
104 | </pre> |
||
105 | 5 | Christian Meyer | |
106 | h2. Running multiple apps for multiple domains |
||
107 | |||
108 | In case you want different apps to be bound to different domains then I have the following configuration for you. |
||
109 | In my case it's a virtual Server for testing and development as well. With Apache to test wordpress and other things. |
||
110 | To not immediately show changes on the Main Page I have a second instance running, but see for yourself: |
||
111 | |||
112 | I hope the comments are self explanatory even for beginners like I have been =) |
||
113 | |||
114 | <pre> |
||
115 | global |
||
116 | maxconn 4096 |
||
117 | user haproxy |
||
118 | group haproxy |
||
119 | daemon |
||
120 | |||
121 | defaults |
||
122 | log global |
||
123 | mode http |
||
124 | option httplog |
||
125 | option dontlognull |
||
126 | |||
127 | option http-pretend-keepalive |
||
128 | option forwardfor |
||
129 | option originalto |
||
130 | option redispatch |
||
131 | |||
132 | retries 3 |
||
133 | |||
134 | timeout connect 5000 |
||
135 | timeout client 50000 |
||
136 | timeout server 50000 |
||
137 | |||
138 | frontend http-in |
||
139 | bind *:80 |
||
140 | |||
141 | # Having a .wt Application-Server for development/testing purposes with access regardless of path |
||
142 | # but subdomain is dev: dev.sample.com / dev.example.com |
||
143 | # While having several domains pointing to the same physical server |
||
144 | acl is_dev_URL hdr_beg(host) -i dev. |
||
145 | |||
146 | # Main-Page to load when connecting to host: should load sample.com/wt1 |
||
147 | acl is_wt_Main hdr_end(host) sample.com |
||
148 | |||
149 | # Secondary Page shown when connecting from 2nd URL: example.com/wt2 |
||
150 | acl is_wt_Second hdr_end(host) example.com |
||
151 | |||
152 | # Having apache for other reasons, too: testing wordpress / something |
||
153 | # refers to specific path: html |
||
154 | acl apache_path path_beg /html |
||
155 | |||
156 | # Following a folder architecture within docroot like: |
||
157 | # docroot/wt1/[styles][images][whatever] |
||
158 | # docroot/wtSecondary/[styles][images] |
||
159 | # ->Just giving an example of having another folder name than deployment path |
||
160 | |||
161 | acl wt_path path_beg /wt1 |
||
162 | acl wt_path path_beg /wt2 |
||
163 | acl wt_resource path_beg /resources |
||
164 | acl wt_resource path_beg /wt1 |
||
165 | acl wt_resource path_beg /wtSecondary |
||
166 | |||
167 | # Checking whether Servers are up or down |
||
168 | acl wt_srv_up nbsrv(wt_hp) gt 0 |
||
169 | acl wt_dev_up nbsrv(wt_dev) gt 0 |
||
170 | |||
171 | # The Redirections: |
||
172 | # Redirect to Location /wt1 if Main-Page, no other app, Server is up, no apache path, no resource path, and no dev-server |
||
173 | redirect location /wt1 if is_wt_Main !wt_path wt_srv_up !apache_path !wt_resource !is_dev_URL |
||
174 | |||
175 | # Redirect Secondary |
||
176 | redirect location /wt2 if is_wt_Second !wt_path wt_srv_up !apache_path !wt_resource !is_dev_URL |
||
177 | |||
178 | # Choose the Backend |
||
179 | use_backend apache if apache_path !wt_srv_up |
||
180 | |||
181 | # HAProxy 1.5.x + : |
||
182 | default_backend wt |
||
183 | |||
184 | # HAProxy 1.4.x - : |
||
185 | # use_backend wt_live if is_wt_Main is_wt_Second wt_path !is_dev_URL wt_srv_up |
||
186 | # use_backend wt_dev if is_dev_URL wt_dev_up |
||
187 | |||
188 | # The Backends |
||
189 | backend wt |
||
190 | |||
191 | # use-server is only available in HAProxy 1.5.x |
||
192 | use-server Wt_Live unless is_dev_URL |
||
193 | server Wt_Live 0.0.0.0:9050 track wt_hp/Wt_Live |
||
194 | |||
195 | use-server Wt_Dev if is_dev_URL |
||
196 | server Wt_Dev 0.0.0.0:9020 track wt_dev/Wt_Dev |
||
197 | |||
198 | backend wt_hp |
||
199 | balance roundrobin |
||
200 | server Wt_Live 0.0.0.0:9050 check |
||
201 | |||
202 | backend apache |
||
203 | balance roundrobin |
||
204 | timeout connect 10s |
||
205 | timeout server 30s |
||
206 | server apache1 0.0.0.0:8050 check |
||
207 | |||
208 | backend wt_dev |
||
209 | balance roundrobin |
||
210 | server Wt_Dev 0.0.0.0:9020 check |
||
211 | </pre> |
||
212 | |||
213 | This is also updated to exclude deprecated keywords |