闲置 VPS 发热计划:搭建一个简单的 CDN 系统

起因 出于科学上网的目的,购买了挺多优质线路的 VPS,但是流量根本用不完,太浪费了。于是想到可以用这些 VPS 搭建一个 CDN 系统,用于加速自己的网站。 方案探索 首先当然是去 Github 上找一些开源的项目,看看有没有现成的解决方案。但是找了一圈,发现这种项目挺少的,倒是找到 GoEdge 这种整套解决方案的,但是看了一下文档,感觉挺复杂的。于是打算自己基于一些现成的组件来手撸一个简易版的 CDN 系统。 架构设计 我设想中的架构是这样的: 首先这些优质线路的 VPS 作为流量入口,通过 GEO DNS 解析,将用户请求分发到最近的 VPS。 VPS 如果有缓存,直接返回缓存内容,如果没有缓存,请求源站获取内容,然后返回给用户,并缓存到本地。 为了区分动态请求和静态请求,需要单独配置 CDN 域名,动态请求直接转发到源站,静态请求走缓存。 下面是整个系统的架构图: flowchart LR A1[用户(CN)] -->|GEO DNS| B1[VPS(CN)] A2[用户(US)] -->|GEO DNS| B2[VPS(US)] A3[用户(JP)] -->|GEO DNS| B3[VPS(JP)] B1 -->|请求| C[源站] B2 -->|请求| C B3 -->|请求| C C -->|返回| B1 C -->|返回| B2 C -->|返回| B3 B1 -->|缓存| A1 B2 -->|缓存| A2 B3 -->|缓存| A3 style C fill:#f9f,stroke:#333,stroke-width:4px style A1 fill:#bbf,stroke:#333,stroke-width:2px style A2 fill:#bbf,stroke:#333,stroke-width:2px style A3 fill:#bbf,stroke:#333,stroke-width:2px Caddy 前置与自动 HTTPS 首先每个 VPS 上都需要安装 Caddy 作为前置,用于自动申请 HTTPS 证书,以及转发请求到源站或者缓存。这里 Caddy 会区分动态请求和静态请求,动态请求直接转发到源站,静态请求走缓存。Nginx 其实也可以,只是 Nginx 自动申请 HTTPS 证书比较麻烦。Caddy 的配置如下: ...

October 14, 2024

k8s下MySQL完美的备份方案

前言 此前一直在使用 mysqlshell 来备份部署在 k8s 上的 MySQL,虽然这个工具比起 mysqlpump 来说要快很多,支持多线程、可以直接备份到远程 s3 等,但是后面使用过程中也陆陆续续发现了一些问题: CPU 占用过高 由于开启了多个核来并行执行提升速度,所以每次执行备份的时候 CPU 只能在凌晨时间,这样极端情况下可能会导致丢失一天的数据。 无法增量备份 每次备份的时候都是全量备份,这样也会导致备份的数据占用空间过大。 恢复数据慢 由于 mysqlshell 备份的数据是逻辑备份,所以恢复数据的时候会很慢。如果另外两个问题还是可以忍受的话,这个问题是无法忍受的。比如在进行服务器迁移的时候,系统恢复的时间就会很长。 使用 xtrabackup 之前也曾调研过 xtrabackup,xtrabackup,强大的 MySQL 备份工具,但是由于 k8s 下的 MySQL 是使用的 PVC,所以无法直接使用 xtrabackup 来备份。后面实在忍受不了 mysqlshell 的问题,所以又重新研究了一下,最终找到了一个比较完美的解决方案。 打包一个基础镜像 Dockerfile 这个 Dockerfile 里面安装了 xtrabackup 和 rclone,rclone 是一个支持多种对象存储的命令行工具,可以用来将备份的数据上传到对象存储等。然后启动的时候会执行 entrypoint.sh,这个脚本会启动一个 cron 定时任务,每小时执行一次 backup.sh,这个脚本会根据是否存在全量备份来执行全量备份或者增量备份,然后将备份的数据上传到对象存储。 FROM ubuntu RUN apt update && \ apt install -y wget cron lsb-release curl gnupg2 zstd unzip && \ wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb && \ dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb && \ apt update && \ percona-release enable-only tools release && \ apt update && \ apt install percona-xtrabackup-80 -y && \ rm -rf percona-release_latest.$(lsb_release -sc)_all.deb RUN curl https://rclone.org/install.sh | bash COPY backup.sh /backup.sh COPY entrypoint.sh /entrypoint.sh RUN chmod +x /backup.sh && chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] backup.sh 这个脚本执行了实际的备份操作,备份的数据会存放在 /backup 目录下,然后会将备份的数据同步到 s3 上。 ...

December 27, 2023

xtrabackup,强大的 MySQL 备份工具

前言 一直在寻找一个最适合自己的 MySQL 备份方案,毕竟数据无价,来来去去也使用了很多种方案,在此记录一下。 使用云数据库 这是最省心的方案了,云数据库比如阿里云的 RDS,腾讯云的云数据库都自带了备份功能,完全不用自己操心,但是这种方案的缺点也很明显,就是价格太贵了,对于个人开发者来说,成本还是太高了,同配置的云数据库比服务器要贵很多。 之前也用了腾讯云最低配置的云数据库,一个月要一百多,放弃了。 自建 MySQL 主从 之前也尝试了在阿里云买了两台轻量服务器组了主从数据库,也用了一段时间,虽然很便宜,但是实际用起来还是有一些问题。 阿里云轻量服务器的磁盘性能很低,不适合搭建数据库,所以我组了主从并且搭配 proxysql 来做读写分离。 阿里云轻量服务器的磁盘太小,后面数据量多了之后,磁盘空间就不够用了,而升级更高配置的话成本又变高了。 使用廉价 VPS 加 mysqlpump 有很多小的 VPS 商家卖的 VPS 比起大厂的更便宜,而且性能更高,但是缺点就是没有大厂稳定,而且有丢失数据的风险,所以定时备份数据就很重要。 之前我使用的是 mysqlpump 加定时任务的方式,为此我还专门写了个项目 https://github.com/long2ice/databack,将备份的数据上传到对象存储,但是后面发现这个方案也有问题,就是数据量大了以后不论是备份或者上传到对象存储花费的时间都很长,更不用说恢复数据的时间了,完全没办法使用在生产环境。 使用廉价 VPS 加 xtrabackup 这是我最终使用的方案,使用 xtrabackup 备份数据,然后上传到对象存储。xtrabackup 备份数据非常快,它是基于物理备份的,并且备份的时候不会影响到线上数据库。同时它也支持增量备份,这样除了第一次上传全量备份的时候会花费一些时间,后面的备份都会很快。 贴一下使用的脚本: #!/bin/bash # 备份函数 function backup() { cp /etc/mysql/mysql.conf.d/mysqld.cnf ./ # 检查备份目录是否存在 if [ ! -d "./backups" ]; then mkdir ./backups fi # 检查是否存在全量备份 if [ -z "$(ls -A ./backups)" ]; then # 执行全量备份命令 xtrabackup --backup --compress=zstd --target-dir=./backups/base echo "全量备份完成。" else # 执行增量备份命令 xtrabackup --backup --compress=zstd --target-dir=./backups/inc-$(date '+%Y-%m-%d_%H:%M:%S') --incremental-basedir=$(ls -d ./backups/* | tail -n 1) echo "增量备份完成。" fi rclone sync /root/backup/mysql greencloud:/backup/mysql/prod } # 恢复函数 function restore() { # 遍历备份目录解压缩 for d in backups/*/; do xtrabackup --decompress --target-dir=$d done # 准备恢复 for d in backups/*/; do if [ $d == "backups/base/" ]; then xtrabackup --prepare --apply-log-only --target-dir=$d else # if is last dir if [ $d == $(ls -d backups/*/ | tail -n 1) ]; then xtrabackup --prepare --target-dir=./backups/base --incremental-dir=$d else xtrabackup --prepare --apply-log-only --target-dir=./backups/base --incremental-dir=$d fi fi done # 执行恢复 xtrabackup --copy-back --target-dir=./backups/base echo "恢复完成。" } case "$1" in backup) backup ;; restore) restore ;; *) echo "Usage: $0 {backup|restore}" ;; esac 完事之后直接 crontab 挂一个定时任务就 OK 了。 ...

July 31, 2023

开发了一个实时同步数据库到meilisearch的工具

前言 在我的个人项目中很多地方都使用到了 meilisearch,之前也写了一篇博客介绍了一下 meilisearch 的使用,可以参考一下:MeiliSearch,一个轻量级搜索引擎。 之前的话就简单粗暴地其了一个定时任务,每隔一段时间就从数据库中同步一次数据到 meilisearch,这样的话就会有一些问题: 数据不实时。 每次都是全量同步,效率很低。 所以希望能有一个能实时增量同步数据库,类似 MySQL 的,到 meilisearch 的工具。在 GitHub 上搜了一圈,发现没有什么好用的,于是打算自己写一个。 项目地址 https://github.com/long2ice/meilisync, 命令行版本。 https://github.com/long2ice/meilisync-admin,在命令行版本的基础上,增加了一个 web 管理界面,可以动态添加同步任务,查看同步状态等。 预览 技术栈 前端:React + daisyui 后端:FastAPI + TortoiseORM + MySQL 架构 目前支持三种数据库: MySQL,使用 binlog 来实现。 PostgreSQL,使用 logical replication 来实现。 MongoDB,使用 change stream 来实现。 最初的版本只是实现了命令行的功能,通过加载配置文件,然后启动一个进程,然后通过 binlog 类似的技术来实现实时地增量同步。 更进一步 命令行版本可以满足基本的需求,但是还是有一些不足的地方: 修改配置需要重启。 无法动态添加同步任务。 只支持单实例。 于是在命令行版本的基础上,增加了一个 web 管理界面,可以动态添加同步任务,查看同步状态,以及增加了登录功能。 遇到的问题 遇到错误如实例连不上,重启进程之类的会丢失数据。 全量刷新数据的实时不能影响线上业务。 MySQL binlog 连接长时间后丢失。 以及一些其他的问题。

July 29, 2023

科学上网与VPN办公的完美结合

前言 工作中很多时候需要使用到 VPN 来访问企业内网,但是同时又需要科学上网,这两个同时开启的时候会出现冲突。所以之前老是要切换来切换去,很麻烦,最近终于找到了完美的解决办法。 准备工作 Clash,https://github.com/Dreamacro/clash,强大的代理分流工具。 Docker,https://www.docker.com,用来跑 openvpn 的容器。将 openvpn 跑在容器里可以防止污染宿主机。 启动 openvpn 将 openvpn 的配置文件放在./config目录下,然后执行docker-compose up -d启动 openvpn。该容器会将 openvpn 转发到 socks5 代理,端口为 1080。 version: "3" services: openvpn: image: curve25519xsalsa20poly1305/openvpn-socks5 restart: always cap_add: - NET_ADMIN ports: - 1080:1080 environment: - OPENVPN_CONFIG=/config/config.ovpn volumes: - ./config:/config devices: - /dev/net/tun 启动 clash 主要是 rules 部分的配置。 proxies: - name: "openvpn" type: socks5 server: 192.168.123.205 port: 1080 rules: - IP-CIDR,172.26.0.0/16,openvpn # 你的公司内网网段 - DOMAIN-SUFFIX,xxx.cn,openvpn # 你的公司内网域名 然后将 clash 设置为 rule 模式,一切 OK,just enjoy it! ...

March 20, 2023