热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

gRPC:集合点终止于(StatusCode.INTERNAL,收到错误代码为2的RST_STREAM)

如何解决《gRPC:集合点终止于(StatusCode.INTERNAL,收到错误代码为2的RST_STREAM)》经验,应该怎么弄,您有好建议吗?

我正在用python实现gRPC客户端和服务器。服务器成功从客户端接收数据,但是客户端接收回“ RST_STREAM,错误代码为2 ”。

它实际上是什么意思,我该如何解决?

这是我的原始文件:

service MyApi {
    rpc SelectModelForDataset (Dataset) returns (SelectedModel) {
    }
}
message Dataset {
    // ...
}
message SelectedModel {
    // ...
}

我的服务实现如下所示:

class MyApiServicer(my_api_pb2_grpc.MyApiServicer):
def SelectModelForDataset(self, request, context):
    print("Processing started.")
    selectedModel = ModelSelectionModule.run(request, context)  
    print("Processing Completed.")
    return selectedModel

我用以下代码启动服务器:

import grpc
from concurrent import futures
#...
server = grpc.server(futures.ThreadPoolExecutor(max_workers=100))
my_api_pb2_grpc.add_MyApiServicer_to_server(MyApiServicer(), server)
server.add_insecure_port('[::]:50051')
server.start()

我的客户看起来像这样:

channel = grpc.insecure_channel(target='localhost:50051')
stub = my_api_pb2_grpc.MyApiStub(channel)
dataset = my_api_pb2.Dataset() 
# fill the object ...
model = stub.SelectModelForDataset(dataset)  # call server

客户端调用后,服务器开始处理直到完成(大约需要一分钟),但是客户端立即返回并显示以下错误:

Traceback (most recent call last):                                                                   
File "Client.py", line 32, in                                                                
    run()                                                                                            
File "Client.py", line 26, in run                                                                    
    model = stub.SelectModelForDataset(dataset)  # call server                                       
File "/usr/local/lib/python3.5/dist-packages/grpc/_channel.py", line 484, in __call__
    return _end_unary_response_blocking(state, call, False, deadline)                                
File "/usr/local/lib/python3.5/dist-packages/grpc/_channel.py", line 434, in _end_unary_response_blocking                                                                                               
    raise _Rendezvous(state, None, None, deadline)                                                 
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with (StatusCode.INTERNAL, Received RST_STREAM with error code 2)>

如果我异步执行请求并等待将来,

model_future = stub.SelectModelForDataset.future(dataset)  # call server
model = model_future.result()

客户端等待直到完成,但是之后仍然返回错误:

Traceback (most recent call last):                                                                   
File "AsyncClient.py", line 35, in                                                           
    run()                                                                                            
File "AsyncClient.py", line 29, in run                                                               
    model = model_future.result()                                                                    
File "/usr/local/lib/python3.5/dist-packages/grpc/_channel.py", line 276, in result                  
    raise self                                                                                     
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with (StatusCode.INTERNAL, Received RST_STREAM with error code 2)>

UPD:启用跟踪后,GRPC_TRACE=all我发现了以下内容:

客户,在请求后立即:

E0109 17:59:42.248727600    1981 channel_connectivity.cc:126] watch_completion_error: {"created":"@1515520782.248638500","description":"GOAWAY received","file":"src/core/ext/transport/chttp2/transport/chttp2_transport.cc","file_line":1137,"http2_error":0,"raw_bytes":"Server shutdown"}            
E0109 17:59:42.451048100    1979 channel_connectivity.cc:126] watch_completion_error: "Cancelled"  
E0109 17:59:42.451160000    1979 completion_queue.cc:659]    Operation failed: tag=0x7f6e5cd1caf8, error={"created":"@1515520782.451034300","description":"Timed out waiting for connection state change","file":"src/core/ext/filters/client_channel/channel_connectivity.cc","file_line":133}
...(last two messages keep repeating 5 times every second)

服务器:

E0109 17:59:42.248201000    1985 completion_queue.cc:659]    Operation failed: tag=0x7f3f74febee8, error={"created":"@1515520782.248170000","description":"Server Shutdown","file":"src/core/lib/surface/server.cc","file_line":1249}                                                                    
E0109 17:59:42.248541100    1975 tcp_server_posix.cc:231]    Failed accept4: Invalid argument                                                                             
E0109 17:59:47.362868700    1994 completion_queue.cc:659]    Operation failed: tag=0x7f3f74febee8, error={"created":"@1515520787.362853500","description":"Server Shutdown","file":"src/core/lib/surface/server.cc","file_line":1249}                                                                                                                                             
E0109 17:59:52.430612500    2000 completion_queue.cc:659]    Operation failed: tag=0x7f3f74febee8, error={"created":"@1515520792.430598800","description":"Server Shutdown","file":"src/core/lib/surface/server.cc","file_line":1249}
... (last message kept repeating every few seconds)                                                             

UPD2:

Server.py文件的全部内容:

import ModelSelectionModule
import my_api_pb2_grpc
import my_api_pb2
import grpc
from concurrent import futures
import time

class MyApiServicer(my_api_pb2_grpc.MyApiServicer):
    def SelectModelForDataset(self, request, context):
        print("Processing started.")
        selectedModel = ModelSelectionModule.run(request, context)
        print("Processing Completed.")
        return selectedModel


# TODO(shalamov): what is the best way to run a python server?
def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=100))
    my_api_pb2_grpc.add_MyApiServicer_to_server(MyApiServicer(), server)
    server.add_insecure_port('[::]:50051')
    server.start()

    print("gRPC server started\n")
    try:
        while True:
            time.sleep(24 * 60 * 60)  # run for 24h
    except KeyboardInterrupt:
        server.stop(0)


if __name__ == '__main__':
    serve()

UPD3:似乎ModelSelectionModule.run是造成问题的原因。我试图将其隔离到单独的线程中,但没有帮助。在selectedModel最终计算,但客户已经消失在那个时候。如何防止此呼叫与grpc混淆?

pool = ThreadPool(processes=1)
async_result = pool.apply_async(ModelSelectionModule.run(request, context))
selectedModel = async_result.get()

呼叫比较复杂,它产生并加入大量的线程,调用不同的库,例如scikit-learnsmac等。如果我将所有内容都张贴在这里,那将太多了。

调试时,我发现在客户端请求后,服务器保持2个连接打开(fd 3fd 8)。如果我手动关闭fd 8或向其中写入一些字节,则在客户端中看到的错误将变为Stream removed(而不是Received RST_STREAM with error code 2)。似乎套接字(fd 8)被子进程破坏了。这怎么可能?如何保护子进程不访问套接字?


推荐阅读
  • java线程池的实现原理源码分析
    这篇文章主要介绍“java线程池的实现原理源码分析”,在日常操作中,相信很多人在java线程池的实现原理源码分析问题上存在疑惑,小编查阅了各式资 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文详细介绍了cisco路由器IOS损坏时的恢复方法,包括进入ROMMON模式、设置IP地址、子网掩码、默认网关以及使用TFTP服务器传输IOS文件的步骤。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • [翻译]PyCairo指南裁剪和masking
    裁剪和masking在PyCairo指南的这个部分,我么将讨论裁剪和masking操作。裁剪裁剪就是将图形的绘制限定在一定的区域内。这样做有一些效率的因素࿰ ... [详细]
author-avatar
迷失港湾的豪
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有