news 2026/6/11 1:10:48

阿里云 OSS 从零到实战:概念、配置与 Spring Boot 集成指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
阿里云 OSS 从零到实战:概念、配置与 Spring Boot 集成指南

阿里云 OSS 从零到实战:概念、配置与 Spring Boot 集成指南

一、OSS 核心概念

1.1 什么是 OSS

OSS(Object Storage Service,对象存储服务)是一种海量、安全、低成本的云存储服务。简单理解就是一个无限容量的网盘,通过 API 上传和下载文件。

与传统文件存储的区别:

维度本地磁盘/NASOSS 对象存储
容量有限,需要扩容无限
访问方式文件路径(/usr/local/file.txt)HTTP URL
可靠性单机故障丢失多副本冗余,99.9999999999%
并发访问有限支持高并发读写
CDN 加速不支持天然支持
成本硬件+运维按量付费

1.2 核心术语

Endpoint (接入点) │ ▼ Bucket (存储空间) │ ├── folder1/ │ ├── file1.xlsx │ └── file2.pdf │ └── folder2/ └── image.png
术语说明类比
EndpointOSS 服务的访问域名,按地域区分数据库的 host:port
Bucket存储空间,是文件的容器数据库中的一个 database
Object存储的基本单元,即文件数据库中的一行记录
Object Key文件在 Bucket 中的唯一标识(路径+文件名)文件路径
AccessKey ID / Secret访问凭证(身份认证)数据库的用户名/密码
Region地域(如 cn-qingdao, cn-hangzhou)数据中心位置

1.3 Endpoint 格式

格式:<BucketName>.<Endpoint> 示例:xxx-img-xxx.oss-cn-xxxx.aliyuncs.com 内网访问:xxx-img-xxx.oss-cn-xxx-internal.aliyuncs.com(同地域免流量费)

1.4 Object Key(文件路径)

OSS 没有真正的文件夹概念,"文件夹"只是 Key 中的前缀:

upload/2026/06/10/abc123.xlsx ← 完整的 Object Key ├── upload/2026/06/10/ ← "文件夹"(实际是Key前缀) └── abc123.xlsx ← "文件名"

1.5 访问权限

权限说明
private默认,需要签名 URL 才能访问
public-read任何人可读,写入需认证
public-read-write任何人可读写(不推荐)

生产环境通常设为 private,程序通过 SDK 生成带签名的临时 URL 供用户下载。


注:

博客:

https://blog.csdn.net/badao_liumang_qizhi

二、首次申请和开通 OSS

2.1 开通步骤

  1. 登录阿里云控制台 → 搜索"对象存储 OSS"
  2. 点击"立即开通"(按量付费,不用的时候几乎不花钱)
  3. 进入 OSS 管理控制台

2.2 创建 Bucket

  1. 点击"创建 Bucket"
  2. 填写信息:
    • Bucket 名称:全局唯一,如my-app-files
    • 地域:选择离服务器最近的地域(如 cn-qingdao)
    • 存储类型:标准存储(频繁访问)/ 低频访问 / 归档
    • 读写权限:私有(推荐)
    • 同城冗余:生产环境建议开启
  3. 点击确认创建

2.3 获取 AccessKey

  1. 鼠标悬停右上角头像 → “AccessKey 管理”
  2. 创建 AccessKey(会得到 AccessKey ID 和 AccessKey Secret)
  3. 重要:Secret 只显示一次,必须保存好

安全建议:不要使用主账号 AccessKey,创建 RAM 子账号并只授予 OSS 权限。

2.4 记录关键信息

创建完成后你会拥有:

Endpoint: oss-cn-xxx.aliyuncs.com Bucket: my-app-files AccessKey ID: xxxx AccessKey Secret: xxxx 访问 URL 前缀: https://my-app-files.oss-cn-xxx.aliyuncs.com/

三、Spring Boot 集成 OSS

3.1 方式一:阿里云官方 SDK(通用)

依赖

<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.17.4</version></dependency>

3.3 配置(application.yml)

# 参考工程中的配置格式jsh:oss:endpoint:oss-cn-xxx.aliyuncs.comaccess-key-id:xxaccess-key-secret:xxxbucket-name:ylh-img-testoss-url:https://image.ylhtest.com# CDN 域名或 Bucket 公网域名max-size:52480000# 上传大小限制(50MB)

3.4 配置项含义详解

配置项含义示例
endpointOSS 服务接入点域名oss-cn-qingdao.aliyuncs.com
access-key-id认证 IDLTAI5tXXXX
access-key-secret认证密钥p9e27XXXX
bucket-name存储空间名称my-app-files
oss-url文件访问的基础 URL(可以是 CDN 域名)https://image.example.com
max-size允许上传的最大文件大小(字节)52428800(50MB)

四、完整示例:Spring Boot + 阿里云 OSS 文件上传下载

4.1 依赖

<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.17.4</version></dependency>

4.2 配置

oss:endpoint:oss-cn-xxx.aliyuncs.comaccess-key-id:your-access-key-idaccess-key-secret:your-access-key-secretbucket-name:my-app-filesurl-prefix:https://my-app-files.oss-cn-qingdao.aliyuncs.com

4.3 配置类

packagecom.example.config;importcom.aliyun.oss.OSS;importcom.aliyun.oss.OSSClientBuilder;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;/** * 阿里云 OSS 客户端配置. */@ConfigurationpublicclassOssConfig{@Value("${oss.endpoint}")privateStringendpoint;@Value("${oss.access-key-id}")privateStringaccessKeyId;@Value("${oss.access-key-secret}")privateStringaccessKeySecret;/** * 创建 OSS 客户端 Bean. * OSS 客户端是线程安全的,全局共享一个实例即可. */@Bean(destroyMethod="shutdown")publicOSSossClient(){returnnewOSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);}}

4.4 工具类

packagecom.example.util;importcom.aliyun.oss.OSS;importcom.aliyun.oss.model.OSSObject;importcom.aliyun.oss.model.PutObjectRequest;importjakarta.annotation.Resource;importjava.io.File;importjava.io.InputStream;importjava.time.LocalDate;importjava.time.format.DateTimeFormatter;importjava.util.UUID;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.stereotype.Component;importorg.springframework.web.multipart.MultipartFile;/** * OSS 文件操作工具类. */@Slf4j@ComponentpublicclassOssUtil{@ResourceprivateOSSossClient;@Value("${oss.bucket-name}")privateStringbucketName;@Value("${oss.url-prefix}")privateStringurlPrefix;/** * 上传 MultipartFile(Web 表单文件). * * @param file 上传的文件 * @param bizFolder 业务文件夹名(如 "import", "export") * @return 文件访问 URL */publicStringuploadMultipartFile(MultipartFilefile,StringbizFolder){StringobjectKey=generateObjectKey(bizFolder,getExtension(file.getOriginalFilename()));try(InputStreamis=file.getInputStream()){ossClient.putObject(bucketName,objectKey,is);Stringurl=urlPrefix+"/"+objectKey;log.info("文件上传成功,objectKey:{}, url:{}",objectKey,url);returnurl;}catch(Exceptione){log.error("文件上传失败",e);thrownewRuntimeException("文件上传失败",e);}}/** * 上传本地 File 对象. * * @param file 本地文件 * @param bizFolder 业务文件夹名 * @return 文件访问 URL */publicStringuploadFile(Filefile,StringbizFolder){StringobjectKey=generateObjectKey(bizFolder,getExtension(file.getName()));PutObjectRequestrequest=newPutObjectRequest(bucketName,objectKey,file);ossClient.putObject(request);Stringurl=urlPrefix+"/"+objectKey;log.info("文件上传成功,objectKey:{}, url:{}",objectKey,url);returnurl;}/** * 上传字节流. * * @param inputStream 输入流 * @param bizFolder 业务文件夹名 * @param extension 文件扩展名(如 "xlsx") * @return 文件访问 URL */publicStringuploadStream(InputStreaminputStream,StringbizFolder,Stringextension){StringobjectKey=generateObjectKey(bizFolder,extension);ossClient.putObject(bucketName,objectKey,inputStream);Stringurl=urlPrefix+"/"+objectKey;log.info("文件上传成功,objectKey:{}, url:{}",objectKey,url);returnurl;}/** * 下载文件,返回输入流. * * @param objectKey 文件在 OSS 中的 Key * @return 文件输入流(调用方需要关闭) */publicInputStreamdownloadFile(StringobjectKey){OSSObjectossObject=ossClient.getObject(bucketName,objectKey);returnossObject.getObjectContent();}/** * 通过完整 URL 下载文件. * * @param fileUrl 文件完整 URL * @return 文件输入流 */publicInputStreamdownloadByUrl(StringfileUrl){// 从 URL 中提取 objectKeyStringobjectKey=fileUrl.replace(urlPrefix+"/","");returndownloadFile(objectKey);}/** * 删除文件. * * @param objectKey 文件在 OSS 中的 Key */publicvoiddeleteFile(StringobjectKey){ossClient.deleteObject(bucketName,objectKey);log.info("文件删除成功,objectKey:{}",objectKey);}/** * 生成唯一的 Object Key. * 格式:bizFolder/yyyy/MM/dd/uuid.extension * 例如:import/2026/06/10/a1b2c3d4.xlsx */privateStringgenerateObjectKey(StringbizFolder,Stringextension){StringdatePath=LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));StringfileName=UUID.randomUUID().toString().replace("-","")+"."+extension;returnbizFolder+"/"+datePath+"/"+fileName;}/** * 获取文件扩展名. */privateStringgetExtension(Stringfilename){if(filename==null||!filename.contains(".")){return"unknown";}returnfilename.substring(filename.lastIndexOf(".")+1).toLowerCase();}}

4.5 业务使用示例

packagecom.example.service.impl;importcom.example.util.OssUtil;importjakarta.annotation.Resource;importjakarta.servlet.http.HttpServletResponse;importjava.io.File;importjava.io.FileOutputStream;importjava.io.InputStream;importlombok.extern.slf4j.Slf4j;importorg.apache.poi.xssf.usermodel.XSSFWorkbook;importorg.springframework.stereotype.Service;importorg.springframework.web.multipart.MultipartFile;@Slf4j@ServicepublicclassFileBusinessService{@ResourceprivateOssUtilossUtil;/** * 场景一:接收用户上传的 Excel 文件,存到 OSS. */publicStringhandleFileUpload(MultipartFilefile){// 直接上传到 OSS 的 "import" 文件夹下returnossUtil.uploadMultipartFile(file,"import");// 返回值如:https://my-app-files.oss-cn-xxx.aliyuncs.com/import/2026/06/10/xxx.xlsx}/** * 场景二:程序生成 Excel 文件(如导入错误报告),上传到 OSS. */publicStringgenerateAndUploadErrorReport(java.util.List<String>errors){FiletempFile=null;try{// 1. 在内存中生成 ExcelXSSFWorkbookworkbook=newXSSFWorkbook();varsheet=workbook.createSheet("错误信息");varheaderRow=sheet.createRow(0);headerRow.createCell(0).setCellValue("行号");headerRow.createCell(1).setCellValue("错误原因");for(inti=0;i<errors.size();i++){varrow=sheet.createRow(i+1);row.createCell(0).setCellValue(i+1);row.createCell(1).setCellValue(errors.get(i));}// 2. 写入临时文件tempFile=File.createTempFile("error_report_",".xlsx");try(FileOutputStreamfos=newFileOutputStream(tempFile)){workbook.write(fos);}workbook.close();// 3. 上传到 OSSreturnossUtil.uploadFile(tempFile,"error-reports");}catch(Exceptione){thrownewRuntimeException("生成错误报告失败",e);}finally{// 4. 清理临时文件if(tempFile!=null&&tempFile.exists()){tempFile.delete();}}}/** * 场景三:从 OSS 下载文件提供给用户. */publicvoiddownloadFromOss(StringfileUrl,HttpServletResponseresponse){try(InputStreamis=ossUtil.downloadByUrl(fileUrl)){response.setContentType("application/octet-stream");response.setHeader("Content-Disposition","attachment;filename=download.xlsx");byte[]buffer=newbyte[8192];intlen;varos=response.getOutputStream();while((len=is.read(buffer))!=-1){os.write(buffer,0,len);}os.flush();}catch(Exceptione){thrownewRuntimeException("文件下载失败",e);}}}

五、OSS 常见使用场景

场景Object Key 设计说明
用户上传的原始文件upload/原始文件名或UUID.xlsx保留用于异步处理
导入失败错误报告error-reports/2026/06/10/xxx.xlsx前端展示下载链接
导出的数据文件export/2026/06/10/xxx.xlsx大文件异步生成后通知用户下载
用户头像avatar/用户ID.jpg公开读,CDN 加速
合同/票据打印件contracts/2026/06/xxx.pdf私有,签名 URL 访问

六、生产环境最佳实践

6.1 安全

  • 使用 RAM 子账号,只授予最小权限(如只能操作特定 Bucket)
  • AccessKey 不硬编码在代码中,放在环境变量或配置中心(如 Nacos)
  • Bucket 设为 private,通过后端接口代理访问或生成临时签名 URL

6.2 签名 URL(临时授权访问)

对于 private 文件,生成有时效的访问 URL:

// 生成有效期 1 小时的签名 URLDateexpiration=newDate(System.currentTimeMillis()+3600*1000);URLsignedUrl=ossClient.generatePresignedUrl(bucketName,objectKey,expiration);

6.3 生命周期管理

配置自动清理规则,避免存储费用无限增长:

  • 临时文件(error-reports/)7 天后自动删除
  • 导出文件(export/)30 天后转低频存储,90 天后删除
  • 在 OSS 控制台 → Bucket → 基础设置 → 生命周期 中配置

6.4 内网访问

如果应用服务器和 OSS 在同一地域,使用内网 Endpoint 可以:

  • 免除流量费
  • 速度更快、更稳定
# 公网endpoint:oss-cn-qingdao.aliyuncs.com# 内网(同地域 ECS 使用)endpoint:oss-cn-qingdao-internal.aliyuncs.com

6.5 大文件处理

文件大小推荐方式
< 5MB普通上传(PutObject)
5MB ~ 5GB分片上传(Multipart Upload)
> 5GB分片上传(必须)

分片上传的好处:

  • 断点续传
  • 并行上传多个分片提速
  • 单个分片失败只需重传该分片

七、费用说明

计费项说明大致费用
存储费按存储容量计费标准存储 ≈ 0.12 元/GB/月
流量费外网下行流量≈ 0.50 元/GB(内网免费)
请求费PUT/GET 请求次数PUT 0.01 元/万次,GET 0.01 元/万次
数据取回费低频/归档存储取回低频 0.075 元/GB

对于导入导出场景(文件存几天就删,主要走内网),费用非常低。


八、总结

步骤操作
1. 开通阿里云控制台开通 OSS 服务
2. 创建 Bucket选地域、命名、设权限
3. 获取凭证创建 RAM 子账号,获取 AccessKey
4. 引入依赖aliyun-sdk-oss或公司封装库
5. 配置endpoint、bucket、accessKey 写入 YAML
6. 编码创建 OSSClient Bean → 封装工具类 → 业务调用
7. 安全私有 Bucket + 签名 URL + RAM 最小权限
8. 运维生命周期规则 + 内网访问 + 监控告警
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 1:08:33

Prolog逻辑编程:构建可解释AI的声明式推理引擎

1. 这不是又一本“AI速成手册”&#xff0c;而是一次对编程思维底层的重新校准如果你最近刷到过任何一篇讲大模型、提示工程或AutoML的文章&#xff0c;大概率会看到类似“逻辑推理仍是AI短板”“符号系统与神经网络如何融合”这样的句子。但很少有人愿意停下来问一句&#xff…

作者头像 李华
网站建设 2026/6/11 1:07:15

高效笔记管理利器:QOwnNotes 开源 Markdown 编辑器全面解析

高效笔记管理利器&#xff1a;QOwnNotes 开源 Markdown 编辑器全面解析 【免费下载链接】QOwnNotes QOwnNotes is a plain-text file notepad and todo-list manager with Markdown support and Nextcloud / ownCloud integration. 项目地址: https://gitcode.com/gh_mirrors…

作者头像 李华
网站建设 2026/6/11 1:03:18

深入解析NXP S12XE XGATE协处理器:架构、编程与双核调试实战

1. 项目概述与XGATE核心价值在汽车电子和工业控制这类对实时性要求极高的嵌入式领域&#xff0c;主处理器&#xff08;CPU&#xff09;常常被频繁的中断和数据搬运任务所淹没&#xff0c;导致核心业务逻辑执行受阻&#xff0c;系统响应延迟。如果你正在使用飞思卡尔&#xff08…

作者头像 李华
网站建设 2026/6/11 1:00:40

梯度累积与大 Batch 训练策略:从显存限制到等效大批量

梯度累积与大 Batch 训练策略&#xff1a;从显存限制到等效大批量一、显存墙与 Batch Size 的囚徒困境 深度学习训练中&#xff0c;Batch Size 的选择直接影响模型收敛质量。大 Batch Size 提供更稳定的梯度估计&#xff0c;训练曲线更平滑&#xff0c;收敛速度更快&#xff1b…

作者头像 李华
网站建设 2026/6/11 1:00:37

基于大模型的数据库运维知识库构建:从日志到智能问答的排障助手

基于大模型的数据库运维知识库构建&#xff1a;从日志到智能问答的排障助手一、数据库运维的知识瓶颈&#xff1a;排障经验难以系统化传承 数据库运维的核心挑战不是缺少监控数据&#xff0c;而是缺少将告警、日志、指标与排障方案关联的知识体系。一个资深 DBA 看到"MySQ…

作者头像 李华
网站建设 2026/6/10 23:54:52

示波器不会选?从原理、分类到选型一次性讲透

自然界中各类震动、声波、电波都以波动形式存在&#xff0c;光线、机械振动、工业工况产生的物理信号&#xff0c;借助传感器均可转化为电信号&#xff0c;示波器就是可视化观测电信号变化的专用仪器。01什么是示波器&#xff1f;本质是一种可视化的绘制和观测电信号图形的设备…

作者头像 李华