Xử lý ngoại lệ trong một chương trình cần chạy 24/7


14

Tôi đã đọc rằng chúng ta chỉ nên nắm bắt các ngoại lệ có thể được xử lý, điều này làm cho việc bắt lớp ngoại lệ cơ sở (C # trong trường hợp này) là một ý tưởng tồi (trên hết các lý do khác). Tôi hiện đang là một phần của một dự án mà cho đến nay tôi vẫn chưa thấy gì ngoại trừ cơ sở bị bắt. Tôi đã đề cập rằng nó được coi là thực hành xấu để làm như vậy, nhưng câu trả lời là "Dịch vụ này cần chạy 24/7, vì vậy đó là như vậy."

Vì tôi không có phản hồi tốt về cách xử lý đúng các trường hợp ngoại lệ trong chương trình cần chạy 24/7, giờ tôi đã ở đây. Tôi đã không quản lý để tìm thấy bất kỳ thông tin / đề xuất nào về cách xử lý ngoại lệ trong các chương trình / dịch vụ "quan trọng" cần chạy suốt ngày đêm (và trong trường hợp này tôi tin rằng có thể ổn nếu dịch vụ ngừng hoạt động trong một phút hoặc hai, vì vậy thậm chí không quan trọng). Tôi hiểu nó phụ thuộc vào bản chất chính xác của chương trình. Các yêu cầu cho một chương trình có thể gây ra các vấn đề đe dọa tính mạng khá khác biệt so với trình quét nhật ký cho một trò chơi trực tuyến.

Hai ví dụ:

1: Dịch vụ chuyển tiếp dành cho khách hàng của đường sắt Brittish, được sử dụng khi họ tìm kiếm trực tuyến các nhà ga.

2: Một chương trình tự động điều khiển các công tắc đường sắt cho các tuyến đường sắt trên dựa trên thông tin thời gian thực được cung cấp từ các cảm biến khác nhau trong đường ray, xe lửa, v.v.

Chương trình đầu tiên có thể sẽ không gây ra vấn đề lớn nếu nó bị hỏng trong một hoặc hai phút, vì cái sau có thể gây thương vong cho con người. Gợi ý về cách đối phó với từng? Con trỏ đến nơi tôi có thể tìm thêm thông tin và suy nghĩ về vấn đề này?


2
Ngăn xếp thư giãn trong quá trình xử lý ngoại lệ trong ứng dụng thời gian thực (sic!) Có thể phá hỏng tàu.
Deer Hunter

4
@DeerHunter Mã hóa xấu mà không có ngoại lệ, có thể có kết quả tương tự.
Bовић

9
Được rồi, vậy bạn catch Exception. Điều đó không có nghĩa là chương trình của bạn hoạt động , điều đó có nghĩa là thất bại cho phép trạng thái ứng dụng bị hỏng trong khi nó tiếp tục thực thi, một nơi nguy hiểm hơn rất nhiều. Một chương trình bị lỗi có thể là thảm họa, nhưng một chương trình ở trạng thái không hợp lệ nhưng vẫn thực hiện các hành động có thể là thảm họa tích cực .
Phoshi

1
Nếu ứng dụng cần chạy 24/7, có một vòng lặp vô hạn ở đâu đó và vòng lặp vô hạn này tốt hơn nên được bao bọc xung quanh một số cấu trúc để nắm bắt tất cả các ngoại lệ chưa được xử lý. Nếu đó không phải là trường hợp, một ngoại lệ chưa được xử lý sẽ thấm vào bộ xử lý bắt tất cả đã tồn tại bên ngoài chính và kaboom! ứng dụng 24/7 chấm dứt.
David Hammen

Câu trả lời:


7

Một số tính năng ngôn ngữ như

  • Thu gom rác thải
  • Hệ thống ngoại lệ
  • Đánh giá lười biếng

thường không hữu ích trong một hệ thống thời gian thực. Có lẽ người ta nên chọn một ngôn ngữ không có các tính năng này và cố gắng chứng minh các thuộc tính nhất định như sử dụng bộ nhớ tối đa hoặc thời gian phản hồi tối đa.


Khi một chương trình cần chạy liên tục, nhưng những thất bại ngắn và không toàn cầu đều được chấp nhận, thì chúng ta có thể sử dụng chiến lược giống như Erlang. Erlang là một ngôn ngữ lập trình chức năng đồng thời. Thông thường, một chương trình được viết bằng Erlang sẽ bao gồm nhiều quy trình worker có thể giao tiếp với nhau (mô hình diễn viên). Nếu một luồng công nhân gặp một ngoại lệ, nó được bắt đầu lại. Trong khi điều này không có nghĩa là thời gian chết ngắn, các diễn viên khác có thể tiếp tục như bình thường.

Để tóm tắt điều này: Trong một chương trình mạnh mẽ, các phần khác nhau được cách ly với nhau và có thể được khởi động lại hoặc thu nhỏ độc lập.

Vì vậy, về cơ bản chúng ta cần một đoạn mã tương đương với điều này:

while (true) {
  try {
    DoWork();
  }
  catch (Exception e) {
    log(e);
  }
}

cộng với một cách để chấm dứt vòng lặp. Một vòng lặp như vậy sau đó sẽ lái mỗi luồng công nhân.


Một vấn đề với việc bỏ qua lỗi thông qua một lỗi tất cả là các bất biến của chương trình của bạn có thể đã bị vi phạm do nguyên nhân lỗi và các hoạt động tiếp theo có thể là vô ích. Một giải pháp tốt cho vấn đề này là không chia sẻ dữ liệu giữa các công nhân độc lập. Khởi động lại một công nhân sẽ xây dựng lại tất cả các bất biến cần thiết. Điều này có nghĩa là họ phải giao tiếp khác nhau, ví dụ thông qua tin nhắn gửi. Trạng thái của một diễn viên có thể không phải là một phần của bất biến của các diễn viên khác.

Một vấn đề khác với việc bắt quá nhiều ngoại lệ là không phải tất cả các ngoại lệ đều có thể sửa được bằng cách khởi động lại, ngay cả khi thực hiện các biện pháp phòng ngừa như vậy. Mặt khác, các vấn đề khó khăn như hết bộ nhớ có thể được xử lý bằng cách khởi động lại. Nhưng khởi động lại sẽ không giúp bạn lấy lại kết nối internet khi rút cáp vật lý.


1
Có, nhưng tình huống như "cáp vật lý đã được rút ra" chính xác là khi bạn chỉ muốn nhật ký ngoại lệ được lấp đầy cho đến khi ai đó đặt lại cáp, sau đó mọi thứ bắt đầu hoạt động trở lại, với việc khởi động lại ứng dụng bằng tay.
Đánh dấu

2

Để trả lời câu hỏi của bạn, người ta phải hiểu ngoại lệ là gì và cách chúng hoạt động.

Các ngoại lệ thường được đưa ra khi xảy ra lỗi như vậy, trong đó cần có sự trợ giúp của người dùng. Trong những trường hợp như vậy, không cần thiết phải mất bao lâu để thư giãn ngăn xếp và xử lý ngoại lệ.

Không có trình xử lý bắt, chương trình dừng thực thi. Tùy thuộc vào thiết lập và yêu cầu của bạn, nó có thể được chấp nhận.

Trong trường hợp cụ thể của bạn:

  1. nếu truy vấn không thể được thực thi (ví dụ, tên thành phố sai), sau đó thông báo cho người dùng về lỗi và yêu cầu sửa nó.
  2. nếu bạn không nhận được thông tin từ một cảm biến quan trọng, sẽ không có ý nghĩa gì khi tiếp tục mà không yêu cầu nhà điều hành khắc phục sự cố.

Điều đó có nghĩa là trong cả hai trường hợp, có thể có ý nghĩa khi sử dụng các ngoại lệ, với sự cẩn thận hơn trong chương trình RT để chỉ ra các vấn đề nghiêm trọng khi không thể tiếp tục thực hiện.


1

Tôi cho đến nay vẫn chưa thấy gì ngoại trừ cơ sở bị bắt.

Có vẻ như có một vấn đề ở đây, nhiều như trường hợp ngoại lệ không được xử lý thích hợp. Nắm bắt các ngoại lệ tại điểm thích hợp và thực hiện hành động thích hợp (tùy thuộc vào loại ngoại lệ) sẽ giữ cho dịch vụ hoạt động theo cách đáng tin cậy hơn nhiều.

Nếu dịch vụ phải tiếp tục, có lẽ điều quan trọng là nó hoạt động như dự định. Lấy ví dụ của bạn, nếu một chương trình điều khiển chuyển mạch đường sắt ném một ngoại lệ, nó có thể chỉ ra rằng có vấn đề khi giao tiếp với các cảm biến liên quan đến an toàn. Nếu bạn bắt ngoại lệ cơ sở và tiếp tục dịch vụ có thể chạy, nhưng có thể không hoạt động như dự định dẫn đến thảm họa.

Ngoài ra, nếu bạn bắt gặp ngoại lệ bị ném khi có lỗi giao tiếp với cảm biến và xử lý nó một cách thích hợp (tức là dừng các chuyến tàu trong khu vực bị ảnh hưởng), dịch vụ của bạn đang chạy và bạn chưa giết ai.

Vì vậy, khi tôi hiểu câu hỏi, tôi đề nghị rằng trong trường hợp đầu tiên, bạn nên tìm cách thêm xử lý ngoại lệ cụ thể hơn là loại bỏ các trình xử lý loại ngoại lệ cơ sở.


0

Liên quan đến điểm 2: không sử dụng C #. Đó không phải là ngôn ngữ thời gian thực và bạn sẽ bị tổn thương nếu bạn cố gắng sử dụng nó như vậy.

Đối với điểm 1: bạn có thể đi theo cách erlang: hãy để nó gặp sự cố, sau đó khởi động lại


Cách sử dụng và chuyên môn C # của tôi không nằm ở điểm 2 (chuyển đổi theo dõi thời gian thực). Tôi tò mò tại sao C # không phù hợp cho một nhiệm vụ như vậy?
Michael O'Neill

1
Chủ yếu là: người thu gom rác thực hiện chương trình, liên quan đến thời gian, không thể đoán trước. Ngoài ra, thời gian chạy quá phức tạp và trong những bối cảnh đó bạn cần những thứ đơn giản, chúng dễ đoán hơn
miniBill

0

Tuyên bố: đây chỉ là những suy nghĩ, tôi chưa có kinh nghiệm.

Tôi đoán rằng một chương trình, đáp ứng các yêu cầu của ví dụ thứ hai nên cực kỳ mô-đun . Do đó, các mô-đun sẽ có khả năng được khởi động lại, mà không làm mất ổn định hệ thống.

Ví dụ, một đối tượng, không khẳng định trạng thái bên trong, có thể bị phá hủy và tạo lại, thông báo trong quá trình tất cả người tiêu dùng và nhà cung cấp của nó. Cụ thể hơn, nếu chương trình đang điều khiển các công tắc của đường sắt và không khẳng định được trong vòng quyết định, nó vẫn có thể chạy mô-đun khẩn cấp, dừng tất cả các đoàn tàu liên quan và chờ mô-đun quyết định chính khởi tạo lại.

Thực tế hơn, người ta sẽ giới thiệu dự phòng - sao chép phần cứng và phần mềm. Một phiên bản được nối với hệ thống được kiểm soát và phiên bản khác là chạy miễn phí. Nếu một lỗi được phát hiện, các hệ thống được chuyển đổi.

Một ví dụ là hai quá trình trên cùng một máy, theo dõi lẫn nhau và nếu một quá trình bị giết, thì quá trình kia sẽ sinh ra nó và tách rời nó ra khỏi bộ cha mẹ của nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.