Polaris Blog - 高性能现代博客系统
项目概述
Polaris Blog 是一个基于 Go 语言开发的高性能、现代化博客系统。采用单体架构设计,内置完整的后台管理系统,支持多数据库、多缓存后端、插件扩展和主题定制,适合个人博客、技术站点和内容发布平台。
核心特性
🚀 极致性能
- 全页面 HTML 缓存:前台页面渲染结果缓存 2 分钟,缓存命中时零数据库查询、零模板渲染、零 Markdown 解析,P50 延迟 <5ms
- 预压缩 gzip:缓存时预计算 gzip 字节,缓存命中请求直接返回预压缩内容,避免实时压缩 CPU 开销
- Singleflight 防击穿:缓存失效时只有一个请求执行渲染,其他并发请求等待结果,消除 thundering herd 问题
- 绕过路由器:缓存检查在
Server.ServeHTTP层执行,缓存命中时 chi 路由器完全不参与,减少中间件链开销 - SQLite WAL 模式:读写并发支持,busy_timeout=5s 避免锁等待失败,cache_size=64MB 提升查询速度
- 连接池优化:MySQL/PostgreSQL 连接池配置(MaxOpenConns=25, MaxIdleConns=10, ConnMaxLifetime=5m)
基准测试(wrk -t20 -c1000,localhost):
- RPS: 46,000+ 请求/秒
- P50 延迟: 20ms
- P99 延迟: 100ms
- 吞吐量: 1.2GB/s
🎨 主题系统
- Pongo2 模板引擎:Django 风格模板语法,支持继承、包含、过滤器
- 主题配置:每个主题可定义可配置选项(banner、颜色、布局等),后台实时调整
- 实时切换:无需重启服务,后台直接切换主题
- 默认主题:现代化响应式设计,支持深色模式、移动端优化、打字机效果 banner
🔌 WASM 插件系统
- WebAssembly 运行时:基于 wazero(纯 Go 实现,无 CGO 依赖)
- 插件 API:提供 HTTP 调用、内容过滤钩子、设置存储等接口
- 安全隔离:每个插件独立 WASM 实例,内存限制 32MB,超时 10s
- 开发语言:支持 Go、AssemblyScript、Rust 等编译为 WASM 的语言
- 示例插件:GitHub 卡片插件、Cloudflare Turnstile 验证插件
🌐 国际化支持
- 多语言:内置英文/中文支持,可扩展其他语言
- 动态切换:用户可通过 cookie 选择语言,后台可设置默认语言
- 模板集成:
{{ t("key") }}函数直接在模板中调用翻译
📝 内容管理
- Markdown 编辑器:基于 EasyMDE,实时预览、语法高亮、工具栏快捷操作
- 分类/标签:多级分类、标签管理,文章可关联多个分类和标签
- 自定义页面:除博客文章外,可创建独立页面(关于、友链等)
- 评论系统:内置评论管理,支持嵌套回复、审核机制
- 媒体管理:图片/文件上传,支持本地存储和外部存储扩展
- 草稿/发布:文章状态管理,草稿保存、定时发布(计划)
🛡️ 安全特性
- CSRF 防护:Origin/Referer 验证,兼容 CDN 环境(X-Forwarded-Host 解析)
- XSS 防护:Markdown 渲染 HTML 安全过滤,模板自动转义
- JWT 认证:无状态认证,access_token + refresh_token 双令牌机制
- Cookie 安全:Secure/HttpOnly 标志,根据协议动态设置
- 路径遍历防护:媒体上传路径验证,禁止访问敏感目录
- 输入验证:所有用户输入严格验证,防止注入攻击
📦 部署便捷
- 单二进制部署:编译后单个可执行文件,无外部依赖
- 嵌入式资源:前端文件、默认配置、默认主题打包进二进制
- 自解压更新:启动时可自动解压前端文件覆盖旧版本
- Docker 支持:提供 Dockerfile,支持容器化部署
- 跨平台:支持 Linux、Windows、macOS,提供多架构编译(amd64/arm64)
🔍 搜索功能
- Bleve 搜索引擎:纯 Go 实现全文搜索,无需外部服务
- 实时索引:文章发布/更新时自动索引
- 高性能:倒排索引支持,毫秒级搜索响应
🗄️ 数据存储
| 类型 | 支持后端 | 适用场景 |
|---|---|---|
| 数据库 | SQLite / MySQL / PostgreSQL | SQLite:单机部署;MySQL/PG:高并发生产环境 |
| 缓存 | Memory / Redis | Memory:小型站点;Redis:分布式缓存 |
| 存储 | Local / (可扩展 S3/OSS) | Local:简单部署;云存储:大规模文件 |
🎛️ 后台管理
- HTMX + Alpine.js:现代化交互,无需重载页面
- 响应式设计:移动端完整支持,侧边栏折叠、触控优化
- 仪表盘:文章/评论/访问统计概览
- 批量操作:文章批量删除、状态修改
- 设置管理:站点标题/URL/SEO 配置实时修改
- 插件管理:插件启用/禁用、配置调整
- 主题管理:主题切换、主题配置调整
技术栈
| 层级 | 技术 |
|---|---|
| Web 框架 | go-chi/chi v5(轻量路由) |
| ORM | GORM v1.31(多数据库支持) |
| 模板引擎 | Pongo2 v6(Django 风格) |
| Markdown | Goldmark v1.7(高性能解析) |
| 语法高亮 | Chroma v2(Go 实现 Pygments 风格) |
| WASM 运行时 | wazero v1.11(纯 Go,无 CGO) |
| 缓存 | go-redis v9 / 内存缓存 |
| 搜索 | Bleve(全文索引) |
| 认证 | JWT golang-jwt/v5 |
| 配置 | YAML v3 |
| 国际化 | 自研 i18n Bundle |
架构设计
flowchart TB
%% 样式定义
classDef cache fill:#e1f5fe,stroke:#01579b,stroke-width:2px
classDef router fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef handler fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
classDef service fill:#f3e5f5,stroke:#6a1b9a,stroke-width:2px
classDef repo fill:#fff8e1,stroke:#f57f17,stroke-width:2px
classDef storage fill:#efebe9,stroke:#4e342e,stroke-width:2px
subgraph L1["🔹 HTTP Server 层"]
direction TB
S1["ServeHTTP<br>(缓存快速路径)"]:::cache
S2["缓存命中 → 直接返回"]:::cache
S3["chi.Router"]:::router
S4["Middleware Chain<br>RequestID → RealIP → Logging → Recoverer<br>SecurityHeaders → CacheControl → Compress"]:::router
S5["Web Handler<br>(前台页面渲染)"]:::handler
S6["Admin Handler<br>(后台管理API)"]:::handler
S1 -->|命中| S2
S1 -->|未命中| S3
S3 --> S4
S4 --> S5
S4 --> S6
end
subgraph L2["🔸 Service 业务层"]
direction LR
T1["PostService"]:::service
T2["CommentService"]:::service
T3["CategoryService"]:::service
T4["TagService"]:::service
T5["AuthService"]:::service
T6["PluginManager"]:::service
T7["ThemeManager"]:::service
T1 --- T2 --- T3 --- T4 --- T5 --- T6 --- T7
end
subgraph L3["🔹 Repository 仓储层"]
direction LR
U1["PostRepo"]:::repo
U2["CommentRepo"]:::repo
U3["CategoryRepo"]:::repo
U4["TagRepo"]:::repo
U5["UserRepo"]:::repo
U6["OptionRepo"]:::repo
U7["MediaRepo"]:::repo
U1 --- U2 --- U3 --- U4 --- U5 --- U6 --- U7
end
subgraph L4["🔸 Storage 存储层"]
direction LR
V1["Database<br>SQLite / MySQL / PG"]:::storage
V2["Cache<br>Memory / Redis"]:::storage
V3["Storage<br>Local / S3"]:::storage
V4["Search<br>Bleve"]:::storage
V1 --- V2 --- V3 --- V4
end
%% 层间连线
L1 --> L2
L2 --> L3
L3 --> L4
性能优化历程
问题:高吞吐量下延迟过大(1s+)
| 优化阶段 | 措施 | 效果 |
|---|---|---|
| 第一轮 | 添加数据库连接池 + 关键索引 | 基础稳定性 |
| 第二轮 | 站点配置内存缓存(减少 7-8 次 DB 查询) | 单请求性能提升 |
| 第三轮 | 全页面 HTML 缓存 | 缓存命中时零开销 |
| 第四轮 | Singleflight 防击穿 | P99 从 800ms → 200ms |
| 第五轮 | 预压缩 gzip | 减少 CPU 开销 |
| 第六轮 | 缓存检查绕过 chi 路由器 | RPS 从 43K → 46K |
| 第七轮 | Content-Length + 预构建 headers | 消除 chunked 开销 |
最终结果:
- RPS: 46,000+
- P50: 20ms
- P99: 100ms
- 超时错误: 0
快速开始
1. 编译
1git clone https://github.com/polaris-blog/blog.git
2cd blog
3go build -o polaris ./cmd/polaris
2. 运行
1./polaris
首次运行会:
- 解压嵌入式前端文件到
./web目录 - 创建默认配置文件
config.yaml - 初始化数据库
- 启动 HTTP 服务(端口 8080)
3. 初始化
访问 http://localhost:8080/admin/setup 创建管理员账号,之后即可进入后台管理。
4. 配置(可选)
编辑 config.yaml 调整:
- 数据库类型(sqlite/mysql/postgres)
- 缓存类型(memory/redis)
- 服务端口
- 主题选择
5. Docker 部署
1docker build -t polaris-blog .
2docker run -d -p 8080:8080 -v ./uploads:/app/uploads polaris-blog
目录结构
polaris-blog/
├── cmd/polaris/ # 入口程序
├── configs/ # 默认配置 + 国际化文件
├── internal/ # 核心代码
│ ├── app/ # 应用初始化
│ ├── cache/ # 缓存抽象层
│ ├── config/ # 配置解析
│ ├── database/ # 数据库初始化
│ ├── http/ # HTTP 处理
│ │ ├── handler/ # 请求处理器
│ │ ├── middleware/ # 中间件
│ │ └── server.go # 服务入口
│ ├── i18n/ # 国际化
│ ├── model/ # 数据模型
│ ├── plugin/ # 插件系统
│ ├── repository/ # 数据访问层
│ ├── service/ # 业务逻辑层
│ ├── storage/ # 文件存储
│ └── theme/ # 主题系统
├── plugins/ # 插件目录
├── themes/ # 主题目录
├── web/ # 前端资源
│ ├── admin/ # 后台前端
│ └── ... # (启动时解压)
├── Dockerfile # Docker 构建
├── embed.go # 嵌入式资源声明
└── go.mod # Go 模块定义
扩展开发
开发插件
- 创建 WASM 模块(Go/AssemblyScript/Rust)
- 实现插件接口:
ProcessContent、OnRequest、OnSettingsSave - 编译为
.wasm文件 - 创建
plugin.yaml定义元数据 - 放入
plugins/目录,后台启用
开发主题
- 创建
themes/mytheme/目录 - 编写
theme.yaml定义配置项 - 编写 Pongo2 模板(继承
base.html) - 添加静态资源(CSS/JS/图片)
- 后台切换激活
CDN 兼容性
- CSRF 验证:自动解析
X-Forwarded-Host/X-Original-Host/Forwarded头,兼容 CDN 代理 - 安全头:移除硬编码 CSP,避免拦截 CDN 资源
- Cookie Secure:根据
X-Forwarded-Proto动态设置,HTTPS 环境自动启用
未来计划
- 定时发布功能
- 文章版本历史
- 多用户协作
- 外部存储扩展(S3/OSS)
- Webhook 支持
- 分析统计集成
- 评论邮件通知
- RSS 自定义输出
许可证
MIT License
Polaris Blog - 简洁、高效、现代化的博客解决方案
暂无评论,来抢沙发!