惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
量子位
腾讯CDC
The Cloudflare Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
云风的 BLOG
云风的 BLOG
Vercel News
Vercel News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
L
LangChain Blog
aimingoo的专栏
aimingoo的专栏
The Hacker News
The Hacker News
T
The Exploit Database - CXSecurity.com
B
Blog
S
SegmentFault 最新的问题
P
Privacy & Cybersecurity Law Blog
T
Threatpost
博客园 - 聂微东
T
Tailwind CSS Blog
The Last Watchdog
The Last Watchdog
C
Check Point Blog
N
Netflix TechBlog - Medium
D
DataBreaches.Net
爱范儿
爱范儿
IT之家
IT之家
S
Secure Thoughts
M
MIT News - Artificial intelligence
NISL@THU
NISL@THU
C
Cisco Blogs
TaoSecurity Blog
TaoSecurity Blog
有赞技术团队
有赞技术团队
A
Arctic Wolf
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Proofpoint News Feed
Spread Privacy
Spread Privacy
Schneier on Security
Schneier on Security
Simon Willison's Weblog
Simon Willison's Weblog
G
GRAHAM CLULEY
雷峰网
雷峰网
Project Zero
Project Zero
博客园 - Franky
H
Heimdal Security Blog
A
About on SuperTechFans
Security Latest
Security Latest
Webroot Blog
Webroot Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Hugging Face - Blog
Hugging Face - Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More

爱吃猫的鱼

当身体被强制暂停 盘点开发者眼里的赛博大善人(一) Windows 注册表原理与实战指南 GitHub Actions 自动化部署全攻略 自研博客系统打造极致极简创作体验 2025 年度总结 替代 Alist 的多存储文件列表程序 OpenList 高通 410 随身 WiFi 刷入 Debian 利用 BAT 脚本实现高效自动化部署方案 B7c61c40 全面详解开箱即用的 AI 工具 Cursor 2024 年度总结 使用 Hexo 多种部署方法搭建个人网站 利用 Termux 让安卓手机成为专属家庭服务器 全面详细的常用Linux命令汇总(2) Follow:信息浏览聚合,万物皆可订阅 QRcodeGen项目介绍,基于Python打造二维码生成新利器 Nginx 可视化编辑工具 Nginx UI 安装和使用 深入探究电子邮件三大协议 使用Ventoy集成多PE打造强大U盘 Xterminal:颜值高、功能强,追求卓越体验的SSH工具 高效利用 GitHub 搜索,精准快速获取所需 IDM:广受欢迎的高速下载管理器 让Meting API解锁音乐开发新可能 零基础Docker入门指南 服务器最佳搭档,宝塔和1Panel的部署与选择 FinalShell:功能强大的服务器管理和远程连接工具 掌握Markdown技巧,轻松应对写作需求 C3dc4fa3 玩转npm:从基础到实践的全面指南 GitHub Desktop:让代码托管不再高深莫测 85af4b3 推荐10个有趣的摸鱼网站,让快乐简单起来 F34ad695 E2f1455b 503a6294 22ea4c20 A43ddadb Ba7d8a84 Caffd8d6 20820ccd E3ddac0 88040fa7 Ca1756cf Aa5669ee 78084f29 98b56a65 Efba7c23
博客系统 FlecBlog 现已正式开源
Talen · 2026-03-13 · via 爱吃猫的鱼

在上篇文章《自研博客系统打造极致极简创作体验》中,我详细介绍了为什么选择自建博客系统以及整体的设计理念。经过一段时间的整理和优化,FlecBlog 终于开源出来了!这篇文章将作为技术特点的汇总,向大家展示这个项目的技术架构和核心实现。

FlecBlog 是一个完全自研的个人博客系统,由 Flec-Server(Go 后端)、Flec-Admin(Vue3 管理端)、Flec-Blog(Nuxt 博客端)三个子项目组成。项目从零开始独立开发,借鉴学习了大量开源系统后台,旨在打造一个真正符合个人习惯的一体化博客解决方案。

图片

1 架构总览

层级 技术选型 版本 优势
后端 Go 1.25 性能优异、资源占用低、部署简单
管理端 Vue 3.5.29 生态熟悉、开发效率高、类型支持好
博客端 Nuxt 4.3.1 SSR支持、SEO友好、Vue生态统一
数据库 PostgreSQL 14+ 功能丰富、JSON支持好、无需额外缓存

整体架构采用前后端分离设计,后端提供 RESTful API,博客端和管理端通过 API 进行数据交互。数据库选型上坚持使用 PostgreSQL,利用其丰富的数据类型和 JSON 支持,可以避免引入额外的缓存和搜索组件。

2 后端

2.1 分层架构设计

后端采用了清晰的分层架构设计,严格遵循依赖注入原则:

TEXT

api/          # 路由和中间件层
  ├── v1/         # API 处理器
  ├── middleware/ # 中间件
  └── router/     # 路由注册

internal/     # 业务逻辑层
  ├── dto/        # 数据传输对象
  ├── model/      # 数据模型
  ├── repository/ # 数据访问层
  └── service/    # 业务逻辑层

pkg/          # 公共包
  ├── ai/         # AI服务封装
  ├── auth/       # OAuth认证
  ├── email/      # 邮件服务
  ├── upload/     # 文件上传
  └── notification/ # 通知服务

这种分层设计使得代码结构清晰,职责明确。Repository 层负责数据库操作,Service 层处理业务逻辑,Controller 层处理 HTTP 请求,通过依赖注入模式实现层间解耦。

2.2 中间件体系

项目实现了一套完整的API安全防护体系:

  • JWT 认证中间件:支持 Access Token(7天)和 Refresh Token(30天)双 Token 机制
  • 可选认证中间件:适用于支持游客和登录用户共存的接口(如评论、文件上传)
  • RBAC 权限控制:超级管理员、管理员、普通用户、游客四级权限体系
  • 限流中间件:基于 IP、用户 ID 或全局的多种限流策略,返回标准限流响应头
  • CORS 中间件:支持配置化白名单,允许携带凭据

2.3 统一存储抽象

项目实现了一套统一的文件存储抽象接口,支持多种存储方案:

GO

type Storage interface {
    Save(reader io.Reader, path string) error
    Delete(path string) error
    Exists(path string) bool
    GetURL(path string, host string) string
}

通过统一的配置,可以无缝切换以下存储后端:

  • 本地存储
  • AWS S3
  • 腾讯云 COS
  • 阿里云 OSS
  • 七牛云 Kodo
  • Cloudflare R2
  • MinIO 自建

这种设计使得存储方案的选择完全配置化,无需修改代码。

2.4 OAuth 多元化登录

项目内置支持多种第三方登录方式:

  • GitHub
  • Google
  • QQ
  • Microsoft

针对国内服务器部署场景,通过 Cloudflare Worker 代理解决服务端调用海外 OAuth API 的网络连通性问题:

GO

// 将 OAuth API 请求转发到代理地址
prefixes := map[string]string{
    "github.com":         "/github",
    "accounts.google.com": "/google",
}

2.5 通知系统

通知系统实现了多渠道推送:

  • 邮件通知:采用滑动时间窗口限流,每个邮箱每小时最多发送 5 封
  • 飞书卡片消息:支持交互式卡片,当收到友链申请、新评论、RSS 订阅等事件时,飞书会推送带有操作按钮的卡片消息,管理员无需切换到博客后台,直接在卡片上点击即可完成审批、回复等操作,真正实现消息即操作台的移动端运维体验

2.6 微信公众号文章导出

这是一个非常实用的功能,可以将 Markdown 文章导出为微信公众号兼容格式:

  • HTML 白名单标签过滤
  • 内联样式转换(微信不支持外部 CSS)
  • 代码块换行符转换
  • 自定义块语法转换(提示框、折叠面板、标签页等)

3 管理端

3.1 双Token刷新机制

前端请求封装实现了完善的 Token 管理:

TYPESCRIPT

// 防止惊群效应的请求队列
let isRefreshing = false
let failedQueue: Array<{ resolve: Function; reject: Function }>[]

// 401时自动刷新,刷新期间将请求加入队列
const processQueue = (error: any = null) => {
  failedQueue.forEach(promise => {
    if (error) promise.reject(error)
    else promise.resolve()
  })
}

这种设计确保了多个并发请求触发 401 时,只会有一个刷新 Token 的请求,避免了惊群效应。

3.2 CodeMirror 编辑器

这是管理端最核心的组件,实现了以下高级功能:

  • 实时预览 :分屏模式下编辑区与预览区双向滚动同步,支持四种视图模式切换
  • 图片处理 :粘贴图片自动上传、在线图片 URL 一键下载转存
  • 扩展语法 :提示框、标签页、折叠面板、链接卡片、照片墙等自定义块
  • 辅助功能 :字数统计、阅读时长估算、目录提取、表情选择器、全屏模式

3.3 数据可视化仪表板

基于 ECharts 构建的数据仪表板,提供全方位的运营数据展示:

  • 访问趋势图 :支持日/月维度切换,展示浏览量与访客量双曲线
  • 分类统计饼图 :文章分类分布可视化
  • 标签云 :热门标签词云展示
  • 文章贡献日历 :类似 GitHub 贡献图,直观展示写作频率

4 博客端

4.1 渲染与性能优化

博客端基于 Nuxt 4 构建,从渲染层到资源加载进行了全方位优化:

  • SSR 服务端渲染,首屏 HTML 直出,配合 Critters 关键 CSS 内联减少渲染阻塞
  • PWA 离线缓存,图片资源 CacheFirst 策略,缓存 30 天,每小时自动检查更新
  • 图片懒加载,优先加载可视区域内容

代码分割采用细粒度策略,将第三方库按功能拆分:

JAVASCRIPT

manualChunks(id) {
  if (id.includes('vue/')) return 'vue-core'
  if (id.includes('markdown-it')) return 'markdown-renderer'
  if (id.includes('highlight.js')) return 'highlight'
  if (id.includes('remixicon')) return 'remixicon'
}

首屏只加载核心代码,其他模块按需加载。

4.2 SEO 与开放生态

  • 动态 Sitemap:构建时从 API 获取文章、分类、标签数据,自动生成站点地图
  • 页面级 SEO:每篇文章配置 title、description、Open Graph、Twitter Card 标签
  • 结构化数据:集成 Schema.org,提供文章发布时间、修改时间、封面图等信息
  • RSS 订阅:提供 Atom Feed,支持 RSS 阅读器订阅
  • 多渠道订阅:公众号、邮件、RSS 三种方式,邮件订阅支持一键退订

4.3 交互功能集成

  • 评论系统:支持游客评论和登录评论,多级回复、引用回复、表情选择器
  • 全局搜索:500ms 防抖,关键词高亮,分页展示
  • 图片预览:集成 medium-zoom,点击全屏预览,支持缩放拖拽
  • 平滑滚动:集成 Lenis,自定义缓动函数,滚动更流畅
  • 反馈系统:用户反馈投诉入口,收集意见持续改进
  • 文章阅读:封面模糊化处理,元数据完善,AI 摘要速读,沉浸阅读模式

4.4 特色页面展示

  • 关于页面:个人介绍、性格测试、座右铭、联系方式、站点统计、访问统计
  • 友链页面:卡片式布局,分组管理,失效友链标记,在线申请入口
  • 动态页面:瀑布流布局,支持图片/视频/音乐/链接分享,图片缩放预览
  • 协议页面:隐私政策、Cookie 政策、版权协议

5 快速部署

强烈推荐使用 Docker Compose 一键部署,通过简单的配置文件,统一管理和启动三端服务,极大简化了部署流程。

  1. 创建 .env 文件:

ENV

# Database Configuration
DB_PASSWORD=your_database_password

# JWT Configuration
JWT_SECRET=your_jwt_secret_key

# Site Configuration
API_URL=https://api.yourdomain.com/api/v1
  1. 创建 docker-compose.yml 文件,使用外部 PostgreSQL 数据库:

YAML

services:
  server:
    image: talen8/flec-server:latest
    container_name: flec_server
    restart: unless-stopped
    environment:
      DB_HOST: localhost
      DB_PORT: 5432
      DB_NAME: postgres
      DB_USER: postgres
      DB_PASSWORD: ${DB_PASSWORD}
      JWT_SECRET: ${JWT_SECRET}
    ports:
      - "8080:8080"
    volumes:
      - /srv/docker/flec_server:/app/data
    networks:
      - flec-network

  blog:
    image: talen8/flec-blog:latest
    container_name: flec_blog
    restart: unless-stopped
    environment:
      NUXT_PUBLIC_API_URL: ${API_URL}
    ports:
      - "3000:3000"
    networks:
      - flec-network
    depends_on:
      - server

  admin:
    image: talen8/flec-admin:latest
    container_name: flec_admin
    restart: unless-stopped
    environment:
      API_URL: ${API_URL}
    ports:
      - "4000:4000"
    networks:
      - flec-network
    depends_on:
      - server

networks:
  flec-network:
    driver: bridge

YAML

services:
  postgres:
    image: postgres:15-alpine
    container_name: flec_postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - flec-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  server:
    image: talen8/flec-server:latest
    container_name: flec_server
    restart: unless-stopped
    environment:
      DB_HOST: postgres
      DB_PORT: 5432
      DB_NAME: postgres
      DB_USER: postgres
      DB_PASSWORD: ${DB_PASSWORD}
      JWT_SECRET: ${JWT_SECRET}
    ports:
      - "8080:8080"
    volumes:
      - /srv/docker/flec_server:/app/data
    networks:
      - flec-network
    depends_on:
      postgres:
        condition: service_healthy

  blog:
    image: talen8/flec-blog:latest
    container_name: flec_blog
    restart: unless-stopped
    environment:
      NUXT_PUBLIC_API_URL: ${API_URL}
    ports:
      - "3000:3000"
    networks:
      - flec-network
    depends_on:
      - server

  admin:
    image: talen8/flec-admin:latest
    container_name: flec_admin
    restart: unless-stopped
    environment:
      API_URL: ${API_URL}
    ports:
      - "4000:4000"
    networks:
      - flec-network
    depends_on:
      - server

networks:
  flec-network:
    driver: bridge

volumes:
  postgres_data:
  1. 启动服务:
  1. 访问地址:

6 写在最后

FlecBlog 作为一个完全自研的个人博客系统,从技术选型到功能实现,尽力坚持着的原则。极简的视觉设计、一体化的功能体验、完全个人化的操作习惯,这些都是我在两年多博客搭建过程中不断打磨的成果。

项目已正式开源,如果你:

  • 想搭建一个完全自主的博客系统
  • 对技术实现感兴趣,想学习 Go+Vue 技术栈
  • 正在寻找一个可深度定制的博客方案

欢迎访问 GitHub 仓库,了解更多细节。

如果这个项目对你有帮助,欢迎 star 支持一下!有任何问题也欢迎在评论区提出。

博客系统 FlecBlog 现已正式开源

https://blog.talen.top/posts/nem9jf8q