python grpc客户端通道复用问题

官方文档:

https://grpc.io/docs/languages/
https://grpc.io/docs/languages/python/

通道复用案例

一、hello.proto文件内容

syntax = "proto3";

package hello;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

二、gRPC工具编译

python -m grpc_tools.protoc -I./ --python_out=. --grpc_python_out=. ./hello.proto

生成了两个文件:

  • hello_pb2.py 此文件包含生成的 request(HelloRequest) 和 response(HelloReply) 类。
  • hello_pb2_grpc.py 此文件包含生成的 客户端(GreeterStub)和服务端(GreeterServicer)的类。

三、greeter_server.py文件内容

from concurrent import futures
import time

import grpc

import hello_pb2
import hello_pb2_grpc

_ONE_DAY_IN_SECONDS = 60 * 60 * 24


class Greeter(hello_pb2_grpc.GreeterServicer):
    # 工做函数
    def SayHello(self, request, context):
        return hello_pb2.HelloReply(message='Hello, %s!' % request.name)


def serve():
    # gRPC 服务器
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    hello_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    server.add_insecure_port('[::]:50051')
    server.start()  # start() 不会阻塞,若是运行时你的代码没有其它的事情可作,你可能须要循环等待。
    try:
        while True:
            time.sleep(_ONE_DAY_IN_SECONDS)
    except KeyboardInterrupt:
        server.stop(0)

if __name__ == '__main__':
    serve()

四、greeter_client.py文件内容

import grpc

import hello_pb2
import hello_pb2_grpc


def run():
    # 创建一个通道ch1
    ch1 = grpc.insecure_channel('localhost:50051')
    # 检测通道ch1是否就绪,在这里会创建一个tcp连接
    grpc.channel_ready_future(ch1).result(timeout=10)

    # 创建一个通道ch2
    ch2 = grpc.insecure_channel('localhost:50051')
    # 检测通道ch2是否就绪,在这里并不会创建一个新的tcp连接,而是会复用前面的连接
    grpc.channel_ready_future(ch2).result(10)
    stub1 = hello_pb2_grpc.GreeterStub(ch1)
    # 如果没有channel_ready_future,则在这里创建tcp连接
    response = stub1.SayHello(hello_pb2.HelloRequest(name='goodspeed'))
    print("Greeter client received: " + response.message)
    stub2 = hello_pb2_grpc.GreeterStub(ch2)
    # 使用的还是第一个连接
    response = stub2.SayHello(hello_pb2.HelloRequest(name='goodspeed2'))
    print("Greeter client received: " + response.message)


if __name__ == '__main__':
    run()

这段代码会复用连接。

如果是windows,使用netstat命令观察到只建立了一个连接:

netstat -an|find "50051"

如果是linux,使用netstat命令观察到只建立了一个连接:

netstat -an|grep ESTABLISHED | grep 50051

通道不复用案例

有时候在做性能测试、压测的时候需要关闭这个特性。

如果是在多线程或者多进程里面,通道不会被复用。

参考到官方文档,有一个参数可以进行控制。

使用参数grpc.use_local_subchannel_pool进行控制。

https://grpc.github.io/grpc/python/grpc.html#grpc.insecure_channel

在这里插入图片描述

在这里插入图片描述

/** If set, uses a local subchannel pool within the channel. Otherwise, uses the
 * global subchannel pool. */
#define GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL "grpc.use_local_subchannel_pool"

greeter_client.py代码如下:

import grpc

import hello_pb2
import hello_pb2_grpc


def run():
    opts = [
        ("grpc.use_local_subchannel_pool", 1),
    ]
    # 创建一个通道ch1
    ch1 = grpc.insecure_channel('localhost:50051',opts)
    # 检测通道ch1是否就绪,在这里会创建一个tcp连接
    grpc.channel_ready_future(ch1).result(timeout=10)

    # 创建一个通道ch2
    ch2 = grpc.insecure_channel('localhost:50051',opts)
    # 检测通道ch2是否就绪,在这里会创建一个tcp连接,不会复用前面的连接
    grpc.channel_ready_future(ch2).result(10)
    stub1 = hello_pb2_grpc.GreeterStub(ch1)
    # 如果没有channel_ready_future,则在这里创建tcp连接
    response = stub1.SayHello(hello_pb2.HelloRequest(name='goodspeed'))
    print("Greeter client received: " + response.message)
    stub2 = hello_pb2_grpc.GreeterStub(ch2)
    # 如果没有channel_ready_future,则在这里创建tcp连接
    response = stub2.SayHello(hello_pb2.HelloRequest(name='goodspeed2'))
    print("Greeter client received: " + response.message)


if __name__ == '__main__':
    run()

这段代码不会复用连接。

如果是windows,使用netstat命令观察到建立了2个连接:

netstat -an|find "50051"

如果是linux,使用netstat命令观察到建立了2个连接:

netstat -an|grep ESTABLISHED | grep 50051
  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shulu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值