---
# System prepended metadata

title: '前後端分流及資料庫讀寫分離（ React , Laravel ）'

---

#  前後端分流及資料庫讀寫分離（ 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
# 如果顯示這樣表示連線成功，正在等待資料更新
```