设置 gRPC DB-less API 网关:415 不支持的媒体类型
Setup gRPC DB-less API gateway: 415 Unsupported Media Type
我正在为我的项目设置kong。最初,服务器是单体架构),我的团队想把它分离成微服务。由于我的项目使用 gRPC 在客户端和服务器之间进行通信,我正在考虑使用 API 网关支持 gRPC。我在 Google 中找到了 Kong,建议使用 Medium。我已经用无数据库模式设置了它。我使用 docker-compose 到 运行。以下是我所做的:
这里是docker-compose.yml
version: '3'
networks:
kong-net:
driver: bridge
services:
gateway:
image: kong:2.0.2
networks:
- kong-net
volumes:
- ./../kong:/var/lib/docker/volumes/kong-vol/_data
environment:
KONG_SSL: "off"
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /var/lib/docker/volumes/kong-vol/_data/kong.yml
#KONG_SSL_CERT: /
#KONG_SSL_CERT_KEY: /
KONG_PROXY_LISTEN: 0.0.0.0:8000, 0.0.0.0:8443 ssl, 0.0.0.0:9080 http2, 0.0.0.0:9081 http2 ssl
KONG_ADMIN_LISTEN: 127.0.0.1:8001, 127.0.0.1:8444 ssl
ports:
- "8000:8000"
- "8443:8443"
- "8001:8001"
- "8444:8444"
- "9080:9080"
- "9081:9081"
healthcheck:
test: ["CMD", "kong", "health"]
interval: 5s
timeout: 2s
retries: 15
restart: on-failure
appserver:
image: saigonparkingmap/appserver:v1.0
networks:
- kong-net
ports:
- "9090:9090"
- "9999:9999"
depends_on:
- gateway
这里是kong.yml
services:
- name: appserver
url: http://localhost:8001/services
protocol: grpc
host: appserser
port: 9999
connect_timeout: 30000
write_timeout: 30000
read_timeout: 30000
routes:
- name: parking-lot-service
protocols:
- grpc
paths:
- /com.bht.parkingmap.api.proto.parkinglot.ParkingLotService/
我遇到了来自 Kong 的 415 Unsupported Media Type Error 响应。
这是我从客户端控制台收到的信息:
Caused by: io.grpc.StatusRuntimeException: UNKNOWN: HTTP status code 415
invalid content-type: text/html; charset=UTF-8
headers: Metadata(:status=415,content-type=text/html; charset=UTF-8,content-length=144,date=Sun, 29 Mar 2020 23:24:57 GMT,access-control-allow-origin=*,server=kong/2.0.2,x-kong-admin-latency=381,x-kong-upstream-latency=381,x-kong-proxy-latency=2,via=kong/2.0.2)
DATA-----------------------------
<html>
<head><title>415 Unsupported Media Type</title></head>
<body>
<center><h1>415 Unsupported Media Type</h1></center>
</body>
</html>
at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:240)
at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:221)
at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:140)
at com.bht.parkingmap.api.proto.parkinglot.ParkingLotServiceGrpc$ParkingLotServiceBlockingStub.getParkingLotById
这是我从 Kong Docker 容器收到的:
gateway_1 | 2020/03/29 23:24:56 [warn] 23#0: *490 a client request body is buffered to a temporary file /usr/local/kong/client_body_temp/0000000001, client: 172.20.0.1, server: kong, request: "POST /com.bht.parkingmap.api.proto.parkinglot.ParkingLotService/getParkingLotById HTTP/2.0", host: "localhost:9080"
gateway_1 | 127.0.0.1 - - [29/Mar/2020:23:24:57 +0000] "POST /services/com.bht.parkingmap.api.proto.parkinglot.ParkingLotService/getParkingLotById HTTP/1.1" 415 144 "-" "grpc-java-netty/1.27.2"
gateway_1 | 172.20.0.1 - - [29/Mar/2020:23:24:57 +0000] "POST /com.bht.parkingmap.api.proto.parkinglot.ParkingLotService/getParkingLotById HTTP/2.0" 415 144 "-" "grpc-java-netty/1.27.2"
我使用来自客户端调用 Kong 网关端口 9080 的 ManagedChannel 的存根,并期待它会到达监听端口 9999 的服务服务器。
客户端(存根)----> Kong :9080 ----> Service :9999
我是否遗漏了配置中的某些内容,或者我对 grpc 网关有任何误解?
我期待着得到您的支持!非常感谢。
您的 kong.yml
有问题。
Kong 服务中的 url
键是 protocol://host:port
属性的 shorthand。
我在我的 kong.yml
:
中做了这个来让它工作
_format_version: "1.1"
services:
- name: grpc
protocol: grpc
host: host.docker.internal
port: 9797
routes:
- name: catch-all-grpc-requests
paths:
- /
protocols:
- grpc
这相当于使用 url
shorthand。这将产生与上面相同的效果:
_format_version: "1.1"
services:
- name: grpc
url: grpc://host.docker.internal:9797
routes:
- name: catch-all-grpc-requests
paths:
- /
protocols:
- grpc
这是假设我的 gRPC 服务器是 运行 在我的 localhost
端口 9797
。
我使用 host.docker.internal
以便我的 Kong Docker 容器可以访问我也 Docker 化的 gRPC 服务器,我暴露给 :9797.
然后我grpcurl
会这样:
grpcurl -v -d '{"name": "Ken"}' -plaintext localhost:9080 facade.GreetingService/SayHello
所以发生的事情是:
客户端 (grpcurl) -> Kong HTTP2 代理侦听器 (:9080) -> gRPC 服务器 (:9797)
我正在为我的项目设置kong。最初,服务器是单体架构),我的团队想把它分离成微服务。由于我的项目使用 gRPC 在客户端和服务器之间进行通信,我正在考虑使用 API 网关支持 gRPC。我在 Google 中找到了 Kong,建议使用 Medium。我已经用无数据库模式设置了它。我使用 docker-compose 到 运行。以下是我所做的:
这里是docker-compose.yml
version: '3'
networks:
kong-net:
driver: bridge
services:
gateway:
image: kong:2.0.2
networks:
- kong-net
volumes:
- ./../kong:/var/lib/docker/volumes/kong-vol/_data
environment:
KONG_SSL: "off"
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /var/lib/docker/volumes/kong-vol/_data/kong.yml
#KONG_SSL_CERT: /
#KONG_SSL_CERT_KEY: /
KONG_PROXY_LISTEN: 0.0.0.0:8000, 0.0.0.0:8443 ssl, 0.0.0.0:9080 http2, 0.0.0.0:9081 http2 ssl
KONG_ADMIN_LISTEN: 127.0.0.1:8001, 127.0.0.1:8444 ssl
ports:
- "8000:8000"
- "8443:8443"
- "8001:8001"
- "8444:8444"
- "9080:9080"
- "9081:9081"
healthcheck:
test: ["CMD", "kong", "health"]
interval: 5s
timeout: 2s
retries: 15
restart: on-failure
appserver:
image: saigonparkingmap/appserver:v1.0
networks:
- kong-net
ports:
- "9090:9090"
- "9999:9999"
depends_on:
- gateway
这里是kong.yml
services:
- name: appserver
url: http://localhost:8001/services
protocol: grpc
host: appserser
port: 9999
connect_timeout: 30000
write_timeout: 30000
read_timeout: 30000
routes:
- name: parking-lot-service
protocols:
- grpc
paths:
- /com.bht.parkingmap.api.proto.parkinglot.ParkingLotService/
我遇到了来自 Kong 的 415 Unsupported Media Type Error 响应。
这是我从客户端控制台收到的信息:
Caused by: io.grpc.StatusRuntimeException: UNKNOWN: HTTP status code 415
invalid content-type: text/html; charset=UTF-8
headers: Metadata(:status=415,content-type=text/html; charset=UTF-8,content-length=144,date=Sun, 29 Mar 2020 23:24:57 GMT,access-control-allow-origin=*,server=kong/2.0.2,x-kong-admin-latency=381,x-kong-upstream-latency=381,x-kong-proxy-latency=2,via=kong/2.0.2)
DATA-----------------------------
<html>
<head><title>415 Unsupported Media Type</title></head>
<body>
<center><h1>415 Unsupported Media Type</h1></center>
</body>
</html>
at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:240)
at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:221)
at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:140)
at com.bht.parkingmap.api.proto.parkinglot.ParkingLotServiceGrpc$ParkingLotServiceBlockingStub.getParkingLotById
这是我从 Kong Docker 容器收到的:
gateway_1 | 2020/03/29 23:24:56 [warn] 23#0: *490 a client request body is buffered to a temporary file /usr/local/kong/client_body_temp/0000000001, client: 172.20.0.1, server: kong, request: "POST /com.bht.parkingmap.api.proto.parkinglot.ParkingLotService/getParkingLotById HTTP/2.0", host: "localhost:9080"
gateway_1 | 127.0.0.1 - - [29/Mar/2020:23:24:57 +0000] "POST /services/com.bht.parkingmap.api.proto.parkinglot.ParkingLotService/getParkingLotById HTTP/1.1" 415 144 "-" "grpc-java-netty/1.27.2"
gateway_1 | 172.20.0.1 - - [29/Mar/2020:23:24:57 +0000] "POST /com.bht.parkingmap.api.proto.parkinglot.ParkingLotService/getParkingLotById HTTP/2.0" 415 144 "-" "grpc-java-netty/1.27.2"
我使用来自客户端调用 Kong 网关端口 9080 的 ManagedChannel 的存根,并期待它会到达监听端口 9999 的服务服务器。
客户端(存根)----> Kong :9080 ----> Service :9999
我是否遗漏了配置中的某些内容,或者我对 grpc 网关有任何误解? 我期待着得到您的支持!非常感谢。
您的 kong.yml
有问题。
Kong 服务中的 url
键是 protocol://host:port
属性的 shorthand。
我在我的 kong.yml
:
_format_version: "1.1"
services:
- name: grpc
protocol: grpc
host: host.docker.internal
port: 9797
routes:
- name: catch-all-grpc-requests
paths:
- /
protocols:
- grpc
这相当于使用 url
shorthand。这将产生与上面相同的效果:
_format_version: "1.1"
services:
- name: grpc
url: grpc://host.docker.internal:9797
routes:
- name: catch-all-grpc-requests
paths:
- /
protocols:
- grpc
这是假设我的 gRPC 服务器是 运行 在我的 localhost
端口 9797
。
我使用 host.docker.internal
以便我的 Kong Docker 容器可以访问我也 Docker 化的 gRPC 服务器,我暴露给 :9797.
然后我grpcurl
会这样:
grpcurl -v -d '{"name": "Ken"}' -plaintext localhost:9080 facade.GreetingService/SayHello
所以发生的事情是:
客户端 (grpcurl) -> Kong HTTP2 代理侦听器 (:9080) -> gRPC 服务器 (:9797)