Bỏ qua tới nội dung
Kiên

Bài học rút ra

Những điều mình rút ra khi làm và vận hành hệ thống thật — mỗi bài là một vấn đề có thật, cái giá phải trả, và thứ mình đã đổi.

· 4 phút đọc

Hai bộ điều phối cùng quản một workload mà chẳng bên nào biết bên kia tồn tại. Cái mức concurrency không ai chọn, cái memory limit thuộc về cgroup chứ không thuộc về worker, và một vòng crash loop nấp trong một pod vẫn báo là khoẻ — và vì sao cách chữa là chọn đúng một tầng cho nó nhân lên.

  • Kubernetes
  • Node.js
  • PM2
  • vận hành

· 4 phút đọc

Một ticket support: tìm khách sạn ở một điểm đến thì không ra gì, các vùng xung quanh vẫn bình thường. Không có gì sập cả — điểm đến đó tồn tại hai lần trong dữ liệu mapping, và khách sạn treo ở row còn lại. Cách chữa sau đó thành một lệnh runbook, bắt buộc phải đếm được kết quả rồi mới được nói "xong".

  • chất lượng dữ liệu
  • debugging
  • observability
  • runbook

· 5 phút đọc

Hai team, hai công ty, khoảng 40 slash command cho AI. Thứ thay đổi không phải là chuyện tự động hoá — mà là runbook và cái tool chạy nó cuối cùng đã thành cùng một file, và mọi lệnh nguy hiểm đều phải tự khai báo.

  • AI tooling
  • Claude Code
  • developer experience
  • tài liệu

· 4 phút đọc

Lệnh đặt phòng timeout ở phía client nhưng đã thành công ở phía trên. Client retry — hoàn toàn hợp lý, vì từ phía nó chẳng có gì trả về — và supplier bây giờ đang giữ hai booking cho cùng một khách. Vì sao transaction không cứu được, vì sao HTTP verb không nói gì về chuyện này, và cái gì mới thật sự đỡ được.

  • tích hợp
  • reliability
  • hệ phân tán
  • backend

· 5 phút đọc

Mình tách "quăng lỗi vào phòng chat" ra khỏi hơn chục service thành một package publish lên npm. Phần đáng nói không phải là mười lăm kênh — mà là lúc nhận ra việc của thư viện này là quyết định cái gì được phép rời khỏi process.

  • Node.js
  • observability
  • bảo mật
  • thiết kế thư viện

· 3 phút đọc

Search hotel, flight và car chạy bất đồng bộ — queue, mỗi supplier một job, progress fraction, deadline 30 giây. Tour và transfer trả lời đồng bộ trong một process duy nhất. Cùng một contract API công khai phủ lên cả hai, và bài học là vì sao nó buộc phải giữ nguyên như thế.

  • thiết kế api
  • kiến trúc
  • async

· 3 phút đọc

Cùng một integration supplier được bán lại dưới nhiều brand code — riêng mảng hotel là 75 code chạy trên 31 module. Nước đi cám dỗ là copy module theo từng brand; cái bọn mình chạy thay vào đó là alias đăng ký theo code cộng một bảng settings thưa, kèm đúng cái failure mode mà lựa chọn này mua về.

  • config
  • white-label
  • supplier
  • dữ liệu

· 4 phút đọc

Audit đường search của engine khách sạn: vì sao worker cứ bị PM2 restart ở mốc 3GB, vì sao event loop đứng 6–20 giây mỗi job, và ba thay đổi kéo Redis từ 1,2GB xuống còn 150–250MB mỗi lượt tìm.

  • Node.js
  • Redis
  • hiệu năng
  • event loop

· 4 phút đọc

Một cái key nói rằng hai request này xứng đáng nhận cùng một câu trả lời, và mọi field bị bỏ ra ngoài key đều đang khẳng định rằng field đó không làm đổi kết quả. Trong gom supplier thì tenant, tập supplier và markup của nó đều làm đổi kết quả — nên một cái key dựng từ mỗi tham số tìm kiếm của khách sẽ trả giá của tenant này cho tenant khác, mà chẳng có lỗi nào bắn ra.

  • Redis
  • cache
  • kiến trúc
  • supplier

· 3 phút đọc

mysql client chuẩn không vào được database của gateway, nên có một dạo mỗi câu query là một màn xoay xở nho nhỏ. Rồi một script query duy nhất thành tool chuẩn — và phần đáng nói là những gì được xây thẳng vào trong nó: SELECT chạy ngay, còn lệnh write thì in hostname và cờ read_only ra trước, bắt confirm rồi mới chạy.

  • tooling
  • database
  • guardrail
  • vận hành

· 3 phút đọc

Một phần lớn API supplier vẫn nói SOAP/XML, và một response search có thể chở hàng nghìn tổ hợp giá. Ở cỡ đó, chọn parser thôi không còn là chuyện khẩu vị — một mapping XML→JSON khai báo đặt cạnh một cú DOM walk dựng nguyên cả cây vào bộ nhớ, và vì sao cái template thắng hết review này tới review khác.

  • xml
  • parsing
  • supplier
  • node.js

· 4 phút đọc

Du lịch chạy trên ngày dân sự ở địa phương, không phải trên mốc thời gian tuyệt đối. Check-in là một cái ngày tại khách sạn; giờ bay là giờ địa phương ở sân bay đi; hạn huỷ là một thời điểm địa phương phía supplier. Lưu bất kỳ cái nào trong đó thành instant UTC thì sớm muộn cũng có chỗ hiển thị sớm hoặc trễ một ngày — với vài người dùng, vào vài ngày nhất định, nên nó sống sót qua review.

  • ngày giờ
  • correctness
  • backend
  • tích hợp

· 3 phút đọc

Bên bảo hiểm xác nhận cấp hợp đồng theo kiểu bất đồng bộ. Callback là đường nhanh — và cũng là đường có thể mất, đến hai lần, hoặc đến trước khi transaction của chính mình kịp hiển thị. Cái poll định kỳ không phải phương án dự phòng; nó mới là câu trả lời thật. Callback chỉ làm câu trả lời đến sớm hơn.

  • integration
  • reliability
  • hệ phân tán
  • backend

Mỗi derived store là một món nợ

+1 store · sync từ 2022

· 4 phút đọc

Một graph store cho danh tính khách sạn và một search index cho reporting đều xứng đáng có mặt — transactional store thật sự không trả lời nổi những câu query đó. Nhưng mỗi cái là một bản sao, và một bản sao là một món nợ consistency với lịch trả nợ mà bạn ký ngay ngày thêm nó vào.

  • kiến trúc
  • neo4j
  • consistency
  • dữ liệu

· 3 phút đọc

Bảo hiểm trễ chuyến gắn vào đơn vé máy bay: các row bảo hiểm, các chặng bay và tổng tiền đơn hàng phải kể cùng một câu chuyện, mà chúng nằm ở ba service thuộc ba code path khác nhau. Từng service đều nhất quán nội bộ. Chỗ lệch chỉ tồn tại ở phép join — thứ không ai sở hữu, cho tới khi mình viết ra cái tính nó.

  • nhất quán dữ liệu
  • microservices
  • đối soát
  • backend

· 4 phút đọc

Lưu giá thành số nguyên theo đơn vị nhỏ nhất thì làm một buổi là xong. Cái tốn kém là quyết định làm tròn xảy ra ở đâu và bao nhiêu lần — markup áp từng phòng rồi cộng lại không bằng markup áp lên tổng rồi làm tròn một lần, và khách có thể đọc được một cái tổng không khớp với mấy dòng ngay phía trên.

  • tiền
  • pricing
  • correctness
  • backend

· 4 phút đọc

Một đơn phê duyệt lên cấp đúng y như thiết kế, và người duyệt ở cấp kế tiếp không hề hay biết — không mail, không chuông. State machine đúng. Dispatch notification kiểu fail-soft cũng đúng. Cái hỏng nằm ở khe hở giữa hai thiết kế đúng: "không được chặn" đã lặng lẽ phình thành "không cần báo là nó đã fail".

  • workflow engine
  • notification
  • testing
  • backend

Sandbox không phải là supplier

cert xanh · prod khác

· 3 phút đọc

Môi trường test của supplier chạy hết bộ certification đều xanh, còn prod thì hành xử khác — kho phòng không bao giờ hết, lỗi không có trong tài liệu, rate limit chỉ tồn tại ở một bên, và độ trễ mà bạn không thể lấy làm căn cứ chỉnh timeout. Certification thật ra chứng minh cái gì, và mấy booking prod đầu tiên dùng để làm gì.

  • tích hợp
  • testing
  • supplier
  • vận hành

· 3 phút đọc

Hai dải mạng phải cùng vào được một lúc — staging và production. Sau một lần đổi mạng, route có thể bind nhầm interface, mà triệu chứng thì không phân biệt nổi với sai credentials, host chết, hay DNS. Thứ chữa được những buổi chiều ngồi đoán không phải một câu lệnh, mà là một thứ tự: route, port, handshake, auth — mỗi câu trả lời loại được nguyên một tầng.

  • networking
  • debugging
  • chẩn đoán
  • tooling

Cái report cãi nhau với database

1 con số · 2 câu query

· 3 phút đọc

Một report tháng và câu query vận hành trả ra hai con số khác nhau cho cùng một chỉ số kinh doanh, và bên nào cũng đúng theo cách của mình. Vấn đề không bao giờ nằm ở phép cộng — nó nằm ở chỗ một định nghĩa có tới hai bản cài đặt, và không ai làm chủ bản nào cả.

  • chất lượng dữ liệu
  • reporting
  • ownership
  • sql

Đang hiện 10/20