Go Web App:如何将PHP脚本从Golang路由到PHP-FPM

Go Web App:如何将PHP脚本从Golang路由到PHP-FPM,go,Go,我有一个主网站和许多小网站。我目前正在使用Nginx和PHP来完成所有这些。我的计划是废除这两种模式,在Go中构建一个单一的web应用程序,它将为所有内容提供服务,这将有望减少负载和内存(特别是因为一些页面的计算量非常大) 我的问题是,如果我尝试移植一些很少使用的PHPBB论坛,那将是对时间的严重浪费。因此,我希望主网站都能通过Go web应用程序提供服务,但其他一些网站可以保留为PHP 我的问题是:我可以使用GoWeb应用程序将PHP脚本请求路由到PHP-FPM吗 我希望它能让我摆脱Nginx

我有一个主网站和许多小网站。我目前正在使用Nginx和PHP来完成所有这些。我的计划是废除这两种模式,在Go中构建一个单一的web应用程序,它将为所有内容提供服务,这将有望减少负载和内存(特别是因为一些页面的计算量非常大)

我的问题是,如果我尝试移植一些很少使用的PHPBB论坛,那将是对时间的严重浪费。因此,我希望主网站都能通过Go web应用程序提供服务,但其他一些网站可以保留为PHP

我的问题是:我可以使用GoWeb应用程序将PHP脚本请求路由到PHP-FPM吗

我希望它能让我摆脱Nginx,web应用程序将处理所有传入的流量,并直接从自己的代码为主站点提供服务,但对于仍然使用PHP的不太重要的站点,可以通过Go应用程序将这些请求路由到PHP-FPM(以及所有完整的请求信息,包括cookies、POST VAR等)来提供服务


有什么想法吗?

要重定向到另一个url,您可以使用
httputil.HostReverseProxy

    origin := "http://php.website.com"
    originUrl, err := url.Parse(origin)
    if err != nil {
        log.Fatal(err)
    }

    proxy := httputil.NewSingleHostReverseProxy(originUrl)
    prev := proxy.Director

    proxy.Director = func(req *http.Request) {
        prev(req)
        req.Host = originUrl.Host
    }

    http.HandleFunc("/php", proxy.ServeHTTP)

PHP-FPM正在unix套接字上侦听。因此,您可以使用以下方法简单地连接到其unix套接字:

然后在生成的连接上写入所需内容。您可以使用该方法,该方法需要使用
net
包进行连接处理(或劫持更经典的
http
服务器)


尽管如此,我还是建议不要用go来处理这个问题:nginx效率高、速度快、内存使用率低,而且会比您做得更好。您应该做的(IMHO)是移植每个您想使用的应用程序,然后使用nginx作为反向代理。如果您关注性能,您可以使用unix socket在nginx和应用程序之间进行通信,因为这比监听TCP端口要快。

我意识到这是一篇古老的文章,但以下是我的答案,因为在遇到基本相同的问题后,我不得不亲自研究这个问题

TL;DR I建议通过HTTP代理Nginx并让它与PHP-FPM对话——不是因为Nginx更好、更快、更光鲜,而是因为这条代码路径经过了几个数量级的测试和维护,缺点也很小。

两种明显的方法:

A) 通过go to PHP使用Nginx和代理请求。这可以通过@fabrizioM的回答中描述的httputil完成,本质上是通过HTTP将请求代理到Nginx,然后Nginx将其转换为FastCGI并调用PHP-FPM

B) 使用FastCGI协议的实现直接从Go调用PHP-FPM。我还没有尝试过,但有很多Go库声称可以做到这一点,包括:

  • 还有更多
n、 b.我意识到其中一些可能不存在于被问到的问题中

截至本文撰写时,上面的第一个有21颗星

在我看来,虽然Nginx是一个很好的web服务器,但与在Go中提供静态文件相比,它几乎没有什么好处。然而,在这里使用Nginx有一个很大的好处,那就是FastCGI代码的稳定性和维护。显然,在Go中通过FastCGI调用并不是一种非常流行的方法,我不知道我对实现有多信任。另一方面,有数以百万计的PHP开发人员对Nginx+PHP-FPM信誓旦旦,而且它经过了良好的测试和维护

在使用HTTP代理时还有其他一些好处,例如,当您在本地开发过程中通过Internet将Go进程的请求转发到PHP服务器所在的任何位置时,它更有可能正常工作。这使得你可以很容易地破解你的Go应用程序,而不必运行所有PHP内容的本地副本,同时还能看到所有功能


因此,虽然这两种方法都是可行的,但我的建议是仅包括Nginx,因为它是一种更好的受支持代码路径,您的请求可以通过它,它具有一些实际的本地开发优势,并且性能损失可以忽略不计。我认为这些论点比“Nginx在服务静态文件方面很好”或“内存使用率低”等论点更有力。

我猜Nginx是您的问题中最小的,我建议您将Nginx与Go结合使用。这也将解决PHP/Go路由问题。你有什么理由放弃nginx吗?不是真的,只是让它在那里运行并浪费我的CPU似乎是多余的。特别是因为它所要做的就是路由到PHP-FPM。你有一个用于所有这些站点的公共会话存储吗?像redis/memcached这样的外部会话存储将有助于迁移。这些站点有单独的会话。我打算为所有将转换为Go的站点实施我自己的会话。PHP用户可以使用他们自己的PHP会话。我的想法是,如果将网站编译到web应用程序中,该应用程序只会运行一个实例。这意味着会话变量可以保存在内存中,而不是重新加载,静态文件也可以保存在内存中。这意味着整个站点几乎没有IO。如果我使用Nginx,并且每次访问页面或文件时都重复执行该操作,那么所有这些性能优势都将丢失。这难道不意味着使用Nginx效率很低吗?此外,我也不确定Nginx做了什么,使其比我的Go web应用更好-是否存在安全风险?即使在Nginx之后并分成小块,您的应用程序仍将运行,并将VAR保留在内存中。除非你的应用程序真的是一个应用程序,否则你没有任何理由共享会话变量、静态文件等。你不会从I/O中获得任何好处,nginx在提供静态文件方面非常高效。而且维护多个小应用程序比维护一个大应用程序更容易。特别是如果那些应用程序是无关的,我仍然看不到任何adv
conn, err:= net.Dial("unix","", "/path/to/php-fpm.sock")