# 前後端分流及資料庫讀寫分離( React , Laravel ) ![](https://i.imgur.com/TBdxlm2.png) ![](https://i.imgur.com/gNDLOB9.png) ## :memo: 所需步驟 ``` 1.前端裝一台有 Nginx 的 CT.以及包含執行 React 的環境(圖片上的Load Balancer是多餘的,不必使用) 2.前後端中間需要有一台有 Nginx 的 CT 做 Load Balancer 將請求後端資料做分流(圖片上的往後端分流的權重就是在這邊設定) 3.後端裝三台有 Nginx 的 CT.以及包含執行 Laravel 的環境(其中將 Nginx 執行 php 時,需透過PHP-FPM的套件才能正常運行,一般的 php 套件是無法執行) 4.資料庫裝兩台有 MySql 的 CT 分別當作 Master 及 Slave(一台做 Read + Write ,另一台則只有 Read) 5.將資料庫 Master 與 Slave 的資料同步 6.修改 Laravel 的 config/database.php 中 MySQL 的 host 做讀寫分離(原本是要用 MaxScale 來做讀寫分離,但好像要付錢) ``` ## :memo: 前端 CT ### 前端環境 ``` apt-get update -y apt-get install net-tools -y apt-get install nodejs -y apt-get install npm -y apt-get install nginx -y ``` ### nginx 文件 ![](https://i.imgur.com/EVxUbB6.png) ``` server { listen 7777 location / { root /var/www/gohiking-web/build; index index.html try_files $uri /index.html$is_args$args =404; add_header Access-Control-Allow-Origin *; } } ``` ## :memo: Load Balancer CT ### Load Balancer環境 ``` apt-get update -y apt-get install net-tools -y apt-get install nginx -y ``` ### nginx 文件 ![](https://i.imgur.com/V87JhWQ.png) ``` 監聽到 7777 有請求進來 利用 proxy_pass 做轉址 upstream 將主機分三台做分流 weight=2 會給予兩倍的請求 ``` ``` upstream dynamic { server 10.2.9.101:7777 fail_timeout=5s weight=2; server 10.2.9.102:7777 fail_timeout=5s weight=1; server 10.2.9.103:7777 fail_timeout=5s weight=1; } server { listen 7777; access_log /var/log/nginx/nginx.log; location / { proxy_pass http://dynamic; } } ``` ## :memo: 後端 CT ### 後端環境 ``` apt-get update -y apt-get install net-tools -y apt-get install nginx -y apt-get install curl -y apt-get install php-mysql -y apt-get install php-fpm -y curl -s https://getcomposer.org/installer | sudo php mv composer.phar /usr/local/bin/composer chmod +x /usr/local/bin/composer ``` ### nginx 文件 ![](https://i.imgur.com/PZwMKf8.png) ``` 要使用 fastcgi_pass 將 root 要執行的 php 使用 php-fpm 來執行 ``` ``` server { listen 7777; root /var/www/gohiking-server/public; server_name https://backend.gohiking.app; index index.php; charset utf-8; access_log /var/log/nginx/nginx.log; location / { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } client_max_body_size 20M; } ``` ![](https://i.imgur.com/hHi5VJY.png)![](https://i.imgur.com/eKrUydb.png) ## :memo: 資料庫 ### 資料庫環境 ``` apt-get update -y apt-get install net-tools -y apt-get install mysql-server -y ``` ### 資料庫同步( Master , Slave ) 更改 MySQL 設定檔 /etc/mysql/my.cnf > Master 主機設定 [color=#ff871d] ``` Master MySQL 設定檔 bind-address = 10.2.9.120 Master host的ip server-id = 1 Master , Slave id 需要不一樣 log_bin = /var/log/mysql/mysql-bin.log ``` ``` Master MySQL 資料庫設定 mysql -u root -p > grant replication slave on *.* to 帳號@'%' identified by '密碼'; 建立一個用作同步的帳號 > flush privileges; 將 MySQL 刷新 > flush tables with read lock; 資料表鎖住,避免匯出的當下有資料變動 > show master status; 查看 Master 的狀態,把 File 跟 Position 記下來 > exit; mysqldump -u deploy -p --all-databases --lock-all-tables --events > /home/deploy/mysql_dump.sql mysql -u root -p > unlock tables; 將鎖定解除 > exit; ``` ![](https://i.imgur.com/5FU7uZc.png) > Slave 主機設定 [color=#ff871d] ``` Slave MySQL 設定檔 bind-address = 10.2.9.120 Slave host的ip server-id = 2 read_only = 1 唯讀屬性 report-host = 10.2.9.121 要同步的主機 log_bin = /var/log/mysql/mysql-bin.log ``` ``` Slave MySQL 資料庫設定 rsync -avzh deploy@10.2.9.120:/home/deploy/mysql_dump.sql ./ 將 master 匯出的資料抓回來 mysql -u root -p < /home/deploy/mysql_dump.sql 將資料匯入資料庫 mysql -u root -p > change master to 設定連線 master 資訊 -> master_host='10.2.9.120', # Master IP -> master_user='帳號', # 剛剛 Master 設定的帳號 -> master_password='密碼', # 剛剛 master 設定的密碼 -> master_log_file='mysql-bin.000001', # 上面得到的 File -> master_log_pos=311; # 上面得到的 Position > start slave; # 啟動 slave > show slave status\G # 查看 slave 狀態 # Slave_IO_State: Waiting for master to send event # 如果顯示這樣表示連線成功,正在等待資料更新 ```