Mổ Xẻ Kiến Trúc Telegram — Phần 3 (Kết): Server-side với Teamgram
Bài viết phân tích kiến trúc server-side của một MTProto server thông qua Teamgram — open-source MTProto server không chính thức viết bằng Go, tại github.com/teamgram/teamgram-server. Đây là Phần 3 và là phần kết của series 3 phần — đọc cùng Phần 1: Android và Phần 2: iOS để có bức tranh end-to-end về một messaging system.
0. Vì sao phần server quan trọng — và vì sao đến giờ mới nói
Hai phần đầu series mổ xẻ client. Nhưng client chỉ là một nửa câu chuyện.
Telegram là một messenger client/server architecture, không phải peer-to-peer. Mỗi message bạn gửi đi qua Telegram data center, được lưu trong database của họ, rồi push xuống device đối phương. Hiệu năng end-to-end phụ thuộc vào server không kém client. Khi bạn thấy tin nhắn xuất hiện trên iPhone của bạn 0.3s sau khi bấm Send trên Android — phần lớn 0.3s đó là round-trip đi-về server.
Vấn đề: Telegram chính thức không bao giờ open-source server.
Pavel Durov đã nói rõ trong nhiều dịp: “We will never open-source the server because the value of Telegram is in our infrastructure tuned over a decade.” Họ open client (Android, iOS, Desktop, Web) — vì client cần verify được để user tin tưởng. Nhưng server giữ kín. Điều đó có nghĩa nếu bạn muốn:
- Self-host messenger cho doanh nghiệp / chính phủ / quân đội
- Học cách build IM scale ở mức triệu users
- Bypass địa chính trị (Telegram bị cấm ở Iran, Trung Quốc, một số khu vực)
- Build sản phẩm tận dụng UX của Telegram client nhưng backend riêng
→ Bạn không có gì để đọc. Cho đến khi Teamgram xuất hiện.
Teamgram là gì và không là gì
Là:
- Implementation độc lập của MTProto 2.0 protocol bằng Go
- Tương thích với Telegram client gốc (qua patch nhỏ đổi DC IP)
- Open-source Apache 2.0
- Khoảng 2.1k stars, 423 forks, 1,342 commits, 99.4% Go
Không phải:
- Telegram chính thức (legally và technically)
- Bản port từ source code của Telegram (Telegram server code không public)
- Drop-in replacement đầy đủ — community edition chỉ có private chat + basic groups; channels, stickers, calls, bots, mini-apps đều ở enterprise edition (closed source)
- Production-ready cho scale lớn — không có user-base verify million-DAU như Telegram thật
Teamgram team Trung Quốc đã reverse engineer MTProto + TL schema từ:
- Public protocol documentation tại core.telegram.org
- Client source code (Android/iOS/Desktop) — đặc biệt phần TL schema
- Black-box testing với client thật ↔ server tự build
Phải mất nhiều năm. Đây là kỳ tích kỹ thuật đáng nể.
1. Tổng quan Teamgram architecture — microservices từ ngày đầu
Khác với Telegram chính thức (chắc chắn cũng microservices nhưng không ai biết chi tiết), Teamgram lộ rõ kiến trúc:
┌─────────────────────────────────────────────────────────────────┐
│ CLIENT LAYER │
│ Android │ iOS │ Desktop │ Web │
└────────┬────────┬─────────┬──────────┬──────────────────────────┘
│ │ │ │
│ MTProto over TCP / WebSocket │
│ │ │ │
┌────────▼────────▼─────────▼──────────▼─────────────────────────┐
│ GATEWAY LAYER (gnetway) │
│ :10443 TCP • :5222 TCP • :11443 WebSocket │
│ MTProto framing, AES-IGE encryption, obfuscated2 transport │
└────────────────────────────┬─────────────────────────────────────┘
│ internal RPC
┌────────────────────────────▼─────────────────────────────────────┐
│ SESSION LAYER (session :20120) │
│ auth_key validation, session routing, msg_id ordering │
└────────────────────────────┬─────────────────────────────────────┘
│
┌────────────────────────────▼─────────────────────────────────────┐
│ BFF — Backend-For-Frontend (bff :20010) │
│ MTProto RPC method → backend gRPC call dispatch │
│ account / messages / chats / contacts / users / ... │
└────────────────────────────┬─────────────────────────────────────┘
│ gRPC
┌────────────────────────────▼─────────────────────────────────────┐
│ BACKEND SERVICES │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌──────────────┐ │
│ │ biz │ │ msg │ │ sync │ │ media │ │ dfs │ │
│ │ :20020 │ │ :20030 │ │ :20420 │ │ :20650 │ │ :20640 │ │
│ └────────┘ └────────┘ └────────┘ └────────┘ └──────────────┘ │
│ ┌────────┐ ┌────────┐ ┌──────────────┐ │
│ │ idgen │ │ status │ │ authsession │ │
│ │ :20660 │ │ :20670 │ │ :20450 │ │
│ └────────┘ └────────┘ └──────────────┘ │
└────────────────────────────┬─────────────────────────────────────┘
│
┌────────────────────────────▼─────────────────────────────────────┐
│ INFRASTRUCTURE │
│ MySQL :3306 │ Redis :6379 │ etcd :2379 │ Kafka :9092 │ MinIO │
│ Primary DB │ Cache/Sess │ Discovery │ Event bus │ S3-store │
└──────────────────────────────────────────────────────────────────┘
Đây là kiến trúc 3-layer + infrastructure:
- Edge layer:
gnetwayxử lý raw MTProto bytes - Session layer:
sessionquản lý connection state per auth_key - Application layer:
bffroute + 8 backend service domain-specific
Một thiết kế như vậy của một startup (vs Telegram tuned 12 năm) chứng tỏ Go ecosystem cho microservices đã rất mature.
2. Cấu trúc thư mục
teamgram-server/
├── app/ # Toàn bộ application services
│ ├── interface/
│ │ ├── gateway/ # gnetway — TCP/WS handler
│ │ ├── session/ # session — connection state
│ │ └── httpserver/ # Optional REST API
│ ├── bff/ # 26 BFF service domains
│ │ ├── account/
│ │ ├── authorization/
│ │ ├── chats/
│ │ ├── contacts/
│ │ ├── dialogs/
│ │ ├── messages/
│ │ ├── users/
│ │ └── ... (20+ nữa)
│ ├── messenger/ # msg, sync — message pipeline
│ │ ├── msg/
│ │ └── sync/
│ └── service/ # Core domain services
│ ├── authsession/
│ ├── biz/ # Business logic chính
│ ├── dfs/ # Distributed file system
│ ├── idgen/ # Snowflake-like ID generator
│ ├── media/ # Image/video processing
│ └── status/ # User online presence
│
├── pkg/ # Shared packages
│ ├── mtproto/ # MTProto codec, encryption
│ ├── crypto/ # AES-IGE, RSA
│ ├── env2/ # Environment helpers
│ └── ...
│
├── data/ # Static data (TL schema files)
│
├── specs/ # Architecture documentation
│ ├── architecture.md
│ ├── protocol-mtproto.md
│ ├── dependencies-and-runtime.md
│ └── roadmap.md
│
├── docs/ # Installation + ops guides
│
├── clients/ # Client patch instructions
│ ├── teamgram-android.md
│ ├── teamgram-ios.md
│ └── teamgram-tdesktop.md
│
├── teamgramd/
│ ├── bin/ # Built binaries
│ ├── etc/ # Manual install configs
│ ├── etc2/ # Docker install configs
│ └── deploy/
│ ├── sql/ # MySQL schemas + migrations
│ ├── filebeat/
│ ├── prometheus/
│ └── go-stash/
│
├── docker-compose-env.yaml # Infrastructure stack
├── docker-compose.yaml # Application stack
├── go.mod # Go 1.21+ module
└── Makefile
Một observation: thư mục clients/ chỉ chứa patch instructions cho client gốc — nghĩa là Teamgram khuyến khích bạn fork client Telegram chính thức rồi đổi vài dòng (DC IP, port). Họ không maintain client riêng. Smart move — không phải compete với DrKLO/TelegramMessenger về client, chỉ tập trung server.
3. gnetway — Gateway Layer
gnetway là mặt tiền của hệ thống. Mọi byte từ client đi qua đây.
3.1 Responsibilities
- Listen TCP port 10443 (primary), 5222 (alternate), WebSocket 11443
- Decode MTProto framing (Abridged / Intermediate / Padded Intermediate / Full)
- Verify obfuscated2 transport (anti-DPI obfuscation layer)
- Decrypt AES-IGE outer layer với
auth_key - Route message lên
sessionservice qua RPC nội bộ - Encrypt response outer layer + frame về client
3.2 Tại sao tên gnetway?
Vì xây trên gnet — Go networking framework epoll-based, performance cao hơn net.Conn chuẩn:
// Conceptual gnet event loop
type gatewayHandler struct {
gnet.BuiltinEventEngine
}
func (h *gatewayHandler) OnTraffic(c gnet.Conn) gnet.Action {
// Đọc raw bytes từ kernel socket
buf, _ := c.Next(-1)
// Parse MTProto frame
frame, n := parseMTProtoFrame(buf)
// Decrypt outer layer
plaintext := decryptAESIGE(frame, authKey)
// Forward lên session layer
routeToSession(plaintext)
return gnet.None
}
gnet cho phép gnetway xử lý ~100k+ concurrent connections trên 1 instance — quan trọng cho gateway phải maintain idle connection cho push.
3.3 4 transport modes của MTProto
MTProto cho phép client chọn 1 trong 4 framing format:
| Mode | Frame format | Use case |
|---|---|---|
| Abridged | [length 1-4 bytes] [payload] | Mobile thường dùng — tiết kiệm 3 bytes per message |
| Intermediate | [length 4 bytes LE] [payload] | Web client |
| Padded Intermediate | [length] [payload] [random padding] | Anti-fingerprinting |
| Full | [length] [seq] [payload] [crc32] | Debug / desktop gốc |
Gateway phải support đủ 4. Code pkg/mtproto/ của Teamgram có 4 codec riêng cho từng mode.
3.4 Obfuscated2 — bypass DPI
MTProto chạy trên TCP nhưng có thêm layer obfuscation tên “obfuscated2” để TCP traffic không bị DPI (Deep Packet Inspection) phát hiện là Telegram. Cụ thể:
- Client tạo random 64-byte init packet
- Init packet xác định protocol mode + DC ID
- Tất cả bytes sau đó được XOR với keystream từ init packet
- Keystream nhìn random — không có signature pattern
Đây là lý do Telegram block khó hơn HTTPS bình thường ở Trung Quốc/Iran — DPI phải nhìn pattern flow rate / connection lifetime, không thể nhìn header.
Gateway Teamgram replicate chính xác obfuscated2 → client gốc kết nối được mà không cần modify.
4. Session Layer — quản lý auth_key state
Sau gateway, message đến session service.
4.1 Session là gì trong MTProto?
Một session trong MTProto = một stateful connection được identify bởi:
auth_key(256 bytes) — shared secret giữa client + server, lifetime hàng nămauth_key_id(8 bytes, prefix của SHA1(auth_key))session_id(8 bytes, random per app launch)
Một auth_key có thể có nhiều session (mở app trên nhiều device, mỗi device 1 session ID khác nhau).
4.2 Trách nhiệm của session service
1. Verify msg_id ordering. MTProto yêu cầu msg_id luôn tăng và unique. Server phải reject duplicate / out-of-order msg để chống replay attack. Session service maintain Redis cache với TTL ngắn cho msg_ids đã xử lý.
2. Salt rotation. server_salt đổi định kỳ (~30 phút). Session service push salt mới cho client trước khi salt cũ expire. Nếu client miss salt update → reconnect.
3. Acknowledge tracking. MTProto là semi-reliable — client gửi message phải ack từ server, server gửi update phải ack từ client. Session track ack window và resend nếu timeout.
4. Container handling. Client có thể bundle nhiều RPC calls vào 1 msg_container. Session unwrap container, dispatch từng inner message song song lên BFF.
4.3 Stateless hay stateful?
Session service nhìn có vẻ stateful (auth_key, msg_id history) nhưng thực tế stateless với Redis là source of truth. Bất kỳ instance session nào cũng xử lý được message của bất kỳ auth_key nào — chỉ cần Redis cluster shared.
Lợi ích: session service có thể scale horizontal (deploy nhiều instance behind etcd-discovered LB), không có sticky session.
5. BFF Layer — pattern Backend-For-Frontend
Đây là điểm thiết kế đáng học nhất của Teamgram.
5.1 BFF là gì?
BFF (Backend-For-Frontend) là pattern trong microservices: thay vì client gọi trực tiếp 10+ backend services, client gọi 1 BFF, BFF orchestrate calls đến backends rồi trả về response gộp.
Trong Teamgram, BFF còn một role nữa: MTProto RPC method dispatch. MTProto có hàng trăm method (messages.sendMessage, users.getUsers, auth.signIn…). BFF có 26 service riêng cho 26 domain method:
app/bff/
├── account/ # account.* methods
├── auth/ # auth.* methods
├── authorization/ # authorization.* methods
├── chats/ # chats.* methods
├── contacts/ # contacts.* methods
├── dialogs/ # dialogs.* methods
├── messages/ # messages.* methods
├── users/ # users.* methods
└── ... (18 nữa)
Mỗi BFF service implement đúng các method của domain mình, route xuống core services nào cần.
5.2 Ví dụ: messages.sendMessage flow
Client gửi: messages.sendMessage(peer, message, ...)
│
▼
gnetway: decrypt MTProto frame
│
▼
session: verify msg_id, ack, route to BFF
│
▼
bff/messages: nhận RPC call
│
├─→ idgen :20660 — generate message ID
│
├─→ biz :20020 — verify peer permission, anti-spam check
│
├─→ msg :20030 — persist message vào MySQL + Redis cache
│ │
│ └─→ Kafka topic "Inbox-T" — push event cho consumers
│
└─→ sync :20420 — fan-out update tới sessions khác của user (multi-device)
Response chain trả ngược lên client với UpdatesShort containing the new message.
5 RPC calls từ 1 client request. BFF orchestrate hết — client chỉ thấy 1 round-trip.
5.3 Vì sao tách BFF khỏi core services?
Có thể hỏi: tại sao không gọi trực tiếp từ session → biz/msg/sync? Tại sao thêm BFF làm trung gian?
Lý do 1: Protocol abstraction. BFF chuyển từ “MTProto RPC vocabulary” sang “internal gRPC vocabulary”. Client nói tiếng MTProto (messages.sendMessage), backend nói tiếng nội bộ (MessageRepository.Insert). Tách BFF cho phép hai bên evolve độc lập.
Lý do 2: Cross-cutting concerns. Rate limit, auth check, logging, tracing — đặt ở BFF một chỗ. Backend services không cần biết về MTProto.
Lý do 3: API versioning. Telegram API có 200+ layers (current 223). BFF version theo layer, dispatch xuống backend version-agnostic. Khi API layer 224 ra, chỉ cần update BFF method, không động backend.
Lý do 4: Aggregation. Một số method MTProto trả về data tổng hợp (messages.getDialogs cần info từ msg + sync + status + biz). BFF làm aggregation, backend không cần biết caller cần gì.
6. Core Services — tách theo domain
8 core services, mỗi cái có DB + cache riêng:
6.1 biz — Business Logic Service (port 20020)
Logic core của user/chat/dialog: tạo user, tạo group, kick member, change permission, anti-spam, peer reachability check. Đây là service “thông minh” nhất, biết business rules.
6.2 msg — Message Service (port 20030)
Persist messages, query history, search. MySQL table messages + Redis cache hot dialogs. Khi insert message mới → publish Kafka topic Inbox-T để các consumer (push notification, search index) catch event.
6.3 sync — Multi-device Sync Service (port 20420)
User mở Telegram trên 3 device → mỗi device là 1 session với auth_key riêng. Khi 1 device gửi message hoặc đọc message, sync service push update tới 2 device còn lại. Subscribe Kafka topic Sync-T để fan-out update.
6.4 dfs — Distributed File System (port 20640)
Wrapper trên MinIO (S3-compatible object store). Upload file 200MB chia thành chunks 512KB, mỗi chunk có ID riêng, lưu MinIO. Download lấy chunks song song, ghép lại. 4 buckets: documents/, encryptedfiles/, photos/, videos/.
6.5 media — Media Processing (port 20650)
Image: tạo thumbnail size 32×32 + 80×80 + 320×320, stripped JPEG sub-100 bytes cho blur preview (xem Phần 1 mục 10.4 để thấy client side dùng cái này). Video: thumbnail từ frame đầu, transcode sang H.264 nếu cần. Dùng FFmpeg subprocess. Audio: opus encoding cho voice message (cùng codec với client side ở Phần 1).
6.6 idgen — Distributed ID Generator (port 20660)
Snowflake-like ID generation. ID 64-bit gồm timestamp + machine ID + sequence. Global unique without coordination — quan trọng vì messages.id phải unique across cluster.
6.7 status — Online Presence (port 20670)
Track user online/offline state. TTL 5 phút trong Redis (không hit MySQL). Heartbeat từ session service mỗi 30s. Privacy filter: không lộ “last seen recently” cho user không trong contact list.
6.8 authsession — Auth State (port 20450)
Lưu authorization state per auth_key: user đã verify SMS chưa, 2FA setup chưa, app version, IP, geo. Truy vấn từ BFF mỗi RPC call để check authentication.
7. Infrastructure stack
7.1 MySQL — primary store
8.x preferred. Lưu:
users,chats,messages,dialogs,contacts,media,auth_keys, etc.- Schema có sẵn ở
teamgramd/deploy/sql/1_teamgram.sql - Migrations theo file
migrate-*.sql
7.2 Redis — cache + session
Multi-purpose:
- Session cache: auth_key state, online users
- Dedup: msg_id processed (chống replay), TTL 5 phút
- Hot data cache: dialog list, peer info, sticker pack
- Rate limit counter: sliding window per user
7.3 etcd — service discovery
Mỗi service register endpoint vào etcd:
/services/biz/instance-1 → 192.168.1.10:20020
/services/biz/instance-2 → 192.168.1.11:20020
BFF query etcd để discover backend instances. Client-side load balancing với health check.
7.4 Kafka — event bus
2 topic chính:
- Inbox-T: Mỗi message mới → publish. Consumers: push notification, search index, audit log.
- Sync-T: Multi-device sync events. Consumer: sync service per-user fan-out.
Lý do dùng Kafka thay vì direct gRPC:
- Decouple producer/consumer (msg service không biết ai care về message mới)
- Replay capability (search index re-index lịch sử bằng cách read từ topic offset 0)
- Burst absorption (peak hour 1M messages/sec, downstream xử lý chậm hơn — Kafka buffer)
7.5 MinIO — object storage
Self-hosted S3 alternative. 4 buckets cho 4 loại file. Compatible API → có thể swap sang AWS S3 / Cloudflare R2 / GCS với zero code change.
7.6 FFmpeg — media transcoding
Subprocess được media service spawn. Transcode video MP4 → optimized H.264, generate thumbnail, encode voice → opus.
8. go-zero framework — backbone của Teamgram
Mỗi service Teamgram build trên go-zero — Go microservices framework của Tencent (kevwan/go-zero).
8.1 Tại sao go-zero?
Trước go-zero, Go microservices thường dùng Kit (gokit), Micro, hoặc handcraft với gRPC + etcd. Mỗi cái có pain point:
- gokit verbose, boilerplate nhiều
- Micro ecosystem fragmented sau v2/v3 split
- Handcraft tốt nhưng tốn time setup
go-zero cung cấp:
- goctl — code generator từ
.api/.protofiles - gRPC server/client với etcd discovery built-in
- Logging, metrics, tracing tích hợp sẵn (Prometheus, Jaeger)
- Rate limit, circuit breaker, load shedding out-of-box
- MySQL/Redis/Kafka client với connection pooling tuned
Code điển hình của 1 Teamgram service:
// app/service/biz/biz.go
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
ctx := svc.NewServiceContext(c)
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
biz.RegisterBizServer(grpcServer, server.NewBizServer(ctx))
})
defer s.Stop()
// Tracing, metrics, logging — tự động enable
s.Start()
}
5 dòng setup gRPC server với full observability. Đây là productivity boost lớn.
8.2 Code generation pipeline
Teamgram có 1 file TL schema cực dài (data/) → generate ra:
- TL types in Go
- gRPC proto definitions
- BFF stubs
- Client SDK stubs
Một command dalgenall.sh chạy lại toàn bộ chain. Tương tự cách Telegram chính thức generate TLRPC.java (Phần 1) và TelegramApi Swift module (Phần 2) từ cùng .tl schema.
9. Reverse engineering MTProto — kỳ tích kỹ thuật
Để có Teamgram chạy được, team đã phải reverse engineer:
9.1 Nguồn dữ liệu
Nguồn 1: Public docs.
core.telegram.org/mtproto— protocol speccore.telegram.org/schema— TL schema definitioncore.telegram.org/api— API method docs
Nhưng public docs không đủ chi tiết:
- Schema định nghĩa input/output types
- Docs nói “method X gửi message đến chat Y”
- Nhưng không nói error nào server trả về khi nào, retry policy ra sao, rate limit là bao nhiêu, side effect là gì
Nguồn 2: Client source code. Đọc DrKLO/Telegram (Android) và TelegramMessenger/Telegram-iOS để xem client expect gì từ server:
- Error codes nào client handle (FILE_MIGRATE_X, USER_MIGRATE_X, FLOOD_WAIT_X…)
- Update types nào client process (updateNewMessage, updateUserStatus…)
- Order of update delivery
- Implicit invariants (vd:
messages.idalways increasing trong 1 dialog)
Nguồn 3: Black-box testing.
- Spin up Teamgram server cục bộ
- Connect client gốc với DC IP đã modify
- Quan sát: client gửi gì, expect response gì
- Debug khi client crash hoặc behave weird
Quá trình này lặp đi lặp lại nhiều năm. Mỗi API layer mới của Telegram (~3 tháng/lần), Teamgram phải catch up.
9.2 Vì sao chỉ community edition mà không full feature?
Community edition của Teamgram chỉ support:
- Private chat
- Basic groups (legacy chat)
- Contacts
- Web client basic
Còn stickers, channels, supergroups, secret chat, 2FA, push (APNs/FCM), audio/video calls, bots, mini-apps đều ở enterprise edition (closed-source, bán license).
Lý do practical: implement những feature này yêu cầu integration sâu với external systems (APNs cần Apple cert, FCM cần Google project, calls cần STUN/TURN server, secret chat cần riêng key derivation pipeline). Mỗi feature là một dự án con. Team Teamgram không đủ resource cho free tier toàn bộ.
Đây là điểm cần biết khi đánh giá Teamgram cho production: không phải drop-in replacement. Bạn dùng Teamgram thì không có channels, không có push notification, không có calls. Tự build hoặc mua license.
10. Khi nào nên / không nên self-host MTProto server
10.1 Khi nên cân nhắc self-host
1. Yêu cầu data sovereignty. Một số industry (banking VN, healthcare, gov) bị quy định data phải lưu trong nước. Telegram chính thức không có DC ở Việt Nam → không qualify. Self-host trong VPS Việt Nam thì OK.
2. Compliance audit. ISO 27001, SOC 2 type 2 yêu cầu audit data flow. Khó audit Telegram chính thức (server đóng). Self-host = bạn audit được toàn bộ.
3. Custom feature cực sâu. Cần thay đổi behavior server (custom moderation, custom auth flow integrate SSO doanh nghiệp). Telegram chính thức không cho. Self-host = full control.
4. Tận dụng Telegram client UX cho sản phẩm riêng. Client của Telegram có UX rất tốt (thấy ở Phần 1, 2). Nếu sản phẩm bạn có user base cần messaging quality cao và bạn fork client thay vì viết mới → cần backend tương thích = self-host MTProto.
5. Bypass địa chính trị. Telegram bị block ở Iran, Trung Quốc, một số khu vực. User nội bộ tổ chức cần messenger riêng = self-host.
10.2 Khi không nên
1. Bạn cần feature đầy đủ Telegram. Channel, calls, bots, mini-apps — community Teamgram không có. Mua enterprise edition tốn tiền (negotiate). Tự build các feature này = team 10-20 dev backend full-time, nhiều năm.
2. User base nhỏ (<10k DAU). Microservices với MySQL + Redis + etcd + Kafka + MinIO + FFmpeg là gánh ops nặng. Cần ít nhất 1 SRE full-time. Với 10k DAU bạn dùng Firebase + Cloud Functions hoặc Supabase rẻ hơn 100x.
3. Bạn ưu tiên ship nhanh. MTProto là protocol phức tạp. Setup Teamgram lần đầu mất 1-2 tuần. Custom feature mất nhiều tháng. Nếu MVP trong 3 tháng — chọn REST + WebSocket + Postgres đơn giản hơn.
4. Cần guarantee uptime. Telegram chính thức 99.99%+ uptime nhờ kinh nghiệm 12 năm + budget vô hạn. Self-host = bạn tự chịu downtime. SLA 99.9% đã rất khó với team nhỏ.
10.3 Lựa chọn alternative cho Việt Nam
Nếu sau khi cân nhắc bạn quyết định không self-host MTProto, đây là lựa chọn theo use case:
| Use case | Stack đề xuất |
|---|---|
| Internal team chat (<100 user) | Mattermost / Rocket.Chat self-host |
| Customer support chat | Crisp / Intercom (managed SaaS) |
| Community chat (<10k users) | Discord bot integration |
| Custom messenger startup | Stream Chat / Sendbird (managed, expensive) |
| Custom messenger với data residency | Matrix Synapse self-host |
| Real-time với scale lớn | Firebase Realtime DB / Firestore + Cloud Functions |
| Native Vietnamese audience | Tự build trên Supabase + custom WebSocket |
Matrix là alternative đáng cân nhắc nhất nếu bạn muốn tránh MTProto: open-source full-stack, federation native, có client iOS/Android/web mature (Element).
11. Bảng kết: Telegram official vs Teamgram
Đối chiếu trực tiếp:
| Khía cạnh | Telegram chính thức | Teamgram (community) |
|---|---|---|
| Server source | Closed | Open (Apache 2.0) |
| Client source | Open (Android/iOS/Desktop) | Reuse client gốc + patch DC IP |
| Language stack | Closed (rumor: Erlang/C++) | Go 99.4% |
| Architecture | 5+ data centers, hidden internals | Microservices, 11 services rõ ràng |
| API Layer | 223 (latest) | 223 |
| MTProto compliance | Reference implementation | Compatible (4 transport modes) |
| Database | Closed | MySQL + Redis + LMDB |
| Object storage | Closed (rumor: custom) | MinIO (S3-compatible) |
| Event bus | Closed | Kafka |
| Service discovery | Closed | etcd |
| Push (APNs/FCM) | Built-in | Enterprise edition only |
| Channels | Built-in | Enterprise edition only |
| Stickers/Themes | Built-in | Enterprise edition only |
| Calls (audio/video) | Built-in | Enterprise edition only |
| Bots / Mini-apps | Built-in | Enterprise edition only |
| Scale verified | 1B+ MAU | Lab setup, no public scale data |
| Self-host | Không | Có |
| Open audit | Không | Có |
| Production readiness | Battle-tested 12 năm | Cần thêm hardening |
| Data sovereignty | Phụ thuộc DC location | Full control |
12. Series finale — bài học toàn cuộc
3 phần series đã đi qua:
- Phần 1: Android client — kiến trúc 2 module, native C++ qua JNI cho MTProto, NotificationCenter event bus, Cells tự draw bằng Canvas, ImageReceiver, build Gradle + CMake.
- Phần 2: iOS client — kiến trúc 270 modules với Bazel, MTProtoKit Obj-C, SSignalKit reactive framework, Postbox database reactive-first, AsyncDisplayKit fork, ListView/TextNode/TransformImageNode, build reproducible với Make.py.
- Phần 3 (kết): Server — Teamgram microservices Go, gateway gnetway → session → BFF → 8 core services, infrastructure MySQL/Redis/etcd/Kafka/MinIO, go-zero framework, reverse-engineered MTProto.
12.1 Bài học #1: Protocol design là điều kiện tiên quyết
MTProto được Pavel Durov cùng team thiết kế từ 2013 với constraint cụ thể: chạy trên mạng Nga 2G/3G yếu, censor heavy, low-end device. Mọi kiến trúc client + server sau đó phải tuân theo protocol đó.
Đây là bài học: trước khi build app messaging/real-time, đầu tư thời gian thiết kế protocol cẩn thận. Không phải “dùng REST hay GraphQL” — mà:
- Connection model (request/response vs stream vs push)
- Authentication model (token vs key vs E2E key derivation)
- Update delivery (pull vs push vs hybrid)
- Reliability guarantees (at-least-once, at-most-once, exactly-once)
- Partition tolerance (multi-DC routing, consistency model)
Nếu sai từ protocol, mọi tối ưu sau đó chỉ là vá. Nếu đúng từ protocol, scale lên triệu users mượt mà.
12.2 Bài học #2: Cross-platform = share data layer, không share UI
Cả 3 phần đều xác nhận điều này:
- Android, iOS share C/C++ code cho MTProto + crypto + codec
- Schema TL share giữa client + server
- UI hoàn toàn riêng (Java/Kotlin Android, Swift/Obj-C iOS, Go/web cho server admin)
Đây là pattern đối nghịch với React Native / Flutter (“share UI”). Telegram chọn ngược lại — share infrastructure, đa dạng UI. Kết quả: UX trên iPhone giống UI iOS native, trên Android giống UI Android native, không cảm giác “app cross-platform giống nhau như sinh đôi”.
12.3 Bài học #3: Native cho hot path, high-level cho UI
| Layer | Telegram dùng |
|---|---|
| Crypto, codec, network protocol | C / C++ |
| Database access | SQLite C qua wrapper mỏng |
| Image processing | C / Metal (iOS) / OpenGL (Android) |
| Business logic | Java (Android) / Swift (iOS) / Go (server) |
| UI | Java + Canvas (Android) / Swift + AsyncDisplayKit (iOS) |
Pattern: càng gần CPU/network, càng native. Càng gần user, càng high-level. Đảo ngược pattern này (vd: Java cho crypto, Rust cho UI) là disaster.
12.4 Bài học #4: Tự viết core, không tự viết phụ
Telegram tự viết:
- Network layer (MTProto)
- Database layer (Postbox / SQLite wrapper)
- UI list/text rendering (ListView, TextNode, Cells)
- Image loading (ImageReceiver, TransformImageNode)
- Reactive framework (SSignalKit cho iOS, NotificationCenter cho Android)
Telegram không tự viết:
- Crypto (BoringSSL)
- Compression (zstd, gzip)
- Codec (FFmpeg, opus, libwebp)
- TLS (BoringSSL again)
- Lottie animation (rlottie)
- HTTP/2 (cho MTProto over HTTPS fallback)
Pattern: tự viết phần khác biệt cạnh tranh + UX-critical. Dùng library cho phần đã chuẩn hóa + battle-tested. Crypto là perfect example — không ai sane tự viết AES.
12.5 Bài học #5: Open-source client tạo trust, đóng server giữ moat
Telegram open-source client để user verify “client không gửi data về Telegram secretly”. Đóng server vì server chính là sản phẩm — 12 năm tuning, không ai duplicate được.
Nếu bạn build sản phẩm tương tự (banking app, health app, B2B SaaS) — cân nhắc strategy này:
- Open client / SDK → user audit được, partner integrate được
- Closed server → giữ competitive moat
Tất nhiên áp dụng có chỗ. Cloud-first SaaS không có “client” để open. Nhưng nếu sản phẩm của bạn có client + server architecture rõ ràng, đây là pattern đáng học.
12.6 Bài học cuối: Đừng ngại độ phức tạp đúng chỗ
Bài học chung của 3 phần: Telegram phức tạp ở những chỗ phức tạp xứng đáng:
- 100k+ dòng
TLRPC.javaautogen — phức tạp xứng đáng (cross-platform schema) - 270 modules iOS với Bazel — phức tạp xứng đáng (parallel build, extension memory)
- 11 microservices server — phức tạp xứng đáng (independent scaling, fault isolation)
- ListView 5000 dòng — phức tạp xứng đáng (60fps trên thiết bị 1GB RAM)
Đồng thời Telegram đơn giản ở những chỗ đơn giản đủ:
- Singleton everywhere (no DI framework)
- Manual SQL (no Room/CoreData)
- Custom Fragment system thay framework navigation
- Object[] args trong NotificationCenter
Điểm cân bằng: complexity nên proportional với value. Khó nhất là biết khi nào cần phức tạp, khi nào không. 12 năm Telegram chứng minh team họ biết.
13. Tài nguyên cuối series
Telegram chính thức:
- Android: github.com/DrKLO/Telegram
- iOS: github.com/TelegramMessenger/Telegram-iOS
- Desktop: github.com/telegramdesktop/tdesktop
- TDLib (cross-platform library): github.com/tdlib/td
Teamgram:
- Server: github.com/teamgram/teamgram-server
- Android patch: github.com/teamgram/teamgram-android
- iOS patch: github.com/teamgram/teamgram-ios
- TDesktop patch: github.com/teamgram/teamgram-tdesktop
Specs & docs:
- MTProto protocol: core.telegram.org/mtproto
- TL schema: core.telegram.org/schema
- API documentation: core.telegram.org/api
- Security guidelines: core.telegram.org/mtproto/security_guidelines
Frameworks & tools:
- go-zero: github.com/zeromicro/go-zero
- gnet: github.com/panjf2000/gnet
- AsyncDisplayKit/Texture: github.com/TextureGroup/Texture
- rlottie: github.com/Samsung/rlottie
Alternative protocols để nghiên cứu:
- Matrix: matrix.org
- XMPP: xmpp.org
- Signal Protocol: signal.org/docs
Lời kết
Series 3 phần này không phải là instruction manual để clone Telegram. Telegram thành công vì 12 năm execution + product judgment + timing thị trường — những thứ không có trong code. Nếu bạn đọc xong và thấy “OK giờ tôi build được Telegram” — bạn hiểu sai mục đích.
Mục đích thật: để hiểu một sản phẩm phần mềm scale lớn được làm như thế nào ở từng layer. Khi bạn làm app messaging tiếp theo, app real-time tiếp theo, hay bất kỳ sản phẩm nào có client + server architecture phức tạp — bạn có frame of reference để so sánh, để biết quyết định nào tốt, quyết định nào không.
Telegram không phải template để copy. Telegram là case study sâu nhất hiện có công khai về việc build messenger ở scale tỷ user. Đọc nó như đọc tiểu sử của một runner Olympic — không phải để bắt chước y nguyên, mà để hiểu nguyên tắc tập luyện áp dụng được vào hành trình của chính mình.
Cuối cùng, một note thực tế cho dev Việt: nếu bạn đang ấp ủ “messenger Việt cho người Việt”, trước khi viết dòng code đầu tiên, hãy tự hỏi: tại sao Zalo thắng và OneZ/Mocha/Bipbip thua? Trả lời được câu đó, kiến trúc tự khắc rõ. Trả lời không được, dù bạn copy chính xác Telegram code, vẫn thua.
Code chỉ là 5%. 95% còn lại là product, distribution, timing, và execution.
Cảm ơn bạn đã đọc đến cuối series.
Bài viết hoàn tất series “Mổ Xẻ Kiến Trúc Telegram” — biên soạn dựa trên source code công khai của DrKLO/Telegram, TelegramMessenger/Telegram-iOS, teamgram/teamgram-server, kết hợp tài liệu kiến trúc và spec MTProto chính thức.
Phần 1: Android · Phần 2: iOS · Phần 3 (Kết): Server-side với Teamgram