Giới thiệu
Dịch vụ rút gọn URL giúp chuyển đổi một URL dài (ví dụ: https://example.com/some/very/deep/path) thành một alias ngắn gọn hơn (ví dụ: https://short.ly/aBcD12). Khi người dùng truy cập vào URL ngắn, họ sẽ được chuyển hướng đến URL gốc. Một số ví dụ điển hình bao gồm TinyURL, Bitly, v.v.
Yêu cầu chức năng
Tính năng
- Rút gọn một URL dài
- Chuyển hướng từ URL ngắn → URL dài
- Phân tích số liệu
Người dùng
- 100 triệu người dùng hoạt động hàng ngày (DAU)
- Tỷ lệ đọc/ghi 100:1
- 1 triệu ghi mỗi ngày
- Kích thước mỗi mục dữ liệu 500 byte
- Thời gian lưu trữ dữ liệu là 5 năm
Yêu cầu phi chức năng
- Tính khả dụng cao - Hệ thống cần phải hoạt động 24/7, thời gian ngừng hoạt động tối thiểu.
- Độ trễ thấp - Chuyển hướng cần phải rất nhanh (~200 ms).
- Độ bền cao - Dữ liệu phải được lưu trữ ngay cả khi máy chủ gặp sự cố.
Các điểm cuối API
POST /api/urls/shorten
Nội dung yêu cầu:
json
{
"longUrl": "https://example.com/some/very/deep/path"
}
Nội dung phản hồi:
json
{
"shortUrl": "https://short.ly/aBcD12"
}
GET /:shorturl
Nội dung phản hồi:
json
{
"longUrl": "https://example.com/some/very/deep/path"
}
Thiết kế cấp cao
Quy trình ban đầu cho dịch vụ rút gọn URL sẽ bao gồm:
-
Khách hàng gửi một URL để rút gọn
- Khách hàng gửi yêu cầu
POSTđến API Gateway, bao gồm URL dài gốc.
- Khách hàng gửi yêu cầu
-
API Gateway chuyển tiếp đến dịch vụ rút gọn URL
- API Gateway định tuyến yêu cầu đến Dịch vụ rút gọn URL.
- Dịch vụ này:
- Tạo một
shortCode - Lưu trữ ánh xạ (
shortCode → longUrl) trong cơ sở dữ liệu - Trả về URL ngắn cho khách hàng (ví dụ:
https://short.ly/abc123)
- Tạo một
-
Khách hàng sử dụng URL ngắn
- Khi ai đó nhấp vào URL ngắn (
https://short.ly/abc123), một yêu cầuGETđược gửi đến API Gateway.
- Khi ai đó nhấp vào URL ngắn (
-
API Gateway định tuyến đến Dịch vụ chuyển hướng URL
- Dịch vụ Chuyển hướng tìm kiếm mã ngắn (
abc123) trong cơ sở dữ liệu.
- Dịch vụ Chuyển hướng tìm kiếm mã ngắn (
-
Chuyển hướng đến URL gốc
- Khi URL dài được lấy ra, dịch vụ phản hồi với một chuyển hướng 301 hoặc 302 đến URL dài gốc.
- Trình duyệt sẽ theo dõi chuyển hướng này và tải URL dài.
Tối ưu thiết kế & Chi tiết sâu
-
Làm thế nào để một người được chuyển hướng đến URL gốc khi nhấp vào URL ngắn?
- Khi một người nhấp vào URL ngắn, Dịch vụ Chuyển hướng tìm mã ngắn tương ứng trong cơ sở dữ liệu.
- Và phản hồi với mã trạng thái HTTP 302 (hoặc 301), cùng với tiêu đề
Location:httpHTTP 302 Found Location: https://www.example.com/very/long/path?ref=campaign
-
Tại sao sử dụng 302 (Found) thay vì 301 (Moved Permanently)?
- 302 là Tạm thời:
- Thông báo cho trình duyệt - "Chuyển hướng này có thể thay đổi sau. Đừng lưu vào bộ nhớ cache vĩnh viễn."
- 301 là Vĩnh viễn:
- Thông báo cho trình duyệt và các công cụ tìm kiếm: "Liên kết này sẽ luôn đến cùng một nơi."
- Trình duyệt sẽ lưu vào bộ nhớ cache vĩnh viễn.
- 302 là Tạm thời:
-
Tại sao sử dụng CSDL NoSQL cho dịch vụ rút gọn URL?
- Dịch vụ rút gọn URL rất phù hợp với NoSQL vì chúng liên quan đến việc tra cứu đơn giản theo cặp khóa-giá trị. Ví dụ, bạn chỉ cần ánh xạ
shortCode → longUrl, điều này không yêu cầu các phép nối hoặc mối quan hệ phức tạp. - NoSQL cung cấp:
- Độ thông lượng đọc/ghi cao
- Tính linh hoạt về cấu trúc (bạn có thể thêm dữ liệu theo dõi sau)
- Khả năng mở rộng theo chiều ngang (dễ dàng xử lý hàng triệu yêu cầu)
- Truy cập dựa trên khóa với độ trễ thấp
- Chúng ta có thể sử dụng một cơ sở dữ liệu có tính khả dụng cao (ví dụ: DynamoDB hoặc Cassandra) để lưu trữ các ánh xạ.
- Dịch vụ rút gọn URL rất phù hợp với NoSQL vì chúng liên quan đến việc tra cứu đơn giản theo cặp khóa-giá trị. Ví dụ, bạn chỉ cần ánh xạ
-
Dữ liệu gì nên được lưu trữ trong CSDL?
- URL
json
{
"shortCode": "abc123",
"longUrl": "https://www.example.com/very/long/article?id=12345",
"createdAt": "2025-09-14T10:00:00Z",
"userId": "77a211ff"
}
- Người dùng
```json
{
"userId": "77a211ff",
....
}
Các phương pháp tối ưu hóa hệ thống rút gọn URL
-
Thêm lớp caching (ví dụ: Redis)
- Lưu trữ các ánh xạ
shortCode → longUrlphổ biến - Giảm số lần đọc từ cơ sở dữ liệu và độ trễ
- Sử dụng chính sách TTL hoặc LRU để quản lý bộ nhớ
- Lưu trữ các ánh xạ
-
Sử dụng chỉ mục trên trường
shortcodetrong CSDL- Đảm bảo cơ sở dữ liệu có chỉ mục đúng trên trường
shortcode. - Tăng tốc độ truy vấn tìm kiếm cho việc chuyển hướng.
- Đảm bảo cơ sở dữ liệu có chỉ mục đúng trên trường
Cách tạo mã duy nhất cho mỗi URL dài?
Việc tạo các mã ngắn duy nhất, không bị xung đột là quan trọng đối với thiết kế của dịch vụ rút gọn URL. Dưới đây là một số phương pháp phổ biến:
-
Bộ đếm tự động tăng + Mã hóa Base62
- Sử dụng một bộ đếm toàn cục tăng lên cho mỗi URL mới.
- Chuyển đổi số bộ đếm sang Base62 (0-9, A-Z, a-z) để có một chuỗi ngắn gọn, thân thiện với URL.
- Ví dụ:
125 → "cb" - Ưu điểm:
- Đơn giản, có thể dự đoán, không xảy ra xung đột.
- Mã rất ngắn.
- Nhược điểm:
- Cần bộ đếm trung tâm (khó mở rộng).
- URL tuần tự có thể tiết lộ lượng truy cập.
-
Chuỗi ngẫu nhiên với kiểm tra xung đột
- Tạo một chuỗi ngẫu nhiên Base62 có độ dài cố định (ví dụ: 6 ký tự).
- Kiểm tra cơ sở dữ liệu để tìm xung đột, tái tạo nếu đã tồn tại.
- Ưu điểm:
- Dễ dàng mở rộng theo chiều ngang.
- Khó đoán mã ngắn tiếp theo (tăng tính riêng tư).
- Nhược điểm:
- Nguy cơ xung đột nhỏ (có thể giảm thiểu bằng độ dài).
- Cần kiểm tra cơ sở dữ liệu cho mỗi lần tạo.
-
Băm URL dài
- Băm URL gốc (MD5/SHA) và sử dụng N ký tự đầu tiên làm mã ngắn.
- URL dài giống nhau luôn nhận được mã ngắn giống nhau.
- Ưu điểm:
- Idempotent (không có bản sao cho cùng một URL).
- Không cần trạng thái trung tâm.
- Nhược điểm:
- Nguy cơ xung đột.
- Mã có thể dài hơn hoặc ít thân thiện hơn.
-
Mã hóa UUID hoặc GUID
- Tạo một UUID, mã hóa thành Base62 hoặc hex.
- Sử dụng một chuỗi con làm mã ngắn.
- Ưu điểm:
- Duy nhất toàn cầu.
- Nhược điểm:
- Mã dài hơn.
Lưu ý: Đối với hầu hết các dịch vụ rút gọn URL, đặc biệt ở quy mô nhỏ đến trung bình, phương pháp Chuỗi ngẫu nhiên + Kiểm tra xung đột là lựa chọn tối ưu nhất.
Cách mở rộng hệ thống để xử lý lưu lượng truy cập cao?
-
Sharding:
- Để xử lý lưu lượng truy cập cao và mở rộng hiệu quả, chúng ta có thể sử dụng sharding để phân phối dữ liệu và tải giữa nhiều máy chủ. Điều này cho phép mở rộng theo chiều ngang, cho phép thêm nhiều nút khi lưu lượng tăng mà không cần cấu hình lại lớn.
-
Cân bằng tải:
- Sử dụng các bộ cân bằng tải để phân phối đồng đều các yêu cầu đến các dịch vụ.
- Ngăn chặn bất kỳ máy chủ nào bị quá tải.
-
Caching CDN ở biên:
- Sử dụng CDN (ví dụ: Cloudflare) để lưu trữ các chuyển hướng tại các vị trí biên.
- Giảm độ trễ cho người dùng toàn cầu.
- Giảm tải yêu cầu trước khi chúng đến backend của bạn.
Thiết kế cuối cùng
Nếu bạn thấy bài viết này hữu ích, hãy:
- 💬 Để lại bình luận - Tôi rất muốn nghe ý kiến của bạn hoặc trả lời các câu hỏi của bạn!
- 🔁 Chia sẻ với những người khác đang học thiết kế hệ thống.
- 📌 Theo dõi tôi trên Dev.to để nhận thêm nhiều bài viết sâu hơn như thế này!
Cảm ơn bạn đã đọc! :)