Thư viện Haskell tốt nhất để vận hành một chương trình là gì? [đóng cửa]


115

Nếu tôi định đưa một chương trình vào sản xuất, có một số điều tôi cần chương trình đó làm để coi nó đã "hoạt động" - nghĩa là, cả kỹ sư và nhân viên vận hành đang chạy và bảo trì theo cách có thể đo lường và kiểm chứng được. Đối với mục đích của tôi, một chương trình đã hoạt động phải:

  • Có thể đăng nhập ở nhiều cấp độ (ví dụ: gỡ lỗi, cảnh báo, v.v.).
  • Có thể thu thập và chia sẻ các số liệu / thống kê về các loại công việc mà chương trình đang thực hiện và thời gian thực hiện công việc đó. Lý tưởng nhất là các chỉ số được thu thập có sẵn ở định dạng tương thích với các công cụ giám sát thường được sử dụng như Ganglia hoặc có thể được trộn lẫn như vậy.
  • Có thể định cấu hình, lý tưởng nhất là thông qua một hệ thống cho phép cập nhật các thuộc tính đã cấu hình trong các chương trình đang chạy mà không cần khởi động lại các chương trình đã nói.
  • Có thể triển khai tới các máy chủ từ xa theo cách có thể lặp lại.

Trong thế giới Scala, có những thư viện tốt để xử lý ít nhất ba yêu cầu đầu tiên. Ví dụ:

Đối với việc triển khai, một cách tiếp cận được thực hiện trong thế giới Scala là kết hợp mã bytecode và các thư viện bao gồm chương trình của một người với một cái gì đó như assembly-sbt , sau đó đẩy gói kết quả (một "fat JAR") đến các máy chủ từ xa bằng một công cụ như Capistrano thực thi các lệnh song song trên SSH. Đây không phải là vấn đề cần đến các công cụ dành riêng cho ngôn ngữ, nhưng tôi tò mò liệu một công cụ như vậy có tồn tại trong cộng đồng Haskell hay không.

Có lẽ có các thư viện Haskell cung cấp các đặc điểm mà tôi đã mô tả ở trên. Tôi muốn biết thư viện có sẵn nào được coi là "tốt nhất"; nghĩa là, những thứ đã trưởng thành nhất, được duy trì tốt, thường được sử dụng trong cộng đồng Haskell và là mẫu mực của các phương pháp hay nhất của Haskell.

Nếu có bất kỳ thư viện, công cụ hoặc thực hành nào khác xung quanh việc tạo mã Haskell "sẵn sàng sản xuất", tôi cũng muốn biết về những điều đó.


1
Dấu đầu dòng thứ tư có thể gây ra rắc rối, vì Haskell được biên dịch thành bản địa chỉ. Bạn có thể thử biên dịch tĩnh, cách này có thể hoạt động hoặc có thể không hoạt động, nhưng tối ưu là bạn có môi trường tương tự trên máy chủ sản xuất, hơn là trên máy chủ phát triển. Cabal-dev là môi trường hộp cát, có thể phù hợp để chuyển sang các máy khác. Thậm chí sau đó nó sẽ yêu cầu ít nhất các thư viện cơ sở phải được cài đặt trên máy đích.
Masse

1
Về công cụ và các kỹ thuật khác, câu hỏi SO này có một cái nhìn tổng quan: stackoverflow.com/questions/3077866/...
Don Stewart

1
Một điều khác - bạn có thể truy cập trên hệ thống * nix một lượng lớn các thống kê quy trình và siêu dữ liệu trực tiếp thông qua hệ thống tệp / proc. Vì vậy, nếu bạn viết một vài quy trình để hiểu rõ điều đó, nó sẽ giúp thay thế cho việc thiếu móc trực tiếp vào thời gian chạy.
sclv

1
triển khai nhị phân dễ dàng miễn là bạn xây dựng trên cùng một môi trường (bạn nên có một máy chủ dàn nếu máy tính của bạn là một kiến ​​trúc khác). Sau đó, bạn có thể rsync tệp nhị phân và bất kỳ tệp bên ngoài nào. Không có thư viện ssh cho haskell để tự động thực hiện các lệnh khởi động lại, nhưng bạn có thể sử dụng capistrano.
Greg Weber

1
@tchrist Anh ấy dành phần còn lại của đoạn đầu tiên và danh sách có gạch đầu dòng ngay sau từ được vận hành giải thích nghĩa của nó bằng tiếng Anh đơn giản.
Will McCutchen

Câu trả lời:


54

Đây là một câu hỏi hay! Đây là phần đầu tiên.

Có thể đăng nhập ở nhiều cấp độ (ví dụ: gỡ lỗi, cảnh báo, v.v.).

hslogger dễ dàng là khung ghi nhật ký phổ biến nhất.

Có thể thu thập và chia sẻ các số liệu / thống kê về các loại công việc mà chương trình đang thực hiện và thời gian thực hiện công việc đó. Lý tưởng nhất là các chỉ số được thu thập có sẵn ở định dạng tương thích với các công cụ giám sát thường được sử dụng như Ganglia hoặc có thể được trộn lẫn như vậy.

Tuy nhiên, tôi không biết về bất kỳ công cụ báo cáo chuẩn hóa nào, trích xuất báo cáo từ +RTS -scác luồng (hoặc thông qua cờ đầu ra hồ sơ) là điều tôi đã làm trước đây.

$ ./A +RTS -s
64,952 bytes allocated in the heap
1 MB total memory in use
 %GC time       0.0%  (6.1% elapsed)
 Productivity 100.0% of total user, 0.0% of total elapsed

Bạn cũng có thể lấy nó ở định dạng máy có thể đọc được:

$ ./A +RTS -t --machine-readable

 [("bytes allocated", "64952")
 ,("num_GCs", "1")
 ,("average_bytes_used", "43784")
 ,("max_bytes_used", "43784")
 ,("num_byte_usage_samples", "1")
 ,("peak_megabytes_allocated", "1")
 ,("init_cpu_seconds", "0.00")
 ,("init_wall_seconds", "0.00")
 ,("mutator_cpu_seconds", "0.00")
 ,("mutator_wall_seconds", "0.00")
 ,("GC_cpu_seconds", "0.00")
 ,("GC_wall_seconds", "0.00")
 ]

Lý tưởng nhất là bạn có thể gắn vào thời gian chạy GHC đang chạy trên một ổ cắm và xem xét các thống kê GC này một cách tương tác, nhưng hiện tại điều đó không quá dễ dàng (cần một FFI liên kết với giao diện "rts / Stats.h"). Bạn có thể đính kèm vào một quy trình bằng cách sử dụng ThreadScopevà giám sát GC và hành vi phân luồng.

Các cờ tương tự có sẵn để lập hồ sơ không gianthời gian đã ghi gia tăng, có thể được sử dụng để theo dõi (ví dụ: các biểu đồ này có thể được xây dựng theo từng bước).

hpcthu thập rất nhiều số liệu thống kê về việc thực thi chương trình, thông qua Tixkiểu của nó và mọi người đã viết các công cụ để ghi nhật ký theo thời gian mã đang thực thi.

Có thể định cấu hình, lý tưởng nhất là thông qua một hệ thống cho phép cập nhật các thuộc tính đã cấu hình trong các chương trình đang chạy mà không cần khởi động lại các chương trình đã nói.

Một số công cụ có sẵn cho việc này, bạn có thể thực hiện tải lại trạng thái kiểu xmonad; hoặc chuyển lên mã hotswapping qua pluginscác gói * hoặc hint. Một số trong số này mang tính thử nghiệm hơn những cái khác.

Triển khai có thể lặp lại

Galois được phát hành gần đây cabal-dev, là một công cụ để thực hiện các bản dựng có thể tái tạo (tức là các phần phụ thuộc được xác định phạm vi và kiểm soát).


6
Gói dyre được cho là trừu tượng hóa quá trình tải lại trạng thái kiểu xmonad, vì vậy tôi nghĩ nên được đề cập cụ thể. Tuy nhiên, nó liên quan đến việc biên dịch lại và triển khai lại, vì vậy thực sự là về những thay đổi trên một máy với toàn bộ chuỗi công cụ. Đối với redeploys từ xa, bạn muốn một cái gì đó giống như trạng thái axit hơn, mặc dù nó hơi nặng đối với sở thích của tôi. Tôi đã có bản tóm tắt mvar dai dẳng này có sự đảm bảo yếu hơn, nhưng bạn có thể coi như một MVar thuần túy được điền một cách kỳ diệu vào mỗi lần khởi chạy tệp nhị phân với dữ liệu cuối cùng mà nó nắm giữ.
sclv

2
Ngoài ra, EventLogkhung ghi nhật ký mới của GHC (sử dụng +RTS -ltrong thời gian chạy) truyền dữ liệu xuất ra một tệp, tệp này có thể được trực quan hóa bằng bất kỳ công cụ nào đọc định dạng nhật ký sự kiện.
Don Stewart

2
Một chương trình sẽ phát ra nhật ký các sự kiện của nó, như sau: galois.com/~dons/tmp/A.event.log - có thể được hiển thị dưới dạng - i.imgur.com/QAe6r.png . Tôi có thể tưởng tượng việc xây dựng các công cụ giám sát khác trên định dạng này.
Don Stewart

2
Cũng lưu ý rằng rất nhiều công cụ tạo hồ sơ rất tốt để thử nghiệm nhưng không quá nhiều cho mã sản xuất. Bỏ chi phí sang một bên, chẳng hạn -prof chỉ có thể được sử dụng với một bộ xử lý duy nhất.
sclv

9
  • Về cấu hình, tôi thấy ConfigFile hữu ích cho các dự án của tôi. Tôi sử dụng nó cho tất cả các daemon của tôi trong quá trình sản xuất. Nó không tự động cập nhật.
  • Tôi sử dụng cabal-dev để tạo các bản dựng có thể tái tạo trên các môi trường (cục bộ, nhà phát triển, đồng nghiệp-cục bộ). Thực sự cabal-dev là không thể thiếu, đặc biệt là khả năng hỗ trợ các phiên bản thư viện cục bộ, được vá trong thư mục dự án.
  • Đối với những gì nó đáng giá, tôi sẽ tải lại trạng thái kiểu xmonad. Sự tinh khiết của Haskell làm cho điều này trở nên tầm thường; di cư là một vấn đề nhưng dù sao nó vẫn là như vậy. Tôi đã thử nghiệm với hsplugins và gợi ý cho IRCd của mình và trong trường hợp trước đây là sự cố thời gian chạy GHC và sau đó là lỗi phân đoạn. Tôi đã để lại các chi nhánh trên Github để khám nghiệm sau: https://github.com/chrisdone/hulk

Ví dụ về ConfigFile:

# Default options
[DEFAULT]
hostname: localhost
# Options for the first file
[file1]
location: /usr/local
user: Fred

9

Tôi sẽ lặp lại tất cả những gì Don đã nói và thêm một vài lời khuyên chung.

Ví dụ: hai công cụ và thư viện bổ sung mà bạn có thể muốn xem xét:

  • Kiểm tra nhanh để kiểm tra dựa trên thuộc tính
  • hlint như một phiên bản mở rộng của-Wall

Cả hai đều nhắm mục tiêu đến chất lượng mã.

Như một phương pháp viết mã, hãy tránh IO Lười biếng. Nếu bạn cần phát trực tuyến IO, thì hãy sử dụng một trong các thư viện lặp lại chẳng hạn như enumerator . Nếu bạn nhìn vào Hackage bạn sẽ thấy các thư viện như http-enumerator sử dụng kiểu liệt kê cho các yêu cầu http.

Đối với việc chọn các thư viện trên hackage, đôi khi có thể giúp bạn xem có bao nhiêu gói phụ thuộc vào một thứ gì đó. Dễ dàng xem các phụ thuộc ngược lại của một gói mà bạn có thể sử dụng trang web này, phản ánh hackage:

Nếu ứng dụng của bạn thực hiện các vòng lặp chặt chẽ, chẳng hạn như một máy chủ web xử lý nhiều yêu cầu, thì sự lười biếng có thể là một vấn đề dưới dạng rò rỉ dung lượng. Thông thường, đây là vấn đề của việc thêm các chú thích về độ nghiêm ngặt vào đúng vị trí. Lập hồ sơ, kinh nghiệm và cốt lõi đọc là những kỹ thuật chính mà tôi biết để chống lại loại điều này. Tài liệu tham khảo tốt nhất mà tôi biết là Chương 25 của Haskell trong thế giới thực .

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.