2011-06-30 32 views
14

Tôi đang sử dụng mod_wsgi để phục vụ một trang web django thông qua Apache. Tôi cũng có một số mã Python chạy như một quá trình nền (dameon?). Nó giữ phiếu bầu một máy chủ và chèn dữ liệu vào một trong các mô hình Django. Điều này hoạt động tốt nhưng tôi có thể có mã này là một phần của ứng dụng Django của tôi và chưa thể chạy liên tục trong nền? Nó không cần phải là một quá trình cho mỗi nghệ sĩ, nhưng một nghệ thuật của trang web Django được hoạt động liên tục. Nếu vậy, bạn có thể chỉ cho tôi một ví dụ hoặc một số tài liệu có thể giúp tôi thực hiện điều này không?Tôi có thể có một số mã liên tục chạy bên trong Django như một daemon

Cảm ơn.

Trả lời

14

Bạn có thể thiết lập một công việc cron chạy một số chức năng bạn đã xác định, hoặc - phương pháp nâng cao hơn và có thể được đề xuất, tích hợp celery trong dự án của bạn (thực sự là khá dễ dàng).

+0

Tôi đã đi với Celery. Làm việc như người ở. –

+0

tác vụ cron không liên tục chạy trong nền, nhưng bắt đầu tại một thời điểm nhất định và kết thúc khi sẵn sàng. Kể từ khi lệnh django mất abut 1,5 giây để bắt đầu (depening trên sự phức tạp của các mô hình), điều này thường không phải là cách để làm điều đó khi hiệu suất cao là cần thiết. – FeedTheWeb

+0

Điều này vẫn hợp lệ? Nếu có, điều gì sẽ là một cách tốt để thực hiện nhiệm vụ Celery để xử lý lâu dài của tôi? –

9

Bạn có thể tạo chuỗi nền từ tập lệnh WSGI khi nó được nhập lần đầu tiên.

import threading 
import time 

def do_stuff(): 
    time.sleep(60) 
    ... do periodic job 

_thread = threading.Thread(target=do_stuff) 
_thread.setDaemon(True) 
_thread.start() 

Để làm việc này, bạn sẽ chỉ phải sử dụng một quy trình daemon nếu không, quy trình sẽ thực hiện tương tự như bạn không muốn.

Nếu bạn đang sử dụng nhiều quy trình trong nhóm quy trình daemon, một cách khác là tạo nhóm quy trình daemon đặc biệt mà mục đích duy nhất là chạy chuỗi nền này. Nói cách khác, quá trình này không thực sự nhận được bất kỳ yêu cầu nào.

Bạn có thể làm điều này bằng cách:

WSGIDaemonProcess django-jobs processes=1 threads=1 
WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \ 
    process-group=django-jobs application-group=%{GLOBAL} 

Chỉ thị WSGIImportScript nói để tải kịch bản đó và chạy nó khi khởi động trong bối cảnh các nhóm quá trình 'django-việc làm'.

Để lưu nhiều tập lệnh, tôi đã chỉ rõ nó là tệp kịch bản WSGI ban đầu của bạn mà bạn đã sử dụng cho WSGIScriptAlias. Chúng tôi không muốn nó chạy khi nó được nạp bởi chỉ thị rằng mặc dù, vì vậy chúng tôi làm:

import mod_wsgi 

if mod_wsgi.process_group == 'django-jobs': 
    _thread = threading.Thread(target=do_stuff) 
    _thread.setDaemon(True) 
    _thread.start() 

Ở đây nó nhìn vào tên của nhóm quá trình daemon và chỉ chạy khi bắt đầu lên trong quá trình daemon đặc biệt nhóm được thiết lập chỉ với một quy trình duy nhất cho việc này.

Nhìn chung, bạn chỉ đang sử dụng Apache như một trình quản lý quy trình tráng lớn, mặc dù đã được biết là mạnh mẽ. Đó là một chút quá mức cần thiết khi quá trình này sẽ tiêu thụ bộ nhớ bổ sung trên đầu trang của những chấp nhận và xử lý yêu cầu, nhưng tùy thuộc vào sự phức tạp của những gì bạn đang làm nó vẫn có thể hữu ích. Một khía cạnh dễ thương của việc này là vì nó vẫn là một ứng dụng Django đầy đủ trong đó, bạn có thể ánh xạ các URL cụ thể cho quá trình này và cung cấp một API từ xa để quản lý hoặc theo dõi nhiệm vụ nền và những gì nó đang làm .

WSGIDaemonProcess django-jobs processes=1 threads=1 
WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \ 
    process-group=django-jobs application-group=%{GLOBAL} 

WSGIDaemonProcess django-site processes=4 threads=5 
WSGIScriptAlias//usr/local/django/mysite/apache/django.wsgi 

WSGIProcessGroup django-site 
WSGIApplicationGroup %{GLOBAL} 

<Location /admin> 
WSGIProcessGroup django-jobs 
</Location> 

Ở đây, tất cả URL ngoại trừ nội dung trong/quản trị chạy trong 'django-site', với/admin trong 'django-jobs'.

Dù sao, điều đó giải quyết câu hỏi cụ thể về việc thực hiện nó trong quy trình Apache mod_wsgi daemon theo yêu cầu.

Như đã chỉ ra, cách khác là có tập lệnh dòng lệnh thiết lập và tải Django và thực hiện công việc và thực hiện tác vụ đó từ công việc định kỳ.Một kịch bản dòng lệnh có nghĩa là sử dụng bộ nhớ tạm thời không thường xuyên, nhưng chi phí khởi động cho công việc cao hơn khi cần tải mọi thứ mỗi lần.

+0

+1 slick Tôi không có ý tưởng mod_wsgi đã có một câu trả lời cho điều này. –

+0

Nếu bạn đang sử dụng Gunicorn, bạn có thể bắt đầu một chuỗi mới bằng cách ghi đè hàm 'when_ready' của Gunicorn. Dưới đây là ví dụ: https://github.com/benoitc/gunicorn/blob/master/examples/example_config.py –

+0

Từ bộ nhớ, '' when_ready'' chạy trong quy trình cha mẹ gunicorn. Nói chung không phải là một ý tưởng tốt để thực hiện các công cụ chạy dài trong quá trình cha mẹ như vậy. Quá trình cha mẹ đó sẽ được chia nhỏ để trở thành các quy trình công nhân và có thể có những tác động từ việc thừa hưởng bất kỳ trạng thái nào gây ra bởi luồng nền của bạn, mặc dù chính nền tảng sẽ không tồn tại ở ngã ba. –

0

Trước đây tôi đã sử dụng một công việc cron nhưng tôi nói với bạn, bạn sẽ chuyển sang cần tây sau một thời gian.

Cần tây là con đường để đi. Ngoài ra, bạn có thể thực hiện quá trình đồng bộ hóa dài để có thể tăng tốc thời gian yêu cầu/phản hồi.