Estoy intentando crear un servicio de Windows para lanzar Apio. Me encontré con un artículo que lo hace usando Task Scheduler. Sin embargo, parece iniciar numerosas instancias de apio y sigue consumiendo memoria hasta que la máquina muere. ¿Hay alguna forma de lanzarlo como un servicio de Windows?¿Cómo crear Apio Windows Service?
Respuesta
Recibí la respuesta de otro sitio web. Celeryd (servicio de daemon para Apio) se ejecuta como una aplicación de pasteurización, en la búsqueda de 'Paster Windows Service', llévame here. Describe cómo ejecutar una aplicación de Pilones como un Servicio de Windows. Al ser nuevo en el marco de paster y en el alojamiento de servicios web de Python, no se me pasó por la mente comprobarlo al principio. Pero esa solución funciona para Aplery con un ligero cambio aquí y allá en el guión.
Modifiqué la secuencia de comandos para facilitar la modificación de la configuración de Apio. Los cambios esenciales son:
- Crear un archivo INI con la configuración para el servicio de apio (mostrada a continuación)
- crear un script Python para crear un servicio de Windows.
archivo INI (celeryd.ini):
[celery:service]
service_name = CeleryService
service_display_name = Celery Service
service_description = WSCGI Windows Celery Service
service_logfile = celeryd.log
script Python para crear servicios de Windows (CeleryService.py):
"""
The most basic (working) Windows service possible.
Requires Mark Hammond's pywin32 package.
Most of the code was taken from a CherryPy 2.2 example of how to set up a service
"""
import pkg_resources
import win32serviceutil
from paste.script.serve import ServeCommand as Server
import os, sys
import ConfigParser
import win32service
import win32event
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
INI_FILE = 'celeryd.ini'
SERV_SECTION = 'celery:service'
SERV_NAME = 'service_name'
SERV_DISPLAY_NAME = 'service_display_name'
SERV_DESC = 'service_description'
SERV_LOG_FILE = 'service_logfile'
SERV_APPLICATION = 'celeryd'
SERV_LOG_FILE_VAR = 'CELERYD_LOG_FILE'
# Default Values
SERV_NAME_DEFAULT = 'CeleryService'
SERV_DISPLAY_NAME_DEFAULT = 'Celery Service'
SERV_DESC_DEFAULT = 'WSCGI Windows Celery Service'
SERV_LOG_FILE_DEFAULT = r'D:\logs\celery.log'
class DefaultSettings(object):
def __init__(self):
if SCRIPT_DIR:
os.chdir(SCRIPT_DIR)
# find the ini file
self.ini = os.path.join(SCRIPT_DIR,INI_FILE)
# create a config parser opject and populate it with the ini file
c = ConfigParser.SafeConfigParser()
c.read(self.ini)
self.c = c
def getDefaults(self):
'''
Check for and get the default settings
'''
if (
(not self.c.has_section(SERV_SECTION)) or
(not self.c.has_option(SERV_SECTION, SERV_NAME)) or
(not self.c.has_option(SERV_SECTION, SERV_DISPLAY_NAME)) or
(not self.c.has_option(SERV_SECTION, SERV_DESC)) or
(not self.c.has_option(SERV_SECTION, SERV_LOG_FILE))
):
print 'setting defaults'
self.setDefaults()
service_name = self.c.get(SERV_SECTION, SERV_NAME)
service_display_name = self.c.get(SERV_SECTION, SERV_DISPLAY_NAME)
service_description = self.c.get(SERV_SECTION, SERV_DESC)
iniFile = self.ini
service_logfile = self.c.get(SERV_SECTION, SERV_LOG_FILE)
return service_name, service_display_name, service_description, iniFile, service_logfile
def setDefaults(self):
'''
set and add the default setting to the ini file
'''
if not self.c.has_section(SERV_SECTION):
self.c.add_section(SERV_SECTION)
self.c.set(SERV_SECTION, SERV_NAME, SERV_NAME_DEFAULT)
self.c.set(SERV_SECTION, SERV_DISPLAY_NAME, SERV_DISPLAY_NAME_DEFAULT)
self.c.set(SERV_SECTION, SERV_DESC, SERV_DESC_DEFAULT)
self.c.set(SERV_SECTION, SERV_LOG_FILE, SERV_LOG_FILE_DEFAULT)
cfg = file(self.ini, 'wr')
self.c.write(cfg)
cfg.close()
print '''
you must set the celery:service section service_name, service_display_name,
and service_description options to define the service
in the %s file
''' % self.ini
sys.exit()
class CeleryService(win32serviceutil.ServiceFramework):
"""NT Service."""
d = DefaultSettings()
service_name, service_display_name, service_description, iniFile, logFile = d.getDefaults()
_svc_name_ = service_name
_svc_display_name_ = service_display_name
_svc_description_ = service_description
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
# create an event that SvcDoRun can wait on and SvcStop
# can set.
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
def SvcDoRun(self):
os.chdir(SCRIPT_DIR)
s = Server(SERV_APPLICATION)
os.environ[SERV_LOG_FILE_VAR] = self.logFile
s.run([self.iniFile])
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
#win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
sys.exit()
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(CeleryService)
Para instalar el servicio que se ejecuta python CeleryService.py install
y luego python CeleryService.py start
para comenzar el servicio NOTA: Estos comandos se deben ejecutar en línea de comandos con derechos de administrador.
Si es necesario eliminar el servicio, ejecute python CeleryService.py remove
.
Estaba intentando alojar Celery como parte de la mejora de mi instalación de RhodeCode. Esta solución parece funcionar. Espero que esto ayude a alguien.
La respuesta aceptada no se aplica al uso de apio con una aplicación de Django. Pero me inspiró a encontrar una solución para ejecutar el apio como servicio de Windows con Django. Tenga en cuenta que lo siguiente es solo para proyectos de Django. Puede funcionar con otras aplicaciones con algunas modificaciones.
Crear una celery_service.py archivo (o lo que quiera) dentro de la carpeta principal de su proyecto de Django, mismo nivel que manage.py, con el siguiente contenido:
'''Usage : python celery_service.py install (start/stop/remove)
Run celery as a Windows service
'''
import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import subprocess
import sys
import os
import shlex
import logging
import time
# The directory for celery.log and celery_service.log
# Default: the directory of this script
INSTDIR = os.path.dirname(os.path.realpath(__file__))
# The path of python Scripts
# Usually it is in PYTHON_INSTALL_DIR/Scripts. e.g.
# r'C:\Python27\Scripts'
# If it is already in system PATH, then it can be set as ''
PYTHONSCRIPTPATH = ''
# The directory name of django project
# Note: it is the directory at the same level of manage.py
# not the parent directory
PROJECTDIR = 'proj'
logging.basicConfig(
filename = os.path.join(INSTDIR, 'celery_service.log'),
level = logging.DEBUG,
format = '[%(asctime)-15s: %(levelname)-7.7s] %(message)s'
)
class CeleryService(win32serviceutil.ServiceFramework):
_svc_name_ = "Celery"
_svc_display_name_ = "Celery Distributed Task Queue Service"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcStop(self):
logging.info('Stopping {name} service ...'.format(name=self._svc_name_))
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
sys.exit()
def SvcDoRun(self):
logging.info('Starting {name} service ...'.format(name=self._svc_name_))
os.chdir(INSTDIR) # so that proj worker can be found
logging.info('cwd: ' + os.getcwd())
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
command = '"{celery_path}" -A {proj_dir} worker -f "{log_path}" -l info'.format(
celery_path=os.path.join(PYTHONSCRIPTPATH, 'celery.exe'),
proj_dir=PROJECTDIR,
log_path=os.path.join(INSTDIR,'celery.log'))
logging.info('command: ' + command)
args = shlex.split(command)
proc = subprocess.Popen(args)
logging.info('pid: {pid}'.format(pid=proc.pid))
self.timeout = 3000
while True:
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
if rc == win32event.WAIT_OBJECT_0:
# stop signal encountered
# terminate process 'proc'
PROCESS_TERMINATE = 1
handle = win32api.OpenProcess(PROCESS_TERMINATE, False, proc.pid)
win32api.TerminateProcess(handle, -1)
win32api.CloseHandle(handle)
break
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(CeleryService)
Antes de la secuencia de comandos se puede ejecutar, necesita
Instalar pywin32.
Ajuste correctamente PYTHONSCRIPTPATH y projectdir en celery_service.py
PYTHONSCRIPTPATH suele ser la carpeta "Scripts" en la ruta de instalación de la pitón,
por ejemplo,C: \ Scripts \ python27
se agregue al camino de su sistema,
o editar celery_service.py
PYTHONSCRIPTPATH = r'C:\Python27\Scripts'
projectdir es el nombre del directorio del proyecto Django.
Es el directorio en el mismo nivel de manage.py, no el directorio principal.
Ahora puede instalar/iniciar/detener/eliminar el servicio con:
python celery_service.py install
python celery_service.py start
python celery_service.py stop
python celery_service.py remove
he creado un proyecto de Django de demostración con apio ejecuta como un servicio de Windows:
https://github.com/azalea/django_celery_windows_service
En caso usted está interesado en un ejemplo corriente.
Tal vez me falta algo, pero incluso en la última documentación, parece que 'apical todavía se está utilizando, aunque también menciona el uso de Django para ' daemonize 'Apio: http://ask.github.io/celery/cookbook/daemonizing.html#init-script-celeryd –
@ViteFalcon Gracias por señalarlo. He editado mi redacción. Siéntete libre de editarlo y mejorarlo. – azalea
La respuesta de @azalea me ayudó mucho, pero una cosa que me gustaría resaltar aquí es que el servicio (apio_servicio.py) debe instalarse con su usuario/contraseña; de lo contrario, cuando ejecute la función subprocess.Popen(args) in SvcDoRun()
, nada sucederá ya que habrá un problema de permiso. Para configurar el usuario/contraseña, puede elegir uno de estos dos métodos:
El uso de línea de comandos:
python33 .\celeryService1.py --username .\USERNAME --password PASSWORD
Ir al ordenador de gestión (locales)> Servicios y Aplicaciones> Servicios, encontrar su servidor (en el ejemplo de @ azalea, es "apio distribuida de tareas en cola de servicio") y, botón derecho del ratón para abrir Propiedades de la página, de entrada "Esta cuenta" en la ficha Iniciar sesión
- 1. WCF Service vs Windows Service
- 2. WCF Service como Windows Service woes (Windows 7)
- 3. Windows Service Plus GUI/C#
- 4. C# Windows Service Método principal
- 5. C# start Windows Service programmatically
- 6. SQL Service Broker y .NET Windows Service: ¿mejores prácticas?
- 7. Multiple SessionFactories in Windows Service con NHibernate
- 8. ¿Cómo se puede depurar el método .NET Windows Service OnStart?
- 9. ¿Comunicarse con WCF Windows Service en VB6?
- 10. Scaling SignalR con Windows Azure Service Bus
- 11. Web hosting WAS vs Windows Service
- 12. controlador UnhandledException en .Net Windows Service
- 13. Linux Mono Equivalente de .NET Windows Service
- 14. Instalación de C# Windows Service en Windows 7
- 15. Apile tareas de apio
- 16. Apio + Django: No se puede iniciar apiarceat en Windows 7
- 17. Elección para WCF Service Hosting con IIS o Self Hosting con Windows Service
- 18. ¿Debo usar Windows Management Service o Remote Agent Service para publicar en un servidor remoto?
- 19. C# Ejecutar Windows Form Application desde Service (y en Vista)
- 20. 0x0eedfade módulo de fallas kernelbase.dll en d7 windows service
- 21. Problema de ruta relativa con .Net Windows Service ..?
- 22. Crear un elemento en Tridion 2011 utilizando Core Service
- 23. ¿Cómo crear una impresora virtual en Windows?
- 24. Cómo crear una unidad de Windows virtual
- 25. Apio con Django - despliegue
- 26. Problemas para detener el apio
- 27. SOAP Web Service/VS2010 Add Service Reference
- 28. WCF Service authorization patterns
- 29. ¿Cómo puedo retrasar una tarea usando Apio?
- 30. ¿Cómo se aplica rate_limit en Apio?
Downvoter (s), por favor indique por qué downvoted . –
¿Cómo se establece un intermediario en un caso así, Redis por ejemplo –