使用nginx终止grpc流量

时间:2018-04-10 15:24:37

标签: php http nginx grpc http2

This recent blogpost说nginx能够终止 http / 2 grpc流量。

从所有插图和文字中看,它看起来根本不能终止grpc流量,只需代理,转发和路由流量。

原因是,我想通过nginx和PHP提供简单的服务。我知道PHP本身有能力实现http / 2和grpc,但这有点"手册",没有什么可以立即使用的。如果我们可以使用nginx进行终止,它可能很容易。

另一件我不喜欢的事情。从同一篇博文中了解:

  

注意:NGINX在明文(非TLS)端口上不支持HTTP / 1和HTTP / 2。它需要先验知道将使用哪个版本的协议。如果要通过明文处理两种协议版本,请为每个协议创建一个监听端口。

当两者都是明文时,实际使用的协议是预先知道的(因为它是明文),我们可以在同一端口上监听两者。当两个协议中的任何一个明文时,两个不同的端口才对我有意义。

有人可以为我清除这两点吗?

1 个答案:

答案 0 :(得分:0)

对我来说,这意味着"终止"从能够从系统外部充当用户的终点的意义上讲。就像你经常"终止"边缘点的HTTPS(例如Nginx),但随后将未加密的HTTP流量传递给下游服务器。

所以你仍然需要一个了解如何处理gRPC的单独服务器,这需要在一个端口上可供nginx使用grpc_pass与之通信。

PHP examples at the gRPC website看来它似乎只使用PHP作为客户端gRPC应用程序而不是服务器端:

  

请注意,目前您只能在PHP中为gRPC创建客户端   服务 - 您可以了解如何在我们的其他服务器中创建gRPC服务器   教程,例如Node.js的。

所以你需要服务器端gRPC服务器(例如Node.js)来回答你的gRPC调用 - 这不仅仅是nginx,尽管nginx可以用来将gRPC调用路由到那个gRPC服务器。在后端应用程序服务器前面有一个像nginx这样的Web服务器有很多原因,包括:SSL / TLS卸载,静态内容处理,负载平衡等等。

  

当两者都是明文时,实际使用的协议是已知的   前面(因为它是明文),我们可以听取两者的意见   同一个港口。

这并不像你想象的那么容易。解析消息以查看它们是否是一种协​​议实际上非常复杂 - 特别是考虑到HTTP / 1是文本的,HTTP / 2是二进制的,而gRPC仅使用HTTP / 2作为传输层,甚至不使用HTTP这下面的语义。

通常,HTTP服务器有三种方式可以知道它是否是HTTP / 2:

  1. 最初使用纯文本HTTP,然后将其升级到HTTP / 2。
  2. 使用加密的HTTPS,在发送第一条HTTP消息之前,使用ALPN(或较旧的NPN)协商它,作为TLS设置的一部分。
  3. 使用明文HTTP,但假设它是HTTP / 2连接(由于某些先前的先前知识关于该端口上的服务),因此只需开始讨论HTTP / 2.
  4. 看起来Nginx确实允许将明文HTTP / 1.1连接转换为HTTP / 2的第一种升级方法。这意味着对于纯文本HTTP,它只允许连接立即用作HTTP / 2("先验知识")。有一个request to allow HTTP/1 and HTTP/2 to be used on the same port for different connections,但说实话,我可以理解为什么还没有完成,因为考虑到目前HTTP / 2的主要用例是浏览器(仅限HTTPS),因此考虑到低优先级)或者像gRPC这样的服务,可能应该知道它们是否是HTTP / 2。

    另外,如上所述,gRPC根本不是关于HTTP的 - 它只是使用HTTP / 2的二进制成帧层通过流控制的多路复用连接发送gRPC消息。这类似于Websockets如何使用HTTP TCP连接发送非HTTP的消息(尽管Web套接字通常使用HTTP语义来协商Web套接字连接)。

    因此,正如我所说的那样,对我来说,不使问题复杂化并尝试在不使用HTTPS时猜测协议实际上是有意义的 - 在大多数情况下应该知道它。