Project

General

Profile

Using HAProxy as a reverse proxy » History » Revision 6

Revision 5 (Christian Meyer, 10/06/2015 04:50 PM) → Revision 6/8 (Checheta Yan, 01/08/2016 04:08 PM)

h1. Using HAproxy as a reverse proxy 

 "HAproxy":http://haproxy.1wt.eu/ has a great feature set when used in conjunction with Wt: 
 * Uses async I/O and thus handles thousands of connections without any problem. Just like Wt! 
 * Supports reverse proxying of WebSocket connections (as per draft-76). 
 * Can be configured to use session affinity without needing cookies. 

 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. 

 h2. Basic setup 

 <pre> 
 global 
         log 127.0.0.1 local0 
         log 127.0.0.1 local1 notice 
         maxconn 4096 
         user haproxy 
         group haproxy 
         daemon 

 defaults 
         log       global 
         mode      http 
         option    httplog 
         option    dontlognull 
         option    http-server-close 
         option    http-pretend-keepalive 
         option    forwardfor 
         option    originalto 
         retries 3 
         option redispatch 
         maxconn 2000 
         contimeout        5000 
         clitimeout        50000 
         srvtimeout        50000 

 listen 0.0.0.0:8181 
         server srv1 0.0.0.0:9090 check 
 </pre> 

 h2. Using session affinity 

 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). 

 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. 

 Below is an example configuration for two back-end servers. <a href="http://svtros.ru">!!!</a> 

 <pre> 
 global 
	 log 127.0.0.1 local0  
	 log 127.0.0.1 local1 notice 
	 maxconn 4096 
	 user haproxy 
	 group haproxy 
	 daemon 

 defaults 
	 log 	 global 
	 mode 	 http 
	 option 	 httplog 
	 option 	 dontlognull 
         option    http-server-close 
         option    http-pretend-keepalive 
         option    forwardfor 
         option    originalto 
	 retries 	 3 
	 option redispatch 
	 maxconn 	 2000 
	 contimeout 	 5000 
	 clitimeout 	 50000 
	 srvtimeout 	 50000 

 frontend wt 
         bind 0.0.0.0:80 
         acl srv1 url_sub wtd=wt1 
         acl srv2 url_sub wtd=wt2 
         acl srv1_up nbsrv(bck1) gt 0 
         acl srv2_up nbsrv(bck2) gt 0 
         use_backend bck1 if srv1_up srv1 
         use_backend bck2 if srv2_up srv2 
         default_backend bck_lb 

 backend bck_lb 
         balance roundrobin 
         server srv1 0.0.0.0:9090 track bck1/srv1 
         server srv2 0.0.0.0:9091 track bck2/srv2 

 backend bck1 
         balance roundrobin 
         server srv1 0.0.0.0:9090 check 

 backend bck2 
         balance roundrobin 
         server srv2 0.0.0.0:9091 check 

 </pre> 

 And start the two Wt httpd servers using: 

 <pre> 
 $ app.wt --session-id-prefix=wt1 --http-port 9090 ... 
 $ app.wt --session-id-prefix=wt2 --http-port 9091 ... 
 </pre> 

 h2. Running multiple apps for multiple domains 

 In case you want different apps to be bound to different domains then I have the following configuration for you. 
 In my case it's a virtual Server for testing and development as well. With Apache to test wordpress and other things.  
 To not immediately show changes on the Main Page I have a second instance running, but see for yourself: 

 I hope the comments are self explanatory even for beginners like I have been =) 

 <pre> 
 global 
     maxconn 4096 
     user       haproxy 
     group      haproxy 
     daemon 

 defaults 
     log       global 
     mode       http 
     option      httplog 
     option      dontlognull 

     option      http-pretend-keepalive 
     option      forwardfor 
     option       originalto 
     option       redispatch 

     retries      3 

     timeout      connect      5000 
     timeout      client      50000 
     timeout server       50000 

 frontend http-in 
     bind *:80 

 # Having a .wt Application-Server for development/testing purposes with access regardless of path 
 #      but subdomain is dev: dev.sample.com / dev.example.com 
 #      While having several domains pointing to the same physical server 
     acl is_dev_URL hdr_beg(host) -i dev. 

 # Main-Page to load when connecting to host: should load sample.com/wt1 
     acl is_wt_Main     hdr_end(host) sample.com 

 # Secondary Page shown when connecting from 2nd URL: example.com/wt2 
         acl is_wt_Second hdr_end(host) example.com 

 # Having apache for other reasons, too: testing wordpress / something 
 #       refers to specific path: html 
         acl apache_path path_beg /html 

 # Following a folder architecture within docroot like: 
 #      docroot/wt1/[styles][images][whatever]  
 #      docroot/wtSecondary/[styles][images]  
 #         ->Just giving an example of having another folder name than deployment path 

     acl wt_path       path_beg /wt1 
     acl wt_path       path_beg /wt2 
     acl wt_resource path_beg /resources 
     acl wt_resource path_beg /wt1 
     acl wt_resource path_beg /wtSecondary 

 # Checking whether Servers are up or down 
     acl wt_srv_up nbsrv(wt_hp) gt 0 
     acl wt_dev_up nbsrv(wt_dev) gt 0 

 # The Redirections: 
 #    Redirect to Location /wt1 if Main-Page,    no other app, Server is up, no apache path, no resource path, and no dev-server 
     redirect location /wt1     if is_wt_Main    !wt_path        wt_srv_up       !apache_path      !wt_resource        !is_dev_URL 

 # Redirect Secondary 
     redirect location /wt2     if is_wt_Second !wt_path wt_srv_up !apache_path !wt_resource !is_dev_URL 

 # Choose the Backend 
     use_backend apache      if apache_path !wt_srv_up  

 # HAProxy 1.5.x + : 
     default_backend wt 

 # HAProxy 1.4.x - : 
 #      use_backend wt_live       if is_wt_Main is_wt_Second wt_path !is_dev_URL wt_srv_up 
 #       use_backend wt_dev      if is_dev_URL wt_dev_up 

 # The Backends 
 backend wt 

 # use-server is only available in HAProxy 1.5.x 
         use-server Wt_Live unless is_dev_URL 
     server Wt_Live    0.0.0.0:9050 track wt_hp/Wt_Live 

     use-server Wt_Dev if is_dev_URL 
     server Wt_Dev     0.0.0.0:9020 track wt_dev/Wt_Dev 

 backend wt_hp 
     balance roundrobin   
     server Wt_Live 0.0.0.0:9050 check 

 backend apache 
     balance roundrobin 
     timeout connect 10s 
     timeout server       30s 
     server apache1 0.0.0.0:8050 check 

 backend wt_dev 
     balance roundrobin 
     server Wt_Dev 0.0.0.0:9020 check 
 </pre> 

 This is also updated to exclude deprecated keywords