SpringBoot 官方推荐,连接池,太快了

背景

在我们平常的编码中,通常会将一些对象保存起来,这主要考虑的是对象的创建成本。

比如像线程资源、数据库连接资源或者 TCP 连接等,这类对象的初始化通常要花费比较长的时间,如果频繁地申请和销毁,就会耗费大量的系统资源,造成不必要的性能损失。

并且这些对象都有一个显著的特征,就是通过轻量级的重置工作,可以循环、重复地使用。

这个时候,我们就可以使用一个虚拟的池子,将这些资源保存起来,当使用的时候,我们就从池子里快速获取一个即可。

在 Java 中,池化技术应用非常广泛,常见的就有数据库连接池、线程池等,本文主讲连接池,线程池我们将在后续的博客中进行介绍。

公用池化包 Commons Pool 2

我们首先来看一下 Java 中公用的池化包 Commons Pool 2,来了解一下对象池的一般结构。

根据我们的业务需求,使用这套 API 能够很容易实现对象的池化管理。

<dependency>    <groupId>org.apache.commons</groupId>    <artifactId>commons-pool2</artifactId>    <version>2.11.1</version></dependency>

GenericObjectPool 是对象池的核心类,通过传入一个对象池的配置和一个对象的工厂,即可快速创建对象池。

public GenericObjectPool(             final PooledObjectFactory<T> factory,             final GenericObjectPoolConfig<T> config)

案例

Redis 的常用客户端 Jedis,就是使用 Commons Pool 管理连接池的,可以说是一个最佳实践。下图是 Jedis 使用工厂创建对象的主要代码块。

对象工厂类最主要的方法就是makeObject,它的返回值是 PooledObject 类型,可以将对象使用 new DefaultPooledObject<>(obj) 进行简单包装返回。

redis.clients.jedis.JedisFactory,使用工厂创建对象。

@Overridepublic PooledObject<Jedis> makeObject() throws Exception {
    Jedis jedis = null;  try {
      jedis = new Jedis(jedisSocketFactory, clientConfig);    //主要的耗时操作    jedis.connect();    //返回包装对象    return new DefaultPooledObject<>(jedis);  } catch (JedisException je) {
      if (jedis != null) {
        try {
          jedis.quit();      } catch (RuntimeException e) {
          logger.warn("Error while QUIT", e);      }      try {
          jedis.close();      } catch (RuntimeException e) {
          logger.warn("Error while close", e);      }    }    throw je;  }}

我们再来介绍一下对象的生成过程,如下图,对象在进行获取时,将首先尝试从对象池里拿出一个,如果对象池中没有空闲的对象,就使用工厂类提供的方法,生成一个新的。

public T borrowObject(final Duration borrowMaxWaitDuration) throws Exception {
      //此处省略若干行    while (p == null) {
          create = false;        //首先尝试从池子中获取。        p = idleObjects.pollFirst();        // 池子里获取不到,才调用工厂内生成新实例        if (p == null) {
              p = create();            if (p != null) {
                  create = true;            }        }        //此处省略若干行    }    //此处省略若干行}

那对象是存在什么地方的呢?这个存储的职责,就是由一个叫作LinkedBlockingDeque 的结构来承担的,它是一个双向的队列。

接下来看一下 GenericObjectPoolConfig 的主要属性:

// GenericObjec
  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Spring Boot 2.0中,默认使用Lettuce客户端来连接Redis服务。默认情况下,不使用连接池,只有在配置`redis.lettuce.pool`属性后才能使用Redis连接池使用连接池可以提升性能。例如,在插入1万条数据时,如果配置了连接池,执行速度会比没有配置连接池快很多[2]。 在Spring Boot中,使用Lettuce连接池时,可以配置连接池的大小。比如,如果当前连接池中已经有3个连接,再加上当前查询窗口的连接,一共就是4个socket连接。通过配置连接池大小,可以控制同时处理的连接数,以及减少与Redis服务器的重复建立和断开连接的开销。 综上所述,Spring Boot整合Redis连接池可以通过配置`redis.lettuce.pool`属性来启用,并且可以提升性能和优化连接管理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [SpringBoot 配置 Redis 连接池](https://blog.csdn.net/web18334137065/article/details/126114299)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [springboot2整合redis使用lettuce连接池(解决lettuce连接池无效问题)](https://blog.csdn.net/qq_41921994/article/details/109627736)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值