什么是华为云对象存储OBS?它有什么优势?

Posted wljslmz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是华为云对象存储OBS?它有什么优势?相关的知识,希望对你有一定的参考价值。

华为对象存储OBS(Object Storage Service)是一种高可用、高可靠、高性能的云存储服务,能够为企业和个人用户提供强大的数据存储和管理功能。本文将对华为对象存储OBS的特点、优势和未来发展进行详细介绍。

一、华为对象存储OBS的特点

1.对象存储:华为对象存储OBS采用对象存储技术,将数据以对象的形式进行存储和管理,避免了传统文件系统存储方式中的文件层级结构和文件系统限制,具有更加灵活的数据存储和访问方式。

2.海量存储:华为对象存储OBS可以存储海量的数据,支持PB级别的存储容量,适合于大规模数据存储和管理的应用场景。

3.高可用性:华为对象存储OBS采用了分布式存储架构和多副本备份机制,能够保证数据的高可用性和可靠性,提供99.9999999%的数据可靠性。

4.高性能:华为对象存储OBS采用了高性能的存储和网络技术,能够实现高速的数据读写和传输,提供了优异的性能表现。

5.安全性:华为对象存储OBS采用了多层次的安全策略和技术,包括数据加密、访问控制、网络隔离等措施,保障了用户的数据和隐私安全。

二、华为对象存储OBS的优势

1.弹性扩展:华为对象存储OBS支持弹性扩展功能,能够根据用户的实际需求和业务规模进行灵活的存储容量扩展和优化,降低了企业的运营成本和管理难度。

2.全球覆盖:华为对象存储OBS在全球多个地区和数据中心都有部署,用户可以选择就近的存储节点进行访问,提高了数据访问的速度和用户体验。

3.多种访问方式:华为对象存储OBS支持多种访问方式,包括API接口、对象存储网关和文件存储网关等,方便用户根据实际需求和应用场景进行选择和使用。

4.数据备份和恢复:华为对象存储OBS支持多副本备份机制和快速恢复功能,能够有效保障数据的安全性和可用性,避免了数据丢失和损坏的风险。

5.价格透明:华为对象存储OBS提供了透明的价格和计费方式,用户可以根据实际存储和使用情况进行精细化的费用管理和控制,避免了因存储和使用过多而导致的高额费用。

三、华为对象存储OBS的未来发展

随着云计算和大数据技术的发展,数据存储和管理成为了一个重要的问题。华为对象存储OBS作为一种高可靠、高可用、高性能的云存储服务,已经得到了广泛的应用和认可。未来,华为对象存储OBS还将继续加强自身的技术研发和创新,提高数据存储和管理的效率和质量,以满足不同用户的需求和应用场景。同时,华为对象存储OBS还将加强与其他云计算技术和服务的整合和协作,提供更加完整和优质的云计算解决方案和服务,促进数字化转型和创新发展。

结论

华为对象存储OBS作为一种高可靠、高可用、高性能的云存储服务,具有许多优秀的特点和优势。用户可以根据自己的需求和应用场景,选择适合自己的存储方式和访问方式,提高数据的存储和管理效率和质量。未来,华为对象存储OBS还将继续加强自身的技术创新和升级,提供更加优秀的云计算服务和解决方案,为用户提供更好的服务和体验。

如果你对华为云OBS产品感兴趣可以访问其官网了解:

https://www.huaweicloud.com/intl/zh-cn/product/obs.html

jeecg-boot中上传图片到华为云obs云存储中

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂。

前言

jeecg-boot框架中,其实对接的功能还是挺多的,其中就有文件云存储服务器,不过是阿里云oss的,那如果我们使用的是七牛云,或者华为云obs呢?我们需要改哪些内容才能实现上传obs的目的呢,今天我们就来看看如何使用jeecg-boot来实现将文件(图片)上传到华为云obs中。

配置nacos

因为我们用的是微服务版本,所以配置都在nacos中,如果是普通的boot版本的话,直接在yml文件中写配置就行。
nacos的配置如下:

  1. 找到jeecg节点,修改uploadType的值:
uploadType: hwobs

记住这个hwobs的值,我们需要在代码中声明一下它,相当于一个变量,这个值必须和代码中声明的那个变量的值一样,不然就找不到了。

  1. 添加obs节点:
  #华为云oss存储配置
  obs:
    endpoint: obs.cn-xxxxx-9.myhuaweicloud.com
    accessKey: KD6BYxxxxxx
    secretKey: Zv83xxxxxx
    bucketName: xxxxx
    staticDomain: xxxxx.obs.cn-xxxxxx-9.myhuaweicloud.com

注意:对应的值需要改成你自己的ak、sk等。

修改POM文件,添加华为云obs的依赖

添加代码如下:

<!--华为云OBS-->
		<dependency>
			<groupId>com.huaweicloud</groupId>
			<artifactId>esdk-obs-java</artifactId>
			<version>3.21.8</version>
			<exclusions>
				<exclusion>
					<groupId>com.squareup.okhttp3</groupId>
					<artifactId>okhttp</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

新建OBS工具类ObsBootUtil

package org.jeecg.common.util.oss;

import com.obs.services.ObsClient;
import com.obs.services.model.ObsObject;
import com.obs.services.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.FileItemStream;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.filter.FileTypeFilter;
import org.jeecg.common.util.filter.StrAttackFilter;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.UUID;

/**
 * @Description: 华为云 oss 上传工具类(高依赖版)
 * @Date: 2019/5/10
 * @author: jeecg-boot
 */
@Slf4j
public class ObsBootUtil 

    private static String endPoint;
    private static String accessKeyId;
    private static String accessKeySecret;
    private static String bucketName;
    /**
     * oss 工具客户端
     */
    private static ObsClient ossClient = null;

    public static String getEndPoint() 
        return endPoint;
    

    public static void setEndPoint(String endPoint) 
        ObsBootUtil.endPoint = endPoint;
    

    public static String getAccessKeyId() 
        return accessKeyId;
    

    public static void setAccessKeyId(String accessKeyId) 
        ObsBootUtil.accessKeyId = accessKeyId;
    

    public static String getAccessKeySecret() 
        return accessKeySecret;
    

    public static void setAccessKeySecret(String accessKeySecret) 
        ObsBootUtil.accessKeySecret = accessKeySecret;
    

    public static String getBucketName() 
        return bucketName;
    

    public static void setBucketName(String bucketName) 
        ObsBootUtil.bucketName = bucketName;
    

    public static ObsClient getOssClient() 
        return ossClient;
    

    /**
     * 上传文件至华为云 OBS
     * 文件上传成功,返回文件完整访问路径
     * 文件上传失败,返回 null
     *
     * @param file    待上传文件
     * @param fileDir 文件保存目录
     * @return oss 中的相对文件路径
     */
    public static String upload(MultipartFile file, String fileDir, String customBucket) throws Exception 
        //update-begin-author:liusq date:20210809 for: 过滤上传文件类型
        FileTypeFilter.fileTypeFilter(file);
        //update-end-author:liusq date:20210809 for: 过滤上传文件类型

        String filePath;
        initOss(endPoint, accessKeyId, accessKeySecret);
        StringBuilder fileUrl = new StringBuilder();
        String newBucket = bucketName;
        if (oConvertUtils.isNotEmpty(customBucket)) 
            newBucket = customBucket;
        
        try 
            //判断桶是否存在,不存在则创建桶
            if (!ossClient.headBucket(newBucket)) 
                ossClient.createBucket(newBucket);
            
            // 获取文件名
            String orgName = file.getOriginalFilename();
            if ("".equals(orgName) || orgName == null) 
                orgName = file.getName();
            
            orgName = CommonUtils.getFileName(orgName);
            String fileName = !orgName.contains(".")
                    ? orgName + "_" + System.currentTimeMillis()
                    : orgName.substring(0, orgName.lastIndexOf("."))
                    + "_" + System.currentTimeMillis()
                    + orgName.substring(orgName.lastIndexOf("."));
            if (!fileDir.endsWith(SymbolConstant.SINGLE_SLASH)) 
                fileDir = fileDir.concat(SymbolConstant.SINGLE_SLASH);
            
            //update-begin-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
            fileDir = StrAttackFilter.filter(fileDir);
            //update-end-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
            fileUrl.append(fileDir).append(fileName);

            filePath = "https://" + newBucket + "." + endPoint + SymbolConstant.SINGLE_SLASH + fileUrl;

            PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream());
            // 设置权限(公开读)
//            ossClient.setBucketAcl(newBucket, CannedAccessControlList.PublicRead);
            if (result != null) 
                log.info("------OSS文件上传成功------" + fileUrl);
            
         catch (Exception e) 
            e.printStackTrace();
            return null;
        
        return filePath;
    

    /**
     * 文件上传
     *
     * @param file    文件
     * @param fileDir fileDir
     * @return 路径
     */
    public static String upload(MultipartFile file, String fileDir) throws Exception 
        return upload(file, fileDir, null);
    

    /**
     * 上传文件至华为云 OBS
     * 文件上传成功,返回文件完整访问路径
     * 文件上传失败,返回 null
     *
     * @param file    待上传文件
     * @param fileDir 文件保存目录
     * @return oss 中的相对文件路径
     */
    public static String upload(FileItemStream file, String fileDir) 
        String filePath;
        initOss(endPoint, accessKeyId, accessKeySecret);
        StringBuilder fileUrl = new StringBuilder();
        try 
            String suffix = file.getName().substring(file.getName().lastIndexOf('.'));
            String fileName = UUID.randomUUID().toString().replace("-", "") + suffix;
            if (!fileDir.endsWith(SymbolConstant.SINGLE_SLASH)) 
                fileDir = fileDir.concat(SymbolConstant.SINGLE_SLASH);
            
            fileDir = StrAttackFilter.filter(fileDir);
            fileUrl.append(fileDir).append(fileName);

            filePath = "https://" + bucketName + "." + endPoint + SymbolConstant.SINGLE_SLASH + fileUrl;

            PutObjectResult result = ossClient.putObject(bucketName, fileUrl.toString(), file.openStream());
            // 设置权限(公开读)
            //ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            if (result != null) 
                log.info("------OSS文件上传成功------" + fileUrl);
            
         catch (IOException e) 
            e.printStackTrace();
            return null;
        
        return filePath;
    

    /**
     * 删除文件
     *
     * @param url 路径
     */
    public static void deleteUrl(String url) 
        deleteUrl(url, null);
    

    /**
     * 删除文件
     *
     * @param url 路径
     */
    public static void deleteUrl(String url, String bucket) 
        String newBucket = bucketName;
        if (oConvertUtils.isNotEmpty(bucket)) 
            newBucket = bucket;
        
        String bucketUrl = "https://" + newBucket + "." + endPoint + SymbolConstant.SINGLE_SLASH;

        //TODO 暂时不允许删除云存储的文件
        //initOss(endPoint, accessKeyId, accessKeySecret);
        url = url.replace(bucketUrl, "");
        ossClient.deleteObject(newBucket, url);
    

    /**
     * 删除文件
     *
     * @param fileName 文件名称
     */
    public static void delete(String fileName) 
        ossClient.deleteObject(bucketName, fileName);
    

    /**
     * 获取文件流
     *
     * @param objectName 对象名
     * @param bucket     桶
     * @return 文件流
     */
    public static InputStream getOssFile(String objectName, String bucket) 
        InputStream inputStream = null;
        try 
            String newBucket = bucketName;
            if (oConvertUtils.isNotEmpty(bucket)) 
                newBucket = bucket;
            
            initOss(endPoint, accessKeyId, accessKeySecret);
            //update-begin---author:liusq  Date:20220120  for:替换objectName前缀,防止key不一致导致获取不到文件----
            objectName = ObsBootUtil.replacePrefix(objectName, bucket);
            //update-end---author:liusq  Date:20220120  for:替换objectName前缀,防止key不一致导致获取不到文件----
            ObsObject ossObject = ossClient.getObject(newBucket, objectName);
            inputStream = new BufferedInputStream(ossObject.getObjectContent());
         catch (Exception e) 
            log.info("文件获取失败" + e.getMessage());
        
        return inputStream;
    

    /**
     * 获取文件外链
     *
     * @param bucketName 桶名称
     * @param objectName 对项名
     * @param expires    日期
     * @return 外链
     */
    public static String getObjectUrl(String bucketName, String objectName, Date expires) 
        initOss(endPoint, accessKeyId, accessKeySecret);
        try 
            //update-begin---author:liusq  Date:20220120  for:替换objectName前缀,防止key不一致导致获取不到文件----
            objectName = ObsBootUtil.replacePrefix(objectName, bucketName);
            //update-end---author:liusq  Date:20220120  for:替换objectName前缀,防止key不一致导致获取不到文件----
            if (ossClient.doesObjectExist(bucketName, objectName)) 
                //URL url = ossClient.generatePresignedUrl(bucketName, objectName, expires);
                //log.info("原始url : ", url.toString());
                //log.info("decode url : ", URLDecoder.decode(url.toString(), "UTF-8"));
                //【issues/4023】问题 oss外链经过转编码后,部分无效,大概在三分一;无需转编码直接返回即可 #4023
                //return url.toString();
                return "";
            
         catch (Exception e) 
            log.info("文件路径获取失败" + e.getMessage());
        
        return null;
    

    /**
     * 初始化 oss 客户端
     */
    private static void initOss(String endpoint, String accessKeyId, String accessKeySecret) 
        if (ossClient == null) 
            ossClient = new ObsClient(accessKeyId, accessKeySecret, endpoint);
        
    


    /**
     * 上传文件到oss
     *
     * @param stream       文件流
     * @param relativePath 相对路径
     * @return 文件路径
     */
    public static String upload(InputStream stream, String relativePath) 
        String filePath = "https://" + bucketName + "." + endPoint + SymbolConstant.SINGLE_SLASH + relativePath;
        initOss(endPoint, accessKeyId, accessKeySecret);
        PutObjectResult result = ossClient.putObject(bucketName, relativePath, stream);
        // 设置权限(公开读)
        //ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
        if (result != null) 
            log.info("------OSS文件上传成功------" + relativePath);
        
        return filePath;
    

    /**
     * 替换前缀,防止key不一致导致获取不到文件
     *
     * @param objectName   文件上传路径 key
     * @param customBucket 自定义桶
     * @return 对象名
     * @date 2022-01-20
     * @author lsq
     */
    private static String replacePrefix(String objectName, String customBucket) 
        log.info("------replacePrefix---替换前---objectName:", objectName);

        String newBucket = bucketName;
        if (oConvertUtils.isNotEmpty(customBucket)) 
            newBucket = customBucket;
        
        String path = "https://" + newBucket + "." + endPoint + SymbolConstant.SINGLE_SLASH;

        objectName = objectName.replace(path, "");

        log.info("------replacePrefix---替换后---objectName:", objectName);
        return objectName;
    

    public static String getOriginalUrl(String url) 
        return url;
    


新建OBS配置类

代码如下:


package org.jeecg.config.oss;

import org.jeecg.common.util.oss.ObsBootUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 华为云存储 配置
 *
 * @author: jeecg-boot
 */
@Configuration
public class ObsConfig 

    @Value("$jeecg.obs.endpoint")
    private String endpoint;
    @Value("$jeecg.obs.accessKey")
    private String accessKeyId;
    @Value("$jeecg.obs.secretKey")
    private String accessKeySecret;
    @Value("$jeecg.obs.bucketName")
    private String bucketName;


    @Bean
    public void initObsBootConfig() 
        ObsBootUtil.setEndPoint(endpoint);
        ObsBootUtil.setAccessKeyId(accessKeyId);
        ObsBootUtil.setAccessKeySecret(accessKeySecret);以上是关于什么是华为云对象存储OBS?它有什么优势?的主要内容,如果未能解决你的问题,请参考以下文章

jeecg-boot中上传图片到华为云obs云存储中

华为云ModelArts和AI Gallery体验之旅

经典毕设项目-企业云盘(springboot+mybaits+vue+华为云obs存储)附全部源码

经典毕设项目-企业云盘(springboot+mybaits+vue+华为云obs存储)github免费源码

经典毕设项目-企业云盘(springboot+mybaits+vue+华为云obs存储)github免费源码

新增Linux资产二级用户登录功能,会话录像支持存储在华为云OBS,JumpServer堡垒机v2.16.0发布