LAMP = Linux + Apache + MySQL/MariaDB + PHP/Perl/Python。本文涵蓋生產級部署全流程:基礎安裝 → 虛擬主機 → 認證授權 → 主從同步 → 文件同步 → 鏡像站點 → 壓力測試。
# RHEL/CentOS/Rocky/AlmaLinux 8/9
dnf install httpd mariadb-server php php-mysqlnd php-fpm -y
# 啟用並啟動
systemctl enable --now httpd mariadb php-fpm
# 安全初始化
mysql_secure_installation
# 掛載光盤/ISO
mount /dev/cdrom /mnt
cd /mnt/Packages
# 安裝核心包 (按依賴順序)
rpm -ivh httpd-*.rpm
rpm -ivh mariadb-server-*.rpm
rpm -ivh php-*.rpm php-mysqlnd-*.rpm
# 解決依賴: rpm -ivh --nodeps (不推薦) 或 yum localinstall
# Apache
systemctl start httpd
curl https://localhost # 頁面顯示 "Testing 123..."
# PHP
echo '' > /var/www/html/info.php
curl https://localhost/info.php | grep "PHP Version"
# MySQL
systemctl start mariadb
mysql -u root -p -e "SHOW DATABASES;"
/etc/httpd/
├── conf/
│ └── httpd.conf # 主配置
├── conf.d/ # 模塊/站點配置片段 (自動 Include)
├── conf.modules.d/ # 模塊加載配置
└── logs/ -> ../../var/log/httpd
# httpd.conf 末尾添加
IncludeOptional conf.d/vhosts/*.conf
# 建立目錄
mkdir -p /etc/httpd/conf.d/vhosts
# /etc/httpd/conf.d/vhosts/site1.conf
ServerName site1.example.com
ServerAlias www.site1.example.com
DocumentRoot /data/web/site1
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
ErrorLog logs/site1-error.log
CustomLog logs/site1-access.log combined
# /etc/httpd/conf.d/vhosts/site2.conf
ServerName site2.example.com
DocumentRoot /data/web/site2
# ... 類似配置
# 映射 /downloads 到 /data/files
Alias /downloads /data/files
Options Indexes FollowSymLinks
Require all granted
# 建立密碼文件
htpasswd -c /etc/httpd/conf.d/.htpasswd admin
htpasswd /etc/httpd/conf.d/.htpasswd user1
# 虛擬主機中啟用
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /etc/httpd/conf.d/.htpasswd
Require valid-user
htdigest -c /etc/httpd/conf.d/.htdigest "Realm" admin
# 配置類似,AuthType Digest, AuthDigestFile
Require ip 192.168.1.0/24 10.0.0.0/8
Require not ip 192.168.1.100
# /etc/my.cnf.d/server.cnf 或 /etc/my.cnf
[mysqld]
server-id=1
log-bin=mysql-bin
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
expire_logs_days=7
max_binlog_size=100M
# 同步用戶
CREATE USER 'repl'@'%' IDENTIFIED BY 'StrongPassw0rd!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
# 獲取二進制日誌位置
SHOW MASTER STATUS;
# 記錄 File 和 Position
# /etc/my.cnf
[mysqld]
server-id=2
relay-log=relay-bin
log-slave-updates=1
read-only=1
gtid_mode=ON
enforce_gtid_consistency=ON
# 建立複製 (GTID 模式,無需手動指定位置)
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl',
MASTER_PASSWORD='StrongPassw0rd!',
MASTER_AUTO_POSITION=1;
START SLAVE;
SHOW SLAVE STATUS\G
# 關鍵: Slave_IO_Running=Yes, Slave_SQL_Running=Yes, Seconds_Behind_Master=0
# 1. 停止主庫寫入
# 2. 確保從庫同步完成 (Seconds_Behind_Master=0)
# 3. 從庫提升為主
STOP SLAVE;
RESET MASTER;
SET GLOBAL read_only=OFF;
# 4. 應用端修改連接地址
# 5. 原主庫修復後作為新從庫加入
# /etc/rsyncd.conf
uid = www
gid = www
use chroot = yes
max connections = 20
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log file = /var/log/rsyncd.log
[webroot]
path = /data/web
comment = Web Root Sync
read only = no
list = yes
auth users = rsync_user
secrets file = /etc/rsyncd.secrets
hosts allow = 192.168.1.0/24
hosts deny = *
# 密碼文件
echo "rsync_user:StrongPassw0rd!" > /etc/rsyncd.secrets
chmod 600 /etc/rsyncd.secrets
# 啟動
systemctl enable --now rsyncd
# 密碼文件 (僅密碼)
echo "StrongPassw0rd!" > /etc/rsync.pass
chmod 600 /etc/rsync.pass
# 單向同步 (推送)
rsync -avz --delete --password-file=/etc/rsync.pass /data/web/ rsync_user@backup_server::webroot
# 定時任務
# crontab -e
# */10 * * * * /usr/local/bin/sync_web.sh >> /var/log/sync_web.log 2>&1
# 1. 來源站點 rsync 服務端 (如上)
# 2. 鏡像站點客戶端腳本 /usr/local/bin/mirror_sync.sh
#!/bin/bash
set -euo pipefail
RSYNC_PASSWORD="StrongPassw0rd!"
export RSYNC_PASSWORD
rsync -avz --delete --bwlimit=5000 \
--exclude='*.log' --exclude='cache/' \
rsync_user@source_server::webroot /data/web/
# 3. 系統定時器
# /etc/systemd/system/mirror-sync.timer
[Unit]
Description=Mirror Sync Timer
[Timer]
OnBootSec=5min
OnUnitActiveSec=15min
[Install]
WantedBy=timers.target
# /etc/systemd/system/mirror-sync.service
[Unit]
Description=Mirror Sync Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mirror_sync.sh
# 啟用
systemctl enable --now mirror-sync.timer
# 1000 請求,50 並發
ab -n 1000 -c 50 https://site1.example.com/
# POST 測試
ab -n 500 -c 20 -p post_data.txt -T "application/x-www-form-urlencoded" https://site1.example.com/api
# 安裝
git clone https://github.com/wg/wrk.git && cd wrk && make
cp wrk /usr/local/bin/
# 基礎測試
wrk -t4 -c100 -d30s https://site1.example.com/
# Lua 腳本模擬真實場景 (post.lua)
wrk -t4 -c100 -d30s -s post.lua https://site1.example.com/api
# 準備數據
sysbench oltp_read_write --mysql-host=master --mysql-user=sbtest --mysql-password=pass --mysql-db=sbtest --tables=10 --table-size=10000 prepare
# 執行測試
sysbench oltp_read_write --mysql-host=master --mysql-user=sbtest --mysql-password=pass --mysql-db=sbtest --tables=10 --threads=64 --time=300 run
# 清理
sysbench oltp_read_write --mysql-host=master --mysql-user=sbtest --mysql-password=pass --mysql-db=sbtest cleanup