web-dev-qa-db-fra.com

Entretien des tâches d'arrière-plan sur un grand site

Nous avons affaire à un problème intéressant sur StackOverflow.

Nous avons tout un tas de petites tâches "à faire bientôt". Un exemple est la mise à jour des listes "Questions connexes". Ce que nous avons fait par le passé, c'est de superposer ces tâches aux chargements de page de certains utilisateurs.

Ce n'était jamais idéal, mais ce n'était pas vraiment perceptible. Maintenant que SO a passé le million d'interrogations, ces malchanceux commencent à le ressentir.

La solution naturelle consiste à pousser ces tâches en arrière-plan. Il y a deux grandes façons de procéder que j'envisage.

1. Dans IIS en tant que Thread-Pool/Work-Queue personnalisé

Fondamentalement, nous faisons tourner quelques threads (non - ThreadPool , afin de ne pas interférer avec IIS) et leur faisons entretenir certaines collections dans lesquelles nous poussons Funcs .

Le gros pro ici, c'est la simplicité. Nous n'avons pas à nous soucier de marshaling quoi que ce soit, ni à nous assurer que certains services externes sont en place et répondent.

Nous avons également accès à l'ensemble de notre code commun.

Le problème est que nous ne devons pas utiliser de threads d'arrière-plan. Les objections que je connais sont toutes centrées sur la famine IIS (si vous utilisez ThreadPool) et les threads qui meurent au hasard (en raison du recyclage AppPool).

Nous avons une infrastructure existante pour faire de la mort aléatoire des threads un problème (sa possibilité de détecter une tâche a été abandonnée, essentiellement), et limiter le nombre de threads (et utiliser des threads non-ThreadPool) n'est pas difficile non plus.

Suis-je en train de manquer d'autres objections dans IIS processus de pool de threads/files d'attente de travail?

Déplacé vers StackOverflow , car ce n'était pas vraiment abordé ici.

2. En tant que service

Soit une solution tierce, soit une solution personnalisée.

Fondamentalement, nous rassemblerions une tâche à travers la limite du processus vers un service et l'oublierions simplement. Vraisemblablement, nous lions du code ou nous sommes limités à du SQL brut + une chaîne de connexion.

Le pro est que c'est la "bonne façon" de le faire.

Les inconvénients sont que soit nous sommes très limités dans ce que nous pouvons faire, soit nous devrons trouver un système pour garder ce service en synchronisation avec notre base de code. Nous devrons également raccorder tous nos systèmes de surveillance et de journalisation des erreurs, ce que nous obtenons gratuitement avec l'option "In IIS".

Y a-t-il d'autres avantages ou problèmes avec l'approche de service?

En un mot, y a-t-il des problèmes imprévus et insurmontables qui rendent l'approche n ° 1 irréalisable et, dans l'affirmative, existe-t-il de bons services tiers que nous devrions examiner pour l'approche n ° 2?

49
Kevin Montrose

Il y a quelques semaines, j'ai posé une question similaire sur SO. Bref, mon approche depuis un certain temps consiste à développer un service Windows. J'utiliserais NServiceBus (essentiellement MSMQ sous les couvertures) pour rassembler les demandes de mon application Web vers mon service. J'avais l'habitude d'utiliser WCF mais obtenir une transaction distribuée pour fonctionner correctement sur WCF semblait toujours être une douleur dans le cul. NServiceBus a fait l'affaire, je pouvais valider des données et créer des tâches dans une transaction et ne pas m'inquiéter si mon service était opérationnel à l'époque. À titre d'exemple simple, si jamais je devais envoyer un e-mail (par exemple un e-mail d'enregistrement), je créerais le compte utilisateur et enverrais un signal à mon service Windows (pour envoyer l'e-mail) lors d'une transaction. Le gestionnaire de messages du côté service prendrait le message et le traiterait en conséquence.

Depuis ASP .NET 4.0 et AppFabric ont été publiés, il existe un certain nombre d'alternatives viables au mécanisme ci-dessus. En revenant à la question que j'ai mentionnée ci-dessus, nous avons maintenant AppInitialize d'AppFabric (via net. pipe) ainsi que ASP La fonction de démarrage automatique de .NET 4.0 qui fait du développement des services Windows en tant qu'applications Web une alternative viable. J'ai commencé à le faire maintenant pour un certain nombre de raisons (la plus importante) être déployé n'est plus une douleur dans le cul):

  1. Vous pouvez développer une interface Web sur votre service (car il fonctionne comme une application Web). Ceci est extrêmement utile pour voir ce qui se passe lors de l'exécution.
  2. Votre modèle de déploiement pour vos applications Web fonctionnera pour votre application de service.
  3. IIS fournit quelques fonctionnalités intéressantes pour gérer les échecs des applications (similaires à certains égards à un service Windows).
  4. Les développeurs Web sont très familiers avec le développement d'applications Web (naturellement), la plupart ne connaissent pas grand-chose aux meilleures pratiques lors du développement d'un service Windows.
  5. Il fournit un certain nombre d'alternatives à l'exposition d'une API à d'autres applications.

Si vous suivez cette voie (pardonnez-moi de copier et coller à partir de mon message d'origine), j'envisagerais certainement d'exécuter la logique d'arrière-plan dans une application Web distincte. Il y a plusieurs raisons à cela:

  1. Sécurité . Il peut y avoir un modèle de sécurité différent pour l'interface utilisateur affichant des informations sur les processus d'arrière-plan en cours d'exécution. Je ne voudrais pas exposer cette interface utilisateur à quelqu'un d'autre qu'à l'équipe des opérations. En outre, l'application Web peut s'exécuter en tant qu'utilisateur différent disposant d'un ensemble élevé d'autorisations.
  2. Maintenance . Ce serait formidable de pouvoir déployer des modifications dans l'application hébergeant les processus d'arrière-plan sans impact sur l'utilisateur utilisant le site Web frontal.
  3. Performances . La séparation de l'application des demandes des utilisateurs du site principal signifie que les threads d'arrière-plan ne diminueront pas la capacité d'IIS à gérer la file d'attente des demandes entrantes. De plus, l'application traitant les tâches d'arrière-plan pourrait être déployée sur un serveur séparé si nécessaire.

Faire cela revient à l'aspect de marshaling. WCF, NServiceBus/RabbitMQ/ActiveMQ etc., Vanilla MSMQ, RESTful API (pensez MVC) sont toutes des options. Si vous utilisez Windows Workflow 4.0, vous pouvez exposer un point de terminaison hôte que votre application Web pourrait consommer.

L'approche d'hébergement Web pour les services est encore assez nouvelle pour moi, seul le temps nous dira si c'était le bon choix. Jusqu'ici tout va bien cependant. Soit dit en passant, si vous ne voulez pas utiliser AppFabric (je ne pouvais pas parce que pour une raison bizarre, Windows Server Web Edition n'est pas pris en charge), la capacité de démarrage automatique mentionnée dans le billet de Gu fonctionne bien. Restez à l'écart du fichier applicationhost.config cependant, tout dans ce post est possible de configurer via la console IIS (Éditeur de configuration au niveau du serveur principal).

Remarque: j'avais initialement publié quelques liens supplémentaires dans ce message, mais hélas, c'est mon premier message à cet échange et un seul lien est pris en charge! Il y en avait essentiellement deux autres, pour obtenir Google "Death to Windows Services ... Long Live AppFabric!" et "auto-start-asp-net-applications". Désolé pour ça.

17
Rohland

Il existe en fait une troisième méthode dans Windows pour exécuter les services d'arrière-plan, et elle est très courante dans le monde UNIX. La troisième façon est un travail CRON qui exécute une partie de votre infrastructure. Sous Windows, ceci est connu sous le nom de task scheduler et est très courant pour exécuter du code de façon planifiée. Pour l'utiliser, vous devez créer une application en ligne de commande qui est exécutée selon un calendrier prédéfini. L'avantage de cela est que vous n'avez pas à vous inquiéter si le processus reste opérationnel comme un service, car s'il échoue pour une raison quelconque, il ne fera que démarrer la prochaine fois.

En ce qui concerne le marshaling de tâches spécifiques, il vous suffit vraiment de stocker ces tâches dans un stockage binaire persistant. Jusqu'à ce que l'application de ligne de commande les retire du stockage et les exécute. J'ai fait cela dans le passé en utilisant la base de données Cassandra en tant que fournisseur d'état de session pour bourrer les tâches d'arrière-plan pour des utilisateurs spécifiques dans la base de données Cassandra, puis en ayant le ligne de commande les sélectionner et les exécuter pour l'utilisateur.

Ce n'était peut-être pas la solution de marshaling typique, mais cela a très bien fonctionné pour moi et cela s'est avéré être une solution très élégante, car les tâches planifiées ont survécu aux arrêts, problèmes de réseau et n'importe quelle machine pouvait exécuter la tâche car elle était centralisée stockée.

Promotion sans vergogne, mais c'est mon projet et la solution que je viens de décrire brièvement est la raison pour laquelle j'ai créé le projet: http://github.com/managedfusion/fluentcassandra/

22
Nick Berardi

Cron + Web App

Il s'agit d'une conception testée au combat qui évolue horizontalement avec votre batterie de serveurs Web et garantit que vous utilisez le pile de technologies web que vous connaissez déjà.

Voici comment ça fonctionne:

  1. Créez un contrôleur/action dans votre application Web pour gérer les tâches d'arrière-plan planifiées. Par convention, j'appelle généralement le mien http://mydomain.com/system/cron.
  2. Pour des raisons de sécurité, cette action doit être verrouillée uniquement pour les adresses IP authentifiées sur le réseau local.
  3. Sur une machine séparée, installez Wget et configurez tâche planifiée pour que wget récupère la ressource à partir de l'étape 1. Vous pouvez exécuter la tâche aussi souvent que vous le souhaitez (je optez pour 30 secondes). N'oubliez pas de transmettre l'argument cookie approprié à Wget pour qu'il s'authentifie auprès de votre application Web.
  4. Pour la redondance, vous pouvez également installer un deuxième wget planifié sur une deuxième machine.

Hourra! Vous avez maintenant un itinéraire qui sera appelé toutes les 30 secondes. Et si la demande prend 5 minutes à traiter, personne ne s'en souciera, car elle ne fait pas partie de la demande de page d'un utilisateur.

L'action cron finit par paraître très simple: il a une liste de méthodes à exécuter sur une certaine fréquence. Lorsqu'une demande arrive, il voit s'il existe une méthode à exécuter et appelle la méthode appropriée. Cela signifie que vous pouvez contrôler le planning dans votre base de données , où vous avez probablement déjà beaucoup d'autres données de configuration importantes pour votre site.

Plus important encore (pour vous), cela signifie que vos travaux ne doivent pas être appelés selon un horaire fixe. Vous pouvez écrire la logique de votre choix pour déterminer quand exécuter une méthode.

Avantages et inconvénients

  • Vous êtes déjà très bon pour écrire du code ASP.NET MVC, cela vous permet donc d'écrire vos tâches d'arrière-plan dans la même plate-forme que vous écrivez le reste de votre solution.
  • Les tâches s'exécutent dans le même contexte que votre application Web, vous pouvez donc partager le cache et utiliser helper méthodes qui existent déjà.
  • Si vous avez wget fetch un URI à charge équilibrée , alors vos tâches d'arrière-plan sont maintenant également à charge équilibrée.
  • Déploiement simultané - vous n'avez pas à vous soucier de synchroniser votre application web avec votre logique de tâche en arrière-plan, car elles sont toutes dans le même déploiement.
  • Au fil des ans, quelques personnes m'ont dit que ce design est "fortement couplé", mais une fois pressé, ils n'ont pas été en mesure d'expliquer pourquoi c'est une mauvaise chose.

Remarque: S'il y a des questions ou des préoccupations, veuillez ajouter un commentaire. Je suis heureux de développer.

10
Portman

J'ai essayé et utilisé à peu près toutes les façons possibles de le faire dans mon application actuelle. J'ai commencé à faire la même chose que vous faites actuellement, en vous appuyant sur une demande utilisateur pour remplir les données, puis en les mettant en cache à l'avenir. J'ai réalisé que c'était aussi une mauvaise idée (surtout que vous évoluez sur plusieurs serveurs Web, plus d'utilisateurs prennent le coup).

J'ai également eu un travail planifié qui atteint une URL dans l'application ASP.NET - c'est une solution décente mais elle commence à tomber en panne à la minute où vous passez au-delà d'un serveur Web.

Actuellement, j'utilise deux méthodes différentes, toutes deux utilisant Quartz.NET qui est une excellente petite bibliothèque. Le premier est Quartz.NET s'exécutant en cours avec ASP.NET, il est configuré dans le global.asax et s'exécute toutes les deux minutes. J'utilise cela pour mettre à jour le cache ASP.NET hors bande, ce qui est la seule raison pour laquelle il est exécuté dans le cadre d'ASP.NET.

La seconde est que j'ai écrit une bibliothèque pour envelopper Quartz.NET appelée DaemonMaster - il est facile de déposer un DLL dans un répertoire et de l'exécuter dans un service Windows. J'ai trouvé que cela aide à éviter certaines des parties ennuyeuses de travailler avec un service Windows et nettoie également l'api Quartz.NET. Les services qui s'exécutent via DaemonMaster sont de deux saveurs différentes, le premier sont des travaux qui doivent s'exécuter chaque nuit ou toutes les X minutes. d'autres travaux fonctionnent à partir d'une file d'attente en fonction des données provenant de l'application ASP.NET. L'application ASP.NET supprime les objets JSON sur RabbitMQ et les services interrogent RabbitMQ puis traitent les données.

Sur cette base, je vous suggère d'utiliser un service Windows (et consultez DaemonMaster) et si nécessaire, utilisez une file d'attente comme RabbitMQ pour transmettre les données de l'application ASP.NET aux services - cela a fonctionné le mieux de toutes ces solutions . Si vous chargez le cache, l'exécution dans ASP.NET est logique, sinon je ne pense pas.

7
James Avery

Je le ferais de la bonne façon et je ferais fonctionner un service Windows qui surveille une "file d'attente". Je dis "file d'attente" parce que la programmation avec MSMQ est semblable à coller des pokers chauds dans vos globes oculaires.

Je suis tombé amoureux de la simplicité de Delayed :: Job dans Rails, et quelque chose de similaire pourrait facilement être fait dans .NET.

Fondamentalement, vous ajoutez n'importe quelle sorte de SomethingOperation (quelque chose qui a une méthode Perform()). Ensuite, sérialisez simplement les paramètres pertinents, donnez-lui une priorité, une sorte de comportement de nouvelle tentative par défaut et insérez-les dans une base de données.

Votre service surveillera simplement cela et exécutera les travaux dans la file d'attente.

6
Ben Scheirman

Nous sommes plutôt satisfaits de l'approche Service Bus/Message Queue/Service. L'architecture de base est la suivante.

Le site Web envoie un message à la file d'attente

bus.Send(new ProjectApproved()); // returns immediately

Le service Windows reçoit et traite les messages en son temps

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Do something "offline"
   }
}

L'avantage est qu'il n'y a pas de retard pour le service frontal auquel les utilisateurs sont également connectés. Le service Windows peut être arrêté et mis à niveau sans interruption sur le site principal. De plus, c'est extrêmement rapide.

Si vous ne pouvez pas stocker toutes vos données dans le message, vous pouvez toujours les stocker et les récupérer plus tard. Je suggère d'utiliser un mécanisme de stockage de documents tel que: RavenDB ou MongoDB où il est très simple de stocker vos classes sans modifications.

Le site Web envoie un message à la file d'attente

// Save your object
store.Save(completeProject);

// Send a message indicating its ready to be processed
bus.Send(new ProjectApproved() { ProjectId = completeProject.Id });

Le service Windows reçoit et traite les messages en son temps

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Retrieve your object back
      var completeProject = store.Get(Message.ProjectId);
   }
}

Pour simplifier les choses, nous utilisons: Rhino ESB et Topshelf . La configuration est extrêmement simple et sa mise en place pour une application existante s'est avérée prendre très peu de temps.

4
Nathan Palmer

Je suis curieux de savoir pourquoi une combinaison des deux n'est pas une option viable. En ce moment, vous déclenchez des travaux sur les pages vues, avec une sève malchanceuse bloquée en attendant 10 secondes pour que la page apparaisse. C'est du moins ma compréhension de votre méthode actuelle.

Cependant, ces travaux prennent de plus en plus de temps à s'exécuter à mesure que le site se développe et vous ne voulez pas faire dérailler l'expérience utilisateur sur le site. Pas même pour quelques-uns (ou peut-être beaucoup) d'utilisateurs malchanceux tout au long de la journée, alors maintenant vous pensez à planifier des travaux en arrière-plan.

Je ne vois pas pourquoi un travail d'arrière-plan exécuté à intervalles réguliers ne peut pas imiter un visiteur. Maintenant, je ne suis pas un programmeur Windows, mais dans le monde Linux, je mettrais en place un travail cron qui s'exécute à intervalle régulier, et il aurait 2 lignes de code.

#!/bin/bash
wget -O /dev/null http://stackoverflow.com/specially_crafted_url

Il combine les avantages des deux systèmes. C'est fait en arrière-plan. Cela n'affecte pas les utilisateurs. Il utilise toujours une vue de page pour lancer le travail. J'ai déjà vu cette approche utilisée. Il tend à être le juste milieu entre les voies simples de l’ancien et les voies plus complexes à venir.

Mise à jour

Je pense que vous pouvez contourner le problème de l'équilibrage de charge en exécutant les lanceurs de travaux sur les serveurs Web eux-mêmes. Le gestionnaire de travaux extrait une URL de la file d'attente des travaux et l'exécute comme suit:

wget -O /dev/null http://localhost/specially_crafted_url

En raison de la nature des files d'attente de tâches/de messagerie, les tâches seront réparties également entre les exécuteurs de tâches, ce qui signifie que spécialement_crafted_url sera finalement distribué entre vos serveurs Web.

3
mellowsoon

Je pense que l'inconvénient de l'approche de service pur est que le code est dispersé dans le service et loin de l'application principale.

Voici ce que nous avons fait avec les gros travaux en arrière-plan non sensibles au temps, ce qui maintient le code ensemble et simplifie le service:

  1. Créer une file d'attente de travaux (en mémoire ou en base de données, quelle que soit la persistance nécessaire pour les types de travaux)
  2. Créer un service Web qui exécutera les travaux en file d'attente
  3. Application de service simple et morte qui appelle le service Web à un intervalle spécifié, laissez tous les éléments complexes (récupération et exécution des travaux) au service Web dans votre base de code principale.

Encore plus simple, il suffit de passer l'appel dans une application console et d'utiliser le Planificateur de tâches ou VisualCron pour le transformer en un "service".

2
Brandon

Resque est sympa. Ou même Kthxbye si vous devez être informé de la valeur résultante une fois qu'elle est terminée.

Tho basé sur Redis/Ruby.

Honnêtement, si vous faites une approche basée sur les services, elle n'a vraiment pas besoin d'être super-intégrée avec votre plate-forme actuelle, ce qui, selon moi, est un plus. J'espère que ce pourrait être un système de mise en place et d'oubli qui fonctionnerait (avec une surveillance quelconque) et terminerait les travaux. Je ne suis pas sûr qu'il doive être exécuté sur la même plate-forme du tout depuis sa mise à jour/modification des informations de la base de données.

Je suis presque sûr que vous pourriez vous en sortir avec beaucoup plus pour beaucoup moins si vous exploitiez ce genre de travail sur une entité distincte, d'autant plus qu'il semble que vous ayez à faire face à des problèmes de thread. Resque et Kthxbye déplacent le traitement vers des processus séparés pour permettre au système d'exploitation de gérer la concurrence.

Resque

Kthxbye

1
Lukas

J'ai aimé TopShelf. Conserve la simplicité tout en fonctionnant correctement en tant que service Windows. Fondamentalement, créez une application console, ajoutez environ 15 à 20 lignes de code, puis installez-la en tant que service.

http://code.google.com/p/topshelf/

1
Shane

Que diriez-vous d'avoir un service Windows très simple qui s'exécute sur le serveur Web et frappe périodiquement une URL de maintenance qui effectue vos tâches diverses. Demandez-lui de limiter la quantité de travail qu'il fait dans une demande donnée.

1
Rob Sobers

Je vais inverser la tendance apparente ici et suggérer d'aller vers le modèle in-IIS. Je l'ai utilisé moi-même et cela fonctionne très bien. Ce n'est vraiment pas si difficile d'implémenter une classe de pool de threads décente (au fil des ans, j'ai étendu ma classe de pool de threads pour prendre en charge la création dynamique et la destruction de threads, la nouvelle tentative de travaux, etc.). Les avantages sont:

  • Aucun service externe à surveiller
  • Simplicité de mise en œuvre: pas de marshaling inter-processus, pas de suivi avancé des travaux
  • Vous êtes toujours à l'intérieur de votre processus IIS, vous pouvez donc faire tous vos enregistrements habituels et ainsi de suite (pas besoin de plusieurs fichiers journaux)
  • Déploiement considérablement simplifié (lorsque vous mettez à jour un service, vous devez arrêter le service, copier les fichiers, démarrer le service - cela s'ajoute à vos mises à jour habituelles du code du site Web)

À mon avis, une solution in-IIS est simplement la "prochaine étape" de la superposition du travail sur des vues de page aléatoires.

1
Dean Harding

File d'attente des tâches Java Présentation de l'API

Concepts des tâches
Dans le traitement en arrière-plan App Engine, une tâche est une description complète d'une petite unité de travail. Cette description se compose de deux parties:

  • Une charge utile de données qui paramètre la tâche.
  • Code qui met en œuvre la tâche.

Tâches en tant que hooks Web hors ligne
Heureusement, Internet fournit déjà une telle solution, sous la forme d'une requête HTTP et de sa réponse. La charge utile des données est le contenu de la demande HTTP, comme les variables de formulaire Web, XML, JSON ou les données binaires codées. La référence du code est l'URL elle-même; le code réel est la logique exécutée par le serveur lors de la préparation de la réponse.

0
antony.trupe

J'utiliserais un service WCF hébergé par WAS en écoutant une file d'attente MSMQ.

Avantages

  • Déclenchez et oubliez les messages à sens unique de l'application Web

  • Limitation et réessai MSMQ/WCF

  • Livraison garantie; D

  • Gestion des lettres mortes

  • Traitement distribué

  • Activation WAS/MSMQ

Les inconvénients

  • MSMQ (ce n'est pas mort ... pourtant)

Les fonctionnalités MSMQ dans WCF rendent l'utilisation de MSMQ vraiment agréable. Oui, vous saignerez sur la configuration, mais les avantages l'emporteront sur le sacrifice.

0
Adam

Je l'ai rencontré plusieurs fois lors du développement d'applications Web. Nous l'avons résolu en créant une application de console Windows qui exécute la tâche et en créant une tâche planifiée qui s'exécute de temps en temps pour réellement effectuer la tâche.

0
John Christensen

Vous pouvez shunter le travail sur un thread d'arrière-plan (ou de nombreux threads d'arrière-plan) en utilisant Rx et quelque chose comme ceci:

var scheduler = new EventLoopScheduler( SchedulerThreadName );
_workToDo = new Subject<Action>();
var queueSubscription = _workToDo.ObserveOn( scheduler ).Subscribe( work => work() );
_cleanup = new CompositeDisposable( queueSubscription, scheduler );

Utiliser:

var work = () => { ... };
_workToDo.OnNext( work ); // Can also put on error / on complete in here

Hébergez tout cela dans une classe dont il n'y a jamais qu'un (alias un singleton, mais faites-le correctement - utilisez votre conteneur IoC pour déterminer le mode de vie).

Vous pouvez contrôler la taille du pool de threads, etc. en écrivant un planificateur personnalisé au lieu d'utiliser EventLoopScheduler (qui exécute un seul thread).

0
Neal

Faire les deux

Ajoutez un paramètre facultatif au chemin de question qui effectue le travail que vous utilisez actuellement sur les demandes des utilisateurs:

Entretien des tâches d'arrière-plan sur un grand site

Créez une application console qui s'exécute sur chaque serveur et ouvre le fichier binaire partagé IIS log et le lit à la fin actuelle du fichier. Utilisez un système de fichiers ou un intervalle de temps pour lire en avant pour collecter les mises à jour en tant que IIS a vidé le journal.

Utilisez ces informations pour déterminer quelles pages ont été actuellement consultées.

Utilisez les URL de page du journal analysé pour appeler la version "extrastuff" de l'URL sur localhost avec un objet webclient.

Ajoutez du code pour changer de fichier à la fin de chaque période de journal ou redémarrez le processus à chaque période de journal.

0
Bill

J'ai implémenté ce type de chose plusieurs fois. Sous Windows, j'ai configuré un programme de ligne de commande python qui fait quelque chose à différents moments. Ce programme expose également une interface xmlrpc sur un port. Ensuite, une tâche planifiée s'exécute toutes les minutes et interroge les interfaces xmlrpc. S'ils ne fonctionnent pas, il essaie de les lancer. Si ce n'est pas le cas, il m'envoie un e-mail.

L'avantage est que le travail qui s'exécute n'est pas lié au programme ni au programme. J'ai un travail de processus qui s'exécute toutes les secondes, mais attendra de plus en plus longtemps entre le démarrage d'un nouveau travail selon qu'il a du travail à faire. En outre, il peut être utilisé pour agir intelligemment en fonction du résultat. Vous avez une erreur 500? Vous avez un très long retard? Faites autre chose. Avertissez un autre service. Etc.

Et le même système fonctionne sur unix, avec des modifications mineures.

0
Christopher Mahan

Je n'ai pas de réponse pour vous moi-même, mais le problème a sonné - je me souviens de quelques gars au hasard en discutant une fois sur un podcast .

Spolsky: J'ai remarqué que l'une des questions que vous posiez sur le blog était comment gérer les tâches récurrentes de maintenance en général?

Atwood: Oui.

Spolsky: Est-ce une description juste? Chaque site Web comporte des tâches que vous ne souhaitez pas exécuter au moment du chargement d'une page Web, mais vous souhaitez les exécuter avec une certaine récurrence.

Atwood: Ya, sorte de tâches en arrière-plan.

Spolsky: Ya, alors qu'as-tu compris?

Atwood: Eh bien, j'ai demandé à l'origine sur Twitter, parce que je voulais juste quelque chose de léger. Je ne voulais vraiment pas écrire un service Windows. J'avais l'impression que c'était hors du code du groupe. De plus, le code qui fait le travail est en fait une page Web, car pour moi, c'est une unité logique de travail sur un site Web, c'est une page Web. Donc, c'est vraiment comme si nous rappelions sur le site Web, c'est comme une autre demande dans le site Web, donc je l'ai vu comme quelque chose qui devrait rester en ligne, et la petite approche que nous avons proposée qui m'a été recommandée sur Twitter était essentiellement d'ajouter quelque chose au cache de l'application avec une expiration fixe, puis vous avez un rappel, donc quand cela expire, il appelle une certaine fonction qui fait le travail, puis vous l'ajoutez dans le cache avec la même expiration. Donc, c'est un peu, peut-être que "ghetto" est le bon mot.

0
Oddthinking