Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 6 — Client-Server Model và HTTP

Technical Product Manager Bài 6/60

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn là PM của một ứng dụng đặt đồ ăn như ShopeeFood hay GrabFood. Một buổi trưa thứ Sáu, app bỗng tải chậm kinh khủng, người dùng bấm "Đặt món" mà spinner quay mãi không xong. Engineer trong phòng war room thì nói với nhau những câu như "response time của endpoint /orders tăng vọt", "API gateway đang timeout 504", "có vẻ keep-alive không hoạt động". Nếu bạn không hiểu mô hình client-server và HTTP, bạn sẽ ngồi đó gật gù mà chẳng nắm được chuyện gì đang xảy ra, không thể đặt câu hỏi đúng, càng không thể giúp ưu tiên cách xử lý.

Đây chính là lý do bài này quan trọng. Mô hình client-server và giao thức HTTP là nền tảng của gần như mọi sản phẩm số mà bạn sẽ làm việc: website, mobile app, API nội bộ, tích hợp với đối tác thanh toán. Khi một Technical PM hiểu được "một request đi từ điện thoại người dùng đến server rồi quay về" diễn ra như thế nào, bạn sẽ đọc được log, hiểu được vì sao tính năng chậm, ước lượng được độ phức tạp khi engineer nói "cái này phải gọi thêm 3 API", và trao đổi với team mà không cần phiên dịch.

Bài này không biến bạn thành lập trình viên backend. Mục tiêu là cho bạn một mô hình tư duy (mental model) đủ vững để nhìn thấu cách dữ liệu di chuyển trên Internet — thứ ẩn sau mọi nút bấm trong sản phẩm của bạn.

Khái niệm cốt lõi

Mô hình Client-Server là gì

Mô hình client-server là cách tổ chức trong đó có hai vai trò rõ ràng. Client (máy khách) là bên khởi xướng yêu cầu — đó có thể là trình duyệt Chrome, app Grab trên điện thoại, hoặc thậm chí một server khác đang gọi sang. Server (máy chủ) là bên ngồi chờ, nhận yêu cầu, xử lý rồi trả về kết quả.

Quy tắc vàng: client luôn là bên chủ động gửi request, server là bên phản hồi bằng response. Server (trong mô hình HTTP cổ điển) không tự nhiên gọi cho client trước. Khi bạn mở app Tiki và thấy danh sách sản phẩm, điều đã xảy ra là: app của bạn (client) gửi một yêu cầu "cho tôi danh sách sản phẩm trang chủ", server Tiki nhận yêu cầu đó, truy vấn cơ sở dữ liệu, rồi trả về dữ liệu để app hiển thị.

Mô hình này phổ biến vì nó tách bạch trách nhiệm. Client lo phần hiển thị và tương tác với người dùng. Server lo phần dữ liệu, logic nghiệp vụ và bảo mật. Hàng triệu client có thể cùng kết nối tới một cụm server, và bạn chỉ cần nâng cấp logic ở server là tất cả người dùng được hưởng — không phải bắt từng người cài lại app.

Request và Response — cuộc đối thoại

Mỗi lần client và server "nói chuyện", cuộc đối thoại gồm hai phần: một request đi ra và một response đi về. Hãy hình dung như bạn gọi điện đến tổng đài ngân hàng: bạn (client) nói rõ mình muốn gì (request), tổng đài viên (server) xử lý rồi đọc kết quả cho bạn (response).

Một HTTP request gồm các thành phần chính:

  • Method (phương thức): cho biết bạn muốn làm gì. GET để lấy dữ liệu, POST để tạo mới, PUT/PATCH để cập nhật, DELETE để xóa. Ví dụ GET /products/123 nghĩa là "cho tôi xem sản phẩm số 123".
  • URL / endpoint: địa chỉ tài nguyên bạn muốn tác động đến, ví dụ https://api.tiki.vn/products/123.
  • Headers: phần thông tin đi kèm, như "tôi muốn nhận dữ liệu dạng JSON", "đây là token đăng nhập của tôi", "ngôn ngữ tiếng Việt".
  • Body (thân): dữ liệu gửi kèm, thường có ở POST/PUT. Ví dụ khi đặt hàng, body chứa danh sách món, địa chỉ giao, phương thức thanh toán.
Một HTTP response trả về gồm:

  • Status code (mã trạng thái): con số ba chữ số tóm tắt kết quả. Đây là thứ PM nên thuộc lòng vì nó xuất hiện liên tục trong các cuộc thảo luận.
  • Headers: thông tin về response, như loại nội dung, kích thước, hướng dẫn cache.
  • Body: dữ liệu thực sự trả về, thường là JSON, HTML hoặc hình ảnh.

Status code — bảng tín hiệu bạn phải đọc được

Status code chia thành các nhóm theo chữ số đầu:

  • 2xx — Thành công. 200 OK là mọi thứ ổn. 201 Created nghĩa là đã tạo mới thành công (ví dụ đơn hàng vừa được tạo).
  • 3xx — Chuyển hướng. 301/302 nghĩa là tài nguyên đã chuyển sang địa chỉ khác.
  • 4xx — Lỗi từ phía client. 400 Bad Request là bạn gửi dữ liệu sai định dạng. 401 Unauthorized là chưa đăng nhập. 403 Forbidden là đã đăng nhập nhưng không có quyền. 404 Not Found là tài nguyên không tồn tại. 429 Too Many Requests là bạn gọi quá nhiều, bị giới hạn tốc độ.
  • 5xx — Lỗi từ phía server. 500 Internal Server Error là server gặp lỗi nội bộ. 503 Service Unavailable là server quá tải hoặc đang bảo trì. 504 Gateway Timeout là server xử lý quá lâu, hết giờ chờ.
Mẹo phân biệt nhanh cho PM: 4xx là lỗi do bên gửi, 5xx là lỗi do bên nhận. Khi tích hợp với đối tác thanh toán mà nhận 400, lỗi nằm ở cách team bạn gửi dữ liệu; nếu nhận 500, lỗi nằm ở hệ thống đối tác. Biết được điều này giúp bạn biết "trách nhiệm thuộc về ai" mà không cần đợi engineer phân tích từ đầu.

HTTP, HTTPS và một vài đặc tính quan trọng

HTTP (HyperText Transfer Protocol) là bộ quy tắc cho cuộc đối thoại request-response trên web. HTTPS là HTTP có thêm lớp mã hóa, đảm bảo dữ liệu giữa client và server không bị đọc trộm trên đường truyền — bắt buộc với mọi sản phẩm có đăng nhập hoặc thanh toán.

Một đặc tính quan trọng: HTTP về bản chất là stateless (không trạng thái). Mỗi request là độc lập, server mặc định không "nhớ" bạn là ai từ request trước. Đây là lý do cần đến token đăng nhập đính kèm trong header mỗi lần gọi — để server biết "à, đây vẫn là người dùng đã đăng nhập lúc nãy". (Chi tiết cách quản lý trạng thái đăng nhập sẽ học ở bài về Authentication.)

Tình huống thực tế

Tình huống 1 — ShopeeFood và lỗi 504 giờ cao điểm

Một sàn giao đồ ăn tại Việt Nam gặp hiện tượng: vào khung 11h–12h trưa, khoảng 8% người dùng bấm "Đặt món" nhưng app báo lỗi "không thể kết nối". Team mở dashboard giám sát và thấy endpoint POST /orders trả về rất nhiều 504 Gateway Timeout.

Diễn giải: 504 nghĩa là API gateway gửi request vào hệ thống xử lý đơn nhưng chờ quá lâu (quá 30 giây) không nhận được response nên tự ngắt. Đào sâu thêm, engineer phát hiện mỗi lần tạo đơn, server phải gọi tuần tự ba dịch vụ con: kiểm tra tồn kho nhà hàng, tính phí ship, và trừ ví khuyến mãi. Vào giờ cao điểm, dịch vụ tính phí ship bị nghẽn vì lượng request gấp 5 lần bình thường, kéo theo toàn bộ chuỗi bị chậm.

Bài học rút ra: là PM, khi nhìn thấy 504 bạn nên nghĩ ngay tới "có một bước nào đó trong chuỗi xử lý đang quá chậm", chứ không phải "mạng người dùng kém". Bạn có thể đặt câu hỏi đúng: "Request đặt đơn phải gọi qua mấy dịch vụ? Bước nào chậm nhất? Có thể gọi song song thay vì tuần tự không?". Đây là cách hiểu mô hình request-response biến bạn từ người ngoài cuộc thành người dẫn dắt buổi thảo luận kỹ thuật.

Tình huống 2 — Tích hợp cổng thanh toán và mã 401 vs 403

Một startup fintech ở TP.HCM tích hợp với cổng thanh toán VNPAY. Trong giai đoạn thử nghiệm, engineer báo cáo "API trả về 401, không gọi được". PM ngồi cùng và nhận ra đây là vấn đề về xác thực: 401 Unauthorized nghĩa là request thiếu hoặc sai thông tin định danh — ở đây là do dùng nhầm khóa bí mật (secret key) của môi trường sandbox cho môi trường production.

Vài ngày sau, lỗi đổi thành 403 Forbidden. Lần này khóa đã đúng, nhưng tài khoản merchant chưa được VNPAY kích hoạt quyền cho loại giao dịch trả góp. 403 nghĩa là "tôi biết bạn là ai, nhưng bạn không được phép làm việc này".

Bài học rút ra: PM hiểu được sự khác nhau tinh tế giữa 401 (chưa chứng minh được mình là ai) và 403 (đã biết là ai nhưng không đủ quyền) sẽ định tuyến vấn đề đúng người: 401 thì làm việc với team kỹ thuật để sửa cấu hình khóa, còn 403 thì cần liên hệ bộ phận vận hành của đối tác để mở quyền. Phân biệt sai sẽ khiến cả hai bên đổ lỗi cho nhau và mất nhiều ngày.

Tình huống 3 — Mobile app gọi API thừa và hóa đơn server phình to

Một ứng dụng tin tức giả định, "BaoNhanh", có 200.000 người dùng hằng ngày. Đội backend phát hiện server nhận tới 12 triệu request mỗi ngày, cao bất thường. Khi soi log, họ thấy màn hình trang chủ của app cứ mỗi lần người dùng kéo lên kéo xuống lại gửi một loạt GET /home-feed mới mà không tận dụng dữ liệu đã có.

Diễn giải: mỗi GET tưởng nhỏ nhưng nhân với hàng triệu lần thành gánh nặng thật. Việc thiếu cơ chế tái sử dụng dữ liệu giữa các request làm server phải xử lý lặp đi lặp lại cùng một thứ, đẩy chi phí hạ tầng và làm app tốn pin, tốn 3G/4G của người dùng — điều rất nhạy cảm ở thị trường mà nhiều người vẫn dùng gói data giới hạn.

Bài học rút ra: số lượng và "trọng lượng" của request là chỉ số sản phẩm thực sự, không chỉ là chuyện kỹ thuật. PM nên quan tâm "một màn hình gọi bao nhiêu API, mỗi API trả về bao nhiêu dữ liệu", vì nó ảnh hưởng trực tiếp đến tốc độ cảm nhận, chi phí và trải nghiệm trên mạng yếu.

Hướng dẫn từng bước

Đây là quy trình để bạn tự "đọc" một luồng client-server trong sản phẩm của mình, ngay cả khi không biết code:

  • Mở công cụ Network của trình duyệt. Trên Chrome, nhấn F12, chọn tab Network, rồi tải lại trang sản phẩm của bạn. Bạn sẽ thấy danh sách tất cả request mà trình duyệt gửi đi.
  • Quan sát cột Method và Name. Đọc xem mỗi hành động trên giao diện tương ứng với request nào. Ví dụ khi bạn bấm "Đăng nhập", để ý một dòng POST /login xuất hiện.
  • Đọc cột Status. Đây là status code. Lọc nhanh xem có dòng nào màu đỏ (4xx, 5xx) không. Nếu một tính năng lỗi, dòng đỏ thường chỉ thẳng vào nguyên nhân.
  • Bấm vào một request để xem chi tiết. Tab Headers cho bạn thấy URL, method, headers; tab Payload cho thấy body gửi đi; tab Response cho thấy dữ liệu trả về. Hãy đọc thử để cảm nhận "client gửi gì, server trả gì".
  • Để ý cột Time (thời gian). Request nào mất quá nhiều thời gian (vài giây) chính là ứng viên gây chậm cho trải nghiệm. Đây là dữ liệu quý để bạn nêu trong buổi họp ưu tiên.
  • Ghi lại thành một sơ đồ đơn giản. Vẽ "người dùng bấm X → app gọi API Y → trả về Z". Khi bạn làm được điều này cho các luồng quan trọng, bạn đã có bản đồ kỹ thuật của sản phẩm trong đầu.

Lỗi thường gặp & mẹo

Lỗi 1 — Nhầm "trang chậm" luôn là do mạng người dùng. Rất nhiều khi nguyên nhân nằm ở phía server (5xx, response chậm) hoặc do app gọi quá nhiều API. Mẹo: luôn hỏi "status code là gì, thời gian response bao nhiêu" trước khi kết luận.

Lỗi 2 — Coi mọi lỗi là như nhau. 404500 cần hai hướng xử lý hoàn toàn khác. 404 thường là vấn đề logic hoặc dữ liệu (đường dẫn sai, sản phẩm đã xóa), 500 là lỗi hệ thống cần engineer điều tra gấp. Mẹo: nhớ "4xx — lỗi bên gửi, 5xx — lỗi bên nhận".

Lỗi 3 — Quên rằng HTTP là stateless. PM hay giả định "server tự nhớ người dùng". Thực tế mỗi request phải tự mang theo định danh. Hiểu điều này giúp bạn không ngạc nhiên khi engineer nói "phải đính token vào mỗi lần gọi".

Lỗi 4 — Bỏ qua số lượng request khi viết yêu cầu tính năng. Một màn hình "đơn giản" về mặt giao diện có thể cần gọi 8 API phía sau. Mẹo: khi mô tả tính năng, hỏi team "màn này cần bao nhiêu lời gọi server" để ước lượng độ phức tạp và hiệu năng sớm.

Mẹo vàng: Hãy tập thói quen mở tab Network mỗi khi bạn dùng thử sản phẩm của chính mình. Chỉ sau vài tuần, bạn sẽ "đọc" được sản phẩm theo cách của engineer.

Bài tập thực hành

  • Quan sát thực tế: Mở một website bạn hay dùng (ví dụ tiki.vn hoặc vnexpress.net), bật tab Network của Chrome, tải lại trang. Ghi ra 5 request đầu tiên: method, đường dẫn rút gọn, status code và thời gian. Nhận xét request nào nặng nhất.
  • Phân loại tình huống: Với mỗi mô tả sau, hãy đoán status code phù hợp và lý do — (a) người dùng nhập sai định dạng email khi đăng ký; (b) người dùng truy cập trang quản trị khi chỉ là tài khoản thường; (c) server cơ sở dữ liệu bị sập; (d) gọi API quá nhiều lần trong một giây.
  • Vẽ sơ đồ luồng: Chọn một tính năng cốt lõi trong sản phẩm bạn đang làm (hoặc một app bất kỳ), vẽ sơ đồ "người dùng thao tác → các request được gửi → dữ liệu trả về". Đánh dấu bước nào có thể chậm hoặc dễ lỗi.
  • Đặt câu hỏi đúng: Viết ra 3 câu hỏi bạn sẽ hỏi engineer khi một tính năng trả về 503 vào giờ cao điểm, dựa trên những gì đã học.

Tóm tắt

Mô hình client-server là nền tảng của gần như mọi sản phẩm số: client chủ động gửi request, server phản hồi bằng response. Mỗi HTTP request gồm method, URL, headers và body; mỗi response gồm status code, headers và body. Là Technical PM, bạn cần đọc được status code — nhớ rằng 2xx là thành công, 4xx là lỗi từ phía gửi, 5xx là lỗi từ phía server — vì đó là ngôn ngữ chung trong mọi cuộc thảo luận sự cố.

Qua các tình huống ShopeeFood (504 giờ cao điểm), tích hợp VNPAY (401 vs 403) và app tin tức gọi API thừa, bạn thấy rằng hiểu HTTP không phải kiến thức hàn lâm — nó giúp bạn định tuyến vấn đề đúng người, đặt câu hỏi sắc bén và đưa ra quyết định ưu tiên dựa trên dữ liệu thật. Hãy biến tab Network của trình duyệt thành công cụ thường trực của bạn. Khi đã quen nhìn dữ liệu di chuyển giữa client và server, bạn sẽ tự tin bước vào các bài tiếp theo về REST API, GraphQL và các giao thức real-time — tất cả đều xây trên nền tảng bạn vừa nắm vững ở đây.