基于Apache-Commons-Pool2实现Grpc客户端连接池

发布时间:2020-07-19 08:08:31 作者:lilugoodjob
来源:网络 阅读:13328

概述

在项目运行过程中,有些操作对系统资源消耗较大,比如建立数据库连接、建立Redis连接等操作,我们希望一次性创建多个连接对象,并在以后需要使用时能直接使用已创建好的连接,达到提高性能的目的。池技术通过提前将一些占用较多资源的对象初始化,并将初始化后的对象保存到池中备用,达到提高应用服务性能的目的,数据库的JDBC连接池和Jedis连接池等都使用了池技术。
Apache-Commons-Pool2提供了一套池技术的规范接口和实现的通用逻辑,我们只需要实现其抽象出来的方法就可以了。这篇博文主要分享基于Apache-Commons-Pool2来实现Grpc连接池的应用。
关于Grpc相关的内容,大家如想了解基本的实现方法,可以参考我的另一篇博客(传送门):https://blog.51cto.com/andrewli/2058908

核心组件

我们先来了解一下Apache-Commons-Pool2规范接口中涉及到的几个核心组件,包括:

工作流程

根据上述对核心组件的类继承关系分析,我们可以梳理出一个流程,逐步实现各个组件,并组合成一套适用于我们业务的连接池架构。我们来看看这个流程该如何定义。
(1)定义我们的池内对象类 ClientObject,并结合我们的实际业务来实现上层接口的方法。
(2)定义对象工厂类ClientFactory,并结合我们的实际业务来实现上层接口的方法。
(3)定义池属性类ClientPoolConfig,结合我们的实际需求来设置属性值。
(4)使用对象池GenericObjectPool,指定泛型类型GenericObjectPool<ClientObject>。

基于Apache-Commons-Pool2实现Grpc客户端连接池

连接池内部的核心业务逻辑:
基于Apache-Commons-Pool2实现Grpc客户端连接池

池内对象的创建和返回逻辑是池技术里的关键,可以查看池对象的borrowObject方法去了解这部分细节内容。

应用实践

代码实现

根据上述对Apache-commons-pool2的特点和实现流程的分析,我们基于Grpc客户端连接池的应用场景,来进行代码实践,主要包括实现池内对象类 ClientObject和实现对象工厂类ClientFactory。
具体代码可以进入我的百度网盘下载,链接如下:
https://pan.baidu.com/s/1eaGpz6XN2a3ssw0eYsNLww

代码测试

为了验证我们的Grpc连接池的作用,我编写了一个测试方法,模拟以下场景,即开启10个线程,每个线程循环10次使用Grpc连接发送消息给grpc服务端,然后查看线程池中累计创建的连接对象个数、线程池中每个连接对象的被使用次数等信息。
通过测试输出的信息,我得到的结论是:不使用连接池时,总共需要进行100次Grpc连接并发送消息;使用连接池后,总共仅需要建立2次Grpc连接来发送100次消息,每个连接被调用了50次。
测试代码如下。

package com.cmcc.littlec.grpc.poolclient;
import com.cmcc.littlec.grpc.util.Constants;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

public class test {
    @SuppressWarnings("unchecked")
    public static GenericObjectPool<ClientObject> getClientPool(){
        ClientPoolFactory factory = new ClientPoolFactory(Constants.grpcHost, Constants.grpcPort);
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxIdle(8);
        config.setMinIdle(3);
        config.setMaxTotal(18);
        config.setTestOnBorrow(true);
        config.setTestOnReturn(true);
        GenericObjectPool<ClientObject> clientPool = new GenericObjectPool<ClientObject>(factory, config);
        return clientPool;
    }

    public static void  main(String[] args ){
        final GenericObjectPool<ClientObject> clientPool = getClientPool();
        for(int i=0; i<10; i++) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        for (int i = 0; i < 10; i++) {
                            ClientObject client = clientPool.borrowObject();                                                        
                            String str = "hello, grpc client_" + i;//参数
                            try {
                                client.sayHello(str);
                            }catch(Exception e){
                                client.invalidate();
                            }
                            System.out.println("Thread : " + Thread.currentThread().getName() + "; clientPool size : " + clientPool.getCreatedCount());
                            System.out.println("clientObj : "+client.toString());
                            clientPool.returnObject(client);
                        }
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                }
            });
            t.start();
            try {
                if(i%2==0) {
                    Thread.sleep(5000L);//每隔两个线程创建后停顿5S
                }
            }catch(Exception e){ }
        }
    }
}
推荐阅读:
  1. gRPC HelloWorld测试
  2. gRPC快速入门(四)——gRPC快速入门

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

连接池 apache commons

上一篇:Git基础入门(七)Git撤销操作和远程仓库管理

下一篇:Docker Harbor私有仓库简介及部署

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》