Design and Implementation of a Two‑Node High Availability Architecture Using Keepalived, Nginx, MySQL, and Atlas
This article describes a complete two‑machine high‑availability solution that uses keepalived to manage virtual IPs, Nginx for load‑balancing, MySQL GTID replication with Atlas as a proxy, and detailed configuration and fail‑over testing steps to ensure seamless service continuity.
The author was asked to create a high‑availability architecture for only two servers, where if one machine fails the other automatically takes over, while both servers can serve traffic during normal operation.
Architecture Overview : keepalived provides dual‑machine HA by managing an external VIP and an internal VIP. Nginx on the active server handles static content locally and forwards dynamic PHP requests to both servers. SQL requests are routed through the Atlas MySQL‑proxy, which directs write operations to the internal VIP and read operations to the second server, achieving read/write separation.
Requirements :
Servers must support internal IP configuration and inter‑communication.
External IPs must be assignable without MAC binding.
MySQL version 5.6.5+ with GTID support.
Environment :
Server1: eth0 10.96.153.110 (external), eth1 192.168.3.100 (internal)
Server2: eth0 10.96.153.114 (external), eth1 192.168.3.101 (internal)
Both run CentOS‑6. VIPs: external 10.96.153.239, internal 192.168.3.150. Hosts file maps the internal IPs to server names.
Nginx, PHP, MySQL Installation – recommended via EZHTTP (details omitted).
Nginx Configuration (Server1):
http {
...
upstream php-server {
server 192.168.3.101:9000;
server 127.0.0.1:9000;
keepalive 100;
}
...
server {
...
location ~ \.php$ {
fastcgi_pass php-server;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
...
}
...
}Server2 uses the same block but swaps the internal IP in the upstream.
MySQL Configuration – install mysql‑utilities, enable GTID, set unique server‑id, enable binary logging, and grant remote root access:
grant all on *.* to 'root'@'192.168.3.%' identified by 'Xp29at5F37' with grant option;
grant all on *.* to 'root'@'server1' identified by 'Xp29at5F37' with grant option;
grant all on *.* to 'root'@'server2' identified by 'Xp29at5F37' with grant option;
flush privileges;Set up master‑slave replication with mysqlreplicate and verify topology with mysqlrplshow and mysqlrplcheck .
Keepalived Installation & Configuration (both servers):
yum -y install keepalived chkconfig keepalived onServer1 keepalived.conf (higher priority, nopreempt ):
vrrp_sync_group VG_1 {
group { inside_network outside_network }
}
vrrp_instance inside_network {
state BACKUP
interface eth1
virtual_router_id 51
priority 101
advert_int 1
authentication { auth_type PASS; auth_pass 3489; }
virtual_ipaddress { 192.168.3.150/24 }
nopreempt
}
vrrp_instance outside_network {
state BACKUP
interface eth0
virtual_router_id 50
priority 101
advert_int 1
authentication { auth_type PASS; auth_pass 3489; }
virtual_ipaddress { 10.96.153.239/24 }
nopreempt
}Server2 keepalived.conf (lower priority, notify_master runs fail‑over script):
vrrp_sync_group VG_1 { group { inside_network outside_network } }
vrrp_instance inside_network {
state BACKUP
interface eth1
virtual_router_id 51
priority 100
advert_int 1
authentication { auth_type PASS; auth_pass 3489; }
virtual_ipaddress { 192.168.3.150 }
notify_master /data/sh/mysqlfailover.sh
}
vrrp_instance outside_network {
state BACKUP
interface eth0
virtual_router_id 50
priority 100
advert_int 1
authentication { auth_type PASS; auth_pass 3489; }
virtual_ipaddress { 10.96.153.239/24 }
}Atlas (MySQL‑Proxy) Setup – download, install, and configure:
proxy-backend-addresses = 192.168.3.150:3306
proxy-read-only-backend-addresses = 192.168.3.101:3306
pwds = root:qtyU1btXOo074Itvx0UR9Q==
event-threads = 8Start Atlas with:
/usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conf/my.cnfFail‑over Testing – shut down Server1, verify VIPs moved to Server2, check that MySQL replication role switched to master, and confirm that Server1 does not pre‑empt the VIP after reboot.
Recovery Procedure – when Server1 returns, demote Server2, promote Server1 using mysqlrpladmin , verify replication health, restart keepalived to move VIP back, and bring Atlas backends online with SET ONLINE 1; .
The article concludes with a disclaimer that the content is sourced from public channels and is provided for reference only.
Art of Distributed System Architecture Design
Introductions to large-scale distributed system architectures; insights and knowledge sharing on large-scale internet system architecture; front-end web architecture overviews; practical tips and experiences with PHP, JavaScript, Erlang, C/C++ and other languages in large-scale internet system development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.