假设我有一个托管服务器的 gRPC Java 服务。
因此,当客户想要调用此服务时,他们使用:
ManagedChannel channel = ManagedChannelBuilder
.forAddress(grpcHost, grpcPort)
.usePlaintext(true)
.build();
Run Code Online (Sandbox Code Playgroud)
没问题。
现在,如果我想从同一个 JVM 调用我的服务该怎么办?这可能吗?或者这可能是完全无效的?
阅读完 HTTP/2 RFC (#7540)和 TLS-ALPN RFC (#7301)后,我仍然无法弄清楚当一端缺少 ALPN 时的预期行为。
假设我有一个使用 HTTP/2“h2”(通过 TLS)的客户端,该客户端与支持 HTTP/2 的服务器通信,但不在“服务器问候”中发送 ALPN 扩展。客户的预期行为是什么?
到目前为止,我见过的大多数客户端都认为服务器不支持 HTTP/2,并将连接降级到 http/1.1,但很少有人忽略(go-gRPC)继续使用 HTTP/2。
如果使用在客户端(“h2”)和服务器(“h2c”)之间执行 SSL 终止的 AWS classic LB,则此场景可能会更加实用。在此示例中,客户端发送值为“h2”的 ALPN 扩展,LB 在没有 ALPN 的情况下执行 SSL 握手(正如其部分所预期的那样),最终 JAVA gRPC 由于 HTTP/1.1 降级而失败。
最近,我正在研究构建 gRPC 客户端-服务器交互。
我写了一个 gRPC 服务:
service SearchService {
rpc Find (SearchReq) returns (SearchRes);
}
Run Code Online (Sandbox Code Playgroud)
然后我应该使用存根(另一个java应用程序)在客户端调用它。
这两种类型的存根有什么区别?
SearchServiceGrpc.SearchServiceFutureStub futureStub = SearchServiceGrpc.newFutureStub(channel);
SearchServiceGrpc.SearchServiceBlockingStub blockingStub = SearchServiceGrpc.newBlockingStub(channel);
Run Code Online (Sandbox Code Playgroud)
blockingStub.find(request);- 用于阻止
futureStub.find(request).get();- 为了未来
我了解 Java 中的 Futures 是如何工作的,但我不明白 gRPC 内部发生了什么以及哪种类型的存根调用更有效率
我在谷歌上没有找到关于它的信息。
谢谢!
这是我的场景。grpc 服务器是一个异步服务器,它从其他源订阅数据。它还为其客户端提供了订阅功能,因此一旦从其他来源接收到数据,它就可以将数据推送到 grpc 客户端。服务器是用Java 实现的。
@Override
public StreamObserver<Message> subscribe (
StreamObserver<Message> responseObserver) {
return new StreamObserver<Message>() {
@Override
public void onNext(Message message) {
api.subscribe(message.value, Message -> {
synchronized (responseObserver) {
...
...
// get data from other source
responseObserver.onNext(Converter.create().toProtobuf(Message.class, data));
}
});
}
@Override
public void onError(Throwable t) {
log.warn("Encountered error in sub", t);
}
@Override
public void onCompleted() {
responseObserver.onCompleted();
}
};
}
Run Code Online (Sandbox Code Playgroud)
我想使用 python 实现 grpc 客户端来订阅该服务器。然而,奇怪的是,Python一旦订阅数据,就立即关闭,而不等待Java服务器的异步返回。然而,Java 客户端可以永远运行并等待来自服务器的异步数据。
原型
message Message{
string value = 1;
}
service test …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一组服务,为外部客户端提供 REST 接口,同时使用 gRPC/protobuf 进行内部服务间通信。Spring Boot 用于帮助提供后台基础设施支持。我大约一周前才开始学习和使用 Google protobuf 和 gRPC。
我已经能够成功地获得更简单的端到端工作处理,但这些返回单个对象(即没有流)。我在进行旨在流式传输响应对象集合的调用时遇到问题。另一件需要注意的事情是,到目前为止我尝试过的所有事情都是 GET 请求。
下面的示例仅显示了我遇到问题的相关部分。
细节:
Protobuf 定义:
syntax = "proto3";
package experiment;
message BOM {
PartSpec part_spec = 1;
string description = 2;
string category = 3;
}
message PartSpec {
string part_number = 1;
string cage_code = 2;
}
service BOMService {
rpc getBOMList(google.protobuf.Empty) returns (stream BOM) {}
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 java GRPC 客户端(netty 和 okhttp)连接到 go 服务器。但他们都间歇性地抛出 UNAVAILABLE: io 异常。
这种情况的发生是随机的,我们不知道是什么导致了这种行为。我们发现请求没有到达go服务器。
用于连接的阻塞存根类似于:
public SomeServiceGrpc.SomeServiceBlockingStub getBlockingStub() {
ManagedChannel channel = OkHttpChannelBuilder
.forAddress(configuration.getHost(), configuration.getPort())
.useTransportSecurity()
.keepAliveTime(1, TimeUnit.MINUTES)
.keepAliveTimeout(5, TimeUnit.SECONDS)
.intercept(deadlineInterceptor)
.build();
return SomeServiceGrpc.newBlockingStub(channel);
}
Run Code Online (Sandbox Code Playgroud)
这些是用于 okhttp 和 protobuf 的库:
compile 'io.grpc:grpc-okhttp:1.21.0'
compile 'io.grpc:grpc-protobuf:1.20.0'
compile 'io.grpc:grpc-stub:1.20.0'
Run Code Online (Sandbox Code Playgroud)
这些是用于 netty 和 protobuf 的库:
compile group: 'io.grpc', name: 'grpc-netty', version: '1.22.1'
compile group: 'io.netty', name: 'netty-handler', version: '4.1.35.Final'
compile group: 'io.netty', name: 'netty-tcnative-boringssl-static', version: '2.0.25.Final'
compile 'io.grpc:grpc-protobuf:1.20.0'
compile 'io.grpc:grpc-stub:1.20.0'
Run Code Online (Sandbox Code Playgroud)
任何帮助或领导表示赞赏。
我正在使用 spring boot (2.2.2) 和 grpc-server-spring-boot-starter java 库开发一个基于 java 的 Grpc 服务器。我的客户端应用程序是 C# 应用程序 (netcoreapp3.1)。这两个应用程序都在我的笔记本电脑上运行以进行此测试。
这是我的原型文件
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.honeywell.EOM.SystemAPI.webapi.web.grpc.service";
//option java_outer_classname = "TestProto";
service Simple {
rpc GetData (Empty) returns (Data) {
}
}
message Empty {
}
message Data {
string name = 1;
}
Run Code Online (Sandbox Code Playgroud)
这是服务代码
@GrpcService
public class TestService extends SimpleGrpc.SimpleImplBase {
@Override
public void getData(Empty request, StreamObserver<Data> responseObserver) {
Data data = Data.newBuilder().setName("Somename").build();
responseObserver.onNext(data);
responseObserver.onCompleted();
}
}
Run Code Online (Sandbox Code Playgroud)
我首先使用这个工具工具测试了服务器 …
我有一个用 Java 编写的 gRPC 服务器,它尝试通过具有项目所有者角色的服务帐户访问 Firestore 和其他服务。服务器成功运行了很多次,但是当我尝试再次运行时,发生了这种情况:
Exception in thread "main" java.util.ServiceConfigurationError: io.grpc.NameResolverProvider: Provider io.grpc.grpclb.SecretGrpclbNameResolverProvider$Provider could not be instantiated
at java.util.ServiceLoader.fail(ServiceLoader.java:232)
at java.util.ServiceLoader.access$100(ServiceLoader.java:185)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
at io.grpc.ServiceProviders.loadAll(ServiceProviders.java:67)
at io.grpc.NameResolverRegistry.getDefaultRegistry(NameResolverRegistry.java:101)
at io.grpc.internal.AbstractManagedChannelImplBuilder.<init>(AbstractManagedChannelImplBuilder.java:107)
at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder.<init>(NettyChannelBuilder.java:136)
at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder.<init>(NettyChannelBuilder.java:131)
at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder.forAddress(NettyChannelBuilder.java:117)
at io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider.builderForAddress(NettyChannelProvider.java:37)
at io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider.builderForAddress(NettyChannelProvider.java:23)
at io.grpc.ManagedChannelBuilder.forAddress(ManagedChannelBuilder.java:39)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createSingleChannel(InstantiatingGrpcChannelProvider.java:270)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.access$1500(InstantiatingGrpcChannelProvider.java:71)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider$1.createSingleChannel(InstantiatingGrpcChannelProvider.java:202)
at com.google.api.gax.grpc.ChannelPool.create(ChannelPool.java:72)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createChannel(InstantiatingGrpcChannelProvider.java:209)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.getTransportChannel(InstantiatingGrpcChannelProvider.java:192)
at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:155)
at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:122)
at com.google.cloud.firestore.spi.v1.GrpcFirestoreRpc.<init>(GrpcFirestoreRpc.java:122)
at com.google.cloud.firestore.FirestoreOptions$DefaultFirestoreRpcFactory.create(FirestoreOptions.java:90)
at com.google.cloud.firestore.FirestoreOptions$DefaultFirestoreRpcFactory.create(FirestoreOptions.java:82)
at com.google.cloud.ServiceOptions.getRpc(ServiceOptions.java:561)
at com.google.cloud.firestore.FirestoreOptions.getFirestoreRpc(FirestoreOptions.java:385)
at com.google.cloud.firestore.FirestoreImpl.<init>(FirestoreImpl.java:67)
at com.google.cloud.firestore.FirestoreOptions$DefaultFirestoreFactory.create(FirestoreOptions.java:73)
at com.google.cloud.firestore.FirestoreOptions$DefaultFirestoreFactory.create(FirestoreOptions.java:66)
at …Run Code Online (Sandbox Code Playgroud) 我想阻止客户端流媒体。该协议的定义如下所示:
rpc RecordRoute(stream Point) 返回 (RouteSummary) {}
正如文档中所述,对于某些类型的流调用,只能使用异步存根:
一个非阻塞/异步存根,它对服务器进行非阻塞调用,并异步返回响应。您可以仅使用异步存根进行某些类型的流调用。
那么我怎样才能使该调用阻塞/同步呢?是否可以?
我将 grpc v1.34.1 与 Java 结合使用,很难配置客户端负载平衡,因为该版本中不推荐使用某些方法。在早期版本中通过以下方式配置客户端负载平衡非常简单:
final ManagedChannel channel = ManagedChannelBuilder.forTarget(target)
.nameResolverFactory(new DnsNameResolverProvider()) // this is on by default
.loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance())
.usePlaintext(true)
.build();
Run Code Online (Sandbox Code Playgroud)
或者通过这个https://sultanov.dev/blog/grpc-client-side-load-balancing/
但是,没有任何可用于已弃用nameResolverFactory并删除 method的新版本的参考loadBalancerFactory。
NameResolver.Factory nameResolverFactory = new MultiAddressNameResolverFactory(
new InetSocketAddress("localhost", 50000),
new InetSocketAddress("localhost", 50001),
new InetSocketAddress("localhost", 50002)
);
channel = ManagedChannelBuilder.forTarget("localhost")
.nameResolverFactory(nameResolverFactory)
.defaultLoadBalancingPolicy("round_robin")
.usePlaintext()
.build();
Run Code Online (Sandbox Code Playgroud)
客户端负载平衡有效。但是,较新的 API 已弃用nameResolverFactory.
有人可以指出我nameResolverFactory在新版本中使用不同服务器(主机和端口)进行客户端负载平衡的替代方案吗?