Table des matières
Solution conventionnelle :
Problèmes existants :
Objectifs d'optimisation :
Solution :
Avantages de l'utilisation de la communication par canal bidirectionnel :
Étapes spécifiques de mise en œuvre :
Grâce au
结论:
相关问题:
Maison développement back-end tutoriel php PHP communique avec Golang

PHP communique avec Golang

Apr 04, 2017 pm 02:40 PM
golang php

Une scène que j'ai rencontrée récemment : phpUne fonction tierce (segmentation des mots balbutiants) doit être utilisée dans le projet, et il se trouve qu'il y a une bibliothèque de classes écrite en Golang sur github Alors la question se pose, comment réaliser la communication entre différentes langues. . Qu'en est-il ?

Solution conventionnelle :

  • Écrivez un service http/TCP en Golang, et php communique avec Golang via http/TCP

  • Golang est encapsulé sous forme d'extension php

  • PHP appelle le fichier exécutable Golang via les commandes système

Problèmes existants :

  • Requêtes http, les E/S réseau prendront beaucoup de temps

  • Beaucoup de code doit être encapsulé

  • Chaque fois que PHP appelle un programme Golang, il doit être initialisé, ce qui prend beaucoup de temps

Objectifs d'optimisation :

  • Le programme Golang n'est initialisé qu'une seule fois (car l'initialisation prend du temps)

  • Toutes les requêtes n'ont pas besoin de passer par le réseau

  • Essayez de ne pas trop modifier le code

Solution :

  • Package Golang simple, compilez la bibliothèque de classes tierce dans un exécutable fichier

  • PHP et Golang communiquent via des tuyaux bidirectionnels

Avantages de l'utilisation de la communication par canal bidirectionnel :

1 : encapsulation minimale de la bibliothèque de classes Golang originale est requise
2 : Meilleures performances (la communication IPC est le meilleur moyen de communiquer entre les processus)
3 : Aucune requête réseau n'est requise, ce qui permet de gagner beaucoup de temps
4 : Le programme ne doit être initialisé qu'une seule fois et reste en mémoire

Étapes spécifiques de mise en œuvre :

  • 1 : Démo d'appel originale dans la bibliothèque de classe

          package main
          import (
              "fmt"
              "github.com/yanyiwu/gojieba"
              "strings"
          )
    
          func main() {
              x := gojieba.NewJieba()
              defer x.Free()
    
              s := "小明硕士毕业于中国科学院计算所,后在日本京都大学深造"
              words := x.CutForSearch(s, true)
              fmt.Println(strings.Join(words, "/"))
          }
    Copier après la connexion

    Enregistrez le fichier sous main.go , vous pouvez exécuter

  • 2 : Le code ajusté est :

          package main
          import (
              "bufio"
              "fmt"
              "github.com/yanyiwu/gojieba"
              "io"
              "os"
              "strings"
          )
    
          func main() {
    
              x := gojieba.NewJieba(
                  "/data/tmp/jiebaDict/jieba.dict.utf8", 
                  "/data/tmp/jiebaDict/hmm_model.utf8", 
                  "/data/tmp/jiebaDict/user.dict.utf8"
              )
              defer x.Free()
    
              inputReader := bufio.NewReader(os.Stdin)
              for {
                  s, err := inputReader.ReadString('\n')
                  if err != nil && err == io.EOF {
                      break
                  }
                  s = strings.TrimSpace(s)
    
                  if s != "" {
                      words := x.CutForSearch(s, true)
                      fmt.Println(strings.Join(words, " "))
                  } else {
                      fmt.Println("get empty \n")
                  }
              }
          }
    Copier après la connexion
    Cela ne prend qu'un quelques ajustements simples à réaliser : à partir de l'entrée standard Recevez

    chaîne , puis sortie
    après la segmentation des mots Test :

      # go build test
      # ./test
      # //等待用户输入,输入”这是一个测试“
      # 这是 一个 测试 //程序
    Copier après la connexion
  • 3 : Utilisez cat pour communiquer avec Golang pour un test simple
  • Sortie normale, indiquant que cat peut interagir avec Golang normalement
      //准备一个title.txt,每行是一句文本
      # cat title.txt | ./test
    Copier après la connexion

  • 4 : PHP communique avec Golang
  • Chat illustré ci-dessus Pour communiquer avec Golang, un tuyau unidirectionnel est utilisé. Autrement dit : les données ne peuvent être transmises que de cat à Golang. Les données sorties par Golang ne sont pas renvoyées à cat, mais sont directement affichées à l'écran. Mais l'exigence de l'article est la suivante : php communique avec Golang. Autrement dit, php doit transmettre les données à Golang, et Golang doit également renvoyer les résultats d'exécution à php. Un pipeline bidirectionnel doit donc être mis en place.
    L'utilisation des pipes en PHP :
    , je n'entrerai pas dans les détails car cette méthode ne peut pas résoudre le problème de l'article. popen("/path/test") Pipeline bidirectionnel :

          $descriptorspec = array( 
              0 => array("pipe", "r"), 
                1 => array("pipe", "w")
          );
          $handle = proc_open(
              '/webroot/go/src/test/test', 
              $descriptorspec, 
              $pipes
          );
          fwrite($pipes['0'], "这是一个测试文本\n");
          echo fgets($pipes[1]);
    Copier après la connexion
    Explication : Utilisez proc_open pour ouvrir un processus et appeler le programme Golang. Dans le même temps, un pipeline bidirectionnel pipes

    array est renvoyé. PHP écrit les données dans $pipe['0'] et lit les données dans $pipe['1'].

  • Eh bien, peut-être avez-vous découvert que je suis le fichier titre, et l'accent ici n'est pas seulement sur la façon dont PHP et Golang communiquent. Au lieu de cela, nous introduisons une méthode :
Laissez n'importe quelle langue communiquer via un canal bidirectionnel.

(Toutes les langues implémenteront le contenu lié au pipeline) Test :

Grâce au

test de comparaison

, calculez le temps pris par chaque processus. Le fichier title.txt mentionné ci-dessous contient 1 million de lignes de texte. Chaque ligne de texte est le titre du produit extrait de la plateforme b2b1 : Le processus global prend du temps

<a. href="http%20://www.php.cn/wiki/1268.html" target="_blank">time<p> cat title.txt ./test > /www.php .cn/wiki/62.html" target="_blank">null<br></p></a.><a href="http://www.php.cn/wiki/1268.html" target="_blank">time</a> cat title.txt | ./test > /dev/<a href="http://www.php.cn/wiki/62.html" target="_blank">null</a>
Prend du temps : 14,819 secondes, dont :

  • Le processus cat lit le texte

  • Transmettre les données à Golang via le tuyau

  • Golang traite les données et renvoie le résultat à l'écran

2 : Il faut du temps pour calculer la fonction de segmentation de mots

. Solution : Supprimez l'appel de la fonction de segmentation de mots, c'est-à-dire : Commentaire et supprimez la ligne de code qui appelle la segmentation de mots dans le code source de Golang
time cat title.txt | ./test > /dev/null

Prend du temps : 1,817 secondes, le temps consommé comprend :

  • le processus cat lit le texte

  • transfère les données vers Golang via un pipeline

  • Golang traite les données et renvoie le résultat à l'écran

分词耗时 = (第一步耗时) - (以上命令所耗时)
分词耗时 : 14.819 - 1.817 = 13.002

3:测试cat进程与Golang进程之间通信所占时间
time cat title.txt > /dev/null

耗时:0.015秒,消耗时间包含:

  • 进程cat读出文本

  • 通过管道将数据传入Golang

  • go处理数据,将结果返回到屏幕

管道通信耗时:(第二步耗时)  - (第三步耗时)
管道通信耗时: 1.817 - 0.015 = 1.802秒

4:PHP与Golang通信的时间消耗
编写简单的php文件:

        <?php
            $descriptorspec = array( 
                0 => array("pipe", "r"), 
                1 => array("pipe", "w")
            );

            $handle = proc_open(
                '/webroot/go/src/test/test', 
                $descriptorspec, 
                $pipes
            );

            $fp = fopen("title.txt", "rb");

            while (!feof($fp)) {
                fwrite($pipes['0'], trim(fgets($fp))."\n");
                echo fgets($pipes[1]);
            }

            fclose($pipes['0']);
            fclose($pipes['1']);
            proc_close($handle);
Copier après la connexion

流程与上面基本一致,读出title.txt内容,通过双向管道传入Golang进程分词后,再返回给php (比上面的测试多一步:数据再通过管道返回)
time php popen.php > /dev/null

耗时:24.037秒,消耗时间包含:

  • 进程PHP读出文本

  • 通过管道将数据传入Golang

  • Golang处理数据

  • Golang将返回结果再写入管道,PHP通过管道接收数据

  • 将结果返回到屏幕

结论:

1 :整个分词过程中的耗时分布

使用cat控制逻辑耗时:        14.819 秒
使用PHP控制逻辑耗时:         24.037 秒(比cat多一次管道通信)
单向管道通信耗时:           1.8    秒
Golang中的分词函数耗时:     13.002 秒
Copier après la connexion

2:分词函数的性能: 单进程,100万商品标题分词,耗时13秒
以上时间只包括分词时间,不包括词典载入时间。但在本方案中,词典只载入一次,所以载入词典时间可以忽略(1秒左右)

3:PHP比cat慢 (这结论有点多余了,呵呵)
语言层面慢: (24.037 - 1.8 - 14.819) / 14.819 = 50%
单进程对比测试的话,应该不会有哪个语言比cat更快。

相关问题:

  • 1:以上Golang源码中写的是一个循环,也就是会一直从管道中读数据。那么存在一个问题:是不是php进程结束后,Golang的进程还会一直存在?

    管道机制自身可解决此问题。管道提供两个接口:读、写。当写进程结束或者意外挂掉时,读进程也会报错,以上Golang源代码中的err逻辑就会执行,Golang进程结束。
    但如果PHP进程没有结束,只是暂时没有数据传入,此时Golang进程会一直等待。直到php结束后,Golang进程才会自动结束。

  • 2:能否多个php进程并行读写同一个管道,Golang进程同时为其服务?

    不可以。管道是单向的,如果多个进程同时向管道中写,那Golang的返回值就会错乱。
    可以多开几个Golang进程实现,每个php进程对应一个Golang进程。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Expliquez les jetons Web JSON (JWT) et leur cas d'utilisation dans les API PHP. Expliquez les jetons Web JSON (JWT) et leur cas d'utilisation dans les API PHP. Apr 05, 2025 am 12:04 AM

JWT est une norme ouverte basée sur JSON, utilisée pour transmettre en toute sécurité des informations entre les parties, principalement pour l'authentification de l'identité et l'échange d'informations. 1. JWT se compose de trois parties: en-tête, charge utile et signature. 2. Le principe de travail de JWT comprend trois étapes: la génération de JWT, la vérification de la charge utile JWT et l'analyse. 3. Lorsque vous utilisez JWT pour l'authentification en PHP, JWT peut être généré et vérifié, et les informations sur le rôle et l'autorisation des utilisateurs peuvent être incluses dans l'utilisation avancée. 4. Les erreurs courantes incluent une défaillance de vérification de signature, l'expiration des jetons et la charge utile surdimensionnée. Les compétences de débogage incluent l'utilisation des outils de débogage et de l'exploitation forestière. 5. L'optimisation des performances et les meilleures pratiques incluent l'utilisation des algorithmes de signature appropriés, la définition des périodes de validité raisonnablement,

Expliquez la liaison statique tardive en PHP (statique: :). Expliquez la liaison statique tardive en PHP (statique: :). Apr 03, 2025 am 12:04 AM

Liaison statique (statique: :) ​​implémente la liaison statique tardive (LSB) dans PHP, permettant à des classes d'appel d'être référencées dans des contextes statiques plutôt que de définir des classes. 1) Le processus d'analyse est effectué au moment de l'exécution, 2) Recherchez la classe d'appel dans la relation de succession, 3) il peut apporter des frais généraux de performance.

Quelles sont les méthodes PHP Magic (__construct, __ destruct, __ call, __get, __set, etc.) et fournir des cas d'utilisation? Quelles sont les méthodes PHP Magic (__construct, __ destruct, __ call, __get, __set, etc.) et fournir des cas d'utilisation? Apr 03, 2025 am 12:03 AM

Quelles sont les méthodes magiques de PHP? Les méthodes magiques de PHP incluent: 1. \ _ \ _ Construct, utilisé pour initialiser les objets; 2. \ _ \ _ Destruct, utilisé pour nettoyer les ressources; 3. \ _ \ _ Appel, gérer les appels de méthode inexistants; 4. \ _ \ _ GET, Implémentez l'accès à l'attribut dynamique; 5. \ _ \ _ SET, Implémentez les paramètres d'attribut dynamique. Ces méthodes sont automatiquement appelées dans certaines situations, améliorant la flexibilité et l'efficacité du code.

Expliquez l'expression de correspondance (PHP 8) et comment elle diffère du commutateur. Expliquez l'expression de correspondance (PHP 8) et comment elle diffère du commutateur. Apr 06, 2025 am 12:03 AM

Dans PHP8, les expressions de correspondance sont une nouvelle structure de contrôle qui renvoie différents résultats en fonction de la valeur de l'expression. 1) Il est similaire à une instruction Switch, mais renvoie une valeur au lieu d'un bloc d'instruction d'exécution. 2) L'expression de correspondance est strictement comparée (===), ce qui améliore la sécurité. 3) Il évite les éventuelles omissions de rupture dans les instructions de commutation et améliore la simplicité et la lisibilité du code.

Qu'est-ce que la contrefaçon de demande inter-sites (CSRF) et comment implémentez-vous la protection CSRF dans PHP? Qu'est-ce que la contrefaçon de demande inter-sites (CSRF) et comment implémentez-vous la protection CSRF dans PHP? Apr 07, 2025 am 12:02 AM

En PHP, vous pouvez prévenir efficacement les attaques du CSRF en utilisant des jetons imprévisibles. Les méthodes spécifiques comprennent: 1. Générer et intégrer les jetons CSRF dans la forme; 2. Vérifiez la validité du jeton lors du traitement de la demande.

PHP et Python: comparaison de deux langages de programmation populaires PHP et Python: comparaison de deux langages de programmation populaires Apr 14, 2025 am 12:13 AM

PHP et Python ont chacun leurs propres avantages et choisissent en fonction des exigences du projet. 1.Php convient au développement Web, en particulier pour le développement rapide et la maintenance des sites Web. 2. Python convient à la science des données, à l'apprentissage automatique et à l'intelligence artificielle, avec syntaxe concise et adaptée aux débutants.

Expliquez des types stricts (Declare (strict_types = 1);) en php. Expliquez des types stricts (Declare (strict_types = 1);) en php. Apr 07, 2025 am 12:05 AM

Les types stricts en PHP sont activés en ajoutant Declare (strict_types = 1); en haut du fichier. 1) Il force la vérification du type des paramètres de fonction et des valeurs de retour pour éviter la conversion de type implicite. 2) L'utilisation de types stricts peut améliorer la fiabilité et la prévisibilité du code, réduire les bogues et améliorer la maintenabilité et la lisibilité.

Comment pouvez-vous empêcher une classe d'être prolongée ou une méthode d'être remplacée en PHP? (mot-clé final) Comment pouvez-vous empêcher une classe d'être prolongée ou une méthode d'être remplacée en PHP? (mot-clé final) Apr 08, 2025 am 12:03 AM

Dans PHP, le mot-clé final est utilisé pour empêcher les classes d'être héritées et les méthodes écrasées. 1) Lors du marquage de la classe comme final, la classe ne peut pas être héritée. 2) Lors du marquage de la méthode comme final, la méthode ne peut pas être réécrite par la sous-classe. L'utilisation de mots clés finaux garantit la stabilité et la sécurité de votre code.

See all articles