思路

我之前研究mysql数据库 发现不同的云服务器之间双向同步 体验感emmm 一般这种情况都是走内网的 必须同一个服务商下的同机房服务器才有内网传输 这对我这个typecho小博客来说简直有点小材大用了 太麻烦了 而且远程数据库那延迟更是没得看 索性放弃了这个方案

于是我有了新的想法 因为我目前主站程序 和数据库都是每天同步到github上的 不瞒黑客们 我的博客就是在我本地服务器上的
因为我的云服务器顶不住你们的攻击 所行云服务器就拿来做cdn了 cdn就要干好cdn的活 因为我学会了多源站和健康监测嘛

我博客放本地 很容易遇到家里断网啥的 网站总是会崩那么一会儿 所以我还是需要把备用源站设置成云服务器 这样我主服务器挂了之后 我备用服务器能立马顶上 但目前我还没有想好是主站放云上还是放本地 很伤脑筋啊 我国内服务器全都曝光完了 当初还是太自信了 以为自己能防住cc就行了 结果udp攻击还是放不住 进黑洞啥办法都没

于是我就又去研究了脚本全自拉取github上最新的数据库 然后获取最新日期的数据库 导入到云服务器的mysql数据库里 因为typecho的所有数据基本都在数据库 主站程序除了装的插件和一些插件日志 其实基本不需要变动什么 这个方案我测试了可行性 确实没啥问题 已经成功了

我每天的情况就是 0点备份上传数据库 备用源站1点拉取最新数据库 然后自动导入数据库 完美充当备胎

思考了一下 走cloudflare cdn的还是上国外云服务器 因为这样速度快
然后我自己的cdn 源站设置我本地 备用设置国外云服务器就好了 虽然这样如果我本地掉线了 网站会卡一点 但至少网站不会崩啊 本地一恢复 网站速度又好起来了 同时我设置了双线路的dns解析 更是稳上加稳
黑客们把我国内cdn全打进黑洞之后 我cf那边会立马介入
具体效果还不清楚 试试就知道了 其实只要做好源站的数据库同步 再多加几个源站都是没问题
但我觉得太麻烦了没必要 不如我主站github构建 一次性就把静态目录全推送到各个服务器 然后再做负载均衡 那样会省事很多

为了避免黑客(可能是脚本小子)听不懂我在说什么 我再次解释一下我的方案 我的国外云服务器 用tengine 设置了多个源站
只要我这台服务器没被你找到源站IP 没被打崩 他就可以自动切换我的后端 但我目前还在思考是否需要在这台tengine上部署php也充当源站 我感觉对付你们还是没啥必要啊 因为我一直想着如何去学习企业级的水平 期间甚至有朋友叫我买硬件防火墙来玩玩了
我说对付你们简直太夸张了一些 说实话我是没把脚本小子放在眼里的 但你是真有水平的黑客d哥 我对你绝对保持敬畏之心
我绝无半点挑衅你的胆子!!!其实就是友好切磋 毕竟你们免费给我网站做压测 我又怎么可能真的恨你们呢?
你打我的网站 我造成不了任何损失 我还能学到技术 我还去告你 那我还是人吗?放心来打吧 如果我真的顶不住了 我会认输的。

利用下面三个脚本即可完成我的想法
具体效果有待测试 个人觉得靠谱

博客主程序同步到Github脚本

#!/bin/bash

# 设置 HOME 环境变量
export HOME=/root  # 根据实际用户修改此路径,若是 root 用户则是 /root

# 设置您的仓库目录
REPO_DIR="/www/wwwroot/blog.darklotus.cn/blog.darklotus.cn"

# 输出调试信息
echo "正在进入仓库目录: $REPO_DIR"

# 添加安全目录配置,避免权限问题
git config --global --add safe.directory "$REPO_DIR"

# 进入仓库目录
cd "$REPO_DIR" || { echo "仓库目录不存在!"; exit 1; }

# 输出 Git 仓库状态
echo "当前仓库状态:"
git status

# 检查当前分支和远程分支的差异
LOCAL_COMMITS=$(git rev-list --count HEAD)
REMOTE_COMMITS=$(git rev-list --count origin/main)

# 输出分支状态信息
echo "本地提交数量: $LOCAL_COMMITS"
echo "远程提交数量: $REMOTE_COMMITS"

# 判断本地和远程分支是否有差异
if [ "$LOCAL_COMMITS" -ne "$REMOTE_COMMITS" ]; then
    echo "检测到本地和远程分支有差异,尝试拉取远程更改并合并..."

    # 拉取远程更改并合并
    git pull origin main --no-rebase || { echo "拉取失败,自动退出。"; exit 1; }
fi

# 检查是否有更改文件
git diff --quiet || {
    # 添加所有更改的文件到暂存区
    git add .

    # 提交更改
    git commit -m "自动同步更新 $(date +'%Y-%m-%d %H:%M:%S')" || { echo "没有更改需要提交!"; exit 0; }
}

# 推送更改到 GitHub
git push origin main || { echo "推送失败!"; exit 1; }

# 输出同步成功的消息
echo "同步成功!"

本地数据库同步到GitHub脚本

#!/bin/bash

# 配置部分
DB_BACKUP_DIR="/www/backup/database/mysql/crontab_backup/typecho"  # 数据库备份文件目录
REPO_DIR="/www/wwwroot/Github/tmp/Typecho-Blog"   # 仓库路径
REPO_URL="[email protected]:lianlianlianlianlianlian/Typecho-Blog.git" # SSH 地址
BRANCH="backup"                                  # 推送备份的分支
MAX_BACKUPS=10                                   # 保留的最大备份数量

# 检查数据库备份文件目录是否有新的备份文件
if [ "$(ls -A $DB_BACKUP_DIR)" ]; then
    # 有备份文件,移动备份文件到仓库路径
    echo "找到新的数据库备份文件,开始移动到仓库路径..."
    mv $DB_BACKUP_DIR/* $REPO_DIR/

    # 进入仓库路径
    cd $REPO_DIR

    # 保留最大备份数量的检查
    BACKUP_COUNT=$(ls -1 | wc -l)
    if [ "$BACKUP_COUNT" -gt "$MAX_BACKUPS" ]; then
        # 如果备份文件数量超过最大保留数量,则删除最旧的备份文件
        echo "备份文件数量超过最大保留数量,删除最旧的备份文件..."
        ls -1t | tail -n +$((MAX_BACKUPS+1)) | xargs rm -f
    fi

    # 执行git操作推送到远程仓库
    git add .
    git commit -m "Backup database files"
    git push origin $BRANCH
    echo "备份文件已推送到远程仓库。"

else
    # 没有新的备份文件,确保仓库同步
    echo "没有新的备份文件,检查本地仓库与远程仓库同步状态..."

    cd $REPO_DIR

    # 检查本地仓库与远程仓库是否同步
    LOCAL_STATUS=$(git status -uno | grep "Your branch is up to date" || true)

    if [ -z "$LOCAL_STATUS" ]; then
        # 本地仓库有变化,推送更新
        echo "本地仓库有变化,推送更新到远程仓库..."
        git add .
        git commit -m "Sync local repository with remote"
        git push origin $BRANCH
    else
        # 本地仓库没有变化,检查远程仓库是否有更新
        echo "本地仓库没有变化,检查远程仓库..."
        git fetch origin $BRANCH

        REMOTE_STATUS=$(git diff --exit-code origin/$BRANCH)

        if [ -n "$REMOTE_STATUS" ]; then
            # 本地仓库没有变化,远程仓库有更新,拉取更新
            echo "远程仓库有更新,拉取更新..."
            git pull origin $BRANCH
        else
            # 本地和远程仓库都没有变化
            echo "本地和远程仓库已同步。"
        fi
    fi
fi

全自动导入数据库脚本

import os
import zipfile
import subprocess
from datetime import datetime

# 配置
backup_dir = "/www/wwwroot/blog.darklotus.cn/mysql"# MySQL压缩文件目录
mysql_user = "root"  # MySQL 用户名
mysql_password = "root密码"  # MySQL 密码
mysql_database = "typecho"  # 要导入的目标数据库

def get_latest_backup(directory):
    files = [f for f in os.listdir(directory) if f.endswith(".zip")]
    if not files:
        raise FileNotFoundError("没有找到任何备份文件!")
    # 按文件名中的日期排序
    files.sort(reverse=True, key=lambda x: datetime.strptime(x.split('_')[1], "%Y-%m-%d"))
    return os.path.join(directory, files[0])

def extract_sql_from_zip(zip_path, extract_to):
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        zip_ref.extractall(extract_to)
    # 找到解压后的 SQL 文件
    sql_files = [f for f in os.listdir(extract_to) if f.endswith(".sql")]
    if not sql_files:
        raise FileNotFoundError("压缩包中未找到 SQL 文件!")
    return os.path.join(extract_to, sql_files[0])

def import_to_mysql(sql_file, user, password, database):
    command = [
        "mysql",
        f"-u{user}",
        f"-p{password}",
        database,
        f"< {sql_file}"
    ]
    result = subprocess.run(" ".join(command), shell=True)
    if result.returncode != 0:
        raise Exception(f"MySQL 导入失败,错误码:{result.returncode}")

def main():
    try:
        # 获取最新的备份文件
        latest_backup = get_latest_backup(backup_dir)
        print(f"找到最新备份文件:{latest_backup}")

        # 解压备份文件
        temp_dir = "/tmp/mysql_backup"
        os.makedirs(temp_dir, exist_ok=True)
        sql_file = extract_sql_from_zip(latest_backup, temp_dir)
        print(f"解压成功,SQL 文件路径:{sql_file}")

        # 导入 SQL 文件到 MySQL
        import_to_mysql(sql_file, mysql_user, mysql_password, mysql_database)
        print("数据库导入成功!")
        
        # 清理临时文件
        os.remove(sql_file)
        print("临时文件已清理。")

    except Exception as e:
        print(f"发生错误:{e}")

if __name__ == "__main__":
    main()
最后修改:2024 年 12 月 20 日
如果觉得我的文章对你有用,请随意赞赏