Comment l'IPC entre PHP clients et un C Démon de Serveur?
et merci de prendre un coup d'oeil à la question.
L'arrière-plan
J'ai plusieurs machines qui ne cesse de générer plusieurs (jusqu'à 300) de PHP console de scripts dans un très court laps de temps. Ces scripts s'exécutent rapidement (moins d'une seconde), puis sur quitter. Tous ces scripts besoin d'un accès en lecture seule à un grand trie structure qui serait très coûteux pour charger en mémoire à chaque fois l'un des scripts fonctionne. Le serveur fonctionne avec Linux.
Ma solution
Créer un C démon qui maintient le trie de structure dans la mémoire et reçoit les demandes du PHP clients. Il serait de recevoir une demande de la part de chacun de PHP clients, effectuer la recherche sur la structure de la mémoire et de répondre avec la réponse, l'économie de l'scripts PHP de faire ce travail. À la fois les demandes et les réponses sont des chaînes courtes (pas plus de 20 caractères)
Mon problème
Je suis très nouveau à C démons et de communication interprocessus. Après beaucoup de recherches, j'ai rétréci les choix pour les Files d'attente et les sockets de domaine Unix. Files d'attente de messages semblent suffisants parce que je pense (je me trompe peut-être) qu'ils en file d'attente toutes les demandes pour le démon de leur répondre en série. Les sockets de domaine Unix semble plus facile à utiliser, mais. Cependant, j'ai plusieurs questions, je n'ai pas été en mesure de trouver des réponses à:
- Comment un script PHP d'envoyer et de recevoir des messages ou d'utiliser une socket UNIX pour communiquer avec le démon? À l'inverse comment le C démon de garder une trace des processus PHP, il doit envoyer une réponse à?
- La plupart des exemples de démons que j'ai vu utiliser une boucle while infinie avec un sommeil condition à l'intérieur. Mon démon besoins de service de connexions qui peuvent venir à tout moment, et la latence de réponse est critique. Comment le démon de réagir si le script PHP qui envoie une demande alors qu'il dort? J'ai lu sur le sondage et epoll, serait-ce la bonne façon d'attendre un message reçu?
- Chaque processus PHP sera toujours envoyer une demande, puis s'attendre à recevoir une réponse. J'ai besoin de faire en sorte que si le démon est en bas /pas disponible, le processus PHP va attendre une réponse pour un maximum de temps, et si aucune réponse n'est reçue continuera sans égard au lieu de la pendaison. Cela peut-il être fait?
La réelle recherche de la structure de données est très rapide, je n'ai pas besoin de tout un complexe multi-threading ou solution similaire, comme je le crois, de la manipulation du demande dans une FIFO façon de faire assez. J'ai aussi besoin de keep it simple stupid, comme c'est une mission essentielle de service, et je suis assez nouveau à ce type de programme. (Je sais, mais je n'ai vraiment aucun moyen de contourner cela, et de l'expérience d'apprentissage sera grand)
Je voudrais vraiment l'apprécier extraits de code qui fait briller un peu de lumière dans les questions précises que j'ai. Des liens vers des guides et des indicateurs qui permettront d'approfondir ma compréhension dans ce monde glauque de bas niveau de la CIB sont également les bienvenus.
Merci pour votre aide!
Mise à jour
Savoir beaucoup plus maintenant que je l'ai fait au moment de poser cette question, je voulais juste faire remarquer à tous ceux qui souhaitent que les deux L'épargne cadre et ZeroMQ font un travail fantastique de l'abstraction à la dure, prise au niveau de la programmation. L'épargne vous donne même l'échafaudage pour le serveur gratuitement!
En fait, au lieu d'aller tout le travail de construction d'un serveur de réseau, pensez juste à vous écrire des applications de serveur de code à l'aide d'un bon serveur asynchrones qui a déjà résolu le problème pour vous. Bien sûr, les serveurs qui utilisent asynchrone IO sont parfaits pour les applications de réseau qui ne nécessitent pas intensive du PROCESSEUR de traitement (ou la boucle d'événement de blocs).
Exemples pour python: Twisted, gevent. Je préfère gevent, et je ne comprend pas la tornade, car il est axé sur le serveur HTTP de côté.
Exemples pour Ruby: EventMachine
Bien sûr, Node.js est essentiellement le choix par défaut pour un serveur asynchrone de nos jours.
Si vous voulez aller plus loin, lire le C10k Problème, et Unix Réseau De Programmation.
- Oui, le démon doit être d'interrogation, et je pense qu'avec les sockets unix tout ce que vous avez à faire est de sockets compiler le support en PHP.. mais je ne suis pas complètement sûr
Vous devez vous connecter pour publier un commentaire.
Je soupçonne L'épargne est ce que vous voulez. Vous devriez écrire un peu de colle le code PHP <-l'épargne-> C++ <-> C, mais ce serait sans doute plus solide que le roulement de votre propre.
Vous pouvez également charger la structure de données dans la mémoire partagée à l'aide de PHP mémoire partagée les fonctions http://www.php.net/manual/en/book.shmop.php.
Oh, ce n'est pas évident à partir de la documentation, mais la coordination de la variable $key dans shmop_open. Tous les processus ont besoin d'accéder à la mémoire partagée doit avoir la même touche$. Ainsi, un processus crée de la mémoire partagée avec la touche$. Les autres processus qui peuvent ensuite accéder à cette mémoire partagée s'ils utilisent la même touche$. Je crois que vous pouvez choisir ce que vous voulez pour la touche$.
Voici un exemple où le script php envoie une demande à un C démon et puis attend la réponse. Il utilise les sockets de domaine Unix en mode datagramme de sorte qu'il est simple et rapide.
client.php
serveur.c
nanomsg est codé dans la plaine, C donc je suppose que c'est mieux adapté pour vos besoins de l'Épargne et de ZeroMQ qui sont codées en C++.
Il a les enveloppeurs pour de nombreux langages dont PHP.
Voici un exemple de travail à l'aide de la
NN_PAIR
protocole: (vous pouvez utiliserNN_REQREP
trop)client.php
serveur.c
Le "problème" (peut-être pas?) il peut certainement être beaucoup de consommateurs/producteurs sur le SysV MQs. Bien que parfaitement possible, pour ce que vous faites si vous n'avez pas nécessairement besoin d'un m:n besoin sur le producteur:la consommation de ressources de modèle, vous avez une demande/réponse modèle ici.
Vous pouvez obtenir un peu étrange décrochements avec SysV MQ comme il est.
Tout d'abord, êtes-vous sûr que INET sockets ne sont pas assez rapide pour vous? Un rapide PHP, par exemple en utilisant les sockets de domaine unix est à http://us.php.net/socket-create-pair (tout comme l'exemple de code bien sûr, l'utilisation socket_create() du PHP endpoint).
Bien que je ne l'ai jamais essayé, memcached appropriée Extension PHP devrait éliminer la plupart des tâches rébarbatives.
Précisions: j'ai été en supposant implicitement que si vous avez fait cela, vous devez mettre les feuilles individuelles de la trie dans la memcache aplaties à l'aide de touches, creusement de fossés de la trie. La faisabilité et l'opportunité de cette approche, bien sûr, dépend de nombreux facteurs, d'abord et avant tout être la source de données.
L'IPC entre script peut être fait beaucoup plus facilement à l'aide de Tuyaux. Ce qui rend beaucoup plus simple de mise en œuvre.