6

I've got a Layer 7 Load Balancer setup using HAProxy for WordPress Multisite.

I'm looking to have anything related to the WordPress backend to be served from a specific group of servers (A/K/A anything in /wp-admin/) while serving the frontend of the WordPress websites from another group of servers.

Do I need to adjust something in wp-config.php to change cookie names so that they include the server ID? or check for the server ID in the WordPress cookie? I feel like problems #1 and #2 are cookie related. I have no idea why #3 is happening. My servers aren't lagging at all, and should be responding plenty fast.

With my current configuration I'm facing a few problems here:

  1. It does indeed appear to be connecting me to the appropriate admin server. However, after a while in the dashboard. The WordPress login form pops up asking me to re-login again.

  2. Most admin pages work just fine however once in a while, again, same as #1, the WordPress login for pops up and asks me to login again.

  3. Every now in then I get a "504 Gateway Time-out - The server didn't respond in time."

Here's what my configuration looks like:

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http
        retries 3
        option redispatch
        maxconn 2000
        timeout connect 5000
        timeout check 5000
        timeout client 30000
        timeout server 30000

frontend http-in
    bind *:80
    option  httplog
    option http-server-close

    acl has_domain hdr(host) -m found
    acl has_www hdr_beg(host) -i www.

    use_backend live_servers if has_domain has_www

    acl has_admin path_beg /wp-admin
    acl has_login path_beg /wp-login.php
    acl has_custom_login path_beg /manage

    use_backend admin_servers if has_admin or has_login or has_custom_login

    default_backend live_servers

backend live_servers
    mode http
    stats enable
    stats uri /haproxy?stats
    balance roundrobin
    option httpclose
    option forwardfor
    cookie SERVERID insert indirect nocache
    server s1 1.1.1.1:80 check cookie s1
    server s2 2.2.2.2:80 check cookie s2

backend admin_servers
    mode http
    stats enable
    stats uri /haproxy?stats
    balance roundrobin
    option httpclose
    option forwardfor
    cookie SERVERID insert indirect nocache
    server s1 1.1.1.1:80 check cookie s1

I'm willing to provide a pretty hefty bounty for this. If there's any settings which I'm missing or you think you could improve upon my configuration, please provide a full configuration including all appropriate settings in your answer.

Edit: I am currently using HAProxy 1.6.x and willing to upgrade to latest version if that's what it takes to get a valid solution.

4
+300

The problem #1 & #2:

Don't know why you need to add and validate extra cookies, but for me, it's simple and quite straight forward:

This is what I have tried on vagrant boxes and with default WordPress structure:

1. Prepare 6 separate servers

  • 111.111.1.10 - MySQL server
  • 111.111.1.11 - HAProxy server
  • 111.111.1.12 & 111.111.1.13 - for admin URLs
  • 111.111.1.14 & 111.111.1.15 - for non-admin URLs

HAProxy (v1.6) configurations:

defaults
    log     global
    mode    http
    option  httplog
    option  forwardfor    
    option  dontlognull
    option  http-server-close
    timeout connect 5000
    timeout client  50000
    timeout server  50000
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 403 /etc/haproxy/errors/403.http
    errorfile 408 /etc/haproxy/errors/408.http
    errorfile 500 /etc/haproxy/errors/500.http
    errorfile 502 /etc/haproxy/errors/502.http
    errorfile 503 /etc/haproxy/errors/503.http
    errorfile 504 /etc/haproxy/errors/504.http

frontend http-revolver
    bind 111.111.1.11:80
    acl url_is_wp_admin path_beg /wp-admin /wp-login.php /manage
    use_backend admin-servers if url_is_wp_admin
    default_backend public-servers

backend public-servers
    server s1 111.111.1.12:80 check
    server s2 111.111.1.13:80 check

backend admin-servers
    server s3 111.111.1.14:80 check
    server s4 111.111.1.15:80 check

listen stats
    bind  111.111.1.11:1984
    stats enable
    stats scope http-revolver
    stats scope public-servers
    stats scope admin-servers
    stats uri /
    stats realm Haproxy\ Statistics
    stats auth user:password

2. Use wpms.dev as a demo domain and point it to 111.111.1.11 in /etc/hosts of host machine.

3. Install a base box with ubuntu/trusty64 (LAMP stack + WP multisite) on server 111.111.1.12.

The most important step to avoid the problem #1 & #2 is, because some WordPress cookies depend on paths, we must make sure these constants are consistent in all servers:

define('WP_HOME', 'http://wpms.dev');
define('WP_SITEURL', 'http://wpms.dev');
define('DOMAIN_CURRENT_SITE', 'wpms.dev');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);

To do it, we just need to add it to wp-config.php in this base box.

4. Package the base box and duplicate it on other servers: 111.111.1.13, 111.111.1.14 and 111.111.1.15. Now vagrant up for all servers and check it out.

If you have ssh authentication failure, you must point config.ssh.private_key_path to the private_key of the base box in Vagrantfiles of the duplicated boxes.

The problem #3 is too abroad and may be off-topic here. It can be storage error, server config error... You should ask it on a appropriate network site. :-)

| improve this answer | |
  • The reason for the cookie validation is for WordPress sessions. If you initially connect to WordPress on Server1 and login, what happens if your connection switches to Server2? You're no longer logged into WordPress anymore. – Michael Ecklund Apr 9 '17 at 18:36
1

Most of your question seem to be server related and would be off topic here, but here's my five cents on the WordPress related part.

WP has a pretty simple login cookies system. It stores three cookies, one for the main url, one for the wp-admin directory and one for wp-content\plugins. They contain just the user name and a double hashed password. Nothing server related. So, if the install is found at the right url, those cookies are not going to block anything unless they expire, an event that is plugin controlable.

You seem to report irregular logouts. From the above it follows that two things could be happening. Either a plugin is messing with the cookie expiration time or the url doesn't match.

Concerning the first. Plenty of (e-commerce) plugins use PHP sessions to store data. That data may be stored server side. If the plugin somehow logs the user out when some session data is missing, you will be logged out when your load balancer decides to redirect you to a different server. This would explain irregular logouts.

Concerning the second. That would involve some redirecting to a different url between servers. To me this seems less likely.

| improve this answer | |
  • 1
    anything server local like php sessions will kill a load balancer setup sooner rather then later. you can not have anything local, unless you are going to "pin" a session to a server, but then you might end up in the worst case with all traffic going to one server which kind of defeats the purpose of having a balancer – Mark Kaplun Sep 9 '16 at 23:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.