What we learned from an iOS app OOMs incident
Bài tóm tắt Pinterest 2021 3. Quy mô lớn Độ khó: Trung bình
Pinterest · 2021 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc
Bối cảnh
- Đầu 2020: crash out-of-memory trên app iOS tăng mạnh; tỉ lệ người dùng không gặp crash (CFUR) giảm từ 99% xuống 96%.
- App gọi REST API qua
NSURLSession; phần lớn endpoint đã chạy HTTP/2 nhiều năm, vài endpoint còn sót. Khi bật HTTP/2 cho một số endpoint đó, OOM tăng khoảng 20 lần.
Thay đổi chính
- Mất vài tháng mới nối OOM với HTTP/2 rồi thu hẹp về một lỗi HTTP chung trong code (loại trừ nhiều nghi phạm trùng thời điểm).
- Endpoint test nhân bản: dựng một endpoint riêng cho HTTP/2, điều khiển client nào gọi nó qua một thí nghiệm; sau này dùng nó cho các bản app đã vá dùng HTTP/2 trước, rồi mới bật lại HTTP/2 trên endpoint gốc (gần một năm sau).
- Log có ngữ cảnh: ghi metadata bộ nhớ (tổng, còn trống, footprint, đỉnh) và metric mạng (latency, mã lỗi, kích thước payload) cùng các event sẵn có, thấy được bộ nhớ tích luỹ và vọt lên quanh lúc chuyển foreground/background hay timeout mạng bất thường. Công cụ memory graph của Xcode thu hẹp tới đúng đoạn code; Apple gợi ý một lỗi đã biết (header quá lớn gây vòng lặp tốn bộ nhớ), dẫn hướng xuống lớp mạng.
- Nguyên nhân: dùng
HTTPBodyStreammà không cài delegateneedNewBodyStream. Bình thường vẫn chạy; khi gặp challenge xác thực hay lỗi server phục hồi được (timeout) và luôn luôn khi gặp redirect HTTP, request rơi vào vòng gửi lại tốn bộ nhớ, rò hàng GB trong một phút. Chỉ vài endpoint bị vì chúng dùng stream sai, được gọi nhiều và chạy cả ở background. - Sửa: gửi body trực tiếp khi được, hoặc cài delegate đúng cách; kiểm trên các tổ hợp.
Vì sao
- Một thay đổi phía server (bật HTTP/2) làm lộ lỗi tiềm ẩn ở client; tài liệu API không nói hệ quả của việc thiếu delegate.
Bài học cho SWE
- Thay đổi giao thức ở server cần được rollout như thay đổi client: qua thí nghiệm, có endpoint tách riêng để quay lại và thử bản vá.
- Ghi metric tài nguyên kèm ngữ cảnh mạng/vòng đời app mới thấy được mẫu dẫn tới crash.
- OOM nên được tính vào điểm ổn định của app.
Liên quan
#Incident#iOS#OOM#HTTP/2#NSURLSession#HTTPBodyStream#Redirect#Crash-free users#Experiment#Contextual logging
Được nhắc tới trong
Chủ đề (1)
Công ty (1)