2010-11-12 31 views
8

Giả sử bạn đang viết một daemon phục vụ một hàng đợi công việc. Nhiều phần mềm khác ghi công việc cho daemon vào hàng đợi. Daemon sẽ thăm dò hàng đợi vài giây một lần cho các công việc đang chờ xử lý. Giả sử hàng đợi được thực hiện như một bảng trong một cơ sở dữ liệu MySQL và daemon là một vòng lặp đơn giản:Làm thế nào để thiết kế một daemon với một kết nối MySQL DB

  1. nhận được tất cả các công việc do từ hàng đợi
  2. làm các công việc
  3. ngủ cho N giây
  4. goto 1

Daemon phải tồn tại dịch vụ bị gián đoạn từ máy chủ MySQL DB và gián đoạn kết nối DB.

Bạn có thiết kế daemon để kết nối với máy chủ DB một lần trên mỗi chu kỳ không? tức là kết nối trước 1. và ngắt kết nối giữa 2 và 3?

Hoặc bạn sẽ có daemon giữ kết nối mở? Trong trường hợp nó cũng cần đến a) phát hiện khi máy chủ hoặc kết nối không hoạt động, b) ngắt kết nối và kết nối lại, và c) làm như vậy mà không tích lũy kết nối DB, mô tả kết nối dud hoặc các tài nguyên chết khác.

Nếu bạn có sở thích, tại sao?

Ưu và nhược điểm?

Các yếu tố tham gia vào thiết kế?

Bất kỳ phương pháp tiếp cận nào khác?

Câu trả lời ở đây: mysql connection from daemon written in php không cho biết lý do tại sao nên giữ kết nối luôn tốt hơn. Tôi đọc ở đâu đó rằng chi phí cho mỗi kết nối trong MySQL rất nhẹ. Vì vậy, nó không phải là rõ ràng lý do tại sao tiêu thụ vĩnh viễn một kết nối máy chủ là tốt hơn so với kết nối/ngắt kết nối mỗi vài giây.

Trong trường hợp của tôi, daemon được viết bằng PHP.

+0

Bạn đang cố gắng làm gì? Tùy thuộc vào từng trường hợp, âm thanh như một tệp FIFO hoặc ổ cắm có thể tốt hơn để kích hoạt daemon ... (Và những gì tôi sẽ làm là tạo lại kết nối mỗi khoảng thời gian thăm dò, nhưng sau đó một lần nữa tôi sẽ không bỏ phiếu sau mỗi vài giây) ... – ircmaxell

+0

@ircmaxell: FIFO không thuận tiện trong trường hợp của tôi bởi vì các quá trình đặt công việc trong hàng đợi cần có khả năng đọc nó và vì trạng thái xếp hàng công việc cần phải tồn tại khi khởi động lại máy chủ. MySQL nhân rộng của hàng đợi cũng là tiện dụng. –

+0

Tôi không có ý định chuyển tất cả dữ liệu qua FIFO. Chỉ cần kích hoạt daemon để đọc từ hàng đợi dựa trên mysql. Vì vậy, về cơ bản bạn sẽ 'INSERT INTO hàng đợi VALUES (công việc)', sau đó 'file_put_contents ('fifo.file', '1');'. Daemon sẽ ngủ cố gắng mở nămo. Vì vậy, nếu nó được thực hiện xử lý tất cả về cơ bản nó sẽ chặn trên 'fopen ('fifo.file', 'r');'. Lần sau một quá trình thêm vào hàng đợi, nó chỉ thông báo cho daemon, sau đó ngay lập tức bắt đầu xử lý công việc. Nhưng trong khi nó đang ngủ nó không tiêu thụ bất kỳ tài nguyên vì nó là một cuộc gọi hệ thống đó là chặn (ngay cả đối với giờ tại một thời điểm). – ircmaxell

Trả lời

7

Tôi thực sự đang làm việc trên something rất gần với những gì bạn đã mô tả, nhưng trong trường hợp của tôi, daemon không thăm dò ý kiến ​​cho sự kiện nó nhận được chúng một cách không đồng bộ qua XMPP (nhưng ngoài điểm).

Cắt Trung Man

Tôi nghĩ thay vì lưu trữ các sự kiện trong cơ sở dữ liệu và bỏ phiếu cho họ w/MySQL có lẽ bạn có thể sử dụng Gearman để gửi cho họ từ các khách hàng không đồng bộ (example).

Garbage Collection

PHP là không thực sự được thiết kế để chạy như một daemon, và nó đã không đến khi PHP 5.3 khi nó đã circular reference garbage collection rằng nó đã trở thành một lựa chọn khả thi. Đó là rất quan trọng là bạn sử dụng PHP 5.3 nếu bạn muốn bất kỳ cơ hội nào hoạt động lâu dài mà không bị rò rỉ bộ nhớ.

Một điều cần ghi nhớ về GC là bộ nhớ chỉ miễn phí nếu nó không còn được tham chiếu (ở bất kỳ đâu). Vì vậy, nếu bạn gán một biến cho phạm vi toàn cầu, nó sẽ ở đó cho đến khi daemon thoát. Điều quan trọng là bất kỳ mã nào bạn tạo hoặc sử dụng không xây dựng các biến ở các vị trí (ví dụ: nhật ký tĩnh, không xóa dữ liệu cũ, v.v.).

Stat cache

Một điều nữa là điều quan trọng để chạy clearstatcache tất cả vì vậy thường xuyên. Vì quá trình PHP của bạn không được khởi động lại, điều quan trọng là thực hiện cuộc gọi này theo cách thủ công để ngăn chặn việc nhận dữ liệu thống kê cũ (có thể có hoặc không ảnh hưởng đến bạn). Theo documentation, các chức năng này được lưu trong bộ nhớ cache.

chức năng bị ảnh hưởng bao gồm stat(), lstat(), file_exists(), is_writable(), is_readable(), is_executable(), is_file(), is_dir(), is_link(), filectime(), fileatime(), filemtime(), fileinode(), filegroup(), fileowner(), filesize(), filetype() và fileperms().

Quản lý nguồn lực

Nếu bạn sẽ được sử dụng điều như MySQL trong suốt cuộc đời của quá trình của bạn, tôi khuyên bạn nên làm một kết nối lúc khởi động và giữ nó còn sống. Mặc dù nó có thể sử dụng nhiều ram hơn ở phía MySQL, bạn sẽ cắt giảm một số thời gian chờ và CPU trên không phải kết nối mỗi 1 giây.

Không yêu cầu URL

Điều này có vẻ hiển nhiên, nhưng với CLI PHP không có thông tin yêu cầu URL. Một số thư viện không được viết với điều này trong tâm trí, và điều này có thể gây ra một số vấn đề.

LooPHP

Tôi sẽ bật một plug biết xấu hổ ở đây cho một khuôn khổ tôi đã viết để giúp đỡ với sự quản lý của PHP daemon. LooPHP là một khung công tác vòng lặp chạy cho phép bạn lên lịch sự kiện xảy ra hoặc tạo các bản nghe cho các nguồn trừu tượng (socket, stream, v.v.). Trong trường hợp của tôi, tôi có daemon làm nhiều hơn 1 điều, vì vậy nó rất hữu ích để có hệ thống theo dõi tất cả các bộ đếm thời gian cho tôi để tôi có thể thăm dò hiệu quả stream_select cho kết nối XMPP.

+0

Đó là một số bình luận rất hữu ích, Kendall. Cảm ơn! Tôi khá chắc chắn tôi không có tài liệu tham khảo vòng tròn nhưng tôi đang chạy trên 5.3.3 vì vậy đó là OK. Không sử dụng 'stat' nhưng đó là một điểm chung tốt. Không có sự xấu hổ trong việc chia sẻ LooPHP chỉ vì bạn đã viết nó. Đó là nhiều hơn tôi cần ngay bây giờ nhưng tôi có một dự án trên đường chân trời mà có thể tìm thấy nó rất hữu ích. –

+0

@fsb Bạn đặt công việc vào hàng đợi như thế nào? Tôi có thể đáng xem Gearman (điểm đầu tiên của tôi). Nó trừu tượng rất nhiều xử lý hàng đợi cho bạn. –

+0

Giống như tôi đã nói trong OP, hàng đợi là một bảng MySQL. Vì vậy, công việc được đặt trong đó với INSERT. –

0

Tôi nghĩ rằng điều tốt nhất bạn có thể làm là đo thời gian cần để kết nối/ngắt kết nối với/từ cơ sở dữ liệu. Sau đó thử và đưa ra một số khả năng của máy chủ cơ sở dữ liệu trở nên không có sẵn. Xác định chi phí của kết nối máy chủ cố định. Và cuối cùng cố gắng xác định chi phí (tính theo giờ, phiền toái hoặc bất kỳ thứ gì) của việc thêm mã liên quan đến các vấn đề kết nối cơ sở dữ liệu. Nếu bạn có thể xác định thành công những con số đó và so sánh chúng, bạn có câu trả lời. Thật khó cho tôi (và tôi giả định bất cứ ai) để đưa ra guesstimates tốt cho những giá trị, nhưng kết luận có lẽ sẽ là một sự lựa chọn giữa hiệu suất so với tính khả thi (về chi phí thấp hơn).

+0

Một nghiên cứu định lượng kết luận về chi phí tài nguyên máy chủ liên quan đến các khó khăn thiết kế daemon sẽ khiến tôi tốn nhiều hơn phí lưu trữ máy chủ ;-) –

+0

@fsb, haha, tôi chắc chắn bạn đã đúng. Và bạn vẫn tự tin rằng bạn không tối ưu hóa hoặc lo lắng về một vấn đề mà bạn không có? –

1

Nếu bạn muốn tạo một daemon đáng tin cậy, bạn sẽ cần phải nắm bắt các lỗi cơ sở dữ liệu/ngắt kết nối và kết nối lại trong cả hai trường hợp (ngắt kết nối hoặc kết nối). Vì bạn vẫn cần làm điều này, bạn cũng có thể sử dụng lại một kết nối.

Nói cách khác, chỉ vì bạn có kết nối mới được mở, điều đó không có nghĩa là truy vấn sẽ không thành công và kết nối cần phải được mở lại và thử lại.

Vì vậy, tôi tin rằng cách sạch nhất là bảo vệ kết nối. Nhưng chỉ hầu như không.

+0

Xin chào Sean. Trong trường hợp của tôi, nó là tốt cho daemon để sử dụng cùng một vòng lặp cho bỏ phiếu như nó không cho kết nối lại. Vì vậy, nếu kết nối mới được mở không hoạt động, hoặc một cái gì đó DB liên quan không thành công trong bước 1 (xem OP) deamon chỉ bỏ qua bước 3. Vì vậy, một chi nhánh mã kết nối lại-on-db-dailure rõ ràng là obviated. –

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