2009-10-17 10 views
3

G'day,Création d'un script Perl détecter les changements dans un module de configuration séparée également en Perl

Nous avons un script Perl qui est en train de traiter les demandes de géolocalisation des serveurs tête de gamme dans un site web majeur. Le script est un courtier fournissant une logique métier supplémentaire interprétant les données renvoyées par un produit COTS qui fournit des données pour une adresse IP donnée, par ex. pays, type de connexion, type de routage, opérateur, etc.

Ce service Géo gère actuellement des charges de pointe d'environ 1 000 requêtes par seconde dans le backend COTS. BTW Il sert actuellement 5 000 demandes p.s. à partir de sa couche d'équilibrage de charge/cache dédiée qui vit directement avant la couche de courtier.

J'ai récemment dû modifier le comportement de ce courtier pour permettre une nouvelle catégorie de connexions que nous avons vu se produire sur le site qui cause des problèmes.

La version originale du script, pas ma conception! btw, a été construit en utilisant un mélange d'éléments de configuration dans le script lui-même et d'autres éléments dans des fragments séparés de Perl. Comme cela a été souligné à juste titre lors de l'examen par les pairs de mes modifications, nous devrions probablement migrer tous les éléments de configuration pour les séparer plutôt que de continuer avec un mélange d'éléments de configuration intégrés et séparés.

Maintenant, je veux aller plus loin et mettre tous les éléments de configuration, créés comme des hachages Perl distincts, dans un seul fichier de configuration.

Pour le moment, nous devons arrêter et redémarrer l'ensemble de l'application pour recharger les nouveaux éléments de configuration qui, étant donné les niveaux de trafic, est un peu incommode même s'il existe quatre instances du courtier sur deux centres de données distincts. nous ne perdons jamais le service.

Je soupçonne que je vais avoir à recourir à une minuterie, ou peut-être un compteur de demandes, et d'effectuer une stat sur le fichier de configuration en question. Ou peut-être même avoir un TTL configuré pour le fichier de configuration et juste le recharger toutes les dix minutes environ.

Mais y a-t-il un moyen de faire en sorte que Perl recharge automatiquement une version plus récente d'un fichier qu'il a précédemment chargé? Je pense à un comportement similaire à celui fourni par le module mod_perl d'Apache.

votre,

Répondre

5

Rob, un couple de points:

1) De préférence, le lecteur résumé de configuration dans une API par opposition à la lecture directe à partir d'un hachage Perl. De cette façon, tout appel à cette API peut à son tour décider ce qui doit être fait avec la configuration (par exemple, le temporisateur est-il en train de faire le changement d'horodatage du fichier de configuration?).

Comme toujours, cela a l'avantage supplémentaire de vous permettre de re-concevoir la config plus tard (perl has => xml => base de données) sans changer le logiciel.

2) Étant donné qu'il s'agit d'un serveur, je recommande également une fonctionnalité de rechargement de configuration à la demande via un type de requête spécial. Cela vous permet de forcer le rechargement de la configuration (par exemple après la mise à jour des fichiers de configuration) en envoyant une commande au serveur au lieu de la faire rebondir. BTW, # 2 est très facile à faire si vous suivez # 1, car tout ce que le gestionnaire "reload config" doit faire est de réinitialiser "config doit être rechargé sur le prochain appel de l'API config".

3) Si vous insistez pour avoir la config comme un hachage sans API (par ex.pour des raisons de performance, éliminer les appels de sous-programmes API, ce qui est plausible mais ne devrait pas aider beaucoup), alors vous devez placer la config dans une variable statique de votre classe, et avoir cette classe avec la méthode "set new config". Ensuite, le serveur définirait une temporisation, et sur un appel de temporisateur (ou sur réception de la commande "reload config" de # 2) vérifierait si l'horodatage et/ou la somme de contrôle du fichier de configuration est différent de la dernière fois que vous avez appelé et recharger.

+1

P.S. Je suppose que quelqu'un peut suggérer d'utiliser des hachages liés, mais j'ai des inquiétudes sur la performance d'un hachage lié à un fichier directement en fonction de votre échelle. – DVK

0

@DVK, ooh, bon appel avec votre point 1) Je n'avais pas pensé à ajouter une couche d'abstraction supplémentaire au-dessus de la config. Je suppose que l'avantage de le laisser en tant que hachage Perl brut est qu'il n'y a pas de couche de conversion requise. Je vais réfléchir aux compromis impliqués. En ce qui concerne le point 2), nous avons trouvé un certain flakiness avec la gestion des signaux dans Perl qui ne l'a pas bien rendu HUP donc nous avons officiellement déprécié les HUP de signaux Perl sur une base de tout le site.

Mais j'aime vraiment votre idée d'une commande de recherche spéciale qui forcerait un rechargement! Je vais l'utiliser si cela ne vous dérange pas. Peut-être utiliser "GET 127.0.0.1" car cela ne va probablement pas venir de l'extérieur! N.B. Notre dernière version de notre protocole geo est basée sur http afin que nous puissions facilement interroger le service à partir d'un navigateur.

Merci! \o/

+1

Si vous implémentez HTTP vous-même, pensez à utiliser une méthode complètement nouvelle au lieu d'un GET "magique". c'est-à-dire 'RESTART/HTTP/1.1' et, bien sûr, assurez-vous de l'authentifier en quelque sorte ... – hobbs

+0

@hobbs, merci pour le conseil. Je ferai peut-être cela en faisant une analyse de la demande entrante. Ces geo rq sont verrouillés par des listes de contrôle d'accès très serrées, de sorte que seules les adresses rq provenant d'hôtes spécifiés sont gérées. Seul le problème que je vois avec ceci est dans l'avenir quand nous pensons remplacer le courtier de Perl par un module dédié s'exécutant sous Apache. –

+2

# 2, je voulais dire une commande spéciale (généralement une toute nouvelle commande mais une certaine valeur vaudou de la commande existante est bien sûr réalisable si nécessaire). Définitivement ne signifiait pas le signal du système ala Apache. – DVK

2

L'approche traditionnelle de ce type de problème sur les machines de type Unix consiste pour le programme serveur à recharger sa configuration à la réception d'un signal. Par exemple, le Apache documentation indique que trois signaux ont une signification particulière pour le serveur: TERM demande au serveur de s'arrêter, HUP force un redémarrage immédiat et USR1 demande un rechargement progressif du fichier de configuration. Ce type de fonctionnalité peut être intégré directement dans votre programme, à condition que vous travailliez dans un environnement prenant en charge les signaux.

+0

@Tim, nous avons tellement de défauts avec la gestion des signaux Perl que nous avons quasiment abandonné l'utilisation du site. –

+0

BTW Ajout de l'étiquette Solaris 10 pour plus de clarté. –

3

Si vous utilisez une version relativement récente de Linux, il existe toujours l'itinéraire inotify. Cela signifie que vous pouvez recharger la configuration dès qu'elle est écrite sur le disque. Découvrez Linux-Inotify. Il y a aussi FAM pour d'autres plateformes.

+0

@aflott, merci, mais nous sommes sur Solaris. –

+1

utilisez File :: ChangeNotify. – jrockway

1

Il est toujours possible de déplacer les configurations dans une base de données et d'utiliser les déclencheurs de base de données DBI plus pour les déclencher en fonction des événements.

+0

@Howard, merci pour la suggestion, mais je pense maintenant à faire de la logique métier un module chargé séparément, comme ils le font avec le serveur de nom d'équilibrage de charge. –

Questions connexes