GopherDay2024
Agenda
Multipart File Upload 情境
只考慮 HTTP 1.1
如果要上傳 1~2 GB 就會開始有問題
上傳檔案時,先把所有資料拆成 TCP packet 送到 server,server 再組回來
graph LR
subgraph Client
direction TB
file[File] --> clientKernel[Client Kernel]
clientKernel --> clientSocket[TCP Socket]
end
clientSocket -- TCP Connection --> serverSocket
subgraph Server
direction TB
serverSocket[TCP Socket] --> serverKernel[Server Kernel]
serverKernel --> application[Application]
application --> handler[Handler]
end
%% Adding a comment to represent Single HTTP Request
file -.->|Single HTTP Request| clientKernel
大檔案的挑戰:memory challenge, network latency, I/O block when parsing the file
Q1. Golang built in http package 如何處理 form data?
用 r.ParseMultipartForm
來 parse 資料、FormFile
讀裡面某個 key 的檔案
Parse 階段不會把 body 全部讀出來,只有先讀 header
要儘早把資料讀出來,避免他的 buffer 被清掉(?)/被佔滿導致後續封包進不來
Q2. 若檔案 size 過大會有什麼問題?(maxMemory Default: 32MB),預設情況下,golang 會將檔案存在 memory;當檔案過大時 Golang 會將接收的檔案存成檔案
ParseMultipartForm
會帶入 maxMemory 參數
Risks
io.ReadAll()
讀出所有內容可能會讓記憶體用量過高Content length header 可以不傳,把大檔案切成多個 request
Golang HTTP package: body reader 會自動切換成用 ChunkedReader
graph LR
subgraph Client
direction TB
file[File] --> clientKernel[Client Kernel]
clientKernel --> clientSocket[TCP Socket]
end
clientSocket -- TCP Connection --> serverSocket
subgraph Server
direction TB
serverSocket[TCP Socket] --> serverKernel[Server Kernel]
serverKernel --> application[Application]
application --> handler[Handler]
end
%% Adding comments to represent Multiple HTTP Requests (Transfer-Encoding: chunked)
file -.->|HTTP Request Chunk 1| clientKernel
file -.->|HTTP Request Chunk 2| clientKernel
file -.->|HTTP Request Chunk 3| clientKernel
io.Copy
取代 io.ReadAll
+ write file,避免全部讀到 memory。io.Copy
預設 buffer size 是 32 KBParseMultipartForm()
讓他可以直接寫到一個指定的檔案路徑,避免先寫到 temp fs 再複製檔案or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing