返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP如何调用Go服务
  • 277
分享到

PHP如何调用Go服务

2023-06-15 05:06:52 277人浏览 独家记忆
摘要

这篇文章将为大家详细讲解有关PHP如何调用Go服务,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。问题服务耦合我们在开发过程中可能会遇到这样的情况:进程依赖于某服务,所以把服务耦合在进程代码中;服务初始化耗

这篇文章将为大家详细讲解有关PHP如何调用Go服务,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

问题

服务耦合

我们在开发过程中可能会遇到这样的情况:

  • 进程依赖于某服务,所以把服务耦合在进程代码中;

  • 服务初始化耗时长,拖慢了进程启动时间;

  • 服务运行要占用大量内存,多进程时内存损耗严重。

文本匹配服务,它是消息处理流程中的一环,被多个消息处理进程依赖,每次初始化进程要 6秒 左右时间构造 Trie 树,而且服务读取关键词大文件、使用树组构造 Trie 树,会占用大量(目前设置为 256M )内存。

我已经把进程写成了守护进程的形式,让它们长时间执行,虽然不用更多地考虑初始化时间了,但占用内存量巨大的问题没有办法。如果关键词量再大一些,一台机器上面跑十来个消息处理进程后就干不了其他了。

而且,如果有需求让我把文本匹配服务封装为接口给外部调用呢?我们知道,WEB 服务时,每一个请求处理进程的生存周期是从受理请求到响应结束,如果每次请求都用大量内存和时间来初始化服务,那接口响应时间和服务器压力可想而知。

服务抽取

这样,服务形式必须要改变,我们希望这个文本匹配这个服务能做到:

  • 随调随走,不依赖,不再与“消息处理服务”耦合在一起;

  • 一次初始化,进程运行期间持续提供服务;

  • 同步响应,高效而准确,最好能不用各种来保持资源占有;

解决办法也很简单,就是把这个文本匹配的服务抽取出来,单独作为一个守护进程来运行,像一个特殊的服务器,多个“消息处理服务”在有需要时能调用此服务进程。

现在,我们需要考虑文本匹配服务进程如何与外界通信,接受匹配请求,响应匹配结果。绕来绕去,问题还是回到了 进程间通信。

Unix Domain Sockets

进程间通信

进程间通信(IPC,Inter-Process Communication),指至少两个进程或线程间传送数据或信号的一些技术或方法。进程是计算机系统分配资源的最小单位(严格说来是线程)。每个进程都有自己的一部分独立的系统资源,彼此是隔离的。为了能使不同的进程互相访问资源并进行协调工作,才有了进程间通信。

进程间通信的方式有很多,网上对此介绍的也很多,下面根据文章的需求来分析一下这些方式:

  • 管道:管道是Unix最初的IPC形式,但它只能用于具有共同祖先进程的各个进程,无法用于在没有亲缘关系的进程。如果使用它,需要在“消息处理服务”中启动“文本匹配服务”,跟原来差别不大。

  • 命名管道:也被称为有名管道,它在Unix称为FIFO,它通过一个文件来进行进程间数据交互,但服务于多个进程时,需要添加锁来保证原子性,从而避免写入和读取不对应。

  • 信号和信号量:用于进程/线程事件级的通信,但它们能交流的信息太少。

  • 消息队列和共享内存:都是通过一个公共内存介质来进行通信

  • socket:通过Unix封装好的网络api来进行通信,像数据库、服务器都是通过这种方式实现,它们也能提供本地服务。不过网络socket固然能使用,但是要面临着数据包装和网络调用开销,也不是完美的选择。

简单介绍

当然还是有完美的方式的,这就是今天的主角 - Unix Domain Sockets ,它可以理解为一种特殊的 Socket,但它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程,所以在系统内通信效率更高。而且免去了网络问题,它也更能保证消息的完整性,既不会丢失也不会顺序错乱。

作为特殊的 Socket,它的创建、调用方式和网络 Socket 一样,一次完整的交互,服务端都要经过create、bind、listen、accept、read、write,客户端要通过create、connect、write、read。与普通 Socket 不同的是它绑定一个系统内的文件,而不是 IP 和端口。

适用场景

Unix Domain Sockets 真的是进程间通信的一个重型武器,用它可以快速实现进程间的数据、信息交互,而且不需要锁等繁杂操作,也不用考虑效率,可谓是简单高效。

当然,“重型武器” 的在各种场景下也有适合不适合。Unix Domain Sockets适用于以下场景:

  • 服务长时间存在。 Unix Domain Sockets 的服务端是个服务器一样的存在,在守护进程中,它阻塞并等待客户端连接的特性可以被充分利用。

  • 一服务器多客户端。它能通过 Socket 的文件描述符来区分不同的客户端,避免资源之间的锁操作。

  • 同一系统内。它只能在同一系统内进行进程数据复制,跨系统请使用传统 Sockets。

代码实现

接下来要 show code 了,不过学 php 的都知道,PHP 不太适合处理 CPU 密集形的任务,我刚好学了点 Go,一时手痒,就用 Go 实现了下 Trie 树,所以才牵扯到 PHP 和 Go 之间的通信,有了今天的文章。当然介绍的方法,并不只适合 PHP 与 Go 通信,其他语言也可以,至少 C系语言中是通用的。

Go 实现的 Trie 树

Trie树不再是今天的主题,这里介绍一下数据结构和需要注意的点。

// trie树结点定义type node struct {    depth    int    children map[int32]Node // 用map实现key-value型的 字符-节点 对应}

需要注意:

  • 使用 slice 的 append() 函数保存递增的匹配结果时,有可能由于 slice 容量不够而重新分配地址,所以要传入 slice 的地址来保存递增后的匹配结果结果,*result = append(*result, Word),最后再将递增之后的 slice 地址传回。

  • 由于 Go 中的编码统一使用的 utf-8,不用像 PHP 一样判断字符的边界,所以在进行关键词拆散和消息拆散时,直接使用 int32() 方法将关键词和消息都转换为成员为 int32 类型的 slice,匹配过程中就使用 int32 类型的数字来代表这个中文字符,匹配完成后再使用fmt.Printf("%c", int32)将其转换为中文。

Go Server

Go 中创建一个 socket 并使用的步骤非常简单,只是 Go 没有异常,判断 error 会比较恶心一点,不知道有没有大神有更好的写法。下面为了精简,把 error 全置空了。

 // 创建一个Unix domain soceket    socket, _ := net.Listen("unix", "/tmp/keyword_match.sock")    // 关闭时删除绑定的文件    defer syscall.Unlink("/tmp/keyword_match.sock")     // 无限循环监听和受理客户端请求    for {        client, _ := socket.Accept()                buf := make([]byte, 1024)        data_len, _ := client.Read(buf)        data := buf[0:data_len]        msg := string(data)                matched := trie.Match(tree, msg)        response := []byte("[]") // 给响应一个默认值        if len(matched) > 0 {            JSON_str, _ := json.Marshal(matched)            response = []byte(string(json_str))        }        _, _ = client.Write(response)    }

PHP Client

下面是 PHP 实现的客户端:

$msg = "msg";// 创建 连接 发送消息 接收响应 关闭连接$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);socket_connect($socket, '/tmp/keyword_match.sock');socket_send($socket, $msg, strlen($msg), 0);$response = socket_read($socket, 1024);socket_close($socket);// 有值则为匹配成功if (strlen($response) > 3) {    var_dump($response);}

小结

效率

这里总结一下这套设计的效率表现:

纯粹用 Go 进行文本关键词匹配,一千条数据运行一秒多,差不多是 PHP 效率的两倍。不过说好的 8倍效率呢?果然测评都是骗人的。当然,也可能是我写法有问题或者 Trie 树不在 Go 的发挥范围之内。然后是 PHP 使用 Unix Domain Socket 调用 Go 服务的耗时,可能是进程间复制数据耗时或 PHP 拖了后腿,3秒多一点,跟纯 PHP 脚本差不多。

杂谈

用 PHP 的都知道,PHP 因为解释型语言的特性和其高度的封装,导致其虽然在开发上速度很快,可是执行与其他语言相比略差。对此,业界的 FB 有 HHVM,PHP7 有 opcache 新特性,据说还要在 PHP8 添加 JIT,用以弥补其先天硬伤。

不过,对于开发者,特别是跟我一样对于效率有执著追求的人来说,在了解使用 PHP 的新特性之外,自己再掌握一门较高执行效率、开发效率略低的语言,用来写一些高计算量,逻辑单一的代码,与 PHP 互补或许会更好一点。

于是,在考虑良久,也见识了各种 Go 的支持者和反对者之间的撕逼后,我觉得还是要相信一下谷歌爸爸,毕竟也没什么其他我觉得可选的语言了。

另外C呢,虽然暂时开发中用不到,可是毕竟是当代N多语言的起源,偶尔写写数据结构、算法什么的以免生锈。而且学了些C,从 PHP 到 Go,切换起来还略有些得心应手的感觉~

关于“PHP如何调用Go服务”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: PHP如何调用Go服务

本文链接: https://lsjlt.com/news/278125.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • PHP如何调用Go服务
    这篇文章将为大家详细讲解有关PHP如何调用Go服务,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。问题服务耦合我们在开发过程中可能会遇到这样的情况:进程依赖于某服务,所以把服务耦合在进程代码中;服务初始化耗...
    99+
    2023-06-15
  • 详解PHP调用Go服务的正确方式
    目录问题服务耦合服务抽取Unix Domain Sockets进程间通信简单介绍适用场景代码实现Go 实现的 Trie 树Go ServerPHP Client小结效率杂谈问题 服务...
    99+
    2024-04-02
  • php如何调用c
    这篇文章将为大家详细讲解有关php如何调用c,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。c语言源码:php语言源码:php 在调用的时候是调用c语言编译后的结果:a.o...
    99+
    2024-04-02
  • Go timer如何调度
    目录1. 使用场景2. 图解源码2.1 四叉堆原理2.3 timer 是如何加入到 timer 堆上的?2.4 Reset 时 timer 是如何被操作的?2.5 Stop 时 ti...
    99+
    2024-04-02
  • 如何调用 PHP 函数?
    通过以下四个步骤调用 php 函数:1. 确定函数名称;2. 在调用前添加函数名称;3. 添加圆括号并传递参数;4. 函数执行,执行与名称关联的任务。 如何调用 PHP 函数:一步一步...
    99+
    2024-04-10
    函数 php
  • 如何使用Eclipse进行PHP的服务器端调试
    这篇文章将为大家详细讲解有关如何使用Eclipse进行PHP的服务器端调试,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。首先,得将您PHP本地运行时的php.ini里的xdebug.remote_enab...
    99+
    2023-06-04
  • 如何在 JavaScript 中调用 Go 函数?
    在现代软件开发领域中,跨语言开发已经成为了一个不可或缺的部分。为了能够在不同的平台之间协调工作,开发人员需要学习如何在不同的编程语言之间进行交互。在这篇文章中,我们将会介绍如何在 JavaScript 中调用 Go 函数。 Go 是一门高效...
    99+
    2023-08-22
    npm 函数 javascript
  • php runtime.php里如何调用别的php
    今天小编给大家分享一下php runtime.php里如何调用别的php的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。方法一...
    99+
    2023-07-05
  • php soap 方法如何调用
    php soap 方法如何调用?php下调用soap实现对接PHP5下SOAP调用实现过程本文以某公司iPhone 6手机预约接口开发为例,介绍PHP5下SOAP调用的实现过程。一、基础概念SOAP(Simple Object Access...
    99+
    2015-01-05
    php soap
  • javascript如何调用php方法
    这篇文章给大家分享的是有关javascript如何调用php方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。javascript调用php的方法:首先创建一个HTML示例文件和PHP示例文件;然后在HTML中添...
    99+
    2023-06-06
  • 如何在php中调用mysql
    本篇文章给大家分享的是有关如何在php中调用mysql,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。PHP访问MYSQL数据库的五个步骤详解(图)数据库在我们PHP日常开发中是...
    99+
    2023-06-15
  • php如何调用static方法
    本篇内容主要讲解“php如何调用static方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php如何调用static方法”吧!php调用static方法:1、创建一个PHP示例文件;2、定义...
    99+
    2023-07-04
  • unipush2 php服务端调用推送
    一、登陆开发者账号与配置unipush 1、注册登陆账号(使用Hbuilder登陆账号)     unicloud后台:uniCloud控制台     开发者中心:开发者中心           点击unipush的 菜单开通unipush...
    99+
    2023-08-31
    php
  • PHP如何用gdb调试源码
    这篇文章主要介绍了PHP如何用gdb调试源码的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇PHP如何用gdb调试源码文章都会有所收获,下面我们一起来看看吧。php编译时有一个debug模式,这个模式会关闭内存优...
    99+
    2023-07-04
  • php如何调用抽象方法
    在 PHP 中,抽象方法是一种不能在抽象类中实现但必须在其实现类中实现的方法。抽象方法可以定义在抽象类或接口中,并且其定义方式类似于普通方法,但以 abstract 关键字开头并省略方法体实现。抽象方法必须在子类中覆写实现。如果您想学习如何...
    99+
    2023-05-14
  • 如何在PHP中调用函数
    在PHP编程中,函数是非常重要的组件之一。函数是一段可被多次调用的代码块,能够执行特定的任务。除了提高代码的可重用性和可维护性,使用函数还可以简化代码,提高开发效率。本文将介绍如何在PHP中调用函数。内置函数PHP语言内置了许多常用的函数,...
    99+
    2023-05-18
    PHP编程 PHP函数 函数调用
  • php如何调用驾照题库
    本篇内容主要讲解“php如何调用驾照题库”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php如何调用驾照题库”吧!php调用驾照题库的方法:1、申请驾照题库API接口;2、配置申请的appkey...
    99+
    2023-07-04
  • php如何调用对象方法
    今天小编给大家分享一下php如何调用对象方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、创建对象在PHP中,调用对象方...
    99+
    2023-07-05
  • php方法如何调用方法
    这篇“php方法如何调用方法”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“php方法如何调用方法”文章吧。PHP是一种流行的...
    99+
    2023-07-05
  • php内部方法如何调用
    这篇文章主要介绍“php内部方法如何调用”,在日常操作中,相信很多人在php内部方法如何调用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php内部方法如何调用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作