PHP kommuniziert mit Golang
Eine Szene, auf die ich kürzlich gestoßen bin: phpEine Funktion eines Drittanbieters (Stammwortsegmentierung) muss verwendet werden im Projekt, und es gibt zufällig eine in Golang geschriebene Klassenbibliothek auf gitHub. Dann stellt sich die Frage, wie man die Kommunikation zwischen verschiedenen Sprachen erreichen kann . Was ist mit?
Konventionelle Lösung:
Schreiben Sie einen http/TCP-Dienst in Golang, und PHP kommuniziert mit Golang über http/TCP
-
Golang ist als PHP-Erweiterung gekapselt
PHP ruft die ausführbare Golang-Datei über Systembefehle auf
Bestehende Probleme:
HTTP-Anfragen und Netzwerk-E/A nehmen viel Zeit in Anspruch
Viel Code muss gekapselt werden
Jedes Mal, wenn PHP ein Golang-Programm aufruft, muss es initialisiert werden, was viel Zeit in Anspruch nimmt
Optimierungsziele:
-
Das Golang-Programm wird nur einmal initialisiert (da die Initialisierung zeitaufwändig ist)
Alle Anfragen müssen nicht über das Netzwerk gehen
-
Versuchen Sie, den Code nicht zu stark zu ändern
Lösung:
Einfaches Golang-Paket, kompilieren Sie die Klassenbibliothek eines Drittanbieters in eine ausführbare Datei Datei
-
PHP und Golang kommunizieren über bidirektionale Pipes
Vorteile der Verwendung bidirektionaler Pipe-Kommunikation:
1: Nur minimale Kapselung der ursprünglichen Golang-Klassenbibliothek ist erforderlich
2: Beste Leistung (IPC-Kommunikation ist die beste Möglichkeit, zwischen Prozessen zu kommunizieren)
3: Es sind keine Netzwerkanforderungen erforderlich, was viel Zeit spart
4: Das Programm Muss nur einmal initialisiert werden und bleibt im Speicher
Spezifische Implementierungsschritte:
-
1: Original-Aufrufdemo in der Klassenbibliothek
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, "/")) }
Nach dem Login kopierenSpeichern Sie die Datei als main.go, Sie können
-
2 ausführen: Der angepasste Code lautet:
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") } } }
Nach dem Login kopierenEs dauert nur eine einige einfache Anpassungen, die erreicht werden müssen: Von der Standardeingabe erhalten Sie Zeichenfolge und geben dann
nach der Wortsegmentierung aus. Test:# go build test # ./test # //等待用户输入,输入”这是一个测试“ # 这是 一个 测试 //程序
Nach dem Login kopieren -
3: Verwenden Sie cat, um für einen einfachen Test mit Golang zu kommunizieren
//准备一个title.txt,每行是一句文本 # cat title.txt | ./test
Nach dem Login kopierenNormale Ausgabe, die anzeigt, dass cat normal mit Golang interagieren kann
-
4: PHP kommuniziert mit Golang
Katze oben abgebildet Zur Kommunikation mit Golang wird eine Einweg-Pipe verwendet. Das heißt: Daten können nur von cat an Golang übergeben werden. Die von Golang ausgegebenen Daten werden nicht an cat zurückgegeben, sondern direkt auf dem Bildschirm ausgegeben. Die Anforderung im Artikel lautet jedoch: PHP kommuniziert mit Golang. Das heißt, PHP muss Daten an Golang übergeben und Golang muss auch die Ausführungsergebnisse an PHP zurückgeben. Daher muss eine bidirektionale Pipeline eingeführt werden.
Die Verwendung von Pipes in PHP:popen("/path/test")
, ich werde nicht auf Details eingehen, da diese Methode das Problem im Artikel nicht lösen kann.
Bidirektionale Pipeline:$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]);
Nach dem Login kopierenErläuterung: Verwenden Sie proc_open, um einen Prozess zu öffnen und das Golang-Programm aufzurufen. Gleichzeitig wird ein bidirektionales Pipeline-Pipesarray zurückgegeben, das PHP Daten in $pipe['0'] schreibt und Daten aus $pipe['1'] liest.
Nun, vielleicht haben Sie herausgefunden, dass ich die Titeldatei bin und der Fokus hier nicht nur darauf liegt, wie PHP und Golang kommunizieren. Stattdessen stellen wir eine Methode vor: Lassen Sie jede Sprache über eine Zwei-Wege-Pipeline kommunizieren. (Alle Sprachen implementieren Pipeline-bezogene Inhalte)
Test:
Berechnen Sie anhand des Vergleichstests die Zeit, die jeder Prozess benötigt. Die unten erwähnte Datei title.txt enthält 1 Million Textzeilen, jede Textzeile ist der Produkttitel, der von der B2B-Plattform übernommen wurde
1: Der Gesamtprozess ist zeitaufwändig<a href="http%20://www.php.cn/wiki/1268.html" target="_blank">time<code><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>
cat title.txt |./test > /www.php .cn/wiki/62.html" target="_blank">null
Zeitaufwendig: 14,819 Sekunden, einschließlich:
- Die Prozesskatze liest den Text vor
- Übergeben Sie die Daten über die Pipe an Golang
- Golang verarbeitet die Daten und gibt das Ergebnis auf dem Bildschirm zurück
2: Die Berechnung der Wortsegmentierungsfunktion dauert einige Zeit. Lösung: Entfernen Sie den Aufruf der Wortsegmentierungsfunktion, also: Kommentar
und entfernen Sie die Codezeile, die die Wortsegmentierung im Golang-Quellcode aufruft time cat title.txt | ./test > /dev/null
Zeitaufwendig: 1,817 Sekunden, die verbrauchte Zeit umfasst:
- Prozesskatze liest Text vor
- Daten über Pipeline in Golang übertragen
Golang verarbeitet die Daten
und gibt das Ergebnis auf dem Bildschirm zurück
分词耗时 = (第一步耗时) - (以上命令所耗时)
分词耗时 : 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);
流程与上面基本一致,读出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 秒
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进程。
Das obige ist der detaillierte Inhalt vonPHP kommuniziert mit Golang. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



JWT ist ein offener Standard, der auf JSON basiert und zur sicheren Übertragung von Informationen zwischen Parteien verwendet wird, hauptsächlich für die Identitätsauthentifizierung und den Informationsaustausch. 1. JWT besteht aus drei Teilen: Header, Nutzlast und Signatur. 2. Das Arbeitsprinzip von JWT enthält drei Schritte: Generierung von JWT, Überprüfung von JWT und Parsingnayload. 3. Bei Verwendung von JWT zur Authentifizierung in PHP kann JWT generiert und überprüft werden, und die Funktionen und Berechtigungsinformationen der Benutzer können in die erweiterte Verwendung aufgenommen werden. 4. Häufige Fehler sind Signaturüberprüfungsfehler, Token -Ablauf und übergroße Nutzlast. Zu Debugging -Fähigkeiten gehört die Verwendung von Debugging -Tools und Protokollierung. 5. Leistungsoptimierung und Best Practices umfassen die Verwendung geeigneter Signaturalgorithmen, das Einstellen von Gültigkeitsperioden angemessen.

Statische Bindung (statisch: :) implementiert die späte statische Bindung (LSB) in PHP, sodass das Aufrufen von Klassen in statischen Kontexten anstatt Klassen zu definieren. 1) Der Analyseprozess wird zur Laufzeit durchgeführt.

Was sind die magischen Methoden von PHP? Zu den magischen Methoden von PHP gehören: 1. \ _ \ _ Konstrukt, verwendet, um Objekte zu initialisieren; 2. \ _ \ _ Destruct, verwendet zur Reinigung von Ressourcen; 3. \ _ \ _ Call, behandeln Sie nicht existierende Methodenaufrufe; 4. \ _ \ _ GET, Implementieren Sie den dynamischen Attributzugriff; 5. \ _ \ _ Setzen Sie dynamische Attributeinstellungen. Diese Methoden werden in bestimmten Situationen automatisch aufgerufen, wodurch die Code -Flexibilität und -Effizienz verbessert werden.

In PHP8 sind Übereinstimmungsausdrücke eine neue Kontrollstruktur, die unterschiedliche Ergebnisse basierend auf dem Wert des Expression zurückgibt. 1) Es ähnelt einer Switch -Anweisung, gibt jedoch einen Wert anstelle eines Ausführungsanweisungsblocks zurück. 2) Der Match -Ausdruck wird streng verglichen (===), was die Sicherheit verbessert. 3) Es vermeidet mögliche Auslassungen in Switch -Anweisungen und verbessert die Einfachheit und Lesbarkeit des Codes.

Backend Learning Path: Die Erkundungsreise von Front-End zu Back-End als Back-End-Anfänger, der sich von der Front-End-Entwicklung verwandelt, Sie haben bereits die Grundlage von Nodejs, ...

In PHP können Sie CSRF -Angriffe effektiv verhindern, indem Sie unvorhersehbare Token verwenden. Spezifische Methoden umfassen: 1. CSRF -Token in der Form erzeugen und einbetten; 2. Überprüfen Sie die Gültigkeit des Tokens bei der Bearbeitung der Anfrage.

Welche Bibliotheken in GO werden von großen Unternehmen oder bekannten Open-Source-Projekten entwickelt? Bei der Programmierung in Go begegnen Entwickler häufig auf einige häufige Bedürfnisse, ...

Strenge Typen in PHP werden durch Hinzufügen von Declare aktiviert (strict_types = 1); oben in der Datei. 1) IT erzwingt die Typprüfung der Funktionsparameter und der Rückgabewerte, um die implizite Typumwandlung zu verhindern. 2) Die Verwendung strenger Typen kann die Zuverlässigkeit und Vorhersehbarkeit des Codes verbessern, Fehler reduzieren und die Wartbarkeit und Lesbarkeit verbessern.
