Boundary-Blind Integration
Failure Pattern của Invisible Boundaries và Cascading Failure
Summary
Boundary-Blind Integration là Failure Pattern trong đó
tích hợp tiến hành mà không làm rõ ràng boundaries
với external systems, other teams, asynchronous processing, v.v.,
và tác động của các thất bại và thay đổi mở rộng một cách dạng tầng.
Điều mà Pattern này đề cập không phải là tính thích hợp của distribution hoặc integration bản thân.
Đúng hơn, nó miêu tả một cấu trúc trong đó, trong quá trình tiến hành tích hợp,
các lựa chọn không cân nhắc có ý thức boundaries tích lũy một cách hợp lý,
và kết quả là, "responsibility của chúng ta đến đâu" không thể được đánh giá.
Context
Software hiện đại
hiếm khi đứng hoàn chỉnh như một hệ thống đơn lẻ.
External APIs, SaaS, services được quản lý bởi các teams khác trong công ty,
asynchronous jobs, event-driven processing, v.v.—
các chức năng giữ qua nhiều boundaries.
Những tích hợp này trông đơn giản ở giai đoạn ban đầu
và thường được xử lý với cùng cảm giác như internal calls.
Tuy nhiên, khi mở rộng mà không làm rõ ràng boundary conditions,
hành vi của hệ thống như một tổng thể trở nên khó nắm bắt.
Forces
Các động lực chính tạo ra Pattern này như sau:
-
Ease of integration
Thông qua phát triển SDKs và libraries,
kết nối với bên ngoài trở nên dễ dàng như triển khai nội bộ. -
Expansion of success experience
Từ kinh nghiệm của tích hợp đầu tiên hoạt động mà không có vấn đề,
tích hợp tăng lên mà không xem xét lại boundary conditions. -
Ambiguity of responsibility boundaries
Khi các thất bại và delays xảy ra,
khó đánh giá responsibility của chính mình đến đâu. -
Invisibility of asynchronous/distributed processing
Thứ tự và thất bại của processing không nổi lên dễ dàng,
và các vấn đề biểu hiện với delay.
Failure Mode
Khi boundaries không được làm rõ ràng,
trở nên khó để giới hạn và nắm bắt phạm vi tác động của các thất bại và thay đổi.
Kết quả là, các dạng hỏng sau đây tiến hành đồng thời:
-
Partial failures không được coi như các giả định
Timeouts và temporary failures được xử lý như exceptions
và không được tích hợp vào thiết kế happy-path. -
Separation of responsibility trở nên khó khăn
Khi các vấn đề xảy ra, nguyên nhân dao động trên boundary,
làm cho khó xác định điểm khởi đầu cho phản ứng. -
Observation paths bị chôn vùi trong các yếu tố bên ngoài
Logs và metrics bị phân mảnh qua các boundaries,
làm cho khó theo dõi các mối quan hệ nhân quả của các thất bại.
Consequences
-
Failure response trở nên không liên tục và load có xu hướng tích lũy
(Part I: What Breaks — Operation / Time) -
Phạm vi tác động change trở nên khó giải thích, và các quyết định nghiêng về thận trọng
(Part I: What Breaks — Boundary / Responsibility) -
Operational costs tăng và improvement có xu hướng bị hoãn lại
(Part II: Why It Breaks — Measurement Gap) -
Các quyết định về distributed configurations nghiêng về chủ nghĩa bảo thủ, và các design choices có xu hướng trở nên cố định
(Part II: Why It Breaks — Decision Avoidance)
Countermeasures
Sau đây không phải là danh sách các giải pháp,
mà là các counter-patterns để coi boundaries như các design decisions chống lại Failure Mode.
-
Định nghĩa boundaries như các điểm phân nhánh của responsibility và assumptions
Làm cho boundaries rõ ràng như các điểm mà các quyết định thay đổi, không phải là chi tiết triển khai. -
Định vị partial failures như các trường hợp bình thường
Coi các thất bại và delays không phải như exceptions, mà là các giả định được dệt vào thiết kế. -
Có các cấu trúc ngăn chặn các quyết định vượt qua boundaries
Áp dụng các thiết kế ngăn processing hoặc các quyết định lan truyền mà không giới hạn trong các thất bại, vì vậy chúng không vượt qua boundaries.
Resulting Context
Integration vẫn cần thiết,
và trả lại mọi thứ về một hệ thống đơn lẻ không thực tế.
Tuy nhiên, bằng cách làm cho boundaries hiển thị,
các thất bại được cục bộ hóa và phạm vi tác động có thể được giới hạn.
Ví dụ, trong các external API failures, có thể chọn tại boundary liệu tiếp tục hay dừng internal processing,
và trong asynchronous processing, có thể thiết kế hành vi cục bộ dựa trên giả định của delay hoặc omission.
Kết quả là, distribution và integration
được coi như các design decisions có thể kiểm soát
và được tái tạo như các cấu trúc có thể chịu được change và operations.
See also
-
Retry-as-Recovery
Một derived pattern trong đó các thất bại trên boundaries được coi như được khôi phục bởi re-execution, mà không được cục bộ hóa. -
Test-Passing Illusion
Một cấu trúc trong đó các giả định distributed/asynchronous không xuất hiện trong verification environments, và thành công hạn chế trở thành một chỉ số proxy của correctness.
Appendix: Conceptual References
- Information Hiding & Boundaries
Theoretical background của các cấu trúc trong đó các thất bại và quyết định rò rỉ qua boundaries. - Systems Thinking & Constraints
Background của các động lực trong đó các local integration decisions bóp méo overall behavior. - Responsibility & Decision
Organizational background trong đó ai thực hiện các quyết định trong các thất bại trở nên không rõ ràng.
Appendix: References
- David L. Parnas, On the Criteria To Be Used in Decomposing Systems into Modules, 1972.
- Fred Brooks, No Silver Bullet—Essence and Accidents of Software Engineering, 1987.
- Donella H. Meadows, Thinking in Systems: A Primer, 2008.
- James O. Coplien, Neil B. Harrison, Organizational Patterns of Agile Software Development, 2004.