精华内容
下载资源
问答
  • 常见的连接池有哪些
    千次阅读
    2021-03-09 09:46:45

    编写标准的数据源(规范)

    Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池!

    常见的第三方连接池如下:

    C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。C3P0是异步操作的,所以一些操作时间过长的JDBC通过其它的辅助线程完成。目前使用它的开源项目有Hibernate,Spring等。C3P0有自动回收空闲连接功能

    阿里巴巴-德鲁伊druid连接池:Druid是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和SQL解析器组成。该项目主要是为了扩展JDBC的一些限制,可以让程序员实现一些特殊的需求。

    DBCP(DataBase Connection Pool)数据库连接池,是Apache上的一个Java连接池项目,也是Tomcat使用的连接池组件。dbcp没有自动回收空闲连接的功能。

    C3P0连接池

    使用步骤

    导入c3p0-0.9.1.2.jar

    拷贝配置文件到src目录

    创建连接池(配置文件自动读取的)

    编写配置文件 c3p0-config.xml

    com.mysql.jdbc.Driver

    jdbc:mysql://localhost:3306/day19

    root

    root

    5

    c3p0连接池常用的配置参数:

    参数说明initialPoolSize初始连接数

    maxPoolSize最大连接数

    checkoutTimeout最大等待时间

    maxIdleTime最大空闲回收时间

    初始连接数:刚创建好连接池的时候准备的连接数量

    最大连接数:连接池中最多可以放多少个连接

    最大等待时间:连接池中没有连接时最长等待时间

    最大空闲回收时间:连接池中的空闲连接多久没有使用就会回收

    编写Java代码

    /**

    * C3P0连接池的工具类

    *

    */

    public class C3P0Utils {

    //1. 创建一个C3P0的连接池对象(会自动读取src目录下的c3p0-config.xml,所以不需要我们解析配置文件)

    public static DataSource ds = new ComboPooledDataSource();

    //2. 提供 从连接池中 获取连接对象的方法

    public static Connection getConnection() throws SQLException {

    Connection conn = ds.getConnection();

    return conn;

    }

    //3. 提供 获得数据源(连接池对象)的方法

    public static DataSource getDataSource(){

    return ds;

    }

    }

    Druid 连接池

    Druid是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是国内目前最好的数据库连接池。在功能、性能、扩展性方面,都超过其他数据库连接池。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。如:一年一度的双十一活动,每年春运的抢火车票。

    DRUID连接池使用的jar包:druid-1.1.16.jar

    Druid连接池工具类编写

    步骤:

    导入DRUID jar 包

    拷贝配置文件到src目录

    根据配置文件 创建连接池对象

    从连接池对象获得连接

    实现:

    创建druid.properties, 放在src目录下

    driverClassName=com.mysql.jdbc.Driver

    url=jdbc:mysql://localhost:3306/day19

    username=root

    password=root

    编写Java代码

    /**

    * 阿里巴巴的连接池 Druid 工具类

    */

    public class DruidUtils {

    /*

    1. 加载 druid.properties 配置文件

    2. 创建 Druid 连接池对象

    3. 提供 获得 连接池对象的方法

    4. 提供 从连接池中 获取连接对象Connection的 方法

    */

    public static DataSource ds = null;

    static {

    try {

    //1. 加载 druid.properties 配置文件

    InputStream is = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");

    Properties prop = new Properties();

    prop.load(is);

    //2. 创建 Druid 连接池对象

    ds = DruidDataSourceFactory.createDataSource(prop);

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    /*

    3. 提供 获得 连接池对象的方法

    */

    public static DataSource getDataSource(){

    return ds;

    }

    /*

    4. 提供 从连接池中 获取连接对象Connection的 方法

    */

    public static Connection getConnetion() throws SQLException {

    Connection conn = ds.getConnection();

    return conn;

    }

    }

    标签:java,配置文件,数据库,Druid,ds,static,public,连接池

    来源: https://blog.csdn.net/qq754772661/article/details/111384030

    更多相关内容
  • 连接池以及常用连接池

    千次阅读 2021-06-13 16:59:51
    连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。 常用连接池:DBCP连接池,C3p0连接池,...

    连接池

         连接池原理:

              连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数 据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户 也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连 接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数 以及每个连接的最大使用次数、最大空闲时间等等,也可以通过其自身的管理机制来监视数据库连接的 数量、使用情况等。

         自定义连接池:

              我们可以通过自定义的方式实现连接池!分析连接池类应该包含特定的属性和方法!
              属性: 集合 放置Connection
              方法: 获取连接方法
                   回收连接方法
              具体实现代码:

    public class Pool{
        static LinkedList list = new LinkedList(); 
        static{ 
            for (int i = 0; i < 10; i++) {
                Connection connection = JDBCUtils.newInstance().getConnection(); 
                list.add(connection); 
            } 
        } 
        /** 
        * 从连接池子中获取连接的方式 
        * @return 
        */ 
        public static Connection getConnection(){ 
            if (list.isEmpty()) {
                 //JDBCUtils类是自定义类,封装了连接数据库的信息代码 
                 Connection connection = JDBCUtils.newInstance().getConnection(); 
                 list.addLast(connection); } Connection conn = list.removeFirst(); 
                 return conn; 
             } 
         /** 
         * 返回到连接池子中 
         */ 
         public static void addBack(Connection conn){ 
             if (list.size() >= 10) { 
                 try { 
                     conn.close(); 
                 } catch (SQLException e) { 
                     // TODO Auto-generated catch block e.printStackTrace(); 
                 } 
             }else{ 
                 list.addLast(conn); //10 
             } 
         } 
         /** 
         * 获取连接池子中连接数量的方法 
         */ 
         public static int getSize(){ 
             return list.size(); 
         } 
     }
    

         java规范实现连接池 Java为连接池实现提供了一个规范(接口),规范的写法,我们需要实现DataSource接口! 但是实现DataSource接口有一个弊端,没有提供回收链接方法!这里我们将使用装饰者模式!
    装饰Connection!具体实现代码如下
             1. 创建装饰Connection
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    最小连接数:
         是数据库一直保持的数据库连接数,所以如果应用程序对数据库连接的使用量不大,将有大量的
         数据库资源被浪费。
    初始化连接数:
          连接池启动时创建的初始化数据库连接数量。
    最大连接数:
          是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求被加入
              到等待队 列中。
    最大等待时间:
         当没有可用连接时,连接池等待连接被归还的最大时间,超过时间则抛出异常,可设置参数为0
         或者负 数使得无限等待(根据不同连接池配置)。
    在这里插入图片描述
    注1:在DBCP连接池的配置中,还有一个maxIdle的属性,表示最大空闲连接数,超过的空闲连接将被释 放,默认值为8。对应的该属性在Druid连接池已不再使用,配置了也没有效果,c3p0连接池则没有对 应的属性。
    注2:数据库连接池在初始化的时候会创建initialSize个连接,当有数据库操作时,会从池中取出一个连 接。如果当前池中正在使用的连接数等于maxActive,则会等待一段时间,等待其他操作释放掉某一个 连接,如果这个等待时间超过了maxWait,则会报错;如果当前正在使用的连接数没有达到 maxActive,则判断当前是否空闲连接,如果有则直接使用空闲连接,如果没有则新建立一个连接。在 连接使用完毕后,不是将其物理连接关闭,而是将其放入池中等待其他操作复用。

    DBCP连接池

         DBCP是一个依赖Jakarta commons-pool对象池机制的数据库连接池.DBCP可以直接的在应用程序中 使用,Tomcat的数据源使用的就是DBCP。
         DBCP连接池的使用
              导入相应jar包
                   mysql-jdbc.jar
                   commons-dbcp.jar
                   commons-pool.jar
         硬编码使用DBCP > 所谓的硬编码方式就是在代码中添加配置
    在这里插入图片描述
    软编码使用DBCP > 所谓的软编码,就是在项目中添加配置文件,这样就不需要每次代码中添加配合!
         项目中添加配置 文件名称: info.properties
         文件位置: src下
    在这里插入图片描述
    在这里插入图片描述

    C3P0连接池

         c3p0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和 jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。

         c3p0与dbcp区别

         1. dbcp没有自动回收空闲连接的功能
              c3p0有自动回收空闲连接功能
         2. dbcp需要手动设置配置文件
              c3p0不需要手动设置
         实现方式
              1 .手动设置 ComboPooledDataSource
              2 加载配置文件方式
    在这里插入图片描述

         实现步骤

              导入jar包
                   c3p0-0.9.1.2.jar
                   mysql-connector-java-5.0.8.jar
              .添加配置文件
               c3p0是在外部添加配置文件,工具直接进行应用,因为直接引用,所以要求固定的命名和文件位置
              文件位置: src
              文件命名:c3p0-config.xml/c3p0-config.properties
    在这里插入图片描述注意: c3p0的配置文件内部可以包含命名配置文件和默认配置文件!默认是选择默认配置!如果需要切换 命名配置可以在创建c3p0连接池的时候填入命名即可!
    .定义代码
    在这里插入图片描述

    Druid(德鲁伊)连接池

    在这里插入图片描述

         使用步骤

              导入jar包
              编写工具类
    在这里插入图片描述
    :在Druid连接池的配置中,driverClassName可配可不配,如果不配置会根据url自动识别dbType(数 据库类型),然后选择相应的driverClassName。

    展开全文
  • JAVA常用数据库连接池

    千次阅读 2021-02-23 18:40:10
    而在计算机工程中常见的池为:连接池、内存池、线程池。 连接池是一种思想和技术:把整个数据库连接放入池内;当访问数据库时,如果连接存在,则直接采用原来的数据库连接;同时,新连接会存在连接池内,方便服用...

    1.连接池

            池化思想是在计算机软件研发中常用的一种思想;该思想为建立一组序列,用于存放各种数据结构,从而对各种数据结构进行管理。池化的优点为:让数据结构有序化和处于控制,从而方便管理。池化本质是一种数学思想,常见的数学池如:整数池、小数池、有理数池、负数池。而在计算机工程中常见的池为:连接池、内存池、线程池。

           连接池是一种思想和技术:把整个数据库连接放入池内;当访问数据库时,如果连接存在,则直接采用原来的数据库连接;同时,新连接会存在连接池内,方便服用。

           连接池带来了数据库访问的极大的效率提升:因为访问数据库一般用TCP连接,TCP建立连接会用三次握手;而连接池会减少很多不必要的重复连接,会极大提升数据库的访问效率。

            池化在很大程度上对我们认识世界和工程管理带来了极大的便利。但池化也会引入麻烦,当数据或数据结构突破池的范围时,会造成整个程序的崩溃,并带来极大的危害。人类认识史上的池的崩溃例子为:人们刚开始只认识10个指头所能标记的数,当数字超过10时,很多小孩直接不再会算数。数学史上的一个池的崩溃为:毕达哥拉斯学派弟子希伯斯发现了无理数根号2,直接造成了数学王国的一段长期的危机。而在计算机工程上,内存池、连接池和线程池的崩溃,则可能造成巨大的损失。        

    2.JAVA常用连接池比较

           JAVA常用的连接池有dbcp、c3p0、tomcat-jdbc、druid和HiKariCP。其中,dbcp、c3p0、tomcat-jdbc是第一代连接池,druid和HiKariCP是第二代连接池。不同连接池对比如下:

    功能dbcpdruidc3p0tomcat-jdbcHikariCP
    是否支持PSCache
    监控jmxjmx/log/httpjmx,logjmxjmx
    扩展性
    sql拦截及解析支持
    代码简单中等复杂简单简单
    更新时间2015.8.62015.10.10 2015.12.09 2015.12.3
    特点依赖于common-pool阿里开源,功能全面历史久远,代码逻辑复杂,且不易维护 优化力度大,功能简单,起源于boneCP
    连接池管理LinkedBlockingDeque数组 FairBlockingQueuethreadlocal+CopyOnWriteArrayList

           目前,大部分软件工程已经开始用Druid和HiKariCP。Druid号称最好的JAVA连接池,但这种“”体现在功能强大,如进行监控,比较性能的话,还是HiKariCP。有兴趣的可以参考这篇博客:《数据库连接池选型 Druid vs HikariCP》(https://juejin.cn/post/6885974851949953031

    3.SpringBoot的默认连接池HiKariCP

           目前SpringBoot中默认的连接池为HiKariCP,从SpringBoot2.0开始,不用配置即可添加HiKari CP。

           可以在默认配置文件添加配置文件,配置样例如下:

    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test1?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
    spring.datasource.username=root
    spring.datasource.password=hongda$123456
    spring.datasource.driverClassName=com.mysql.jdbc.Driver
    
    spring.datasource.max-idle=10
    spring.datasource.max-active=15
    spring.datasource.max-lifetime=86430000
    spring.datasource.log-abandoned=true
    spring.datasource.remove-abandoned=true
    spring.datasource.remove-abandoned-timeout=60
    spring.datasource.initialize=false
    spring.datasource.sqlScriptEncoding=UTF-8

    4.设置样例

          可以在SpringBoot程序中动态设置HiKariCP,样例如下:

         

    public static SessionFactory getSessionFactory() {
    		SessionFactory sessionFactory = null;
            try {        	
            	Configuration configuration = new Configuration();
            	
            	Properties settings = new Properties();
            	
                settings.put(Environment.DIALECT, "org.hibernate.dialect.MySQL5Dialect");
                settings.put(Environment.SHOW_SQL, "true");
                settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");        	
    			settings.put(Environment.DRIVER, "com.mysql.cj.jdbc.Driver");
    			settings.put(Environment.USER, "***");
    			settings.put(Environment.PASS, "***");
    			settings.put(Environment.URL, "jdbc:mysql://地址:端口号/数据库名称?serverTimezone=GMT%2B8");
    
    			// HikariCP settings            
                // Maximum waiting time for a connection from the pool
                settings.put("hibernate.hikari.connectionTimeout", "20000");
                // Minimum number of ideal connections in the pool
                settings.put("hibernate.hikari.minimumIdle", "10");
                // Maximum number of actual connection in the pool
                settings.put("hibernate.hikari.maximumPoolSize", "20");
                // Maximum time that a connection is allowed to sit ideal in the pool
                settings.put("hibernate.hikari.idleTimeout", "300000");
    
                configuration.setProperties(settings);
                configuration.addAnnotatedClass(GsmTaskSpecs.class);  //可以加更多的配置
    
                ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                		.applySettings(configuration.getProperties()).build();
    
    
                sessionFactory = configuration.buildSessionFactory(serviceRegistry);
            } catch (Throwable ex) {
                // Make sure you log the exception, as it might be swallowed
            	sessionFactory = null;
            	ex.printStackTrace();
            }
            
            return sessionFactory;
        }

    5.参考文献

    [1]主流数据库连接池性能比较 hikari druid c3p0 dbcp jdbc,https://www.cnblogs.com/barrywxx/p/8506571.html

    [2]主流Java数据库连接池比较及前瞻,https://www.jianshu.com/p/b9b98ac3e010

    展开全文
  • 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
  • 连接池 这里主要介绍这些知识点~???? 数据库连接池 回忆下 JDBC 的写法 ✍ ,就能感受到连接池的好处了~ void jdbcTest() throws ClassNotFoundException { String url = "jdbc:mysql://localhost:3306/db"; ...

    连接池

    这里主要介绍这些知识点~😝

    image-20210601002212731

    数据库连接池

    回忆下 JDBC 的写法 ✍ ,就能感受到连接池的好处了~

    void jdbcTest() throws ClassNotFoundException {
        String url = "jdbc:mysql://localhost:3306/db";
        String username = "";
        String password = "";
    
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = DriverManager.getConnection(url, username, password);
            preparedStatement= connection.prepareStatement("select * from User where name=?");
            preparedStatement.setString(1, "Java4ye");
            preparedStatement.executeQuery();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            try {
                if (preparedStatement!=null){
                    preparedStatement.close();
                }
                if (connection != null){
                    connection.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    
    }
    

    可以发现在这种模式下,每次都要去创建和销毁连接,造成了很大的浪费。我们可以尝试去优化下,

    比如,参考上面 线程池的思想

    • 用完不销毁,先存起来;
    • 一开始的时候,就初始化多个连接;
    • 给连接加上最大空闲时间限定;
    • 加上最大连接数限定;

    最后,你可以发现,你封装了一个简单的连接池了😄

    img

    数据库连接池原理图

    数据库连接池原理图

    那数据库连接池有啥作用呢?

    负责连接的管理,分配和释放,当连接的空闲时间超过最大空闲时间时,会释放连接,避免连接泄露

    常见的数据库连接池

    这里就主要说说这个 HikariCPDruid 了,其他的如 C3P0DBCP 等就不说啦(主要是没用上 哈哈哈)

    HikariCP

    HikariCPSpringboot2 开始默认使用的连接池(官方认证~🐷),速度最快

    优点
    1. 字节码精简 :优化代码,编译后的字节码最少,这样,CPU缓存可以加载更多的程序代码;
    2. 优化代理和拦截器 :减少代码,例如 HikariCP 的 Statement proxy 只有100行代码,只有 BoneCP 的十分之一;
    3. 自定义数组类型(FastStatementList)代替ArrayList :避免每次get()调用都要进行range check,避免调用remove()时的从头到尾的扫描;
    4. 自定义集合类型(ConcurrentBag) :提高并发读写的效率;
    5. 其他针对 BoneCP 缺陷的优化。
    源码

    有机会可以研究看看 ~

    下面这段代码是 HikariCPgetConnection() 的源码~ 给大家感受下👇 ([[HikariCP 源码]])

       // ***********************************************************************
       //                          DataSource methods
       // ***********************************************************************
    
       /** {@inheritDoc} */
       @Override
       public Connection getConnection() throws SQLException
       {
          if (isClosed()) {
             throw new SQLException("HikariDataSource " + this + " has been closed.");
          }
    
          if (fastPathPool != null) {
             return fastPathPool.getConnection();
          }
    
          // See http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
          HikariPool result = pool;
          if (result == null) {
             synchronized (this) {
                result = pool;
                if (result == null) {
                   validate();
                   LOGGER.info("{} - Starting...", getPoolName());
                   try {
                      pool = result = new HikariPool(this);
                      this.seal();
                   }
                   catch (PoolInitializationException pie) {
                      if (pie.getCause() instanceof SQLException) {
                         throw (SQLException) pie.getCause();
                      }
                      else {
                         throw pie;
                      }
                   }
                   LOGGER.info("{} - Start completed.", getPoolName());
                }
             }
          }
    
          return result.getConnection();
       }
    

    看下来就捕捉到单例设计模式的影子~

    小伙伴们可以看看之前这篇 《一文带你看遍单例模式的八个例子,面试再也不怕被问了

    是不是用到了单例的 双重检查锁模式 😄

    配置属性

    有这么多!🐷

    private static final char[] ID_CHARACTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
    private static final long CONNECTION_TIMEOUT = SECONDS.toMillis(30);
    private static final long VALIDATION_TIMEOUT = SECONDS.toMillis(5);
    private static final long IDLE_TIMEOUT = MINUTES.toMillis(10);
    private static final long MAX_LIFETIME = MINUTES.toMillis(30);
    private static final int DEFAULT_POOL_SIZE = 10;
    
    private static boolean unitTest = false;
    
    // Properties changeable at runtime through the HikariConfigMXBean
    //
    private volatile String catalog;
    private volatile long connectionTimeout;
    private volatile long validationTimeout;
    private volatile long idleTimeout;
    private volatile long leakDetectionThreshold;
    private volatile long maxLifetime;
    private volatile int maxPoolSize;
    private volatile int minIdle;
    private volatile String username;
    private volatile String password;
    
    // Properties NOT changeable at runtime
    //
    private long initializationFailTimeout;
    private String connectionInitSql;
    private String connectionTestQuery;
    private String dataSourceClassName;
    private String dataSourceJndiName;
    private String driverClassName;
    private String exceptionOverrideClassName;
    private String jdbcUrl;
    private String poolName;
    private String schema;
    private String transactionIsolationName;
    private boolean isAutoCommit;
    private boolean isReadOnly;
    private boolean isIsolateInternalQueries;
    private boolean isRegisterMbeans;
    private boolean isAllowPoolSuspension;
    private DataSource dataSource;
    private Properties dataSourceProperties;
    private ThreadFactory threadFactory;
    private ScheduledExecutorService scheduledExecutor;
    private MetricsTrackerFactory metricsTrackerFactory;
    private Object metricRegistry;
    private Object healthCheckRegistry;
    private Properties healthCheckProperties;
    
    private volatile boolean sealed;
    

    默认值👉

    image-20210515200950942

    简单介绍下上面红框中的配置:

    CONNECTION_TIMEOUT = SECONDS.toMillis(30); // 连接超时,默认 30 秒
    VALIDATION_TIMEOUT = SECONDS.toMillis(5); // 验证连接有效性的超时时间,默认 5 秒
    IDLE_TIMEOUT = MINUTES.toMillis(10); // 空闲连接存活最大时间 , 默认 10 分钟
    MAX_LIFETIME = MINUTES.toMillis(30); // 连接最大存活时间 , 默认 30 分钟
    DEFAULT_POOL_SIZE = 10;             // 默认连接池大小 , 10
    

    一些常见的配置

    spring:
      datasource:
        hikari:
          # 最小空闲连接数量
          minimum-idle: 5
          # 连接超时,默认 30 秒
          connection-timeout: 30
          # 空闲连接存活最大时间 , 默认 10 分钟
          idle-timeout: 3
          # 连接池最大连接数,默认是10
          maximum-pool-size: 20
          # 连接池名称
          pool-name: 4yePool_HikariCP
          # 自动提交事务,默认 true
          auto-commit: true
          # 连接最长的生命周期,默认 30 分钟
          max-lifetime: 1800
    

    魔力转转转

    嘿嘿 再来介绍下阿里的 Druid 🐂

    Druid

    阿里云计算平台团队出品,为监控而生的数据库连接池

    Alibaba-Druid

    下面那个是 ApacheDruid ,两个是不同的! 一个是连接池,一个是数据库~

    Apache Druid是一个高性能的实时分析型数据库

    Druid连接池介绍

    主要特点是监控,提供了web页面给我们监控 SQL,Session,Spring 等等~ 而且据说监控对性能的影响很小🐷

    小伙伴们点击下面连接就可以看到啦~👇

    介绍

    常见问题

    Druid 常见问题 可以在 githubwiki 中查看😃

    常见问题

    很多问题都可以在上面找到答案~ 比如

    功能:

    如图~ (原来这么多!)

    功能

    优点:

    经历了阿里大规模验证!😄

    是 阿里巴巴内部唯一使用的连接池,在内部数据库相关中间件 TDDL/DRDS 都内置使用强依赖了Druid连接池

    Springboot 集成 druid 👇

    集成文档

    这里配置超级全,大家就直接看文档就好啦 😄

    img

    HttpClient连接池

    http请求过程

    如果所示,这是一个 Http 请求的大致过程

    http请求过程

    HTTP keep-alive 机制

    上面的请求也是一个短链接的过程,每次请求结束就关闭连接了,很浪费资源,而长连接和短链接的最主要区别就是这个 keep-alive 机制。

    这里简单说下这个 长连接 keep-alive

    http1.0 中 ,请求头中是默认没有这个 Connection: keep-alive

    而在 http1.1 中 , 请求头中默认是带上这个的。

    TCP keep-alive (保活)机制

    除了应用层的 HTTP 有这个机制外,传输层的 TCP 也有。

    TCP 保活机制的主要特点是 每隔一段时间会通过心跳包检测对端是否存活

    这里参考下 linux

    我们可以通过 sysctl -a | grep keepalive 查看内核参数

    net.ipv4.tcp_keepalive_intvl = 75 
    net.ipv4.tcp_keepalive_probes = 9
    net.ipv4.tcp_keepalive_time = 7200
    
    • 保活时间(tcp_keepalive_time)默认:7200 秒
    • 保活时间间隔(tcp_keepalive_intvl)默认:75 秒
    • 探测循环次数(tcp_keepalive_probes)默认:9 次

    这里的意思是,在两个钟(7200秒)内没有收到报文的话,会每隔75秒发送一个 保活探测包 ,重复9 次,直到收到响应,到达9次的话,如果还是没有响应,就会关闭连接。

    保活机制的区别

    HTTP 是为了复用连接 , 而 TCP 是为了保证对端存活,如果对端挂了的话,会关闭 TCP 连接。

    连接池

    这里和大家扯这么多主要是为了简单说说这个 Http 建立连接的麻烦 ,哈哈哈 频繁的创建和销毁连接很不友好。(说来说去都是这句话😝)

    img

    而且在 HTTP 的背后,还有着这么一个保活机制,这也意味着我们的连接池在实现这个连接的复用时,还要考虑这个Keep-alive 机制~

    所以。。说了这么多,还是来看看这个 apachehttpcomponents 中的 httpclient 有啥秘密叭 😝

    HttpClient 介绍

    总体上分为下面七大块

    1. Fundamentals
    2. Connection management
    3. HTTP state management
    4. HTTP authentication
    5. Fluent API
    6. HTTP Caching
    7. Advanced topics
    Keep Alive 策略

    Keep Alive 策略

    官网介绍

    The HTTP specification does not specify how long a persistent connection may be and should be kept alive. Some HTTP servers use a non-standard Keep-Alive header to communicate to the client the period of time in seconds they intend to keep the connection alive on the server side. HttpClient makes use of this information if available.

    If the Keep-Alive header is not present in the response, HttpClient assumes the connection can be kept alive indefinitely.

    可以看到如果返回头中没有设置这个 Keep-Avlie 的话,HttpClient 会认为它是无限期存活的!

    However, many HTTP servers in general use are configured to drop persistent connections after a certain period of inactivity in order to conserve system resources, quite often without informing the client. In case the default strategy turns out to be too optimistic, one may want to provide a custom keep-alive strategy.

    这里直接用官网的简单例子运行下,从debug日志中可以看到,没配置的话,确实输出了 kept alive indefinitely

    debug日志

    代码 demo
     public static void main(String[] args) throws IOException {
            CloseableHttpClient httpclient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet("http://www.baidu.com");
            CloseableHttpResponse response1 = httpclient.execute(httpGet);
    // The underlying HTTP connection is still held by the response object
    // to allow the response content to be streamed directly from the network socket.
    // In order to ensure correct deallocation of system resources
    // the user MUST call CloseableHttpResponse#close() from a finally clause.
    // Please note that if response content is not fully consumed the underlying
    // connection cannot be safely re-used and will be shut down and discarded
    // by the connection manager.
            try {
                System.out.println(response1.getStatusLine());
                HttpEntity entity1 = response1.getEntity();
                // do something useful with the response body
                // and ensure it is fully consumed
                EntityUtils.consume(entity1);
            } finally {
                response1.close();
            }
    
            HttpPost httpPost = new HttpPost("http://www.baidu.com");
            List <NameValuePair> nvps = new ArrayList <NameValuePair>();
            nvps.add(new BasicNameValuePair("username", "vip"));
            nvps.add(new BasicNameValuePair("password", "secret"));
            httpPost.setEntity(new UrlEncodedFormEntity(nvps));
            CloseableHttpResponse response2 = httpclient.execute(httpPost);
    
            try {
                System.out.println(response2.getStatusLine());
                HttpEntity entity2 = response2.getEntity();
                // do something useful with the response body
                // and ensure it is fully consumed
                EntityUtils.consume(entity2);
            } finally {
                response2.close();
            }
        }
    
    源码分析

    嘿嘿 ,来都来了,就顺手 debug 分析下上面这个 execute 方法~

    从下图中我们可以发现,这里会去调用 reuseStrategy.keepAlive() 做判断,接着通过keepAliveStrategy.getKeepAliveDuration 去获取该连接的存活时间 🐷

    源码

    这两个策略分别为 重用策略 ConnectionReuseStrategy 和 保活策略 ConnectionKeepAliveStrategy

    源码

    省去debug步骤~ 🐷

    我们直接来到这个默认的重用策略 DefaultConnectionReuseStrategy ,来看看这里是怎么去判断这个连接可以不可以重用叭~

    keepAlive 源码

    public boolean keepAlive(HttpResponse response, HttpContext context) {
        Args.notNull(response, "HTTP response");
        Args.notNull(context, "HTTP context");
        if (response.getStatusLine().getStatusCode() == 204) {
            Header clh = response.getFirstHeader("Content-Length");
            if (clh != null) {
                try {
                    int contentLen = Integer.parseInt(clh.getValue());
                    if (contentLen > 0) {
                        return false;
                    }
                } catch (NumberFormatException var11) {
                }
            }
    
            Header teh = response.getFirstHeader("Transfer-Encoding");
            if (teh != null) {
                return false;
            }
        }
    
        HttpRequest request = (HttpRequest)context.getAttribute("http.request");
        if (request != null) {
            try {
                BasicTokenIterator ti = new BasicTokenIterator(request.headerIterator("Connection"));
    
                while(ti.hasNext()) {
                    String token = ti.nextToken();
                    if ("Close".equalsIgnoreCase(token)) {
                        return false;
                    }
                }
            } catch (ParseException var13) {
                return false;
            }
        }
    
        ProtocolVersion ver = response.getStatusLine().getProtocolVersion();
        Header teh = response.getFirstHeader("Transfer-Encoding");
        if (teh != null) {
            if (!"chunked".equalsIgnoreCase(teh.getValue())) {
                return false;
            }
        } else if (this.canResponseHaveBody(request, response)) {
            Header[] clhs = response.getHeaders("Content-Length");
            if (clhs.length != 1) {
                return false;
            }
    
            Header clh = clhs[0];
    
            try {
                long contentLen = Long.parseLong(clh.getValue());
                if (contentLen < 0L) {
                    return false;
                }
            } catch (NumberFormatException var10) {
                return false;
            }
        }
    
        HeaderIterator headerIterator = response.headerIterator("Connection");
        if (!headerIterator.hasNext()) {
            headerIterator = response.headerIterator("Proxy-Connection");
        }
    
        if (headerIterator.hasNext()) {
            try {
                TokenIterator ti = new BasicTokenIterator(headerIterator);
                boolean keepalive = false;
    
                while(ti.hasNext()) {
                    String token = ti.nextToken();
                    if ("Close".equalsIgnoreCase(token)) {
                        return false;
                    }
    
                    if ("Keep-Alive".equalsIgnoreCase(token)) {
                        keepalive = true;
                    }
                }
    
                if (keepalive) {
                    return true;
                }
            } catch (ParseException var12) {
                return false;
            }
        }
    
        return !ver.lessEquals(HttpVersion.HTTP_1_0);
    }
    

    哈哈哈 不想看分析的话 往下滑动一点点,有图~ 😝

    分析

    1. 判断 HTTP 响应头中的状态码是不是 204 ,是的话进入下面的判断

      • 响应头中是否有 Content-Length ,有的话看它的值是否大于0,大于的时候 不重用

      • 响应头 中是否有 Transfer-Encoding ,有的话 不重用

        ( Tip: 204 表示 No Content:服务器成功处理了请求,但没返回任何内容 ,但是上面两种都表示还有内容,是错误的❌,所以不重用)

    2. 判断 请求头中是否有 Connection:Close ,有的话也 不重用

    3. 判断 响应头 中是否有 Transfer-Encoding,有的话看它的值,如果值 不等于 chunked不重用

    4. 判断 响应头中是否有 Content-Length , 有的话看它的值,如果值 小于 0 , 不重用

    5. 判断 响应头中是否有 Connection 或者 Proxy-Connection 其中的一个 ,有的话看它的值,如果是 Close不重用,如果是 Keep-Alive 重用

    6. 最后,如果上面的判断条件都不成立,会判断 http 的版本是不是 小于 1.0,是的话也返回 false

    贴心的 4ye 居然画了这么详细的 流程图😝 (感谢老板的 一键三连 😝)

    HttpClient重用策略

    这里要注意,连接池中有两个默认的参数很重要(下图👇),而且官网的 demo 肯定是不能直接用在生产环境下的, 不然… 等监控报警的时候,就有得难受了 哈哈

    下面整理了一些配置 给小伙伴们参考下~ 😝

    如下图
    HttpClientConnectionManager

    这两个分别是

    路由最大连接数defaultMaxPerRoute ,默认值 2 ,表示对某个 ip / 路由 一次能处理的最大并发数 。例如,如果我去请求百度,则同一时刻,最多能处理两个请求,所以 别忘了修改它!🐷 ,不然你的连接池配多少连接都没用~

    总连接数maxTotal , 默认值 20 , 这个表示总的连接数,即 连接的最大并发数是20

    HttpClientConnectionManager

    PoolingHttpClientConnectionManager 设置
    PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
    poolingHttpClientConnectionManager.setMaxTotal(6);
    poolingHttpClientConnectionManager.setDefaultMaxPerRoute(1);
    poolingHttpClientConnectionManager.setMaxPerRoute(new HttpRoute(new HttpHost("www.baidu.com")),4);
    

    如上所示,还可以自定义某个 route 的最大值,效果如下~

    DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection leased: [id: 41][route: {}->http://www.baidu.com:80][total available: 1; route allocated: 2 of 4; total allocated: 6 of 6]
    

    其他参数 如 SocketConfigRequestConfig 等也要进行相应的配置,设置 等待数据的超时时间 和 请求超时时间 等,还有 重发策略 serviceUnavailStrategyKeep-Alive 策略 ConnectionKeepAliveStrategy

    img

    RequestConfig 设置
    1. connectionRequestTimout:从连接池获取连接超时

    2. connetionTimeout:连接服务器超时

    3. socketTimeout : 等待数据超时

    RequestConfig requestConfig = RequestConfig.custom()
            .setConnectionRequestTimeout(1000) 
            .setConnectTimeout(1000)
            .setSocketTimeout(1000).build();
    
    ConnectionKeepAliveStrategy (保活策略)设置

    代码如下

    ConnectionKeepAliveStrategy myStrategy = (response, context) -> {
                // Honor 'keep-alive' header
                HeaderElementIterator it = new BasicHeaderElementIterator(
                        response.headerIterator(HTTP.CONN_KEEP_ALIVE));
                while (it.hasNext()) {
                    HeaderElement he = it.nextElement();
                    String param = he.getName();
                    String value = he.getValue();
                    if (value != null && param.equalsIgnoreCase("timeout")) {
                        try {
                            return Long.parseLong(value) * 1000;
                        } catch (NumberFormatException ignore) {
                        }
                    }
                }
                HttpHost target = (HttpHost) context.getAttribute(
                        HttpClientContext.HTTP_TARGET_HOST);
                if ("www.baidu.com".equalsIgnoreCase(target.getHostName())) {
                    // Keep alive for 5 seconds only
                    return 5 * 1000;
                } else {
                    // otherwise keep alive for 30 seconds
                    return 30 * 1000;
                }
            };
    

    okhttp 就不展开啦,嘿嘿,这里的连接池使用场面也挺多的,比如我们接着要来讲的 RestTemplate ,还有这个 Feign (这个就先记着啦 嘿嘿 有时间再补上)

    现在来简单说下怎么在 RestTemplate 中使用这个连接池~ 🐷

    RestTemplate

    它提供了一个简单的 SimpleClientHttpRequestFactory , 该类里面主要有 connetionTimeoutreadTimeout 这两个超时设置,额 实在是太简单了… 大部分时候还是不能满足的,所以我们还是要选择其他的连接池呀~ !

    image-20210501203538974

    可以看到上面中还有 OkHttp ,还有 Netty 等等,小伙伴们可以根据需要选择~ (๑•̀ㅂ•́)و✧

    不过为啥 Netty 会标记为已过期了呢?

    嘿嘿,这里下载了 Netty4ClientHttpRequestFactory 源码 ,可以看到 第一个红框里说,每次 http 请求的连接都会被关闭 。

    这显然不能重用连接以及保持长连接了~ 😄

    image-20210509224325366

    配置 HttpClient

    我们也可以这样配置,就可以使用到这个 HttpClient 了 。

    @Configuration
    public class RestTemplateConfig {
        @Bean
        public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
            RestTemplate restTemplate = new RestTemplate(factory);
            // 支持中文编码
            restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
            return restTemplate;
        }
    
        @Bean
        public ClientHttpRequestFactory httpComponentsClientHttpRequestFactory() {
            return  new HttpComponentsClientHttpRequestFactory(httpClient());
        }
        @Bean
        public HttpClient httpClient() {
    
            PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
            poolingHttpClientConnectionManager.setMaxTotal(6);
            poolingHttpClientConnectionManager.setDefaultMaxPerRoute(1);
            poolingHttpClientConnectionManager.setMaxPerRoute(new HttpRoute(new HttpHost("www.baidu.com")), 4);
    
            ConnectionKeepAliveStrategy myStrategy = (response, context) -> {
                // Honor 'keep-alive' header
                HeaderElementIterator it = new BasicHeaderElementIterator(
                        response.headerIterator(HTTP.CONN_KEEP_ALIVE));
                while (it.hasNext()) {
                    HeaderElement he = it.nextElement();
                    String param = he.getName();
                    String value = he.getValue();
                    if (value != null && param.equalsIgnoreCase("timeout")) {
                        try {
                            return Long.parseLong(value) * 1000;
                        } catch (NumberFormatException ignore) {
                        }
                    }
                }
                HttpHost target = (HttpHost) context.getAttribute(
                        HttpClientContext.HTTP_TARGET_HOST);
                if ("www.baidu.com".equalsIgnoreCase(target.getHostName())) {
                    // Keep alive for 5 seconds only
                    return 5 * 1000;
                } else {
                    // otherwise keep alive for 30 seconds
                    return 30 * 1000;
                }
            };
    
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(5000)
                    .setConnectTimeout(10000)
                    .setSocketTimeout(5000).build();
    
           return HttpClients.custom()
                    .setConnectionManager(poolingHttpClientConnectionManager)
                    .setKeepAliveStrategy(myStrategy)
                    .setDefaultRequestConfig(requestConfig)
                    .build();
        }
    
    }
    

    img

    前往下一站,Redis 连接池

    Redis 连接池

    redis 的官网中 ,我们可以发现有下面这些客户端

    客户端地址

    image-20210531085114518

    这里我们主要介绍这个 lettuce

    Jedis 和 Lettuce

    好久以前,在花菜🥦 lettuce 还没有出现以前,Springboot 默认使用的是Jedis

    为啥现在默认使用的是这个 lettuce 呢?

    作者的回答

    image-20210510080302046

    嘿嘿,翻译下作者的原话 😝

    1. Jedis 是一个直连Redis 客户端,在多线程环境下共享同一个 Jedis 实例,这是线程不安全的。
    2. 在多线程环境中使用 Jedis 的方法是使用连接池。每个使用 Jedis 的并发线程在Jedis 交互期间获得自己的 Jedis 实例。连接池是以每个 Jedis 实例的物理连接为代价的,这增加了 Redis 连接的数量。
    3. lettuce 是建立在 netty 和连接实例(StatefulRedisConnection)之上,可以跨多个线程共享。因此,多线程应用程序可以使用单个连接而不考虑与 Lettuce 交互的并发线程数。

    配置

    <!-- spring boot redis 缓存引入 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- lettuce pool 缓存连接池 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
    
    @Bean
    public LettuceConnectionFactory lettuceConnectionFactory() {
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMinIdle(minIdle);
        genericObjectPoolConfig.setMaxTotal(maxActive);
        genericObjectPoolConfig.setMaxWaitMillis(maxWait);
        genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(100);
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setDatabase(database);
        redisStandaloneConfiguration.setHostName(host);
        redisStandaloneConfiguration.setPort(port);
        redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
        LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                .commandTimeout(Duration.ofMillis(timeout))
                .shutdownTimeout(Duration.ofMillis(shutDownTimeout))
                .poolConfig(genericObjectPoolConfig)
                .build();
    
        LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfig);
        factory.setShareNativeConnection(false);
        return factory;
    }
    

    注意这里,如果想要连接池生效的话,必须设置配置这句话,不然默认只用一条连接的🐖

    lettuceConnectionFactory.setShareNativeConnection(false);

    特意去官网看了下,发现真是这样操作的 (⊙﹏⊙)

    image-20210531220518918

    而且当你配置了最小连接数时,你会发现在 redis 中,查到的连接数是比你配置的多一个,额 目前还不知道是啥连接,先记录下 嘿嘿~

    img

    最后

    这篇文章就分享到这里啦,至于 常量池 又要夹着 jvm ,还有字节码这一块来说,所以还是另外再写✍ 啦!

    欢迎关注,交个朋友呀!! ( •̀ ω •́ )y

    文章首发于公众号~

    地址在这~

    作者简介 :Java4ye , 你好呀!!😝

    公众号: Java4ye 博主滴个人公众号~ ,嘿嘿 喜欢就支持下啦 😋

    让我们开始这一场意外的相遇吧!~

    欢迎留言!谢谢支持!ヾ(≧▽≦*)o

    1

    展开全文
  • 连接池比较.rar,proxool.xml,proxool-0.9.0RC3.jar,dbcp.xml,c3p0.xml
  • 几种常见数据库连接池

    万次阅读 2017-06-30 07:54:01
    感觉在介绍之前必要阐述一下连接池的几个概念,助于后边一些文字的理解。 最原始的数据库使用就是打开一个连接并进行使用,使用过后一定要关闭连接释放资源。由于频繁的打开和关闭连接对jvm包括数据库 都...
  • 什么是连接池 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。 为什么要使用连接池  数据库连接是一种关键的有限的昂贵的资源,这一点在多...
  • 目录 ...4.2常见的第三方连接池 5.如何使用Druid 5.1 导入jar包 5.2 入门案例 1.为什么需要连接池呢? Java程序操作数据库,必须获得一个连接Connection 实际操作中,我们要先获得..
  • java中几个主流的数据库连接池

    万次阅读 多人点赞 2018-08-12 19:12:03
    这里所说的池是一种广义上的池,比如数据库连接池、线程池、内存池、对象池等。其中,对象池可以看成保存对象的容器,在进程初始化时创建一定数量的对象。需要时直接从池中取出一个空闲对象,用完后并不直接释放掉...
  • 几种常见数据库连接池的使用比较

    千次阅读 2018-06-06 18:39:35
    感觉在介绍之前必要阐述一下连接池的几个概念,助于后边一些文字的理解。最原始的数据库使用就是打开一个连接并进行使用,使用过后一定要关闭连接释放资源。由于频繁的打开和关闭连接对jvm包括数据库都一定的...
  • java连接池详解与自定义es连接池

    千次阅读 2021-11-10 10:48:35
    目录1 版本选择2 导入依赖3 使用commons-pool构造连接池3.1 pom.xml3.2 对象池类GenericObjectPool普通对象池GenericKeyedObjectPool带Key的对象池3.3 实现PoolableObjectFactory接口类3.4 继承...
  • 使用连接池要注意哪些事项? 一个普通的Java程序,要查询数据库的数据,基本流程是这样的:(每次访问数据库都要进行一次tcp连接和数据库认证等操作,而这些操作非常影响服务器的性能) 可以看到,进行一次查询,要...
  • 阿里巴巴主流数据库连接池Druid入门

    千次阅读 多人点赞 2022-04-09 09:45:36
    数据库连接池的必要性 (一).传统数据库连接模式的的步骤 1.在主程序中创建连接 2.进行sql操作 3.关闭数据库连接 (二).传统数据库连接模式存在的问题 1.浪费时间:每次连接时都要验证登录和将conn加载到内存...
  • 1.1 什么是连接池 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。 1.2 为什么要使用连接池 数据库连接是一种关键的有限的昂贵的资源,这一点在...
  • 更高的mysql版本需要使用 mysql-connector-java-8.0.19.jar(最新版本)数据库版本不对应会导致连接失败的。 mysql-connection-java的jar包 官网下载点击 不用登录,直接下载 如果你不想下载最新版本,点击Archives...
  • 数据库连接池基本使用步骤
  • Oracle数据库连接池的创建和使用

    千次阅读 2021-06-30 10:28:20
    Oracle数据库连接池的创建和使用 数据库连接池的主要操作如下: 建立数据库连接池对象(服务器启动)。 按照事先指定的参数创建初始数量的数据库连接(即:空闲连接数)。 对于一个数据库访问请求,直接从连接池中...
  • (10)常见的几种数据库连接池的配置和使用

    万次阅读 多人点赞 2020-03-17 15:59:04
    今天主要介绍几款常见的数据库连接池 并且对它们的使用做一个总结,本篇文章是以SpringBoot 项目为例,一起随着小编看一下吧! 在文章的开始,提出一个问题: 一.为什么要使用数据库连接池? 影响一个系统使用...
  • 作者曾经主持以及经历的几个产品及项目中,包括了各种数据库及应用服务器,基本上几种常见的数据库连接池都用到了,根据使用的情况把这些连接池比较一下吧。感觉在介绍之前必要阐述一下连接池的几个概念,助于...
  • Hikari连接池

    千次阅读 2022-01-11 18:13:43
    常见连接池有C3P0、DBCP、它们都比较成熟稳定,但性能不是十分好。 所以了BoneCP这个连接池,它是一个高速、免费、开源的JAVA连接池,它的性能几乎是C3P0、DBCP的25倍,十分强悍。 HikariCP连接池 HiKariCP是...
  • Springboot连接池的配置 前言:最近发现项目日志中经常会出现有关数据源的一些警告信息,说实话看着这种日志就很闹心,而且对于数据源这么重要的东西还是必要去着重解决,学习的。 可以看出,两个关于数据源的...
  • 线程池就是事先将多个线程对象放到一个容器中,当使用的时候就不用 new 线程而是直接去中拿线程即可,节 省了开辟子线程的时间,提高的代码执行效率。 线程池的优点: 第一:降低资源消耗。通过重复利用已创建的...
  • MySQL-连接池

    千次阅读 2022-03-31 21:28:01
    连接池是connection对象的缓冲区,他里面会存放一些connection,当程序需要使用connection时,如果连接池,则直接从连接池获取,不需要再重新创建connection。连接池让程序能够复用连接。 2、为什么使用连接池 ...
  • MySQL数据库连接池

    千次阅读 2021-11-04 20:07:41
    第一节:数据库连接池 1.为什么使用数据库连接池 回顾:jdbc步骤: 1.加载驱动 2.创建连接 3.sql预编译 (Statement/PreparedStatement ?) 4.执行sql(DQL:executeQuery(), DML:executeUpdate()) 5.关闭连接 在...
  • Druid数据库连接池

    千次阅读 2022-05-11 19:34:00
    1.数据库连接池简介 数据库连接池是个容器,负责分配、管理数据库连接(Connection)。它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个; 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有...
  • TongWeb的数据源连接池常见问题

    千次阅读 2020-11-06 10:18:02
    TongWeb的数据源连接池占满时的日志 [2019-05-13 11:15:56] [WARNING] [other] [Failed to obtain/create connection from connection pool [ test ]. Reason : The connection could not be allocated:...
  • mybatis数据库连接池配置

    千次阅读 2021-01-19 09:23:06
    为中国首个且唯一入选BI产品 广告 Mybatis的整体架构 1、 mybatis配置文件,2类配置文件 a) 全局配置文件,只能一个,文件名不是固定的,约定文件名:mybatis-config.xml,配置了运行参数、插件、连接池等信息...
  • 项目——C++实现数据库连接池

    千次阅读 2022-03-26 15:04:46
    前言 在学习Mysql的时候,我们都这个常识:对于DB的...增加连接池,来提高MYsql Server的访问效率,在高并发的情况下,每一个用户大量的TCP三次握手。Mysql Server的连接认证,Mysql Server关闭连接回收资源和TCP四次
  • 文章目录十五、配置数据库连接池-整合Druid15.1 常见连接池15.2 添加Druid依赖15.3 将MyBatis的连接池替换为Druid 十五、配置数据库连接池-整合Druid MyBatis作为一个ORM框架,在进行数据库操作时是需要和数据库...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 128,781
精华内容 51,512
热门标签
关键字:

常见的连接池有哪些