Micronaut通用GRPC代理

huangapple go评论75阅读模式
英文:

Micronaut generic GRPC proxy

问题

在替换旧的遗留服务为新服务的过程中,我们希望临时将到达新服务的请求转发到旧服务。对于HTTP请求,我们可以通过自定义的HttpFilter来实现这一点:

@Filter("/**/legacy-service/**")
public class LegacyHttpProxyFilter implements HttpFilter {

  @Inject
  @Named("legacy-http-client")
  private ProxyHttpClient httpClient;

  @Override
  public Publisher<? extends HttpResponse<?>> doFilter(HttpRequest<?> request, FilterChain chain) {
    return httpClient.proxy(request);
  }
}

对于GRPC的类似方法将是使用ServerInterceptor,如下所示:

@Singleton
public class LegacyGrpcProxyInterceptor implements ServerInterceptor {

  @Inject
  @Named("legacy-grpc-client")
  MyLegacyServiceGrpc.MyLegacyServiceStub legacyServiceStub;

  @Override
  public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
    return null; // 如何以通用方式处理GRPC请求?
  }
}

区别在于,使用ProxyHttpClient我们可以转发任何HTTP请求,但似乎不能使用MyLegacyServiceStub GRPC stub 实现相同功能。看起来正确的方法是实现一个自定义的ServerCallHandler,但我并不真正明白如何做,任何示例将不胜感激。

我如何转发任何传入的GRPC请求?

英文:

In the process of replacing an old legacy service by a new one we want to temporarily forward the requests reaching the new service to the legacy one. For HTTP requests we achieve this with a custom HttpFilter:

@Filter(&quot;/**/legacy-service/**&quot;)
public class LegacyHttpProxyFilter implements HttpFilter {

  @Inject
  @Named(&quot;legacy-http-client&quot;)
  private ProxyHttpClient httpClient;

  @Override
  public Publisher&lt;? extends HttpResponse&lt;?&gt;&gt; doFilter(HttpRequest&lt;?&gt; request, FilterChain chain) {
    return httpClient.proxy(request);
  }
}

The analogous approach for GRPC would be something similar to this with a ServerInterceptor:

@Singleton
public class LegacyGrpcProxyInterceptor implements ServerInterceptor {

  @Inject
  @Named(&quot;legacy-grpc-client&quot;)
  MyLegacyServiceGrpc.MyLegacyServiceStub legacyServiceStub;

  @Override
  public &lt;ReqT, RespT&gt; ServerCall.Listener&lt;ReqT&gt; interceptCall(ServerCall&lt;ReqT, RespT&gt; call, Metadata headers, ServerCallHandler&lt;ReqT, RespT&gt; next) {
    return null; // How to handle GRPC requests in a generic way?
  }
}

The difference is that with a ProxyHttpClient we can forward any HTTP request, while this doesn't seem to be possible with MyLegacyServiceStub GRPC stub. It looks like the right approach is to implement a custom ServerCallHandler but I don't really see how, any example would be highly appreciated.

How can I forward any incoming GRPC request?

答案1

得分: 1

在grpc-java中有一个示例

你说得对,它的核心应该是实现一个ServerCallHandler。你还需要一个MethodDescriptor,并将它们打包到一个ServerMethodDefinition中。

该示例使用一个备用的HandlerRegistry来代理所有方法,但如果你只需要静态代理,你可以为要代理的每个服务创建一个ServerServiceDefinition(实质上是一个服务的一组ServerMethodDefinitions),然后将其像平常一样添加到ServerBuilder中:serverBuilder.addService()

示例的其余部分是将客户端和服务器调用连接在一起,对于流式RPC,还有适当的流量控制。

英文:

There is such an example in grpc-java.

You are right that the core of it should be to implement a ServerCallHandler. You will also need a MethodDescriptor and to package them together into a ServerMethodDefinition.

The example uses a fallback HandlerRegistry to proxy all methods, but if you only need static proxying you could create a ServerServiceDefinition (essentially a set of ServerMethodDefinitions for one service) for each service you want proxied and add it to the ServerBuilder as normal: serverBuilder.addService().

The rest of the example is gluing the client and server calls together, with proper flow control for streaming RPCs.

huangapple
  • 本文由 发表于 2023年7月3日 17:51:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76603634.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定