美文网首页
文件存储引擎模块封装和使用

文件存储引擎模块封装和使用

作者: Zonezzc | 来源:发表于2023-11-08 12:51 被阅读0次
    image

    作者:Zonezzc
    最后更新时间:2023-11-15 17:56:16


    背景

    需求

    在项目开发过程中,经常会使用到文件存储相关的功能,如:

    1. 存储发票文件
    2. 提供发票下载地址
    3. ……

    调研

    诸如此类的功能就需要使用到本地存储或云服务商提供的存储功能。当然,这对于开发高手的 zone 来说都是小意思,上网一查,对象存储哪家强?

    image

    第一位赫然显示了百家号创作者推荐的阿里云 OSS 服务,那行,就你吧,还要赶紧摸鱼等下班呢。接 API 嘛,小意思分分钟搞定,写个工具类封装一点上传下载方法那有多难。

    开发

    在下班点过了 1 小时之后 zone 终于写完了基于 OSS 对象存储服务封装的 FileUploadUtil.java,并且与业务方法结合,实现了产品的需求。

    同事问:「为什么是 FileUploadUtil,光上传了那下载呢?」
    zone 淡定回答:「奥,下载也在工具类里面,用 OssUtil 命名怕后来的同事找不到,FileUploadUtil 多见名知意呀。」
    同事问:「下载方法也在里面那为什么不用 FileUtil 命名工具类呢?」
    zone 淡定回答:「当然是因为 FileUtil 被之前的开发占用掉了,我这个工具类里面有云存储,当然比 FileUtil 更高级咯,得区分开来。」
    同事问:「行吧,大佬 NB,回头我直接抄了昂。」
    zone 淡定回答:「随便用。」

    多项目复用

    半年时间匆匆流逝,曾经的 FileUploadUtil 工具类随着 zone 和同事娴熟的 CV 大法,在公司的项目里遍地开花。闲暇时间,每当看到新接手的项目中不是由自己 V 过去的 FileUploadUtil,自豪感爆棚,我太牛了!!!

    服务商迁移

    但是好景不长,今天新来的技术总监说 OSS 的云服务太贵了,我们要「降本」,更换 AWS 的 S3 对象存储能免费用一年,所有项目都给我迁。随着总监的一声令下,正摸鱼的 zone 不爽了,由于公司里 80% 的项目用的都是 FileUploadUtil,迁移的事情不出所料的落在了自己头上。得,曾经觉的自己有多牛,如今就觉的自己有多苦。活还是得干,zone 看了一下 S3 的接口文档,刷刷刷的把 FileUploadUtil 给改了,顺便把剩下的 20% 项目里也 V 过去了新改到接入 S3 的 FileUploadUtil

    技术总监验收之后说:「小伙子做的不错,降本这件事情我肯定记你一笔。」就这样 zone 亲眼看到总监真就打开了云笔记记了一笔,就再也没了下文。期待的升职加薪还没有发生,半个月后新的运维总监来了,直接以数据安全为由说服了爱国老板,说要把对象存储迁回 OSS。身为底层开发人员的 zone 当然什么也不知道,只看到任务系统来了个紧急任务,标题「云存储服务迁移」内容直接就三字「迁回去」。zone 看了看手里的奶茶和任务系统里的驳回选项,忍住了即将破口而出的爆珠还是选择嚼碎了吞下去,毕竟生活已然不易,更容不得一丝一毫的浪费,忍了……

    多重实现导致 P0 事件

    就是这次,还发现了一些隐藏问题。之前的那 20% 的项目中,为了抓紧时间下班陪妹子,并没有把别的同事写的 ossClient 对象删除掉,人是偷了懒,但程序可不惯着,这回 zone 在把 FileUploadUtil 换回来的时候,项目直接启动失败。这咋回事啊,查看报错信息,原来是有同名 Bean!

    APPLICATION FAILED TO START
    
    Description:
    
    The bean 'ossClient', defined in class path resource [com/zonezzc/FileUploadUtil.class], could not be registered. A bean with that name has already been defined in class path resource [com/zonezzc/OssConfiguration.class] and overriding is disabled.
    
    Action:
    
    Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
    
    已与地址为 ''127.0.0.1:52291',传输: '套接字'' 的目标虚拟机断开连接
    
    

    修复这个问题的同时,zone 仔细搜了搜代码,发现这还不是最坑的,最坑的是竟然还有更多的 ossClient Bean 并不叫这个名字,叫什么 ossClient1ossClient2,由于之前没有仔细检查,在切换了 S3 服务半个月后的今天,竟然还有文件的上传和下载在使用 OSS 服务,这把 zone 吓得出了一身冷汗,赶紧修复了代码并上报了技术总监。技术总监也不含糊,10 分钟后就定了个 P0 事件给捅上去了,20 分钟后全公司就通过邮件知道了 zone 这个名字,通宵达旦的问题修复就此展开了序幕。

    复盘

    经过这次 P0 事件,zone 痛定思痛,决定从根本上解决。

    之前存在的技术问题

    1. 工具类的使用没有在公司内进行培训,导致 CV 现象和重新开发并存,没有形成统一。
    2. 没有考虑文件存储服务商变更的可能性,导致服务商变更之后不能实现快速安全切换。
    3. 没有抽象文件存储功能,FileUploadUtil 工具类代码侵入性太高,没有与业务系统解耦。

    看着这些问题,zone 把脑袋一拍,接着就有了一个大胆的想法,不如就趁这次,设计一个「文件存储引擎」。

    概念

    image

    设计

    模板模式

    StorageEngine

    效果

    第一版

    实现内容

    .
    ├── java
    │   └── com
    │       └── zonezzc
    │           └── storage
    │               └── engine
    │                   ├── StorageApplication.java
    │                   ├── config
    │                   │   ├── CosStorageEngineConfig.java
    │                   │   ├── KodoStorageEngineConfig.java
    │                   │   └── OssStorageEngineConfig.java
    │                   ├── core
    │                   │   ├── AbstractStorageEngine.java
    │                   │   ├── StorageEngine.java
    │                   │   └── context
    │                   │       ├── DeleteFileContext.java
    │                   │       ├── DownloadUrlContext.java
    │                   │       ├── ReadFileContext.java
    │                   │       └── StoreFileContext.java
    │                   ├── cos
    │                   │   └── CosStorageEngine.java
    │                   ├── kodo
    │                   │   └── KodoStorageEngine.java
    │                   ├── oss
    │                   │   └── OssStorageEngine.java
    │                   └── utils
    │                       └── FileUtils.java
    └── resources
        ├── application-dev.yml
        ├── application-prod.yml
        ├── application-test.yml
        └── application.yml
    
    
    # application.yml
    storage:
      engine:
        oss:
          endpoint: oss-cn-shanghai.aliyuncs.com
          accessKeyId: xxxxxxxxxxxxxxxxxxxxxxxx
          accessKeySecret: xxxxxxxxxxxxxxxxxxxxxxxx
          bucketName: zonezzc
        cos:
          secretId: xxxxxxxxxxxxxxxxxxxxxxxx
          secretKey: xxxxxxxxxxxxxxxxxxxxxxxx
          region: ap-shanghai
          bucketName: zonezzc-1253326811
        kodo:
          region: z2
          accessKey: xxxxxxxxxxxxxxxxxxxxxxxx
          secretKey: xxxxxxxxxxxxxxxxxxxxxxxx
          bucketName: zonezzc
    
    

    使用方式

    CV 大法,在项目中把所有代码复制粘贴,人工适配

    注入 StorageEngine 对象
        @Resource
        private StorageEngine storageEngine;
    
    使用 StorageEngine 提供的文件上传下载方法
    image

    第二版

    实现内容

    image

    使用方式

    1. 引入对应的文件存储引擎依赖
    2. 根据提示配置 applecation.yml
    3. 注入 StorageEngine 对象
    4. 使用 StorageEngine 提供的文件上传下载方法
    引入依赖
    <dependency>
        <groupId>com.zonezzc</groupId>
        <artifactId>storage-engine-oss</artifactId>
        <version>0.0.1</version>
    </dependency>
    
    配置引擎需要的信息
    image
    com:
      zonezzc:
        storage:
          engine:
            oss:
              access-key-id: xxxxxxxxxxxxxxxxxxxxxxxx
              access-key-secret: xxxxxxxxxxxxxxxxxxxxxxxx
              endpoint: oss-cn-shanghai.aliyuncs.com
              bucket-name: zonezzc
              auto-create-bucket: true
    
    注入 StorageEngine 对象
        @Resource
        private StorageEngine storageEngine;
    
    使用 StorageEngine 提供的文件上传下载方法
    image

    相关文章

      网友评论

          本文标题:文件存储引擎模块封装和使用

          本文链接:https://www.haomeiwen.com/subject/nfsqwdtx.html