对我来说,这意味着“终止”,即能够充当来自系统外部的用户的终点。就像您经常在边缘点(例如 Nginx)“终止”HTTPS 但随后将未加密的 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 这样的网络服务器有多种原因,包括:SSL/TLS 卸载、静态内容处理、负载平衡......等等。
当两者都是明文时,实际使用的协议是已知的
前面(因为它是明文),我们可以在
同一个端口。
这并不像你想象的那么容易。解析消息以查看它们是一种协议还是另一种实际上非常复杂 - 特别是考虑到 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(“先验知识”)。有一个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 消息。这类似于 Websocket 使用 HTTP TCP 连接发送非 HTTP 消息的方式(尽管 Web 套接字通常使用 HTTP 语义来协商 Web 套接字连接)。
所以,正如我所说,在不使用 HTTPS 时不要让事情复杂化并尝试猜测协议对我来说实际上是有道理的 - 在大多数情况下应该知道它。