换掉阿里云 OSS!苍穹外卖图片上传改用 GitHub+jsDelivr,0 费用永不过期

> 业务完整、改造量极小、永久直链、全球 CDN 加速,面试也能吹。


1. 为什么要换?

对比项 阿里云 OSS GitHub+jsDelivr
费用 按量计费,图片多=钱多 完全 0 元
签名 1 h 过期,调试烦 永久直链
速度 国内节点快 jsDelivr 全球 CDN,实测 ≈ OSS
备案 需备案 无需

2. 方案总览

  1. 新建 公开仓库 picbed
  2. 生成 GitHub Token(classic 勾选 repo)
  3. SpringBoot 引入 GitHubBedUtil
  4. 上传后返回 jsDelivr 加速链接
  5. 前端直传,原 OSS 代码改 3 行即可

3. 核心代码(复制即用)

① application-dev.yml

//需换成自己的仓库以及地址
github-bed:
  token: ghp_你的Token
  repo: unclecss/picbed
  branch: main
  path: img
  cdn: https://cdn.jsdelivr.net/gh/unclecss/picbed@main  

② GitHubBedUtil.java

public String upload(byte[] bytes, String fileName) throws IOException {
        String fullPath = (path.isEmpty() ? fileName : path + "/" + fileName).trim();

        GitHub github = new GitHubBuilder().withOAuthToken(token).build();
        GHRepository repository = github.getRepository(repo);

        try {
            GHContent old = repository.getFileContent(fullPath, branch);
            repository.createContent()
                    .branch(branch)
                    .path(fullPath)
                    .content(bytes)          // 直接字节
                    .message("Add " + fileName)
                    .sha(old.getSha())
                    .commit();
        } catch (GHFileNotFoundException e) {
            repository.createContent()
                    .branch(branch)
                    .path(fullPath)
                    .content(bytes)          // 直接字节
                    .message("Add " + fileName)
                    .commit();
        }

        return "https://cdn.jsdelivr.net/gh/" + repo + "@" + branch + "/" + fullPath;
    }

③ CommonController

public Result<String> upload(MultipartFile file) {
        log.info("文件上传:{}", file);
        try {
            // 原始文件名
            String originalFilename = file.getOriginalFilename();
            // 取后缀
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            // 新文件名
            String objectName = UUID.randomUUID() + extension;

            // 上传到 GitHub → 返回 jsDelivr 加速链接
            String filePath = gitHubBedUtil.upload(file.getBytes(), objectName);
            return Result.success(filePath);
        } catch (IOException e) {
            log.error("文件上传失败:{}", e);
        }
        return Result.error(MessageConstant.UPLOAD_FAILED);
    }

4. 加速技巧

国内备用节点:
https://fastly.jsdelivr.net/gh/用户名/仓库@分支/路径
单文件 < 100 MB(GitHub 限制)
仓库流量 1 GB/月 → 超了用 Git LFS 或压缩

5. 效果对比

同一张 2 MB 商品图:

节点 OSS GitHub+jsDelivr
北京 180 ms 220 ms
广州 200 ms 240 ms
伦敦 600 ms 280 ms

结论:国内慢 40 ms 可忽略;国外反而更快!

6. 踩坑记录

Token 泄露 → 存环境变量,不要提交 YAML
同名文件冲突 → 用 UUID 重命名
大图片加载慢 → 前端压缩 ≤ 500 KB

7. 结论

0 成本、永不过期、全球 CDN
改造量 < 30 行代码,回滚只需改回 OSS Bean
面试可吹:「我自己给项目换了图床,省了几百块/年」

8. 源码 & 一键运行

图床仓库:https://github.com/unclecss/picbed
PDF 速查表:https://github.com/unclecss/blog/releases

🔥 下期预告:《苍穹外卖支付改造笔记》

微信小程序只能真商户?测试环境 0 元搞定!
微信支付 → 浏览器跳转支付宝沙箱
前端缺源码?H5 二维码页 30 行手写
沙箱公钥、私钥、回调 一次配通
支付成功页自动回跳小程序(伪闭环)

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐