我正在使用golang创建一个简单的http服务器。我有两个问题,一个是理论上的问题,另一个是关于实际程序的问题。

  • 并发请求处理
  • 我创建了一个服务器并使用s.ListenAndServe()处理请求。
    据我了解,这些请求是同时进行的。我使用一个简单的处理程序来检查它:

    我看到,如果我发送多个请求,我将看到所有的" 1"出现,而仅一秒钟后所有的" 2"出现。
    但是,如果我删除了睡眠行,我会看到该程序永远不会在上一个请求结束之前启动请求(输出为1 2 1 2 1 2 ...)。
    所以我不明白它们是否是并发的。如果他们是我,我希望在印刷品中看到一些混乱……

  • 现实生活中的问题
  • 在实际的处理程序中,我将请求发送到另一台服务器,然后将答案返回给用户(对请求和答案进行了一些更改,但从思想上讲,这是一种代理)。所有这一切当然要花费时间,而且从可见的角度(通过向处理程序添加一些打印),请求是一个接一个地处理的,它们之间没有并发性(我的打印向我显示了请求已开始,经过所有步骤,结束,然后我才看到一个新的开始。
    如何使它们真正并发?
    将处理程序函数设置为goroutine会产生错误,该请求的主体已经关闭。同样,如果已经并发了,那么添加更多的goroutine只会使情况变得更糟。

    谢谢!

    您的示例很难说明正在发生的事情。

    下面的示例将清楚地说明请求是并行运行的。

    向http:// localhost:8000发出一个请求

    在5秒钟内再次请求http:// localhost:8000?case-two = true

    控制台输出将是

    当Go同时处理请求时,客户端实际上可能处于阻塞状态(等待第一个请求完成,然后发送第二个请求),然后一个人就会看到最初报告的行为。

    我遇到了同样的问题,我的客户端代码通过XMLHttpRequest向慢速处理程序发送了" GET"请求(我使用了上面发布的类似处理程序代码,超时时间为10秒)。事实证明,这样的请求相互阻塞。 JavaScript客户端代码示例:

    请注意,xhr.send()将立即返回,因为这是一个异步调用,但这不能保证浏览器会立即发送实际的" GET"请求。

    GET请求需要进行缓存,如果尝试获取相同的URL,则缓存可能(实际上将)影响对服务器的请求方式。 POST请求不会被缓存,因此,如果在上面的示例中将"GET"更改为"POST",则Go服务器代码将显示同时触发/slowhandler(您将看到" 1 1 1 [...暂停...] 2 2 2"打印)。

    如来源https://golang.org/src/net/http/server.go#L2293所示,它确实以并发方式处理请求。

    这是一个人为的示例:

    通过几次运行,可以很容易地看到发送请求的go例程的完成顺序是完全随机的,并且鉴于通道是fifo的事实,我们可以总结出,服务器以并发方式处理了请求,而不管HandleFunc是否睡与否。
    (假设所有请求大约在同一时间开始)。

    除上述内容外,如果您在HandleFunc中睡了一秒钟,则完成所有10个例程所需的时间始终为1.xxx秒,这进一步表明服务器同时处理请求,以及完成所有请求的总时间应该已经超过10秒。

    例:

    通过不同步进行打印来分析并发性几乎总是不确定的。