使用 nginx 终止 grpc 流量
Terminate grpc traffic with nginx
This recent blogpost 表示 nginx 能够终止 http/2 和 grpc 流量。
从所有的插图和文字来看,它似乎根本无法终止 grpc 流量,只是代理、转发和路由流量。
原因是,我想通过 PHP 通过 nginx 提供简单的服务。我知道 PHP 本身有能力实现 http/2 和 grpc 但这有点像 "manual",没有现成可用的东西。如果我们可以使用nginx来终止,它可能会很容易工作。
我从同一篇博文中不明白的另一件事:
Note: NGINX does not support HTTP/1 and HTTP/2 at the same time on a cleartext (non-TLS) port. It needs prior knowledge as to which version of the protocol will be used. If you want to handle both protocol versions over cleartext, create a listen port for each.
当两者都是明文时,实际使用的协议是预先知道的(因为它是明文),我们可以在同一个端口上侦听两者。两个不同的端口只对我有意义,当其中一个协议是不是明文时。
有人可以帮我解决这两点吗?
对我来说,这意味着 "terminate" 能够充当系统外部用户的终点。与您经常在边缘点(例如 Nginx)使用 "terminate" HTTPS,然后将未加密的 HTTP 流量传递到下游服务器的方式相同。
所以你仍然需要一个单独的服务器来理解如何处理 gRPC 并且这需要在端口上可用,以便 nginx 使用 grpc_pass
.
与其通信
从 PHP examples at the gRPC website 看来,它似乎只使用 PHP 作为客户端 gRPC 应用程序而不是服务器端:
Note that currently you can only create clients in PHP for gRPC
services - you can find out how to create gRPC servers in our other
tutorials, e.g. Node.js.
因此您需要服务器端 gRPC 服务器(例如 Node.js)来应答您的 gRPC 调用 - 这不能只是 nginx,尽管 nginx 可用于将 gRPC 调用路由到该 gRPC 服务器。在后端应用程序服务器前面安装像 nginx 这样的网络服务器有多种原因,包括:SSL/TLS 卸载、静态内容处理、负载平衡等。
When both are cleartext, the protocol to be used actually is known up
front (because it's cleartext) and we could listen for both on the
same port.
这并不像您想的那么容易。解析消息以查看它们是一种协议还是另一种协议实际上非常复杂 - 特别是考虑到 HTTP/1 是文本的,HTTP/2 是二进制的并且 gRPC 仅使用 HTTP/2 作为传输层而不是'甚至在此之下使用 HTTP 语义。
通常,HTTP 服务器可以通过三种方式了解它是否 HTTP/2:
- 最初使用纯文本 HTTP,然后将其升级到 HTTP/2。
- 在发送第一个 HTTP 消息之前使用 ALPN(或旧的 NPN)作为 TLS 设置的一部分协商使用加密的 HTTPS。
- 使用纯文本 HTTP,但假设它是一个 HTTP/2 连接(由于之前关于该端口上的服务的一些先验知识)所以开始讨论 HTTP/2.
看起来 Nginx 不 允许将明文 HTTP/1.1 连接转换为 HTTP/2 的第一种升级方法。这意味着对于纯文本 HTTP,它只允许连接立即用作 HTTP/2 ("prior knowledge")。有一个 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 的二进制框架层通过 flow-controlled 多路复用连接发送 gRPC 消息。这类似于 Websockets 使用 HTTP TCP 连接发送非 HTTP 消息的方式(尽管 Web 套接字通常使用 HTTP 语义来协商 Web 套接字连接)。
因此,正如我所说,在不使用 HTTPS 时不要使事情复杂化并尝试猜测协议对我来说实际上是有意义的 - 在大多数情况下应该是已知的。
This recent blogpost 表示 nginx 能够终止 http/2 和 grpc 流量。
从所有的插图和文字来看,它似乎根本无法终止 grpc 流量,只是代理、转发和路由流量。
原因是,我想通过 PHP 通过 nginx 提供简单的服务。我知道 PHP 本身有能力实现 http/2 和 grpc 但这有点像 "manual",没有现成可用的东西。如果我们可以使用nginx来终止,它可能会很容易工作。
我从同一篇博文中不明白的另一件事:
Note: NGINX does not support HTTP/1 and HTTP/2 at the same time on a cleartext (non-TLS) port. It needs prior knowledge as to which version of the protocol will be used. If you want to handle both protocol versions over cleartext, create a listen port for each.
当两者都是明文时,实际使用的协议是预先知道的(因为它是明文),我们可以在同一个端口上侦听两者。两个不同的端口只对我有意义,当其中一个协议是不是明文时。
有人可以帮我解决这两点吗?
对我来说,这意味着 "terminate" 能够充当系统外部用户的终点。与您经常在边缘点(例如 Nginx)使用 "terminate" HTTPS,然后将未加密的 HTTP 流量传递到下游服务器的方式相同。
所以你仍然需要一个单独的服务器来理解如何处理 gRPC 并且这需要在端口上可用,以便 nginx 使用 grpc_pass
.
从 PHP examples at the gRPC website 看来,它似乎只使用 PHP 作为客户端 gRPC 应用程序而不是服务器端:
Note that currently you can only create clients in PHP for gRPC services - you can find out how to create gRPC servers in our other tutorials, e.g. Node.js.
因此您需要服务器端 gRPC 服务器(例如 Node.js)来应答您的 gRPC 调用 - 这不能只是 nginx,尽管 nginx 可用于将 gRPC 调用路由到该 gRPC 服务器。在后端应用程序服务器前面安装像 nginx 这样的网络服务器有多种原因,包括:SSL/TLS 卸载、静态内容处理、负载平衡等。
When both are cleartext, the protocol to be used actually is known up front (because it's cleartext) and we could listen for both on the same port.
这并不像您想的那么容易。解析消息以查看它们是一种协议还是另一种协议实际上非常复杂 - 特别是考虑到 HTTP/1 是文本的,HTTP/2 是二进制的并且 gRPC 仅使用 HTTP/2 作为传输层而不是'甚至在此之下使用 HTTP 语义。
通常,HTTP 服务器可以通过三种方式了解它是否 HTTP/2:
- 最初使用纯文本 HTTP,然后将其升级到 HTTP/2。
- 在发送第一个 HTTP 消息之前使用 ALPN(或旧的 NPN)作为 TLS 设置的一部分协商使用加密的 HTTPS。
- 使用纯文本 HTTP,但假设它是一个 HTTP/2 连接(由于之前关于该端口上的服务的一些先验知识)所以开始讨论 HTTP/2.
看起来 Nginx 不 允许将明文 HTTP/1.1 连接转换为 HTTP/2 的第一种升级方法。这意味着对于纯文本 HTTP,它只允许连接立即用作 HTTP/2 ("prior knowledge")。有一个 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 的二进制框架层通过 flow-controlled 多路复用连接发送 gRPC 消息。这类似于 Websockets 使用 HTTP TCP 连接发送非 HTTP 消息的方式(尽管 Web 套接字通常使用 HTTP 语义来协商 Web 套接字连接)。
因此,正如我所说,在不使用 HTTPS 时不要使事情复杂化并尝试猜测协议对我来说实际上是有意义的 - 在大多数情况下应该是已知的。