400或500级别的HTTP响应

2022-02-25 00:00:00 django grpc javascript nuxt.js envoyproxy

我是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'
...

铬截图:

我必须进行特定配置吗?

我只需要配置提示。

更新:

This link表示您应该使用特使。但是我们为什么需要它呢?我如何配置它?

BloomRPC截图:

如图右侧所示,返回的答案是正确的。


解决方案

问题出在哪里?

问题在于请求不会到达服务器。因此,服务器是启动还是关闭都无关紧要。

>;简短答案:

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

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


>;长答案:

1.构建nuxt项目生成html/css/js文件 我将网站文件放在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打开并侦听端口 并将请求发送到端口500051。

有关envoy的更多信息,请阅读this尼斯博客:

特使角色:

特使将客户端生成的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端口(whereenvoy正在侦听):

# 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之间的接口,接收 请求并将其发送到端口50051。

完成

相关文章