grpc-python07—拦截器 & 多进程

书写拦截器

调用链路、身份验证

  1. init code、detail
  2. 错误函数 grpc_code、abort
  3. intercept_service(self, continuation, header_call_details)

    def _abort(code, details): # unary, stream
    def terminate(ignored_request, context):
        context.abort(code, details)
    
    return grpc.unary_unary_rpc_method_handler(terminate)

class TestInterceptor(grpc.ServerInterceptor):
def init(self, key, value, code, detail):
self.key = key
self.value = value
self.code = code
self._abort = _abort(code, detail)

def intercept_service(self, continuation, handler_call_details):
    """
    :param continuation: 函数执行器
    :param handler_call_details: header
    :return:
    """
    headers = dict(handler_call_details.invocation_metadata)
    if self.key not in headers:
        return self._abort
    # if (self.key, self.value) not in handler_call_details.invocation_metadata:
    #     return self._abort
    if headers.get(self.key) != self.value:
        return self._abort
    return continuation(handler_call_details)

grpc_server = grpc.server(
futures.ThreadPoolExecutor(max_workers=1),
interceptors=(validator, ),
)

# 因为cPython 有全局解释器锁,所以如何改造成多进程呢?

```python
@contextlib.contextmanager
def _reserve_port():
    # with _reserve_port() as xx:
    """
    find and reserve a port for all subprocesses to use
    sudo pop3 install --no-binary grpcio
    由于很多linux系统不支持so_reuseport,所以安装grpcio的时候需要按照上面的这种模式
    安装,时间比较长(多进程监听函数)
    :return:
    """
    sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 0:
        raise RuntimeError("Fail to set SO_REUSEPORT")
    sock.bind(("", 6000))
    try:
        yield sock.getsockname()[1] # 返回的就是端口号
    finally:
        sock.close()

# 启动进程数量
_PROCESS_COUNT = multiprocessing.cpu_count()
# 线程数量
_THREAD_CONCURRENCY = _PROCESS_COUNT

def serve(port=6000):
    grpc_server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), compression=grpc.Compression.Gzip)
    pb2_grpc.add_SayHelloServicer_to_server(SayHello(), grpc_server)
    grpc_server.add_insecure_port('localhost:{}'.format(port))
    print("----in serve 子进程 pid=%d ,父进程的pid=%d---" % (os.getpid(), os.getppid()))
    grpc_server.start()
    grpc_server.wait_for_termination()

def main():
    print("----in main 子进程 pid=%d ,父进程的pid=%d---" % (os.getpid(), os.getppid()))
    with _reserve_port() as port:
        # sys.stdout.flush() # 刷新缓存区
        workers = []
        for _ in range(_PROCESS_COUNT):
            worker = multiprocessing.Process(target=serve, args=(port, ))
            worker.start()
            workers.append(worker)

        for worker in workers:
            worker.join()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值