`
zk_chs
  • 浏览: 215862 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Grpc应用,搭配commons-pool2连接池实现连接复用

阅读更多

commons-pool2是apache的连接池框架,方便我们创建连接池,实现tcp连接的复用,不需要每次请求都发送握手请求、断开请求等操作,很多开源项目都采用了commons-pool,例如jedis。

 

上一篇的Grpc应用博客只是简单地实现了一个Grpc应用,但是,一个致命的缺点在于每次创建连接、断开连接时的高消耗,这次博客使用commons-pool2来实现一个Grpc的连接池。

 

首先,我们需要知道,服务端是不需要连接池的,google的Grpc服务端使用的是netty这个nio框架,能有效的处理每一个请求,而不是每次请求创建一个线程进行处理,等下我们会看到具体操作。而客户端则不同,我们需要自己创建一个连接池来维持tcp连接。

 

废话不多说了,上代码:

pom.xml
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.4.2</version>
</dependency>

首先添加commons-pool2依赖 。

 

 

 

接下来创建一个GrpcClientFactory,以及测试代码:

public class GrpcClientFactory extends BasePooledObjectFactory<GrpcClient> {

    @Override
    public GrpcClient create() throws Exception {
        return new GrpcClient("localhost", 38628);
    }

    @Override
    public PooledObject<GrpcClient> wrap(GrpcClient client) {
        return new DefaultPooledObject<>(client);
    }

    public static void main(String[] args) throws Exception {

        /** 连接池的配置 */
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();

        /** 下面的配置均为默认配置,默认配置的参数可以在BaseObjectPoolConfig中找到 */
        poolConfig.setMaxTotal(8); // 池中的最大连接数
        poolConfig.setMinIdle(0); // 最少的空闲连接数
        poolConfig.setMaxIdle(8); // 最多的空闲连接数
        poolConfig.setMaxWaitMillis(-1); // 当连接池资源耗尽时,调用者最大阻塞的时间,超时时抛出异常 单位:毫秒数
        poolConfig.setLifo(true); // 连接池存放池化对象方式,true放在空闲队列最前面,false放在空闲队列最后
        poolConfig.setMinEvictableIdleTimeMillis(1000L * 60L * 30L); // 连接空闲的最小时间,达到此值后空闲连接可能会被移除,默认即为30分钟
        poolConfig.setBlockWhenExhausted(true); // 连接耗尽时是否阻塞,默认为true

        /** 连接池创建 */
        GenericObjectPool<GrpcClient> objectPool = new GenericObjectPool<>(new GrpcClientFactory(), poolConfig);

        new Thread(makeTask(objectPool)).start();
        new Thread(makeTask(objectPool)).start();
        new Thread(makeTask(objectPool)).start();
        new Thread(makeTask(objectPool)).start();

    }

    private static Runnable makeTask(GenericObjectPool<GrpcClient> objectPool){
        return () -> {
            GrpcClient client = null;
            try {
                client = objectPool.borrowObject();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                String req = "world!";
                String resp = client.request(req);
                System.out.println(resp);
            } finally {
                /** 将连接对象返回给连接池 */
                objectPool.returnObject(client);
            }
        };
    }
}

 

 

代码很短,但是该有的功能却已经齐全了,如果觉得格式不好看的话,可以自行将main方法、maskTask方法的代码再移出到一个测试类中,这里为了代码的紧凑,所以使用了一个类完成了所有操作。

 

首 先看GrpcClientFactory这个类,它继承了BasePooledObjectFactory<GrpcClient>,用来实 现创建连接池中连接对象的功能,如果觉得连接池这个名字不容易理解的话,可以将连接池看成对象池,将连接对象看成GrpcClient,这样依赖,便容易 理解些了。

 

 

这个类中需要实现两个方法,但其实这就是一个方法,因为BasePooledObjectFactory<GrpcClient>中是这样创建我们的连接对象的:

这个PooledObject,将我们的GrpcClient作为它的一个属性,并另外添加了一些其他的属性,例如创建时间、最后一次调用时间等:

 

继续看main方法,里面先创建了一个GenericObjectPoolConfig,用来配置连接池的属性,最主要属性已经在代码中了,并且配上了注解,相信大家都能看懂:)

 

 

最后一步,连接池的创建,commons-pool2为我们提供了连接池的快捷创建方式。它接受两个参数,分别对应连接池中连接对象创建工厂、连接池配置,如下:

连接池对象 = 连接池所维护的对象的创建工厂 + 连接池对象配置

 

至此,一个连接池对象创建完毕,接下来测试一下吧。修改一下我们之前的HelloWorldRpcServiceImpl:

public class HelloWorldRpcServiceImpl implements HelloWorldRpcServiceGrpc.HelloWorldRpcService {

    /** Grpc并不是单线程的 */
//    public static int count = 0;

    /** 原子Integer */
    public static AtomicInteger count = new AtomicInteger(0);

    @Override
    public void sayHello(HelloWorldRequest request, StreamObserver<HelloWorldResponse> responseObserver) {
        String req = request.getRequest();
        HelloWorldResponse resp = HelloWorldResponse.newBuilder()
                .setResponse("hello " + req + " ")
                .build();
        responseObserver.onNext(resp);
        responseObserver.onCompleted();

        System.out.println(count.incrementAndGet() + Thread.currentThread().getName());
    }

}

 

我们使用了一个共有属性count,Thread.currentThread().getName()来测试线程安全性,毕竟服务端单线程就太坑爹了。

 

先启动服务端,然后运行我们的GrpcClientFactory,测试结果如下:

 

可以看到,我们的Grpc服务端至少开了4条线程,你也可以试试将我们的任务线程多开点看看,试试极限在哪,由此可知公有可变属性需要进行同步。

 

下面这个是我开了15个任务的截图,可供参考:

结果(客户端):

结果(服务端):

如图所示,服务端应该是8线程。

 

 

至此,Grpc的commons-pool2连接池篇也结束了,希望对大家有所帮助。

 

Grpc应用,基本实现,http://zk-chs.iteye.com/blog/2308422

Grpc应用,搭配commons-pool2连接池实现连接复用,http://zk-chs.iteye.com/blog/2308730
  • 大小: 76.2 KB
  • 大小: 86.6 KB
  • 大小: 112.1 KB
1
6
分享到:
评论

相关推荐

    grpc-core-1.24.0-API文档-中文版.zip

    赠送jar包:grpc-core-1.24.0.jar; 赠送原API文档:grpc-core-1.24.0-javadoc.jar; 赠送源代码:grpc-core-1.24.0-sources.jar; 赠送Maven依赖信息文件:grpc-core-1.24.0.pom; 包含翻译后的API文档:grpc-core-...

    grpc-vs2017-x64-release.7z

    标题中的“grpc-vs2017-x64-release.7z”表明这是一个使用7-Zip压缩格式的文件,其中包含了gRPC在Visual Studio 2017环境下针对x64架构的Release版本编译结果。gRPC是一个高性能、开源且语言无关的RPC框架,它基于...

    protoc-gen-grpc-java-1.40.0-osx-aarch_64.exe

    protoc-gen-grpc-java-1.40.0-osx-aarch_64 mac arm芯片平台grpc生成java的支持。官网上面没有,这是基于源码编译生成的。 pom.xml:(protoc-gen-grpc-java-1.40.0.pom) &lt;?xml version="1.0" encoding="UTF-8"?&gt; ...

    grpc-api-1.24.0-API文档-中文版.zip

    赠送jar包:grpc-api-1.24.0.jar; 赠送原API文档:grpc-api-1.24.0-javadoc.jar; 赠送源代码:grpc-api-1.24.0-sources.jar; 赠送Maven依赖信息文件:grpc-api-1.24.0.pom; 包含翻译后的API文档:grpc-api-...

    grpc-api-1.24.0-API文档-中英对照版.zip

    赠送jar包:grpc-api-1.24.0.jar; 赠送原API文档:grpc-api-1.24.0-javadoc.jar; 赠送源代码:grpc-api-1.24.0-sources.jar; 赠送Maven依赖信息文件:grpc-api-1.24.0.pom; 包含翻译后的API文档:grpc-api-...

    protoc-gen-grpc-java-1.9.1-windows-x86_64.exe

    protoc-gen-grpc-java-1.9.1-windows-x86_64.exe

    protoc-gen-grpc-java-1.4.0-linux-aarch_64.exe

    protoc-gen-grpc-java-1.4.0-linux-aarch_64.exe

    grpc_x64-windows编译后的版本

    grpc_x64-windows编译后的版本vs2019环境编译64位版本编译命令 vcpkg.exe install grpc:x64-windows输出文件包括debug和release模式

    开源项目-grpc-ecosystem-go-grpc-middleware.zip

    开源项目-grpc-ecosystem-go-grpc-middleware.zip,gRPC Middleware - reusable auth, logging, retry, tracing libraries for Golang

    grpc-core-1.24.0-API文档-中英对照版.zip

    赠送jar包:grpc-core-1.24.0.jar; 赠送原API文档:grpc-core-1.24.0-javadoc.jar; 赠送源代码:grpc-core-1.24.0-sources.jar; 赠送Maven依赖信息文件:grpc-core-1.24.0.pom; 包含翻译后的API文档:grpc-core-...

    opencensus-contrib-grpc-metrics-0.21.0-API文档-中英对照版.zip

    赠送jar包:opencensus-contrib-grpc-metrics-0.21.0.jar; 赠送原API文档:opencensus-contrib-grpc-metrics-0.21.0-javadoc.jar; 赠送源代码:opencensus-contrib-grpc-metrics-0.21.0-sources.jar; 赠送Maven...

    jmeter-grpc-request-1.1.2.jar

    jmeter压测grpc接口需要的jar包

    grpc-stub-1.24.0-API文档-中文版.zip

    赠送jar包:grpc-stub-1.24.0.jar; 赠送原API文档:grpc-stub-1.24.0-javadoc.jar; 赠送源代码:grpc-stub-1.24.0-sources.jar; 赠送Maven依赖信息文件:grpc-stub-1.24.0.pom; 包含翻译后的API文档:grpc-stub-...

    dart grpc所需的dart-grpc-plugin dart-grpc-gen protoc,

    2. **dart-grpc-gen**: Dart-grpc-gen是dart-grpc-plugin的一部分,它是一个代码生成工具。当protoc执行时,dart-grpc-gen作为插件运行,生成Dart代码,包括服务接口、客户端存根、消息类型和枚举。这些生成的代码...

    rpc-grpc-impl-1.3.8-API文档-中文版.zip

    赠送jar包:rpc-grpc-impl-1.3.8.jar; 赠送原API文档:rpc-grpc-impl-1.3.8-javadoc.jar; 赠送源代码:rpc-grpc-impl-1.3.8-sources.jar; 赠送Maven依赖信息文件:rpc-grpc-impl-1.3.8.pom; 包含翻译后的API文档...

    开源项目-grpc-ecosystem-grpc-gateway.zip

    开源项目-grpc-ecosystem-grpc-gateway.zip,GitHub - grpc-ecosystem/grpc-gateway: gRPC to JSON proxy generator

    grpc-context-1.24.0-API文档-中文版.zip

    赠送jar包:grpc-context-1.24.0.jar; 赠送原API文档:grpc-context-1.24.0-javadoc.jar; 赠送源代码:grpc-context-1.24.0-sources.jar; 赠送Maven依赖信息文件:grpc-context-1.24.0.pom; 包含翻译后的API文档...

    grpc-protobuf-1.24.0-API文档-中文版.zip

    赠送jar包:grpc-protobuf-1.24.0.jar; 赠送原API文档:grpc-protobuf-1.24.0-javadoc.jar; 赠送源代码:grpc-protobuf-1.24.0-sources.jar; 赠送Maven依赖信息文件:grpc-protobuf-1.24.0.pom; 包含翻译后的API...

    opencensus-contrib-grpc-metrics-0.21.0-API文档-中文版.zip

    赠送jar包:opencensus-contrib-grpc-metrics-0.21.0.jar; 赠送原API文档:opencensus-contrib-grpc-metrics-0.21.0-javadoc.jar; 赠送源代码:opencensus-contrib-grpc-metrics-0.21.0-sources.jar; 赠送Maven...

Global site tag (gtag.js) - Google Analytics