Hướng dẫn cấu hình Load Balancing cho WordPress

Trong hướng dẫn này chúng tôi sẽ huớng dẫn các bạn cách tạo và mở rộng website chạy wordpress, có khá là nhiều công cụ giúp cân bằng tải(loadbalancer) như HAProxy, Nginx, LVM,… nhưng trong huớng dẫn này tôi sẽ huớng dẫn các bạn cách dùng HAProxy

Mô hình

Khi chưa có load balancer thì có dạng như thế này:

sau khi thực hiện load balancer cho wordpress thì nó sẽ có dạng như sau:

Haproxy là gì

HAProxy là từ viết tắt của High Availability Proxy, nó là phần mềm cân bằng tải TCP/HTTP tức nó hỗ trợ ở tầng layer 4 và tầng layer 7, nếu bạn nào muốn hiểu về Networking Terminology thì xem tại đây. Nó thường được dùng để cải thiện hiệu suất và sự tin cậy trong môi trường máy chủ bằng cách phần tán lưu luợng trên nhiều máy chủ như web, app, database

Hiện tại có khá là nhiều công ty lớn trên thế giới dùng nó như Github, Imgur, Instagram, Airbnb, Twitter, Reddit, các bạn có thể xem thêm tại đây trong bài viết này chúng tôi chỉ hướng dẫn các bạn cách cấu hình cho nó hoạt động với WordPress, nếu muốn tìm hiểu rõ về các thuật toán cân bằng tải cũng như công nghệ tạo nên sự khác biệt của HAProxy thì bạn có thể tham khảo trên tang chủ của nó

Trước khi bắt đầu chúng ta cần có những thành phần sau đây:

  • Một con VPS chạy MySQL
  • Hai con VPS chạy Nginx và PHP-FPM
  • Một con VPS làm Loadbalance

Toàn bộ huớng dẫn này tôi sẽ thao tác trên hệ điều hành Centos7 và được thực thi qua script ansible, tất nhiên bạn cũng có thể áp dụng cho bất cứ phiên bản hệ điều hành Gnu/Linux nào tùy sở thích của bạn. Nếu bạn không có điều kiện sở hữu VPS thì có thể tạo nó thông qua máy ảo. Toàn bộ mã nguồn hướng dẫn của demo này bạn có thể tải nó trên github chú ý rằng bên duới đây có thể chúng tôi sẽ không huớng dẫn chi tiết cài đặt từng cái mà chỉ nói hướng đi cụ thể cho các bạn hiểu.

Cài đặt MySQL/MariaDB

Tùy hệ điều hành và nhà cung cấp VPS mà bạn chọn cách cái đặt, để cho nhanh gọn thì tôi sẽ chọn MySQL trên AWS bạn có thể tham khảo giá thêm tại Amazon RDS for MySQL còn nếu bạn muốn cài đặt từ đầu thì có thể xem bài viết Xây Dựng Hosting WordPress phần 2. Tôi giả sử bạn đã cài dặt thành công thì bước kế tiếp chúng ta cần tạo một cơ sở dữ liệu(database) với tên gọi là demo_loadbanlancer_wp_gsviec, vì wordpress cần điều đó.

## Connect to shell MariaDB
create database demo_loadbanlancer_wp_gsviec

tất nhiên chúng tôi có cung cấp script làm tự động mọi thứ cho bạn, nếu bạn muốn bạn có thể tham khảo tại đây

Cài đặt Nginx và PHP-FPM

Trong demo này chúng tôi sẽ cài đặt trên 2 con VPS với địa chỉ IP là 52.91.57.224, 54.198.47.182. Bỏi vì WordPress viết bằng ngôn ngữ PHP nên chúng ta phải cài PHP, nhưng tại vì chúng tôi dùng Nginx làm web server nên cài PHP-FPM để cho nó có tốc độ tối ưu nhất.

Truớc tiên chúng ta cần cập nhật các bản update mới nhất cũng như cài các thành phần bổ trợ cho hệ điều hành Centos7:

yum install epel-release -y
yum install gcc libxml2-devel libXpm-devel gmp-devel libicu-devel
t1lib-devel aspell-devel openssl-devel bzip2-devel libcurl-devel
libjpeg-devel libvpx-devel libpng-devel freetype-devel readline-devel
libtidy-devel libxslt-devel libmcrypt-devel pcre-devel curl-devel
mysql-devel ncurses-devel gettext-devel net-snmp-devel libevent-devel
libtool-ltdl-devel libc-client-devel postgresql-devel bison gcc make -y

Cài đặt Nginx:

Để cài đặt em nó thì bạn chỉ cần chạy duy nhất một dòng lệnh dưới đây

####
yum install nginx -y

PHP và PHP-FPM

Cài đặt thêm gói epel và webtatic repository:

Sau khi chạy lệnh bên trên kia xong bạn chỉ cần chạy lên bên dưới để cài đặt PHP và PHP-FPM

yum install php70w php70w-fpm php70w-opcache
php70w-bcmath  php70w-cli php70w-common
php70w-devel php70w-gd php70w-intl php70w-mbstring
php70w-mcrypt php70w-mysqlnd php70w-pdo php70w-pecl-imagick
php70w-xml  php70w-json --skip-broken -y
yum remove ImageMagick-last-6.9.5.10-1.el7.remi.x86_64 -y
yum install php70w-pecl-imagick -y

sau khi cài đặt xong cho con web1 thì bạn làm các thao tác tương tự cho con web2, nếu như bạn dùng các dịch vu của Linode, DO, AWS thì nó sẽ có tính năng clone hay snap bạn chỉ cần click thế là có ngay con mới y chang như con web1 bạn vừa cài đặt. Trong trường hợp của chúng tôi sau khi cài đặt thành công có thể xác nhận thông qua lệnh sau:

curl 54.198.47.182
curl 52.91.57.224

Đồng bộ hóa thư mục web

Như bạn biết khi bạn dùng 2 con web server tức là những file của ứng dụng bạn sẽ phải ở hai nơi, do đó làm thế nào để đồng bộ nó có khá là nhiều cách như dùng scp, sync nhưng cách này không tối uư lắm, một trong những giải pháp là cài thằng glusterFS lên mỗi con server của bạn để nó đồng bộ hóa media hay hình ảnh khi bạn upload lên web server.

Chú ý rằng file ở đây tùy truờng hợp cụ thể, ví dụ web site của bạn là blog hay chia sẽ hình ảnh gì đó, thì lúc này một user upload hình ảnh lên có thể nó ở trên con wordpress-1 hoặc wordpress-2 khi đó glusterFS nó sẽ sync giúp bạn, còn nếu bạn dùng Amazon Cloudfront hay Amazon S3 để lưu trữ các file này thì không cần thiết phải cài glusterFS

Việc dùng NFS để xử lý phân bố hình ảnh nó rất chậm đặt biệt là khi dùng kết hơp CDN bạn có thể tham khảo bài viết Needle in a haystack của các kỹ sư Facebook viết tại sao họ từ bỏ nó NFS chuyển sang công nghệ họ gọi là haystack!

Vậy chúng ta thì sao khi, câu trả lời của cá nhân tôi bạn nên dùng Amazon S3 để xử lý luư trữ file là tốt nhất với giá cả phải chăng và gần như 99,999999% không gặp sự cố die!!!!

Một câu hỏi nữa:): Nếu ta dùng S3 thế thì mã nguồn code của ta xử lý thế nào khi ta thêm một file vào?

Câu trả lời của tôi là như sau: Khi bạn triển khai mã nguồn code lên web server thông thuờng theo cách truyển thống bạn dùng FTP, SCP, Git pull, nhưng khi chúng ta cấu hình cho hàng chục hay hàng trăm con web server thì dùng cách đó rất là vất quả, bạn phải login vào từng con để cập nhật mã nguồn web bạn khi bạn thêm tính năng nào đó rất là vất quả, và thông thuờng không ai làm thế cả, chúng ta sẽ dùng một tool để làm chuyện đó tự động. Có khá nhiều dịch vụ công cấp cho ta làm chuyện đó như Amazon commit nhưng cá nhân tôi thích tool open source hơn chẳng hạn như CapitranoDeployer và công cụ yêu thích của tôi là ansible

Cài đặt wordpress

Việc cài đặt wordpress khá là đơn giản, bạn chỉ việc tải mà nguồn WordPress về và sau đó upload lên trên 2 con server ở trên thế là xong, nếu bạn nào chưa hiểu cách cài đặt wordpress trên Linux là gì thì có thể xem khóa học WordPress căn bản, nhưng như chúng tôi đã nói ở phần đồng bộ hóa thư mục web thì rất là vất quả, ví dụ chúng ta có 5 con web server thì phải upload cho cả 5 con, do đó chúng tôi sẽ dùng ansiable để deploy chúng, bạn có thể xem trong mã nguồn của chúng tôi.

Cài đặt HAProxy

Việc cài đặt HAProxy có 2 cách, bạn có thể cài dặt từ mã nguồn của nó hoặc cái đặt thông qua repo của Centos trong demo này chúng tôi cài đặt thông qua repo với lệnh sau:

####
sudo yum install haproxy

mặt định thư mục cấu hình của haproxy nó sẽ nằm trong /ect/haproxy và cái tập tin chúng ta thao tác nhiều nhất là /etc/haproxy/haproxy.cfg, để cấu hình haproxy thì chúng ta cần sữa tập đó, nhưng trước hết chúng ta cần backup tập tin này trước khi thây đổi chúng, có gì sau này chúng ta còn rollback ?

sudo cp /etc/haproxy/{haproxy.cfg,haproxy.cfg.back}

sau đó bạn chỉnh sữa tập tin đó có dạng như bên duới:

ttings
#---------------------------------------------------------------------
global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
frontend http
    bind *:80
    default_backend app
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
    balance     leastconn
    server  app1 54.198.47.182:80 check
    server  app2 52.91.57.224:80 check
listen stats *:8080
    stats enable
    stats uri /
    #stats hide-version
    #stats auth phanbook:phanbook

trong đó bạn cần chú ý các phần sau, truớc tiên là phương thức balance mặc định của nó là roundrobin nó là phương thức đơn giản nhất với phương thức này thì mỗi một request gửi từ client thì sẽ chọn các máy chủ lần luợt, ví dụ trong demo này thì request đầu tiên thì haproxy sẽ chuyển đến app1, tiếp tục request thứ 2 thì nó sẽ chuyến đến app2. Với các này nó không tối ưu cho lắm do đó tôi khuyên các bạn nên chọn phưong thức là leastconn

Vậy leastconn là gì? Nó là phương thức chọn máy chủ có ít kết nối nhất ví dụ trong demo trên chúng tôi giả sử vì một lý do nào đó mà cái app1 nó có qua nhiều connect thì những request từ client nó sẽ tư động chuyển đến app2 cho đến khi nào lượng connect trên nó lớn hơn app1 thì nó sẽ dừng lại. Tất nhiên chúng ta có nhiều phương thức khác như sourceHealth checkStick session

Còn phần cấu hình

listen stats *:8080
    stats enable
    stats uri /
    #stats hide-version
    #stats auth phanbook:phanbook

này chỉ là tạo giao diện web GUI của HAProxy để quản lý các web server mà chúng ta cấu hình, mặc định nó không có chứng thực password nếu bạn muốn thì bạn xóa dấu # truớc dòng #stats auth phanbook:phanbook, giao diện nó như sau nếu bạn truy cập qua đường dẫn: http://34.207.217.19:8080/

HaProxy gsviec

Như hình trên thì hiện tại phần backend có 2 web server lần luợt là app1 và app2, nó đang hoạt động bình thường nên nó có màu xanh, nếu nó bị chết(die) thì sẽ xuất hiện màu đỏ:) Bạn thử stop một con web app1 sau đó refresh trình duyệt xem có gì thây đổi không

Sử dụng Ansiable để deploy

Ansible là cái gì và nó làm việc như thế nào? thì trong khuôn khổ bài viết này chúng tôi không thể giải thích hết cho các bạn được, ngay lúc này các bạn chỉ cần hiểu nó là một công cụ giúp chúng ta cài đặt toàn bộ các thao tác mà chúng tôi miêu tả ở trên thông qua một dòng lệnh duy nhất, còn để hiểu nó như thế nào thì có thể truy cập vào trang chủ của ansible

Chúng tôi sẽ sử bạn đã cài đặt thành công trên máy của bạn, nếu chưa có thì có thể cài đặt thông qua câu lệnh sau:

sudo easy_install pip
sudo pip install ansible

vì chúng tôi dùng ansitrano để deploy mã nguồn wordpress do đó bạn cần phải cài vào nếu như muốn thực hiện demo bên dưới

ansible-galaxy install carlosbuenosvinos.ansistrano-deploy carlosbuenosvinos.ansistrano-rollback

công việc tiếp theo là bạn clone mã nguồn của chúng tôi tại https://github.com/gsviec/haproxy-wordpress

sau đó mở tập tin ansiable/hosts rồi chỉnh các thông số IP lại cho đúng với các IP VPS của bạn, trong trường hợp của chúng tôi có dạng như sau:

web01 ansible_ssh_host=54.198.47.182 ansible_ssh_port=22
web02 ansible_ssh_host=52.91.57.224 ansible_ssh_port=22
db1 ansible_ssh_host=34.207.202.109 ansible_ssh_port=22
ha1 ansible_ssh_host=34.207.217.19 ansible_ssh_port=22
[web]
web01
web02
[db]
db1
[haproxy]
ha1

mặt định chúng tôi sẽ tạo database với tên là demo_loadbanlancer_wp_gsviec, nếu bạn muốn thây đổi nó thì có thể vào tập tin all tại đây

Mọi thứ gần như đã xong công việc cuối cùng còn lại của bạn thì chỉ cần chạy lệnh sau:

cd haproxy-wordperess/ansiable
ansible-playbook -i hosts playbook.yml
ansible-playbook -i hosts deploy

sau đó bạn chỉ việc chờ đợi cho nó cài đặt, cuối cùng bạn truy cập thông qua địa chỉ IP(ha1) ở phần khai báo trong hosts file của tập tin ansible, trong demo này của chúng tôi là http://34.207.217.19/ thì bạn nên thấy kết quả như hình bên dưới đây:

Xin chúc mừng bạn đã setup thành cồng cân bằng tải cho web site wordpress của bạn

Test

Để kiểm tra nó có hoạt động hiểu quả hay không chúng ta cần phải dùng tool để test nó, có khá là nhiều công cụ như ab apache, siege, beeswithmachineguns nhưng trong demo này chúng tôi sẽ dùng dịch vụ bên thứ 3 đó là loader.io, sau khi verify và chạy test cho 10k request trong vòng 15s thì 100% web site đáp ứng tốt bạn có thể xem hình bên dưới hoăc link này ha-10000

Kết luận

Mô hình cần bằng tải trong hướng dẫn này vẫn chưa đáp ứng được cơ chế failover tức là nếu con load balancer(ha1) hoặc con db1 nó die thì nguời dùng không thể truy cập được, để khắc phục nhược điểm đó thì ta cần phải tại thêm con một con load balancer va database nữa, sau đó kết hợp với cơ chế Keepalived để tự động thêm hoặc xóa load balancer khi có nhiều người hoặc ít nguời truy cập