Góc khuất của ParrotEdu: Bảng điều khiển học tập thời gian thực với Django 5.2.4
By hientd, at: 11:35 Ngày 05 tháng 7 năm 2025
Thời gian đọc ước tính: __READING_TIME__ phút


Tại Glinteco, chúng tôi đang xây dựng ParrotEdu, một nền tảng học tiếng Anh dựa trên trí tuệ nhân tạo được thiết kế cho học sinh từ mẫu giáo đến lớp 12. Một trong những tính năng thú vị và đầy thách thức nhất của nền tảng này là bảng điều khiển học tập thời gian thực dành cho cả học sinh và giáo viên.
Khi học sinh tương tác với các bài tập, hệ thống sẽ theo dõi hiệu suất, tài liệu học tập, chuỗi ngày học liên tiếp và hơn thế nữa. Bảng điều khiển phải phản ánh ngay lập tức các thay đổi, hiển thị phản hồi và phân tích trực tiếp, tất cả trong khi xử lý hàng nghìn người dùng đồng thời.
Nghe có vẻ đơn giản? Không phải vậy. Nhưng đây là cách chúng tôi đã giải quyết vấn đề bằng Django 5.2.4, Redis, Celery, và Django Channels.
Thử thách
Chúng tôi cần xây dựng một hệ thống backend có thể:
-
Xử lý việc nộp bài tập của học sinh ngay lập tức.
-
Xử lý khối lượng lớn dữ liệu học tập mà không bị chậm trễ.
-
Cập nhật bảng điều khiển thời gian thực mà không gây quá tải cho cơ sở dữ liệu.
-
Tăng khả năng mở rộng trên nhiều lớp học và trường học.
Mặc dù Django rất mạnh mẽ, nhưng để thực hiện các tác vụ thời gian thực ở quy mô lớn cần nhiều hơn chỉ là Model.objects.all().
Kiến trúc của chúng tôi tổng quan
Thành phần | Vai trò |
---|---|
Django 5.2.4 | Backend cốt lõi (nay có hỗ trợ async) |
Django Channels | Hỗ trợ WebSocket thời gian thực |
Redis | Bộ nhớ đệm + Pub/Sub + lưu trữ bảng xếp hạng |
Celery | Hàng đợi tác vụ nền cho xử lý nặng |
PostgreSQL | Cơ sở dữ liệu chính với lập chỉ mục thông minh và view |
Cách chúng tôi giải quyết vấn đề tốc độ & thời gian thực trong ParrotEdu
1. Async Views trong Django 5.2.4
Hỗ trợ async def gốc của Django 5.2 đã mang lại cho chúng tôi sự tăng hiệu năng đáng kể trên các điểm cuối xử lý I/O nặng.
from django.http import JsonResponse
from asgiref.sync import sync_to_async
async def get_user_progress(request):
data = await sync_to_async(fetch_progress)(request.user.id)
return JsonResponse(data)
Chúng tôi đã sử dụng sync_to_async()
để kết nối giữa ORM cũ và các async view.
2. Cập nhật thời gian thực qua WebSockets
Với Django Channels, chúng tôi có thể:
-
Đẩy các cập nhật tiến độ khi học sinh hoàn thành bài tập.
-
Gửi các cập nhật bảng xếp hạng trực tiếp cho tất cả học sinh trong một lớp.
-
Hiển thị cho giáo viên khi học sinh đang tích cực làm việc.
# Gửi cập nhật bảng xếp hạng trực tiếp
async def send_leaderboard(class_id, data):
await get_channel_layer().group_send(
f"class_{class_id}",
{"type": "leaderboard.update", "data": data}
)
Redis được sử dụng làm lớp kênh để hỗ trợ nhiều tiến trình worker.
3. Celery cho xử lý nặng
Chúng tôi nhanh chóng nhận ra rằng việc tính toán:
-
chuỗi ngày học liên tiếp
-
điểm XP
-
huy hiệu tiến độ
-
và thứ hạng trên bảng xếp hạng
…trong thời gian thực sẽ chặn các view và làm chậm API. Vì vậy, chúng tôi đã giao phó mọi thứ nặng nề cho các tác vụ Celery:
@shared_task
def update_metrics(user_id, exercise_id):
# Cập nhật XP, chuỗi ngày học liên tiếp, huy hiệu
...
Điều này cho phép chúng tôi phản hồi người dùng ngay lập tức trong khi xử lý logic ở phía sau.
4. Redis để lưu trữ cache tức thời
Chúng tôi lưu trữ cache tất cả dữ liệu được đọc thường xuyên (như thanh tiến độ và bảng xếp hạng) trong Redis với TTL.
cache.set(f"user:{user_id}:xp", 2500, timeout=300)
Khi một tác vụ Celery cập nhật XP hoặc chuỗi ngày học liên tiếp, nó sẽ ghi trực tiếp vào Redis, và một phát sóng WebSocket sẽ kích hoạt việc làm mới giao diện người dùng.
Điều này giúp việc đọc dữ liệu nhanh chóng mà không cần truy cập cơ sở dữ liệu mỗi lần.
5. Sử dụng PostgreSQL thông minh
Bảng exercise_attempts của chúng tôi phát triển nhanh chóng. Để giữ cho truy vấn nhanh:
-
Chúng tôi sử dụng
select_related()
vàprefetch_related()
để tránh truy vấn N+1.
-
Chúng tôi đã tạo ra các view vật chất hóa cho bảng điều khiển của giáo viên (như điểm trung bình theo thời gian).
-
Chúng tôi đã thêm chỉ mục GIN vào các trường JSON để tìm kiếm siêu dữ liệu linh hoạt.
Luồng kết quả trực tiếp trong ParrotEdu
-
Học sinh hoàn thành bài tập
-
Kết quả được lưu → Tác vụ Celery được kích hoạt
-
Bộ nhớ đệm Redis được cập nhật
-
WebSocket đẩy cập nhật trực tiếp lên bảng điều khiển
-
Các tác vụ hàng loạt PostgreSQL cập nhật tổng hợp dài hạn (mỗi vài phút)
Bài học kinh nghiệm
-
Khả năng async của Django 5.2 là một bước ngoặt.
-
Celery là người bạn tốt nhất của bạn khi mọi thứ bắt đầu trở nên phức tạp.
-
WebSockets làm cho trải nghiệm người dùng trở nên tuyệt vời.
-
Redis là không thể thiếu khi xây dựng giao diện người dùng thực sự nhanh nhạy.
-
Hiệu năng không phải là về việc làm mọi thứ nhanh hơn (nhanh hơn 50%), mà là về việc làm ít hơn trong thời gian chạy.
Những gì chúng tôi đang xây dựng tiếp theo
Đối với các phiên bản ParrotEdu trong tương lai, chúng tôi đang khám phá:
-
Sử dụng SSE (Server-Sent Events) để truyền phát nhẹ hơn
-
Thông tin chi tiết dựa trên AI được xử lý hàng loạt thông qua Celery
-
Một lớp GraphQL API để linh hoạt hơn trong các truy vấn bảng điều khiển
Suy nghĩ cuối cùng
Việc xây dựng ParrotEdu đã thách thức đội ngũ của chúng tôi đẩy Django đến giới hạn của nó và nó đã mang lại kết quả.
Nếu bạn đang làm việc trên một nền tảng giáo dục hiệu năng cao, hoặc đang xây dựng một bảng điều khiển thời gian thực cho bất kỳ trường hợp sử dụng nào, kiến trúc này có thể mang lại cho bạn cả hai điều tốt nhất: tốc độ phát triển và hiệu năng cấp sản xuất.
👉 Cần trợ giúp với các ứng dụng Django thời gian thực? Hãy liên hệ với chúng tôi tại Glinteco.com