我试图在我的本地运行这个grpc-Java示例.相应的原型文件在这里.当我尝试在本地运行它会从这里抛出以下异常:
Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
at io.grpc.ServiceDescriptor.validateMethodNames(ServiceDescriptor.java:129)
at io.grpc.ServiceDescriptor.<init>(ServiceDescriptor.java:83)
at io.grpc.ServiceDescriptor.<init>(ServiceDescriptor.java:51)
at io.grpc.ServiceDescriptor$Builder.build(ServiceDescriptor.java:219)
at io.grpc.examples.helloworld.GreeterGrpc.getServiceDescriptor(GreeterGrpc.java:251)
at io.grpc.examples.helloworld.GreeterGrpc$GreeterImplBase.bindService(GreeterGrpc.java:84)
at io.grpc.internal.AbstractServerImplBuilder.addService(AbstractServerImplBuilder.java:125)
at io.grpc.internal.AbstractServerImplBuilder.addService(AbstractServerImplBuilder.java:63)
at com.cw.predictive.HelloWorldServer.start(HelloWorldServer.java:56)
at com.cw.predictive.HelloWorldServer.main(HelloWorldServer.java:92)
Run Code Online (Sandbox Code Playgroud)
这是我在这里提到的pom.xml :
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud) 在gRPC中,如何添加拦截任何RuntimeException并将有意义的信息传播给客户端的全局异常拦截器?
例如,一个divide方法可能引发ArithmeticException与/ by zero消息.在服务器端,我可以写:
@Override
public void divide(DivideRequest request, StreamObserver<DivideResponse> responseObserver) {
int dom = request.getDenominator();
int num = request.getNumerator();
double result = num / dom;
responseObserver.onNext(DivideResponse.newBuilder().setValue(result).build());
responseObserver.onCompleted();
}
Run Code Online (Sandbox Code Playgroud)
如果客户端通过denominator = 0,它将得到:
Exception in thread "main" io.grpc.StatusRuntimeException: UNKNOWN
Run Code Online (Sandbox Code Playgroud)
并且服务器输出
Exception while executing runnable io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$2@62e95ade
java.lang.ArithmeticException: / by zero
Run Code Online (Sandbox Code Playgroud)
客户不知道发生了什么.
如果我想将/ by zero消息传递给客户端,我必须将服务器修改为:(如本问题所述)
try {
double result = num / dom;
responseObserver.onNext(DivideResponse.newBuilder().setValue(result).build());
responseObserver.onCompleted();
} catch (Exception e) {
logger.error("onError …Run Code Online (Sandbox Code Playgroud) 我有一个用例,其中许多客户端需要不断向服务器发送大量指标(几乎是永久的)。服务器需要存储这些事件,并在以后处理它们。我不希望服务器对这些事件有任何响应。
我正在考虑为此使用grpc。最初,我认为客户端流可以做(就像 envoy 那样),但问题是客户端流不能确保在应用程序级别的可靠交付(即,如果流在两者之间关闭,则实际处理了多少发送的消息由服务器),我负担不起。
我的思考过程是,我应该使用双向流、服务器流中的 acks 或多个一元 rpc 调用(可能在重复字段中对事件进行一些批处理以提高性能)。
这些哪个会更好?
grpc-java在ServerBuilder其中使用了一个执行程序,如果没有由该builder.executor()方法定义,则默认情况下使用静态缓存线程池.这个遗嘱执行人的确切用途是什么?它只是执行处理程序方法还是执行"其他"操作?
另外,grpc如何定义网络工作者EventLoopGroup?具体来说,我想知道如何将工作线程分配给此工作组.是否有线程数的默认值,或者它是机器核心数的函数?另外,关于上述问题,这些网络工作者如何与遗嘱执行人合作?他们只处理I/O - 读取和写入通道吗?
编辑:Netty,默认创建(2*个核心数)工作线程.
我正在工作gRPC,我想在同一个端口上运行多个服务
Server server = ServerBuilder.forPort(8080)
.addService(new HelloServiceImpl())
.addService(new ByeServiceImpl())
.build();
Run Code Online (Sandbox Code Playgroud)
这是在同一端口上运行多个 GRPC 服务的正确方法吗?完整代码如下。
HelloWorld.proto
Server server = ServerBuilder.forPort(8080)
.addService(new HelloServiceImpl())
.addService(new ByeServiceImpl())
.build();
Run Code Online (Sandbox Code Playgroud)
ByWorld.proto
syntax = "proto3";
option java_multiple_files = true;
package proto3.rpc;
message HelloRequest {
string firstName = 1;
string lastName = 2;
}
message HelloResponse {
string greeting = 1;
}
service HelloService {
rpc hello(HelloRequest) returns (HelloResponse);
}
Run Code Online (Sandbox Code Playgroud)
HelloServiceImpl.java
syntax = "proto3";
option java_multiple_files = true;
package proto3.rpc;
message ByeRequest {
string firstName …Run Code Online (Sandbox Code Playgroud) 我已经阅读了https://github.com/grpc/grpc/blob/master/doc/load-balancing.md上的负载平衡页面,但仍然对后端GRPC之间正确的负载均衡方法感到困惑实例.我们正在部署多个gRPC"微服务"实例,并希望我们的其他gRPC客户端能够在它们之间进行路由.我们将这些作为pods部署在kubernetes(实际上是Google Container Engine)中.
任何人都可以解释在gRPC服务器之间加载平衡gRPC客户端请求的"推荐"方法吗?似乎客户需要了解端点 - 是否不可能利用Container Engine中的内置LoadBalancer来提供帮助?
我想使用 gRPC 让客户端订阅服务器生成的事件。我有一个 RPC 声明如下:
rpc Subscribe (SubscribeRequest) returns (stream SubscribeResponse);
Run Code Online (Sandbox Code Playgroud)
其中返回的流是无限的。要“取消订阅”,客户端取消 RPC(顺便说一句。有没有更干净的方法?)。
我已经弄清楚客户端如何取消呼叫:
rpc Subscribe (SubscribeRequest) returns (stream SubscribeResponse);
Run Code Online (Sandbox Code Playgroud)
但是,服务器似乎没有注意到客户端已取消其调用。我正在用一个虚拟服务器实现来测试这个:
Context.CancellableContext cancellableContext =
Context.current().withCancellation();
cancellableContext.run(() -> {
stub.subscribe(request, callback);
});
// do other stuff / wait for reason to unsubscribe
cancellableContext.cancel(new InterruptedException());
Run Code Online (Sandbox Code Playgroud)
服务器会很高兴地继续将其消息发送到以太坊中。服务器如何识别调用已被客户端取消并因此停止发送响应?
我使用 gRPC 生成代码“@javax.annotation.Generate”,如下图所示。
\n\n\n\n然后我使用maven构建项目,它报告“错误:(20,18)java:找不到符号”,如下图所示。
\n\n\n\n怎么解决\xef\xbc\x9f
\n问题标题可能不那么有用,因为我正在尝试实现各种功能.我想根据他发送的标题授权调用者,并将此信息传播给gRPC方法处理程序.问题在于授权过程的异步性质.我最终得到了这个:
case class AsyncContextawareInterceptor[A](
f: Metadata ? Future[Either[Status, (Context.Key[A], A)]]
)(implicit val system: ActorSystem)
extends ServerInterceptor
with AnyLogging {
import system.dispatcher
sealed trait Msg
case object HalfClose extends Msg
case object Cancel extends Msg
case object Complete extends Msg
case object Ready extends Msg
case class Message[T](msg: T) extends Msg
override def interceptCall[ReqT, RespT](call: ServerCall[ReqT, RespT],
headers: Metadata,
next: ServerCallHandler[ReqT, RespT]): ServerCall.Listener[ReqT] =
new ServerCall.Listener[ReqT] {
private val stash = new java.util.concurrent.ConcurrentLinkedQueue[Msg]()
private var interceptor: Option[ServerCall.Listener[ReqT]] = None
private def …Run Code Online (Sandbox Code Playgroud) 查看 gRPC Java doc - ManagedChannelBuilder,有两个选项可以管理连接。似乎 idleTimeout() 是默认/首选配置。但是当我尝试搜索比较时,大多数帖子都在谈论 keepAlive 选项。
我很好奇什么是常见做法以及这两种选择的优缺点是什么?
在进入空闲模式之前设置没有正在进行的 RPC 的持续时间。在空闲模式下,通道关闭所有连接、NameResolver 和 LoadBalancer。新的 RPC 将使通道退出空闲模式。通道以空闲模式启动。默认为 30 分钟。
这是一个建议选项。不要依赖与此选项相关的任何特定行为。
设置当连接上没有未完成的 RPC 时是否执行 keepalive。默认为假。
在启用此选项之前,客户端必须获得服务所有者的许可。未使用连接上的 Keepalive 很容易意外地消耗大量带宽和 CPU。通常应使用 idleTimeout() 代替此选项。
grpc-java ×10
grpc ×9
java ×6
keep-alive ×1
kubernetes ×1
maven ×1
netty ×1
scala ×1
scalapb ×1
stream ×1