400 或 500 级别的 HTTP 响应

Sae*_*eed 6 javascript django grpc nuxt.js envoyproxy

我是 gRPC 新手。我的程序是用 \xe2\x80\x8d\xe2\x80\x8d 编写的nuxtjs,是一个简单的程序login page,它接收username并password使用 gRPC 将其发送到服务器。\n当我使用BloomRPC提交请求时,一切都很好。但使用浏览器时,请求不会发送到服务器。

\n

我的auth班级如下:

\n
// auth.js\n\nexport default class {\n  constructor(vars) {\n    this.tokenKey = vars.tokenKey\n    this.proto = vars.proto\n    this.client = new vars.proto.AuthenticationClient(\'http://127.0.0.1:50051\', null, null)\n  }\n\n  async loginRequest(user) {\n    const request = new this.proto.LoginRequest()\n    request.setUsername(user.username.trim().toLowerCase())\n    request.setPassword(user.password.trim()) \n    return await this.client.login(request, {})    \n  } \n}\n
Run Code Online (Sandbox Code Playgroud)\n

无论服务器是否启动,用浏览器向服务器请求时都会出现此错误。

\n
net ERROR_CONNECTION_REFUSED\nmessage: \'Http response at 400 or 500 level\'\n...\n
Run Code Online (Sandbox Code Playgroud)\n

Chrome 屏幕截图: \n铬屏幕截图

\n

我需要进行特定配置吗?

\n

我只是想要一个配置提示。

\n

更新:

\n

此链接表明您应该使用 Envoy。但为什么我们需要它呢?我该如何配置它?

\n

BloomRPC 截图:

\n

正如您在图像右侧看到的,正确返回了答案。\n布卢姆RPC截图

\n

Sae*_*eed 6

问题出在哪里?

\n

问题是请求无法到达服务器。所以服务器启动或关闭并不重要。

\n

> 简答:

\n

我需要一个代理来接收来自服务器的请求。所以我使用了 \xe2\x80\x8d envoy proxy。这样,nginx就收到了浏览器的请求,然后发送到某个端口(例如5000)。另一方面,envoy监听端口 5000,然后将请求发送到在端口 50051 上运行的服务器。

\n

这就是我设计连接跟踪的方式gRPC。

\n

gRPC 跟踪请求

\n
\n

> 长答案:

\n

1.使用构建项目生成 html/css/js 文件nuxt。\n我将网站文件放在root/site\xe2\x80\x8d文件夹中。

\n

2.envoy配置: \n我envoy.yaml根据grpc-web文档配置如下 文件如下。

\n
static_resources:\n  listeners:\n    - name: listener_0\n      address:\n        socket_address: { address: 0.0.0.0, port_value: 5000 }\n      filter_chains:\n        - filters:\n            - name: envoy.filters.network.http_connection_manager\n              config:\n                codec_type: auto\n                stat_prefix: ingress_http\n                route_config:\n                  name: local_route\n                  virtual_hosts:\n                    - name: local_service\n                      domains: ["*"]\n                      routes:\n                        - match: { prefix: "/" }\n                          route:\n                            cluster: sample_cluster\n                            max_grpc_timeout: 0s\n                      cors:\n                        allow_origin_string_match:\n                          - prefix: "*"\n                        allow_methods: GET, PUT, DELETE, POST, OPTIONS\n                        allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout\n                        max_age: "1728000"\n                        expose_headers: grpc-status,grpc-message\n                http_filters:\n                  - name: envoy.filters.http.grpc_web\n                  - name: envoy.filters.http.cors\n                  - name: envoy.filters.http.router\n  clusters:\n    - name: sample_cluster\n      connect_timeout: 0.25s\n      type: logical_dns\n      http2_protocol_options: {}\n      lb_policy: round_robin\n      hosts: [{ socket_address: { address: 0.0.0.0, port_value: 50051 }}]\n
Run Code Online (Sandbox Code Playgroud)\n

该 yaml 文件有两部分listeners和clusters. 在第一部分(listeners)中,我们指定监听哪个端口和地址(例如,这里是地址 0.0.0.0 和端口 5000),在第二部分(clusters)中,我们告诉它向哪里发送请求(这里是地址0.0.0.0 和端口 50051)。要使用此文件,我们将其交给Docker。所以我创建了一个Dockerfile。

\n
# Dockerfile\nFROM envoyproxy/envoy:v1.14.3\nCOPY ./envoy.yaml /etc/envoy/envoy.yaml\nEXPOSE 5000\nCMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml\n
Run Code Online (Sandbox Code Playgroud)\n

为了构建容器,我在里面使用以下命令Dockerfile文件夹中使用以下命令,然后运行它。

\n
docker build -t my-grpc-container:1.0.0 .\ndocker run -d --net=host my-grpc-container:1.0.0\n
Run Code Online (Sandbox Code Playgroud)\n
\n

通过执行上述命令,envoy启动并监听5000端口并向500051端口发送请求。

\n
\n

有关更多信息,请envoy阅读这个不错的博客:

\n
\n

特使的角色:

\n

Envoy 将客户端产生的 HTTP/1.1 调用转换为可由这些服务处理的 HTTP/2 调用\n(gRPC 使用 HTTP/2 进行传输)。

\n
\n

3.nginx配置:

\n

我转到/etc/nginx/sites-enabled/文件夹并打开default文件并设置我的网站文件的路径(参见第 1 节),如下所示:

\n
# server block\nroot /root/site;\n
Run Code Online (Sandbox Code Playgroud)\n

然后告诉nginx如果请求以 开头url,/rpc/则将其发送到 5000 端口(在哪里envoy监听):

\n
# server block\nlocation /rpc/ {\n    proxy_http_version 1.1;\n    proxy_pass http://127.0.0.1:5000/;\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

然后我重新启动nginx:

\n
sudo systemctl restart nginx\n
Run Code Online (Sandbox Code Playgroud)\n
\n

通过执行此部分,nginx将启动并将以 \n 开头的请求发送到已准备好接收的/rpc/端口 5000 。envoy

\n
\n
\n

总之:

\n
    \n
  1. 服务器在端口 50051 上运行。
  2. \n
  3. \xe2\x80\x8dnginx向端口 5000 发送请求。
  4. \n
  5. envoyserver,作为和之间的接口nginx,\n接收来自端口 5000 的请求并将它们发送到端口 50051。
  6. \n
\n

完毕

\n

  • 非常感谢@Saeed,清晰详细的答案。 (2认同)