<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      短視頻上傳怎么做|寫個支持分片上傳/斷點續傳/秒傳功能的文件服務吧

      前言

      各位平時使用的短視頻應用,微信 & 微博等圖文社區,它們的圖文動態 & 視頻上傳的能力,都是極其核心的業務。

      本質來說,這都是文件的上傳,這篇文章帶大家寫一個文件上傳服務,探究其核心原理,相信能為你帶來一些幫助。

      感謝我的好友 Trembling 對本文的支持

      主要包含以下能力:

      • 文件上傳
      • 文件下載
      • 分片上傳
      • 斷點續傳
      • 文件秒傳

      往期視頻講解 ??:B站:白澤talk,公眾號:白澤talk

      image-20240726234405804

      FileService 主要能力

      pd定義:

      service FileService {
        // pre sign a file url for user get it
        rpc PreSignGet(PreSignGetRequest) returns (PreSignGetResponse);
        // pre sign a file url for user put it
        rpc PreSignPut(PreSignPutRequest) returns (PreSignPutResponse);
        // report a file has been uploaded
        rpc ReportUploaded(ReportUploadedRequest) returns (ReportUploadedResponse);
        // pre sign a file url for user put it with slicing
        rpc PreSignSlicingPut(PreSignSlicingPutRequest) returns (PreSignSlicingPutResponse);
        // get upload progress rate for slicing put
        rpc GetProgressRate4SlicingPut(GetProgressRate4SlicingPutRequest) returns (GetProgressRate4SlicingPutResponse);
        // merge a slicing uploading file
        rpc MergeFileParts(MergeFilePartsRequest) returns (MergeFilePartsResponse);
        // remove a file
        rpc RemoveFile(RemoveFileRequest) returns (RemoveFileResponse);
      }
      

      FileService用于向各個業務領域提供文件上傳、下載的能力。在FileService的所有接口中,都存在一個名為file context的結構體,該參數通常用于指定文件相關的信息。其結構如下:

      message FileContext {
        // 所屬業務領域,用于創建bucket
        string domain = 1;
        // 所屬業務名稱
        string biz_name = 2;
        // 文件id
        int64 file_id = 3;
        // 文件sha256 hash
        string hash = 4;
        // 文件類型
        string file_type = 5;
        // 文件大小,單位byte
        int64 size = 6;
        // 文件訪問鏈接的過期時間
        int64 expire_seconds = 7;
        // 文件名
        string filename = 8;
      }
      

      在各個請求中,domainbiz_name兩個參數為必傳項,這個2個參數組合后,將使得FileService所依賴的表以業務領域為維度進行第一次分表。在此基礎上,可以為每個業務領域配置一個對應的二次分表,可以指定其分為若干張子表。

      Quick Start

      FileService對于不同業務領域和不同業務項,其文件數量的擴增速度是不同的,帶來的數據量很有可能天差地別。所以,要使用FileService的能力,需要在FileService中進行配置分表數量。

      config.yaml中,可以配置如下內容:

      data:
        db_sharding_config:
          file_shortvideo_short_video:
            sharding: file_shortvideo_short_video
            sharding_number: 5
      

      db_sharding_config項用于配置分表數量,其下的file_shortvideo_short_video為分表key,其中"file"為固定值,shortvideo為業務領域,short_video為業務名稱。sharding_number為分表數量。業務領域和業務名稱需要在使用FileService時傳入。如不進行配置,則默認分表數量為1。

      主要鏈路

      普通上傳/下載

      sequenceDiagram participant up as 上游服務 participant fs as FileService participant minio as Minio Server up->>fs: PreSignPut fs-->>up: PreSignPutResponse(Minio上傳鏈接) up->>minio: 上傳文件 minio-->>up: 上傳結果 up ->> fs: ReportUploaded fs-->>up: ReportUploadedResponse up->>fs: PreSignGet fs-->>up: PreSignGetResponse(下載鏈接) up->>minio: 下載文件 minio-->>up: 返回文件

      分片上傳/斷點續傳

      sequenceDiagram participant up as 上游服務 participant fs as FileService participant minio as Minio Server up->>fs: PreSignSlicingPut fs-->>up: PreSignSlicingPutResponse(分片上傳鏈接數組) up->>minio: 上傳一部分文件 minio-->>up: 上傳結果 up->>up: 喝杯咖啡 up->>fs: GetProgressRate4SlicingPut fs-->>up: GetProgressRate4SlicingPutResponse(分片上傳進度) up->>minio: 上傳剩余文件 minio-->>up: 上傳結果 up->>fs: MergeFileParts fs-->>up: MergeFilePartsResponse up->>fs: PreSignGet fs-->>up: PreSignGetResponse(下載鏈接) up->>minio: 下載文件 minio-->>up: 返回文件

      主要能力

      普通上傳

      FileService.PreSignPut提供了最基礎的上傳能力。該接口需要額外上傳的參數包括:

      • hash: 文件的sha256值
      • file_type: 文件類型
      • size:文件大小(字節數)
      • expire_seconds:文件上傳鏈接的過期時間

      例如,可以向此接口傳入這樣的參數:

      {
          "file_context": {
              "domain": "shortvideo",
              "biz_name": "short_video",
              "hash": "8D6BB0819A2C1E66F846031DC54AAF47",
              "file_type": "pdf",
              "size": 1181178,
              "expire_seconds": 86400
          }
      }
      

      訪問后,該接口將返回一個上傳鏈接(http),由上游服務/前端直接將文件上傳到該鏈接。一個上傳示例代碼(Python):

      with open(file_path, 'rb') as file_data:
          response = requests.put(
              minio_url, # 接口返回的上傳鏈接
              data=file_data,
              headers={"Content-Type": "application/octet-stream"}
          )
          print(response)
          return response.status_code
      

      通過上述Python代碼的方式上傳完成后,并不能直接訪問到該文件,需要通過FileService.ReportUploaded接口來進行上傳確認,只有上傳確認后的文件,才會在數據庫中被標記為uploaded并能被訪問到。關于FileService.ReportUploaded的具體使用,將在下文中詳細介紹。

      分片上傳

      在一些情況下,需要上傳的文件較大,如果直接上傳,可能出現如下問題:

      1. 上傳較慢
      2. 上傳過程中如果出現問題,則需要重新上傳整個文件

      所以,FileService提供了分片上傳的能力。

      首先,可以通過FileService.PreSignSlicingPut預注冊一個分片上傳任務。該接口需要傳入的參數與FileService.PreSignPut相同。接口返回的主要內容包括:

      • urls:數組,各個分片的上傳鏈接,且已經按照分片號排序
      • upload_id:上傳任務的id
      • parts:分片總數
      • file_id:文件id

      參數示例:

      {
          "file_context": {
              "domain": "shortvideo",
              "biz_name": "short_video",
              "hash": "8D6BB0819A2C1E66F846031DC54AAF47",
              "file_type": "pdf",
              "size": 72246060,
              "expire_seconds": 86400
          }
      }
      

      此時,由上有服務/前端對文件進行分片(每一片大小為5MB),然后將各個分片進行上傳,一個文件分片的示例如下(Python):

      def slicing(filename):
          file_size = 5 * 1024 * 1024  # 10MB
          
          files = list()
      
          # 打開文件
          with open(filename, 'rb') as f:
              index = 0
              while True:
                  # 定位到要讀取的位置
                  f.seek(index * file_size)
                  # 讀取數據
                  data = f.read(file_size)
                  # 如果已經讀到文件末尾,退出循環
                  if not data:
                      break
                  # 寫入分割后的文件
                  with open(f'{filename}_{index}', 'wb') as f1:
                      f1.write(data)
                  files.append(data)
                  # 更新位置
                  index += 1
          return files
      

      全部分片上傳完成后,可以通過FileService.MergeFileParts來合并分片。主要參數包括:

      • file_id
      • upload_id

      參數示例:

      {
          "upload_id": "ZDNlOWI2MjktMjAzOC00NzJkLWE0ODYtOGMzZTBlZmJlODUwLmRmN2M5ZWQyLTYxMzMtNDM4NS1hNTljLWEwMzRlNTI5NWNkNHgxNzIzNzM5ODA2MTM2NzU3MzE5",
          "file_context": {
              "file_id": 1824123073628999680,
              "domain": "shortvideo",
              "biz_name": "short_video"
          }
          
      }
      

      與不同上傳不同的是,分片上傳在上傳完成并調用FileService.MergeFileParts后,會自動進行上傳確認,無需再次調用FileService.ReportUploaded

      斷點續傳

      在上述分片上傳的過程中,可以通過FileService.GetProgressRate4SlicingPut來獲取分片上傳的具體情況,主要傳入的參數包括:

      • file_id
      • upload_id

      該接口的返回值中包含一個名為parts的map,key為分片號,value為該分片是否上傳完成,上游服務或服務端可以根據該信息來決定哪些分片需要重新上傳

      示例參數:

      {
          "upload_id": "ZDNlOWI2MjktMjAzOC00NzJkLWE0ODYtOGMzZTBlZmJlODUwLjA3ZTgyNmY0LWE4YjQtNDQxMC04M2QzLWY4ODQ4MTRiZGM4Y3gxNzIzNzM4ODUzMTMzMjY4ODQ3",
          "file_context": {
              "file_id": 1824119076553756672,
              "domain": "shortvideo",
              "biz_name": "short_video"
          }
          
      }
      

      返回值示例:

      {
          "parts": {
              "1": true,
              "2": true,
              "3": true,
              "4": true,
              "5": true,
              "6": true,
              "7": true,
              "8": true,
              "9": true,
              "10": true,
              "11": true,
              "12": true,
              "13": true,
              "14": true
          },
          "meta": {
              "reason": [],
              "biz_code": 0,
              "message": "success",
              "domain": ""
          },
          "progress_rate": 100
      }
      

      上傳確認

      在上傳完成時(分片上傳除外,分片上傳結束時調用FileService.MergeFileParts會自動進行上傳確認),都需要調用FileService.ReportUploaded來進行上報,該接口必傳參數為:

      • file_id

      這一接口主要完成這樣一件事:檢查文件的hash,檢查通過后將文件標記為“上傳成功狀態”,否則文件將不可被查詢到。

      參數示例:

      {
          "file_context": {
              "domain": "shortvideo",
              "biz_name": "short_video",
              "file_id": "1824118603822141440"
          }
      }
      

      下載文件

      通過FileService.PreSignGet接口則可以獲取下載文件鏈接,該接口主要傳入的參數包括:

      • file_id
      • expire_seconds

      參數示例:

      {
          "file_context": {
              "domain": "shortvideo",
              "biz_name": "short_video",
              "file_id": "1824123073628999680",
              "expire_seconds": 86400,
              "filename": "data.mp4"
          }
      }
      

      秒傳

      FileService.PreSignPutFileService.PreSignSlicingPut接口中,如果傳入的hash已經存在,則會返回一個file_id,這個file_id可以用于獲取下載鏈接,從而不需要再次上傳文件。

      posted on 2024-08-17 11:07  白澤talk  閱讀(524)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 日韩一区二区在线看精品| 精品人妻无码一区二区三区| av无码一区二区大桥久未| 小嫩模无套内谢第一次| 狠狠亚洲丁香综合久久| 日日碰狠狠添天天爽超碰97| 国产一区二区三区黄色片| 欧洲lv尺码大精品久久久| 91人妻熟妇在线视频| 《特殊的精油按摩》3| 野外做受三级视频| 中文文精品字幕一区二区| 久久99精品久久久久麻豆| 欧美日韩v| 日本高清www无色夜在线视频| 亚洲欧美日韩综合久久久| 免费播放一区二区三区| 亚洲国产成人精品综合色| 人妻少妇偷人无码视频| 肇州县| 九九热在线视频观看最新| 99久久国产成人免费网站| 92精品国产自产在线观看481页| 亚洲精品一区二区三区蜜| 久久香蕉国产线看观看精品yw| 插入中文字幕在线一区二区三区 | 国产99久60在线视频 | 传媒| 亚洲视频一区| 国产亚洲精品久久yy50| 性做久久久久久久久| 日本黄色一区二区三区四区| 九九热视频在线观看精品| 久久97人人超人人超碰超国产| 色九月亚洲综合网| 久久精品国产99久久久古代| 开鲁县| 日本丶国产丶欧美色综合| 国产免费人成网站在线播放 | 久久96热人妻偷产精品| 呻吟国产av久久一区二区| 欧美中文亚洲v在线|