Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 在围棋中+;FastCGI,使用多个处理程序有意义吗?_Go_Fastcgi - Fatal编程技术网

Go 在围棋中+;FastCGI,使用多个处理程序有意义吗?

Go 在围棋中+;FastCGI,使用多个处理程序有意义吗?,go,fastcgi,Go,Fastcgi,这里是地鼠新手。请善待:-) 我有一个设置,我在一个共享服务器上有一个帐户,该服务器运行Apache+FastCGI,我对此没有控制权。不过,它与Go的接口很平滑。我更习惯于在net/http中使用Go,但弄清楚如何在net/http/fcgi中使用它似乎很简单。以下是我的最小测试应用程序: package main import ( "fmt" "net/http" "net/http/fcgi" ) func handler(w http.ResponseWrit

这里是地鼠新手。请善待:-)

我有一个设置,我在一个共享服务器上有一个帐户,该服务器运行Apache+FastCGI,我对此没有控制权。不过,它与Go的接口很平滑。我更习惯于在
net/http
中使用Go,但弄清楚如何在
net/http/fcgi
中使用它似乎很简单。以下是我的最小测试应用程序:

package main

import (
    "fmt"
    "net/http"
    "net/http/fcgi"
)

func handler(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Header().Set("Content-type", "text/plain; charset=utf-8")
    fmt.Fprintln(w, "This was generated by Go running as a FastCGI app")
}

func main() {
    /*
     *  
     *  Everything that is done here should be setup code etc. which is retained between calls
     *  
     */
    http.HandleFunc("/", handler)
    // This is what actually concurrently handles requests
    if err := fcgi.Serve(nil, nil); err != nil {
            panic(err)
    }
}
现在,这项工作完美无瑕:在将其编译为(比如)go-fcgi-test.fcgi并将其放置在适当的目录下之后,go代码将从类似
http://my.shared.web.server/go-fcgi-test.fcgi
。为了简单起见,我省略了大部分实际处理过程——但这对于提取表单参数、环境变量(在Go 1.9下!)等非常有效,因此我知道基本设置必须是正确的

让我们尝试一个稍微复杂一点的例子:

package main

import (
    "fmt"
    "net/http"
    "net/http/fcgi"
)

func handler1(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Header().Set("Content-type", "text/plain; charset=utf-8")
    fmt.Fprintln(w, "This comes from handler1")
}

func handler2(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Header().Set("Content-type", "text/plain; charset=utf-8")
    fmt.Fprintln(w, "This comes from handler2")
}

func main() {
    http.HandleFunc("/first", handler1)
    http.HandleFunc("/", handler2)
    if err := fcgi.Serve(nil, nil); err != nil {
            panic(err)
    }
}
现在,在这个场景中,我希望
http://my.shared.web.server/go-fcgi-test.fcgi
到输出
这来自handler2
,事实上,这正是发生的情况

但是为什么
http://my.shared.web.server/go-fcgi-test.fcgi/first
实际调用
handler2
,即
handler1
被完全忽略?请注意,
handler2
确实获得了URL的
/first
位—Apache没有将其剥离—因为我可以读取
r.URL.Path[1://code>,并确认这是发送到Go应用程序的整个路径

我在Web上找到的所有使用类似FastCGI框架的示例都只显示了一个处理程序。这是FastCGI包本身的限制吗?FastCGI协议的一个限制(但是为什么正确发送整个路径?)?在Apache配置中执行的某些操作施加了此限制(请记住,我无法接触Apache配置)?还是我做错了什么

(为了完整起见,我应该补充一点,是的,我已经尝试了上面的几种变体,重命名Go应用程序,使用子文件夹,使用多个处理程序,而不仅仅是一个,等等)

我的现实世界场景实际上是一个小应用程序,它可以作为使用
net/http
的独立web服务器运行,也可以作为FastCGI应用程序运行,以防独立模型不受支持甚至被禁止(这是一些共享环境提供商的情况)。由于这两种情况的实际处理方式完全相同,唯一的区别是调用
fcgi.service()
,而不是
http.listenandservice()
。但是,如果能够在FastCGI下使用
net/http
包的路由功能和不同的处理程序,那就太好了


提前感谢您提供的任何见解。即使答案是“是的,这正是FastCGI实现在Go-one处理程序下工作的方式!”这仍然是有用的-这意味着我只需要围绕自己的代码工作,并以不同的方式做事(基本上,根据表单接口传递的参数创建自己的路由器/调度器-没什么大不了的,这是可行的!)

我意识到这是一篇老文章,但我自己刚开始玩围棋和fcgi,遇到了同样的问题

简单的回答是肯定的,使用多个处理程序是有意义的。您的示例中的缺陷是您没有考虑到
go-fcgi test.fcgi
是URL的一部分


当Go的ServeMux处理URL时,它使用的是请求的完整URL,而不仅仅是由fcgi进程处理的部分。在
http://my.shared.web.server/go-fcgi-test.fcgi/first
,程序正在寻找与
/go fcgi test.fcgi/first
最接近的匹配项,即
/

在阅读了@Kodiak提供的答案后,我重新阅读了,发现了这一段:

请注意,由于以斜杠结尾的模式将根子树命名,因此模式“/”将匹配其他已注册模式未匹配的所有路径,而不仅仅是路径为=“/”的URL

如果已注册子树,并且收到一个请求,该请求命名子树根而不带尾随斜杠,则ServeMax会将该请求重定向到子树根(添加尾随斜杠)。可以使用不带尾随斜杠的路径的单独注册来覆盖此行为。例如,注册“/images/”会导致ServeMux将对“/images”的请求重定向到“/images/”,除非“/images”已单独注册

(斜体)

我的假设是,
ServeMux
几乎表现为
nginx
和/或Apache的
rewrite
模块的基于规则的模式匹配特性,即。E规则是根据它们注册的顺序进行处理的,因此我希望首先匹配
/first
(双关语),并且只有在没有找到匹配项的情况下,
/
下一步才会匹配

但这并不是文件所说的。相反,登记顺序没有实际区别
ServeMux
,在我给定的场景中,因为我忘了添加一个尾随斜杠,所以总是“退回”到
“/”
的处理程序,这不是因为匹配算法的一些错误或扭曲,而是因为这是Go开发人员编写的预期行为!换句话说,如果您有一个处理程序来处理
“/”
,那么它将充当每个非斜杠终止子树的全部处理程序


我只是没能正确地阅读文档!(或者早在2017年,这一段还不够清楚)

fcgi只是提供HTTP服务器部分;处理程序及其注册由mux提供,在本例中,mux是标准的
net/http
ServeMux
。它的行为应该不会有任何不同,我也不确定这两种情况怎么可能同时发生