我使用Link提供的示例在C#中创建了一个GRPC服务器.现在我想弄清楚我应该如何托管这个服务器,以便我实现以下目标:
欢迎任何有关更好架构的参考资料.
在我写这篇文章的时候,Play Framework的版本是v2.6.0-M4.由于Netty冲突,框架的v2.5版本难以使用gRPC(请参阅此stackoverflow答案).
我开始研究gRPC和protobufs.已经从Play Framework 2.5> 2.6.0-M4移植了一个项目,以期实际发布.目前我对gRPC的整合有一些疑问.我想知道如何让gRPC服务器与Play Framework很好地协同工作.我知道v2.6切换到Akka HTTP服务器而不是Netty,而我grpc-netty在sbt中使用依赖,所以也许我必须再次将项目切换到Netty(这里是如何).
出于测试目的,我创建了一个快速而脏的GrpcServer.scala类,它启动了一个带有GrpcServer监听的线程.我设法用gRPC 添加ScalaPB并生成/编译我的protobufs.它非常适合与小型测试NodeJS应用程序通信,但我必须独立于主项目启动此服务器应用程序:
private def start(): Unit = {
server = ServerBuilder.forPort(GrpcServer.port).addService(GreeterGrpc.bindService(new GreeterImpl, executionContext)).build.start
GrpcServer.logger.info("Server started, listening on " + GrpcServer.port)
sys.addShutdownHook {
System.err.println("*** shutting down gRPC server")
self.stop()
System.err.println("*** server shut down")
}
}
Run Code Online (Sandbox Code Playgroud)
现在,对于Play Framework v2.6中的真正集成,我正在寻找建议.这是我可以做的一些事情:
有关清洁集成的任何提示/想法都很有帮助,因为除了以前的2.5版本中存在问题之外,没有太多关于Play Framework和gRPC的信息.
我正在尝试与不安全的 gRPC 服务器建立连接。我使用 gRPC 在 Docker 容器内的两个进程之间进行通信,这就是为什么我不需要任何加密或强身份验证。
服务器按预期运行,我可以像这样使用 grpcurl 进行调用:
grpcurl -plaintext localhost:42652 SomeService.DoSomething
Run Code Online (Sandbox Code Playgroud)
现在我正在尝试从 .Net Core 应用程序调用相同的 RPC 方法:
// Registration of the DI service
services.AddGrpcClient<DaemonService.DaemonServiceClient>(options => {
// Enable support for unencrypted HTTP2
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
options.Address = new Uri("http://localhost:42652");
// Just a test, doesn't change anything.
options.ChannelOptionsActions.Add(channelOptions => channelOptions.Credentials = ChannelCredentials.Insecure);
});
// Call
var reply = _someServiceClient.DoSomething(new Request());
Run Code Online (Sandbox Code Playgroud)
但是最后一行中的调用导致异常:
fail: Grpc.Net.Client.Internal.GrpcCall[6]
Error starting gRPC call.
System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.IO.IOException: The response …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 C++ 实现异步服务器端流。但我找不到任何好的例子。我很难异步读取流。
服务器代码
class ServerImpl final
{
public:
~ServerImpl()
{
server_->Shutdown();
cq_->Shutdown();
}
void Run()
{
std::string server_address("0.0.0.0:50051");
ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service_);
cq_ = builder.AddCompletionQueue();
server_ = builder.BuildAndStart();
std::cout << "Server listening on " << server_address << std::endl;
HandleRpcs();
}
private:
class CallData
{
public:
CallData(MultiGreeter::AsyncService* service, ServerCompletionQueue* cq)
: service_(service)
, cq_(cq)
, responder_(&ctx_)
, status_(CREATE)
, times_(0)
{
Proceed();
}
void Proceed()
{
if (status_ == CREATE)
{
status_ = PROCESS;
service_->RequestsayHello(&ctx_, &request_, &responder_, cq_, cq_, …Run Code Online (Sandbox Code Playgroud) 在哪里可以找到将 gRPC 与 ktor 结合使用的示例。有可能吗,以前有人这样做过吗?我需要帮助。
我尝试遵循此示例: https: //github.com/renannprado/ktor-grpc-sample但我无法让它工作,并且示例可能不完整。
这是我的第一个 gRPC 应用程序。我尝试从 .NET 5 gRPC 客户端 (Grpc.Net.Client 2.35.0) 调用服务器流式 RPC 调用,这会在我的本地开发环境中导致以下异常:
Grpc.Core.RpcException:Status(StatusCode =“Internal”,Detail =“启动gRPC调用时出错。HttpRequestException:使用版本策略RequestVersionOrHigher请求HTTP版本2.0,而未启用HTTP/2。”
无论服务器应用程序是否正在运行,都会发生这种情况。这是我用来拨打电话的代码:
using var channel = GrpcChannel.ForAddress(@"http://localhost:5000");
var client = new AlgorithmRunner.AlgorithmRunnerClient(channel);
using var call = client.RunAlgorithm(new RunAlgorithmRequest());
while (await call.ResponseStream.MoveNext())
{
}
Run Code Online (Sandbox Code Playgroud)
我的理解是,.NET 5 gRPC 默认情况下应该启用 HTTP/2:为什么异常表明 HTTP/2 未启用以及如何解决?
我对 GRPC 比较陌生,希望确保我正在使用 golang 正确进行连接管理。我不想为每次调用都创建一个新连接,但我也不想在扩展时产生瓶颈。
我所做的是在 init 函数中创建一个连接:
var userConn *grpc.ClientConn
var userServiceName string
func init() {
userServiceName := os.Getenv("USER_SERVICE_URL")
if userServiceName == "" {
userServiceName = "localhost"
}
logging.LogDebug("userClient: Connecting to: "+userServiceName, "")
tempConn, err := grpc.Dial(userServiceName, grpc.WithInsecure())
if err != nil {
logging.LogEmergency("account_user_client.Init() Could not get the connection. "+err.Error(), "")
return
}
userConn = tempConn
}
Run Code Online (Sandbox Code Playgroud)
然后对于每个函数,我将使用该连接创建一个客户端:
c := user.NewUserClient(userConn)
// Contact the server and print out its response.
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err …Run Code Online (Sandbox Code Playgroud) 查看 gRPC Java doc - ManagedChannelBuilder,有两个选项可以管理连接。似乎 idleTimeout() 是默认/首选配置。但是当我尝试搜索比较时,大多数帖子都在谈论 keepAlive 选项。
我很好奇什么是常见做法以及这两种选择的优缺点是什么?
在进入空闲模式之前设置没有正在进行的 RPC 的持续时间。在空闲模式下,通道关闭所有连接、NameResolver 和 LoadBalancer。新的 RPC 将使通道退出空闲模式。通道以空闲模式启动。默认为 30 分钟。
这是一个建议选项。不要依赖与此选项相关的任何特定行为。
设置当连接上没有未完成的 RPC 时是否执行 keepalive。默认为假。
在启用此选项之前,客户端必须获得服务所有者的许可。未使用连接上的 Keepalive 很容易意外地消耗大量带宽和 CPU。通常应使用 idleTimeout() 代替此选项。
我有两个网络服务 - gRPC 客户端和 gRPC 服务器。服务器是用 .NET Core 编写的,因此对 gRPC 强制执行 HTTP/2。但是,客户端是托管在 IIS 8.5 上的 .NET Framework 4.7.2 Web 应用程序,因此它仅支持 HTTP/1.1。
由于升级客户端需要一些时间,我在想是否可以在服务器端使用 HTTP/1.1 而不是 HTTP/2,但我找不到任何有关如何实现的信息。
是否可以将 HTTP/1.1 用于用 .NET Core 编写的 gRPC 服务器?如果是这样 - 如何?
我试图将一个协议缓冲区消息导入另一个,但无法识别导入。只要我不尝试将一个 protobuf 导入另一个,就会生成 protobuf 代码(在 Java 中),代码会按预期编译和运行。
我正在使用:
我的 gradle 构建文件如下所示:
plugins {
id 'java'
id 'com.google.protobuf' version "0.8.8"
}
group 'tech.tablesaw'
version '1.0-SNAPSHOT'
sourceCompatibility = 9.0
def grpcVersion = '1.30.1' // CURRENT_GRPC_VERSION
def protobufVersion = '3.12.0'
def protocVersion = protobufVersion
repositories {
mavenCentral()
}
test {
useJUnitPlatform()
}
dependencies {
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
implementation "io.grpc:grpc-stub:${grpcVersion}"
compileOnly "org.apache.tomcat:annotations-api:6.0.53"
// advanced - need this for JsonFormat
implementation "com.google.protobuf:protobuf-java-util:${protobufVersion}"
runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}"
testImplementation …Run Code Online (Sandbox Code Playgroud)