如何解决Scala gRPC 服务器仅在 GKE 容器上没有响应
gRPC服务器托管在GKE容器上,通过端口转发到目标POD后grpcurl调用服务时,不处理onComplete,发生Timeout。 奇怪的是,这个服务器在 Docker 进程和本地主机上运行
## Run from sbt console
> sbt server/run
## or Run from Docker image
> sbt clean docker:stage
> docker build -t test-server:latest ./server/target/docker/stage/
> docker run -d -p 8080:8080 test-server:latest
## Successfully requests.
> grpcurl -plaintext -vv -d '{"organizationId": "f"}' 0.0.0.0:8080 com.test.Server/CreateAccount
Resolved method descriptor:
rpc CreateAccount ( .com.test.Request ) returns ( .com.test.Request );
Request Metadata to send:
(empty)
Response headers received:
content-type: application/grpc
grpc-accept-encoding: gzip
Estimated response size: 3 bytes
Response contents:
{
"organizationId": "f"
}
Response trailers received:
(empty)
Sent 1 request and received 1 response
这是应用容器的配置。 Envoy 是 sidecarred,但它不会影响应用容器,因为唯一的问题是端口转发给它。
- containers
- env:
- name: JAVA_OPTS
value: -xms1500m -Xmx1500m
- name: TZ
value: Asia/Tokyo
image: asia.gcr.io/my-project/test-server:latest
imagePullPolicy: Always
name: admin
ports:
- containerPort: 8080
name: http
protocol: TCP
resources:
limits:
cpu: "1"
memory: 2000Mi
requests:
cpu: "1"
memory: 2000Mi
securityContext: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-bjhmx
readOnly: true
因此,似乎没有来自服务器的标头响应。 但是,这可能是 grpcurl 的一个问题。
> kobectl port-forward server-xxxx-xxxx 8080:8080
> grpcurl -plaintext -vv -d '{"organizationId": "f"}' 0.0.0.0:8080 com.test.Server/CreateAccount
Resolved method descriptor:
rpc CreateAccount ( .com.test.Request ) returns ( .com.test.Request );
Request Metadata to send:
(empty)
<-- waiting...
// service implementation
override def CreateAccount(request:Request): Future[Request] = {
println("Received request.")
Future(request)
}
==================
object GrpcInterceptor extends ServerInterceptor with Injector {
override def interceptCall[ReqT,RespT](
serverCall: ServerCall[ReqT,RespT],headers: Metadata,next: ServerCallHandler[ReqT,RespT]
): ServerCall.Listener[ReqT] = {
val listener = next.startCall(serverCall,headers)
new ForwardingServerCallListener.SimpleForwardingServerCallListener[ReqT](listener) {
override def onHalfClose(): Unit = {
println("On half close")
super.onHalfClose()
}
override def onComplete(): Unit = {
println("On complete")
super.onComplete()
}
override def onMessage(message: ReqT) {
println("On message")
val value = message.asInstanceOf[GeneratedMessage]
try {
super.onMessage(message)
} catch {
case e: Throwable =>
closeWithException(e,headers)
}
}
private def closeWithException(t: Throwable,requestHeader: Metadata) = {
println("Reciever intercept Failed.",t)
throw new StatusRuntimeException(Status.Code.INTERNAL.toStatus.withDescription(t.getMessage).withCause(t))
}
}
}
}
此实现仍然不会在 GKE 容器上输出“On complete”日志。
On message
On half close
Received request.
然而,似乎只有 GrpcReflectionApi 响应正常。
## On GKE port-forwarding
> grpcurl -plaintext 0.0.0.0:8080 list
com.test.TestServer
grpc.reflection.v1alpha.ServerReflection
我可以确认它适用于相同的 Docker 映像,所以我唯一能想到的是它要么是 GKE 问题,要么需要完成一些特定于 gRPC 的处理。您还可以隔离哪些其他问题?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。