Go on One VPS: Production Handbook

Cách viết một service Go để bạn cứ thế chạy trên một server: shutdown, timeout, bộ nhớ và systemd, với một service tham chiếu chạy được đứng sau mọi đoạn code trong sách.

Mua trên Polar: $39 Mua một lần · v0.1.0 · tải ngay qua Polar sau khi thanh toán

Ảnh bìa Go on One VPS: Production Handbook
Kết quả của một lần chạy test thật, không phải ảnh dựng.

Dành cho ai

Bạn viết Go, và service chạy trên một máy Linux duy nhất dưới systemd. Có thể đó là một API kèm worker nền và SQLite, một bộ nhận webhook, hoặc công cụ nội bộ mà cả công ty đang dựa vào. Nó chạy ổn. Điều bạn muốn biết là chuyện gì xảy ra ở các biên: deploy lúc request còn đang xử lý dở, một client mãi không gửi xong header, một container thiếu bộ nhớ, một cú crash lúc 3 giờ sáng.

Đây không phải sách dạy Go. Nó giả định bạn đã biết ngôn ngữ và đã đưa thứ gì đó lên production. Nếu bạn đang tìm phần nhập môn về goroutine, mấy cuốn sách Go nổi tiếng là chỗ bắt đầu tốt hơn.

Trong sách có gì

Một cuốn 16 chương, khoảng 2,000 dòng, cùng một service tham chiếu nhỏ, là nguồn của mọi đoạn code Go trong sách. Một script kiểm tra từng khối trong 60 khối code có khớp với source đã test hay không, nên không có đoạn nào trong sách là snippet chưa ai chạy.

#Chương
1Cấu trúc dự án cho một service nhỏ
2Config từ biến môi trường: kiểm tra mọi thứ, lỗi thì dừng ngay
3Structured logging với log/slog mà không lộ secret
4Timeout của HTTP server
5Graceful shutdown
6Health và readiness khác nhau thế nào
7Context, hủy tác vụ và cách bắt goroutine leak
8Truy cập database với SQLite: WAL, một writer, migration
9Lỗi và panic
10Metrics và pprof, theo cách an toàn
11Viết test
12Build: binary tĩnh, build lặp lại ra kết quả y hệt
13systemd: unit, siết bảo mật, restart, stop
14Bộ nhớ: process Go làm gì khi bị ép
15Deploy bằng thư mục release
16Các bug production hay gặp, mỗi bug kèm một phép kiểm tra bắt được nó

Bạn còn có service tham chiếu (thư viện chuẩn cộng một driver SQLite), một công cụ tạo tải, một thí nghiệm nhỏ về bộ nhớ, systemd unit và Dockerfile, ba checklist, và một harness Docker chạy lại mọi phép kiểm tra từ container sạch. Kết quả lần chạy đầy đủ gần nhất cũng có sẵn để bạn so.

Test cho thấy gì

Các chương về shutdown và systemd có test đi kèm: test khởi động binary thật và gửi signal thật.

Việc đã làmKết quả
SIGTERM khi một job 1.5 s đang chạy dởKết nối mới bị từ chối sau 11 ms, request đang xử lý xong sau 1.399 s, process thoát với code 0 sau 1.669 s
SIGTERM gửi tới service đang rảnhThoát sau 2 ms
SIGTERM khi có job 9 s và giới hạn shutdown 500 msThoát sau 515 ms với code 1, job được trả lại queue
Client gửi header chậm, header timeout 300 msKết nối bị cắt sau 295 ms
systemctl stop khi một request 3 s đang chạyRequest trả 200, lệnh stop mất 3.19 s
kill -9 dưới systemdKhỏe lại sau 2.10 s
Hai lần build từ hai thư mục khác nhauBinary giống nhau từng byte (và khác nhau khi bỏ -trimpath, làm đối chứng)

systemd unit đi kèm các tùy chọn siết bảo mật, và chúng tôi đọc kết quả ngược lại từ process đang chạy thay vì tin vào file: không có capability nào, có bộ lọc seccomp, /usr và /etc chỉ đọc, có giới hạn bộ nhớ. systemd-analyze security chấm unit này 1.4 điểm mức độ phơi nhiễm.

Thông lượng và bộ nhớ

Cách đo: Docker Desktop trên laptop Apple Silicon, 8 CPU, service, công cụ tạo tải và database nằm trong một container, 16 client, ba lần chạy 8 giây cho mỗi chế độ.

Chế độRequest mỗi giây (3 lần chạy)
Ghi9,190 đến 11,189 (p99 từ 8.4 đến 11.7 ms)
Đọc13,541 đến 18,421
Endpoint health23,032 đến 26,757

Bộ nhớ resident là 13 MiB lúc rảnh và 23 MiB sau khi chạy tải, đỉnh là 25 MiB.

GOMEMLIMIT, có số đo

Chương 14 không dừng ở câu "hãy đặt GOMEMLIMIT". Nó chạy một chương trình nhỏ có heap sống 40 MiB trong container bị giới hạn 80 MiB. Không đặt giới hạn thì bị OOM kill cả 3 trong 3 lần chạy. Đặt GOMEMLIMIT=56MiB thì sống sót 3 trong 3 lần, với cái giá là số lần garbage collection tăng khoảng gấp bốn. Sách cũng giải thích vì sao giới hạn này là giới hạn mềm và điều đó ảnh hưởng thế nào đến cách chọn kích thước.

Yêu cầu và định dạng

Go 1.24 trở lên. Chỉ cần Docker nếu bạn muốn chạy lại harness. Mọi thứ là Markdown, source Go, shell và file config: không khóa PDF, không cần tài khoản, đọc ở đâu cũng được.

Câu hỏi hay gặp

Đây có phải sách cho người mới không?

Không. Sách giả định bạn đã viết Go. Nội dung xoay quanh phía production: process làm gì khi có chuyện.

Có nói về Postgres không?

Service tham chiếu và các test của nó dùng SQLite. Chương về database cũng có hướng dẫn cho Postgres.

Nó khác gì Go Webhook Receiver Starter?

Starter là một sản phẩm nhỏ để bạn chạy. Sổ tay này là phần lập luận và test đằng sau một service Go cư xử đàng hoàng, dùng một service tham chiếu khác.

Tôi dùng code trong dự án của mình được không?

Được, trong dự án của bạn và trên server của bạn hoặc của công ty bạn. Xin đừng bán lại hay phân phối lại cuốn sách hoặc bộ kit.

Lịch sử thay đổi

  • 0.1.0: bản đầu tiên.

Bài liên quan

Mua sản phẩm này

Mua trên Polar: $39

Polar lo thanh toán, thuế và hóa đơn (họ là merchant of record). Thanh toán xong bạn nhận link tải ngay.