当前位置: 首页 > news >正文

计算机网站建设 是什么意思网站seo设计

计算机网站建设 是什么意思,网站seo设计,虾皮跨境电商平台,政务网站开发协议背景 我们的项目每天都会并行上传好几万份文件到下游的GCP Cloud Storage,当文件比较大时,会采用GCP的可续上传方案,通过把文件切分成多个数据块,分多次HTTP请求上传到GCP Bucket,具体可参考https://cloud.google.com…

背景

我们的项目每天都会并行上传好几万份文件到下游的GCP Cloud Storage,当文件比较大时,会采用GCP的可续上传方案,通过把文件切分成多个数据块,分多次HTTP请求上传到GCP Bucket,具体可参考https://cloud.google.com/storage/docs/performing-resumable-uploads。 但是在实际应用中,会发现文件比较大时,由于数据包会被分成多次HTTP请求上传,偶尔GCP会返回400错误码导致上传失败,但是查看各个请求参数都属于正常,目前不确定GCP一些网络限制导致还是该 API 存在性能问题。于是我选择使用另一种替代方案,尝试使用以下方式,通过GCP 官方SDK进行文件上传。

 GoogleCredentials apiCredentials = GoogleCredentials.fromStream(new FileInputStream(jsonKeyPath)).createScoped(scopes);Storage storage = StorageOptions.newBuilder().setCredentials(apiCredentials).build().getService();BlobId blobId = BlobId.of(bucketName, objectName);BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("application/json;charset=UTF-8").setMd5(checksum).build();byte[] bytes = Files.readAllBytes(sourceFIle.toPath());storage.create(blobInfo,bytes);

SDK API参考https://cloud.google.com/java/docs/reference/google-cloud-storage/latest/overview

文件小的时候速度还是比较快,因为它是直接Upload,不做数据分块,但是当文件大点或者数量多点,就会出现如下异常

java.lang.OutOfMemoryError: Required array size too large

原因是这句代码Files.readAllBytes(sourceFIle.toPath())会一次过把文件直接加载到内存,当文件比较大或者文件数量很多的时候,就会直接导致内存溢出。

虽然官方SDK也有针对大文件上传提供了可续上传方案,例如:

 String bucketName = "my-unique-bucket";String blobName = "my-blob-name";BlobId blobId = BlobId.of(bucketName, blobName);byte[] content = "Hello, World!".getBytes(UTF_8);BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("text/plain").build();try (WriteChannel writer = storage.writer(blobInfo)) {writer.write(ByteBuffer.wrap(content, 0, content.length));} catch (IOException ex) {// handle exception}

WriteChannel底层原理也是会在传输的时候会分块上传,并且遇到网络波动导致传输失败会自动基于上一次传输的数据包进行重传,但是这个也只是解决大文件上传性能问题,并没办法解决我们在加载源文件就已经内存溢出。

解决方案

其实解决办法也很简单,我们只需要把每次读书源文件的数据包在可控范围即可,也就是分块读取,分块上传,这样既保证大文件上传效率,也不会因为一次过加载文件太多导致内存溢出。

以下是示范代码:

主程序入口:
以下scope对应的是我们所需要的权限https://cloud.google.com/storage/docs/authentication

    public static void main(String[] args) throws IOException {List<String> scopes = new ArrayList<>(Arrays.asList("https://www.googleapis.com/auth/devstorage.full_control","https://www.googleapis.com/auth/devstorage.read_write"));//GCP Json Key PathString jsonKeyPath = "";//File used to be uploadedFile sourceFile = new File("filePath");//Calculate file checksumString checksum = DigestUtils.md5Hex(new FileInputStream(sourceFile));//GCS BucketNameString bucketName = "";//GCS Target ObjectNameString objectName=sourceFile.getName();//Prepare connection details//https://cloud.google.com/storage/docs/authenticationGoogleCredentials apiCredentials = GoogleCredentials.fromStream(new FileInputStream(jsonKeyPath)).createScoped(scopes);Storage storage = StorageOptions.newBuilder().setCredentials(apiCredentials).build().getService();BlobId blobId = BlobId.of(bucketName, objectName);BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("application/json;charset=UTF-8").setMd5(checksum).build();uploadToBucket(storage, sourceFile, blobInfo);}

上传方法:
这里的文件大小需要根据自己服务器实际的内存和带宽去设置,一般小文件使用直接上传方法效果最好,如果文件比较大,就需要进行数据包拆分。
关于数据块大小设置,以下是GCP的建议:

The chunk size should be a multiple of 256 KiB (256 x 1024 bytes), unless it's the last chunk that completes the upload. Larger chunk sizes typically make uploads faster, but note that there's a tradeoff between speed and memory usage. It's recommended that you use at least 8 MiB for the chunk size.

    public static void uploadToBucket(Storage storage, File sourceFIle, BlobInfo blobInfo) throws IOException {//For small files, we can upload the file in one go// less than 10 MBif(sourceFIle.length() < 10000000){byte[] bytes = Files.readAllBytes(sourceFIle.toPath());storage.create(blobInfo,bytes);return;}//For big files , we need to split it into multiple chunkstry(WriteChannel writer = storage.writer(blobInfo)){//Don't read the whole file because it will cause OutOfMemory issuebyte[] buffer = new byte[10240];try(InputStream input = Files.newInputStream(sourceFIle.toPath())){int limit;while((limit = input.read(buffer))>=0){writer.write(ByteBuffer.wrap(buffer,0,limit));}}}}

以下这一句是解决这个问题的关键,每次只读取一部分数据,所以不会导致内存溢出。

  while((limit = input.read(buffer))>=0){

测试效果

这里使用了项目用的GCP Storage和账号进行测试,多线程并行去上传4个210MB文件,由于我电脑在中国网络,而对应GCP Bucket部署在欧洲,所以速度不算快。

总结

其实这里解决方案不只适用于谷歌云,以前我们使用阿里云的时候,上传一些大文件也是采用这样的方式,适用于所有的文件传输场景,这里其实就是利用分治思想去解决问题。

完整代码

https://github.com/EvanLeung08/cloud-solutions/tree/main/gcs-largefile-upload

http://www.mmbaike.com/news/49627.html

相关文章:

  • 惠网 做网站接外包网站
  • 贺州市住房与城乡建设局网站今日头条热搜
  • 专业网站设计公司哪里有seo站长平台
  • 安利的网站谁做的怎么推广一个app
  • 本溪网站建设磁力链最佳的搜索引擎
  • 相城做网站的公司湘潭高新区最新新闻
  • 网站建设平台合同模板seo免费资源大全
  • 美国做3d+h动画的网站网站优化排名方法有哪些
  • 建站哪家好论坛网站外链推广平台
  • php做简单网站教程seo是什么意思呢
  • 网站的基本建设投资seo相关岗位
  • 宁波营销型网站建设百度推广的方式有哪些
  • 网站备案要关站吗百度一下app下载安装
  • 搞笑资讯网站源码seoaoo
  • 网站 案例展示快速排名优化推广手机
  • 国内做的比较好的旅游网站网站建设黄页
  • 四川建设人才考试官网简述seo
  • 石河子市建设局网站seo最新
  • 做ppt的网站什么广告推广最有效果
  • 怎么做基金公司网站网销怎么做
  • 新手学纪事本html代码做网站优帮云查询数据云查询
  • 做搜狗网站快速排名网站如何进行seo
  • 河北企业建站推广方法有哪几种
  • 做网站开发的公司销售现在百度怎么优化排名
  • 想在中国网站做海外代购链接怎么做
  • 环保设备在那个网站做注册网站
  • 网站开发过程中遇到的问题超级推荐的关键词怎么优化
  • 杭州 建设网站制作十种营销方法
  • 做网站系统源云推广
  • 山东济南网网站建设百度推广业务电话