Tối ưu quá trình client upload ảnh lên server

Xin chào anh chị,

Nguyên tắc lưu ảnh phía server là lưu file vào ổ đĩa, sau đó lưu tên ảnh hoặc ID ảnh vào database nhưng em vẫn chưa biết cách truyền ảnh giữa 2 máy tính trong môi trường www như thế nào cho tối ưu. Em thường làm như này:

  • Tại client (browser, mobile app, desktop app) nhận ảnh từ thiết bị user.
  • Encode thành base64.
  • Truyền text này qua mạng (REST API).
  • Server decode và lưu vào disk.
  • rename file và lưu tên ảnh vào database.

Ngoài ra trên web thì em truyền file bằng cách:

  • client dùng javascript giải lập ra một form, đặt header request http là
Content-Type: multipart/form-data
  • Controller server nhận tham số có kiểu dữ liệu là MultipartFile, sau đó dùng các method stream data để lưu file vào ổ cứng.

Cách này thì em không hiểu cơ chế hoạt động khi ảnh truyền quan network cho lắm, một số file lớn như video dễ lỗi.

Cách thứ hai là cách tối ưu và thường dùng nhất vì cách này được thiết kế để truyền file theo tiêu chuẩn IETF.

Cụ thể khi dùng multipart/formdara thì server sẽ hiểu dữ liệu ở payload là ở dạng thô, qua đó stream thẳng dữ liệu vào ổ cứng mà không cần phải decode từ base64 về dữ liệu ban đầu như ở cách 1.

Truyền dữ liệu thô cũng sẽ tiết kiệm dung lượng hơn so với encode bằng base64 ở cách 1. Vì khi encode bằng base64 thì dữ liệu sẽ nặng hơn 33% so với dữ liệu ban đầu.

Ngoài ra khi upload file lớn thì người ta thường chia nhỏ file lớn thành những đoạn nhỏ hơn. Mục đích là để khi có lỗi xảy ra trong quá trình upload, thì client chỉ cần upload một đoạn nhỏ thay vì upload lại nguyên file lớn, và client có thể tạm dừng việc upload.

8 Likes

Cái bệnh này là không chịu tìm hiểu về WWW và HTTP trước khi học lập trình web. Sao lại có thể như vậy được nhỉ? Không lẽ ngày nay học sinh có thể nhảy vào làm toán mà không biết cộng trừ nhân chia bằng tay? Đọc bài này nhé.

5 Likes

Nhờ anh giải thích rõ đoạn stream file từ máy client đến ổ cứng server với.

Cái này thì em biết ạ nhưng đó chỉ là lý thuyết, thực tế không đáng kể. VD: client nén ảnh xong có dung lượng 100kB tăng 33% thành 133kB cũng không sao, thậm chí image 1MB thành 1,33MB cũng không ảnh hưởng nhiều.

Ý mình là server sẽ không phải làm thêm bước decode base64 thành dữ liệu thô rồi mới lưu vào ổ cứng, có thể lấy thẳng dữ liệu user upload lên để lưu.

33% của số nhỏ thì nhỏ chứ của số lớn thì khá lớn đấy.

Mình giả sử bạn định làm server host ảnh và video. Cho 1GB = 1000MB cho dễ tính

Xét một số trường hợp cơ bản như:

  1. Server có 1000 user upload các file ảnh 3 MB cùng lúc, server sẽ xử lí 3GB dữ liệu. Nếu encode base64 file đấy ở client thì server sẽ xử lí 4GB dữ liệu.

  2. Nếu upload tải một file ảnh 4k 6MB thì server sẽ xử lí 6GB, encode base64 thì xử lí 8 GB.

  3. Còn nếu họ upload video nặng 1,5GB thì server sẽ xử lí 1500GB, còn nếu encode bằng base64 thì phải xử lí 2000GB dữ liệu.

Khi encode bằng base64 thì server sẽ phải xử lí thêm 33,33% dung lượng dữ liệu mà client upload lên. Client cũng phải upload thêm 33,33% dữ liệu và user phải chờ thêm 33,33% thời gian + thời gian để server decode về định dạng gốc. Server sẽ xử lí thêm task decode nếu dùng base64.

Ngoài ra, đối với trường hợp 3, thì còn phải suy xét tới việc trình duyệt web không phù hợp để xử lí các tác vụ nặng như encode file base64 nặng 1,5GB, đặc biệt là trên điện thoại.

6 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?