【问题标题】:Http response at 400 or 500 level400 或 500 级别的 Http 响应
【发布时间】:2022-01-20 09:31:19
【问题描述】:

我是 gRPC 的新手。我的程序是用‍‍nuxtjs编写的,是一个简单的login page,它接收usernamepassword并使用gRPC将其发送到服务器。 当我使用BloomRPC 提交请求时,一切都很好。但是在使用浏览器时,请求并没有发送到服务器。

我的auth 班级如下:

// auth.js

export default class {
  constructor(vars) {
    this.tokenKey = vars.tokenKey
    this.proto = vars.proto
    this.client = new vars.proto.AuthenticationClient('http://127.0.0.1:50051', null, null)
  }

  async loginRequest(user) {
    const request = new this.proto.LoginRequest()
    request.setUsername(user.username.trim().toLowerCase())
    request.setPassword(user.password.trim()) 
    return await this.client.login(request, {})    
  } 
}

使用浏览器向服务器请求时会显示此错误,无论服务器是否已启动。

net ERROR_CONNECTION_REFUSED
message: 'Http response at 400 or 500 level'
...

Chrome 屏幕截图:

我必须进行特定配置吗?

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

更新:

This link 说你应该使用 Envoy。但我们为什么需要它?以及如何配置?

BloomRPC 截图:

如您在图片右侧所见,答案已正确返回。

【问题讨论】:

  • nuxt 真的在运行并监听 5005 端口吗?它会记录什么吗?
  • 好像127.0.0.1:5005实际上没有在听(另外,听localhost和听127.0.0.1不一样)。
  • @GiovanniEsposito 谢谢。我以前看过这个答案。投票赞成的问题和答案是由我完成的。我正在使用grpc-web,但它看起来有我不知道的配置。我需要阅读更多内容。
  • @Saeed 如果您找到解决方案,请在此处添加答案。可能非常有用!
  • @GiovanniEsposito 问题是请求没有到达服务器,我需要一个代理将请求从客户端发送到服务器。请看我的回答。

标签: javascript django nuxt.js grpc envoyproxy


【解决方案1】:

问题出在哪里?

问题是请求没有到达服务器。所以不管服务器是开还是关。

> 简答:

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

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


> 长答案:

1. 生成 html/css/js 文件,构建 nuxt 项目。 我将我的网站文件放在root/site‍ 文件夹中。

2。 envoy 配置: 我根据documentionsgrpc-web所说的配置envoy.yaml文件如下。

static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address: { address: 0.0.0.0, port_value: 5000 }
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              config:
                codec_type: auto
                stat_prefix: ingress_http
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: local_service
                      domains: ["*"]
                      routes:
                        - match: { prefix: "/" }
                          route:
                            cluster: sample_cluster
                            max_grpc_timeout: 0s
                      cors:
                        allow_origin_string_match:
                          - prefix: "*"
                        allow_methods: GET, PUT, DELETE, POST, OPTIONS
                        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
                        max_age: "1728000"
                        expose_headers: grpc-status,grpc-message
                http_filters:
                  - name: envoy.filters.http.grpc_web
                  - name: envoy.filters.http.cors
                  - name: envoy.filters.http.router
  clusters:
    - name: sample_cluster
      connect_timeout: 0.25s
      type: logical_dns
      http2_protocol_options: {}
      lb_policy: round_robin
      hosts: [{ socket_address: { address: 0.0.0.0, port_value: 50051 }}]

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

# Dockerfile
FROM envoyproxy/envoy:v1.14.3
COPY ./envoy.yaml /etc/envoy/envoy.yaml
EXPOSE 5000
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml

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

docker build -t my-grpc-container:1.0.0 .
docker run -d --net=host my-grpc-container:1.0.0

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

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

特使的作用:

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

3. nginx 配置:

我去了/etc/nginx/sites-enabled/文件夹并打开default文件并设置我的网站文件的路径(见第1节)如下:

# server block
root /root/site;

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

# server block
location /rpc/ {
    proxy_http_version 1.1;
    proxy_pass http://127.0.0.1:5000/;
    }

然后我重启nginx:

sudo systemctl restart nginx

通过执行此部分,nginx 启动并发送以 /rpc/ 到端口 5000,envoy 已准备好接收。


总结:

  1. 服务器正在端口 50051 上运行。
  2. nginx向5000端口发送请求。
  3. envoy,作为servernginx之间的接口,接收 来自端口 5000 的请求并将它们发送到端口 50051。

完成

【讨论】:

  • 非常感谢@Saeed,清晰而详细的回答。
【解决方案2】:

根据chrome screenshot,你试图在JS中访问5005端口,但根据BloomRPC,截图你的服务监听50051

【讨论】:

  • 请看新截图。没有变化。
  • @Saeed 我建议您尝试更改端口,并确保您的应用程序和服务器使用相同的主机(即两个 127.0.0.1 或两个 localhost)
  • 另外,这是您的问题吗? - github.com/grpc/grpc-web/issues/1175
  • 问题是请求没有到达服务器。请看我的回答。我希望它有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 2017-10-09
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多