2009-12-03 35 views
5

Tôi cần phải viết một máy chủ sẽ nhận được hướng dẫn từ các mô-đun khác và thực hiện hành động tùy thuộc vào hướng dẫn nhận được. Hiệu quả là mối quan tâm chính của tôi. Vì vậy, tôi sử dụng gen_server hoặc tôi viết máy chủ của riêng mình. Bằng cách "máy chủ của riêng tôi" Ý tôi là cái gì đó như:Erlang: gen_server hoặc máy chủ tùy chỉnh của riêng tôi?

-module(myserver). 
-export([start/0, loop/0]). 

start() -> 
     spawn(myserver, loop, []). 

loop() -> 
    receive 
     {From, Msg} -> %Do some action here... ; 
     message2 -> %Do some action here...; 
     message3 -> %Do some action here...; 
     message4 -> %Do some action here...; 
     . 
     . 
     . 
     _-> ok 
    end, 
    loop(). 

Vì vậy, để sử dụng myserver, tôi có lẽ sẽ đăng ký quá trình dưới một tên đăng ký trong khi bắt đầu nó, và sau đó mỗi khách hàng sẽ gửi tin nhắn đến máy chủ sử dụng pid này .

Vì vậy, tôi nên sử dụng phương pháp này, hoặc thay vào đó triển khai máy chủ bằng cách sử dụng hành vi gen_server? Có lợi thế nào khi sử dụng gen_server? Nhưng sẽ sử dụng gen_server thêm bất kỳ chi phí nào, khi so sánh với myserver?

+1

Bạn đã rất quan tâm đến hiệu quả cho một vài câu hỏi trước đây. Bạn có bất kỳ số nào về các yêu cầu về hiệu suất không? – Christian

+1

Ồ, và chắc chắn đi với gen \ _server cho đến khi bạn có thể đo lường vị trí tắc nghẽn của bạn. – Christian

+0

Tôi không có bất kỳ số lượng nào để định lượng các yêu cầu hiệu suất cho hệ thống ngay bây giờ. Đây là một hệ thống thử nghiệm, vì vậy tất cả những gì tôi biết bây giờ là các máy chủ sẽ phải xử lý một lượng lưu lượng đáng kinh ngạc. Vì vậy, tôi đang cố gắng để có thêm ý thức về hiệu quả và tối ưu hóa càng nhiều càng tốt. – ErJab

Trả lời

10

gen_server sẽ có chi phí không đáng kể so với các máy chủ tự thực hiện vì nó yêu cầu một vài cuộc gọi chức năng bổ sung cho mỗi tin nhắn (một trong số đó là động). Tôi không nghĩ rằng bạn nên xem xét điều này tại thời điểm thực hiện này. Bạn đã thay đổi ý định của mình bất cứ lúc nào, di chuyển từ gen_server đến máy chủ của riêng bạn phải đơn giản.

gì bạn nhận được với gen_server so với một vòng lặp đơn giản là:

  • gỡ lỗi (với sys)
  • SASL đăng
  • hỗ trợ hibernation
  • hỗ trợ nâng cấp đang
+1

Nhưng bạn có thể thêm sys và proc_lib để làm cho vòng lặp tương thích OTP đơn giản của bạn, và nhận được tất cả những lợi thế được liệt kê ở trên. Xem http://erlang.org/doc/design_principles/spec_proc.html và một ví dụ điển hình từ cuốn sách "khả năng mở rộng với mũ eralang otp". 10, https://github.com/francescoc/scalabilitywitherlangotp/blob/master/ch10/tcp_wrapper.erl –

3

Tôi sẽ đi với gen_server đơn giản chỉ vì rất nhiều suy nghĩ đã đi vào làm cho nó làm điều đúng trong các hoàn cảnh khác nhau. Nó sẽ chăm sóc các chi tiết rất khó để có được quyền. Tôi tưởng tượng gen_server có thể thêm một số chi phí nhưng tôi đã ngừng đưa ra lời khuyên về hiệu suất. Nếu bạn thực sự quan tâm thì hãy thực hiện cả hai và đo tốc độ, đó là cách chắc chắn duy nhất để tìm ra.

10

Tôi cũng sẽ sử dụng số gen_server. Một khi bạn đã sử dụng cơ sở này, bạn sẽ học cách đánh giá cao giá trị của nó. Hàm gọi lại hàm có thể hơi khó xử (ví dụ: handle_cast cho các cuộc gọi không đồng bộ) nhưng cuối cùng, bạn sẽ quen với nó.

Hơn nữa, tôi sẽ được khuyên không nên tham gia vào "tối ưu hóa sớm" mà không thực hiện một số thử nghiệm. Bạn có thể không muốn hy sinh khả năng đọc/bảo trì để đạt được hiệu quả biên.

2

Bạn cũng có thể sử dụng gen_server2 bởi những kẻ đứng sau RabbitMQ.

Nó giống như gen_server trừ những điều chỉnh sau (từ các ý kiến):

1) the module name is gen_server2 

2) more efficient handling of selective receives in callbacks 
gen_server2 processes drain their message queue into an internal 
buffer before invoking any callback module functions. Messages are 
dequeued from the buffer for processing. Thus the effective message 
queue of a gen_server2 process is the concatenation of the internal 
buffer and the real message queue. 
As a result of the draining, any selective receive invoked inside a 
callback is less likely to have to scan a large message queue. 

3) gen_server2:cast is guaranteed to be order-preserving 
The original code could reorder messages when communicating with a 
process on a remote node that was not currently connected. 
2

Tôi giả sử từ câu hỏi của bạn rằng bạn đang viết một nhiều máy chủ "vĩnh viễn".

Nói chung, máy chủ của riêng bạn linh hoạt hơn và nhanh hơn một chút, nếu bạn làm đúng. Nhưng, và đây là một lớn NHƯNG:

  • Bạn sẽ phải làm tất cả mọi thứ cho mình, làm tăng nguy cơ bị lỗi!

  • Nếu bạn muốn máy chủ của mình được quản lý theo cách OTP, điều mà bạn có thể làm nếu bạn đang xây dựng một hệ thống mạnh mẽ, thì bạn sẽ phải tự mình xử lý tất cả. Và làm cho nó đúng.

Nếu tôi đang làm máy chủ vĩnh viễn, tôi sẽ bắt đầu sử dụng gen_server và chỉ dự phòng và tự cuộn nếu tôi gặp khó khăn nghiêm trọng trong việc triển khai những gì tôi cần.

Máy chủ sống ngắn là một vấn đề khác.

Các vấn đề liên quan