線程池-連接池-JDBC實例-JDBC連接池技術

来源:https://www.cnblogs.com/yuanziren/archive/2019/07/01/11113119.html
-Advertisement-
Play Games

線程池和連接池 線程池的原理: 來看一下線程池究竟是怎麼一回事?其實線程池的原理很簡單,類似於操作系統中的緩衝區的概念,它的流程如下:先啟動若幹數量的線程,並讓這些線程都處於睡眠狀態,當客戶端有一個新請求時,就會喚醒線程池中的某一個睡眠線程,讓它來處理客戶端的這個請求,當處理完這個請求後,線程又處於 ...


線程池和連接池
  
線程池的原理:    
      來看一下線程池究竟是怎麼一回事?其實線程池的原理很簡單,類似於操作系統中的緩衝區的概念,它的流程如下:先啟動若幹數量的線程,並讓這些線程都處於睡眠狀態,當客戶端有一個新請求時,就會喚醒線程池中的某一個睡眠線程,讓它來處理客戶端的這個請求,當處理完這個請求後,線程又處於睡眠狀態。

 為什麼要使用線程池:

  高峰期客戶端請求併發量大,如果為每個客戶端請求創建一個新線程的話,那耗費的CPU時間和記憶體將是驚人的,如果採用一個擁有多個線程的線程池,那將會節約大量的的系統資源,使得更多的CPU時間和記憶體用來處理實際的商業應用,而不是頻繁的線程創建與銷毀。

    資料庫連接池:
   一個資料庫連接對象均對應一個物理資料庫連接,每次操作都打開一個物理連接,使用完都關閉連接,這樣造成系統的 性能低下。

 資料庫連接解決方案:

  資料庫連接池(Connection Pool)。系統初始運行時,主動建立足夠的連接,組成一個池.每次應用應用程式請求資料庫連接時,無需重新打開連接,而是從池中取出已有的連接,使用完後,不再關閉,而是歸還。

  資料庫連接池的解決方案是在應用程式啟動時建立足夠的資料庫連接,並將這些連接組成一個連接池(簡單說:在一個“池”里放了好多半成品的資料庫聯接對象),由應用程式動態地對池中的連接進行申請、使用和釋放。對於多於連接池中連接數的併發請求,應該在請求隊列中排隊等待。並且應用程式可以根據池中連接的使用率,動態增加或減少池中的連接數。
  連接池技術儘可能多地重用了消耗記憶體地資源,大大節省了記憶體,提高了伺服器地服務效率,能夠支持更多的客戶服務。通過使用連接池,將大大提高程式運行效率,同時,我們可以通過其自身的管理機制來監視資料庫連接的數量、使用情況等。
    1) 最小連接數是連接池一直保持的資料庫連接,所以如果應用程式對資料庫連接的使用量不大,將會有大量的資料庫連接資源被浪費;
    2) 最大連接數是連接池能申請的最大連接數,如果資料庫連接請求超過此數,後面的資料庫連接請求將被加入到等待隊列中,這會影響之後的資料庫操作。

 為什麼要使用連接池技術?

  這個可以從資料庫連接缺陷和連接池優勢來回答。

  資料庫連接缺陷: 一個資料庫連接對象均對應一個物理資料庫連接,每次操作都打開一個物理連接,使用完都關閉連接,這樣造成系統的 性能低下。

  連接池技術:系統初始運行時,主動建立足夠的連接,組成一個池.每次應用應用程式請求資料庫連接時,無需重新打開連接,而是從池中取出已有的連接,使用完後,不再關閉,而是歸還。

 連接池的組成部分:連接池的建立、連接池中連接的使用管理、連接池的關閉。

  1.連接池的建立
    在系統初始化時,根據相應的配置創建連接並放置在連接池中,以便需要使用時能從連接池中獲取,這樣就可以避免連接隨意的建立、關閉造成的開銷。
  2.連接池中連接的使用管理
    連接池管理策略是連接池機制的核心。當連接池建立後,如何對連接池中的連接進行管理,解決好連接池內連接的分配和釋放,對系統的性能有很大的影響。連接的合理分配、釋放可提高連接的復用,降低了系統建立新連接的開銷,同時也加速了用戶的訪問速度。
        採用的方法是一個很有名的設計模式:Reference Counting(引用記數)。該模式在復用資源方面應用的非常廣泛,把該方法運用到對於連接的分配釋放上,為每一個資料庫連接,保留一個引用記數,用來記錄該連接的使用者的個數。
    (1)當客戶請求資料庫連接時,首先查看連接池中是否有空閑連接(指當前沒有分配出去的連接)。如果存在空閑連接,則把連接分配給客戶並作相應處理(即標記該連接為正在使用,引用計數加1)。如果沒有空閑連接,則查看當前所開的連接數是不是已經達到maxConn(最大連接數),如果沒達到就重新創建一個連接給請求的客戶;如果達到就按設定的maxWaitTime(最大等待時間)進行等待,如果等待maxWaitTime後仍沒有空閑連接,就拋出無空閑連接的異常給用戶。
    (2)當客戶釋放資料庫連接時,先判斷該連接的引用次數是否超過了規定值,如果超過就刪除該連接,並判斷當前連接池內總的連接數是否小於minConn(最小連接數),若小於就將連接池充滿;如果沒超過就將該連接標記為開放狀態,可供再次復用。可以看出正是這套策略保證了資料庫連接的有效復用,避免頻繁地建立、釋放連接所帶來的系統資源開銷。
  3.連接池的關閉
    當應用程式退出時,應關閉連接池,此時應把在連接池建立時向資料庫申請的連接對象統一歸還給資料庫(即關閉所有資料庫連接),這與連接池的建立正好是一個相反過程。
    我們採用DBCP(DataBase connection pool),資料庫連接池。DBCP(是 apache 上的一個 java 連接池項目,也是 tomcat 使用的連接池組件。單獨使用dbcp需要3個包:commons-dbcp.jar,commons-pool.jar,commons-collections.jar由於建立資料庫連接是一個非常耗時耗資源的行為,所以通過連接池預先同資料庫建立一些連接,放在記憶體中,應用程式需要建立資料庫連接時直接到連接池中申請一個就行,用完後再放回去。

 連接池的實現:

    1.使用Idea創建一個Maven項目,如下是Maven的項目結構:

    2.resources文件夾下麵的db.properties文件

1 jdbc.driver=com.mysql.cj.jdbc.Driver
2 jdbc.url=jdbc:mysql://localhost:3306/crm01?useUnicode=true&characterEncoding=utf8
3 jdbc.user=root
4 jdbc.password=123456
5 initsize=1
6 maxactive=1
7 maxwait=5000
8 maxidle=1
9 minidle=1
#dbcp的基本配置的介紹
#1.initialSize :連接池啟動時創建的初始化連接數量(預設值為0)
#2.maxActive :連接池中可同時連接的最大的連接數(預設值為8,調整為20,高峰單機器在20併發左右,自己根據應用場景定)
#3.maxIdle:連接池中最大的空閑的連接數,超過的空閑連接將被釋放,如果設置為負數表示不限制
#(預設為8個,maxIdle不能設置太小,因為假如在高負載的情況下,連接的打開時間比關閉的時間快,會引起連接池中idle的個數 上升超過maxIdle,而造成頻繁的連接銷毀和創建,類似於jvm參數中的Xmx設置)
#4.minIdle:連接池中最小的空閑的連接數,低於這個數量會被創建新的連接(
#預設為0,調整為5,該參數越接近maxIdle,性能越好,因為連接的創建和銷毀,都是需要消耗資源的;但是不能太大,因為在機器很空閑的時候,也會創建低於minidle個數的連接,類似於jvm參數中的Xmn設置)
#5.maxWait  :最大等待時間,當沒有可用連接時,連接池等待連接釋放的最大時間,超過該時間限制會拋出異常,
#如果設置-1表示無限等待(預設為無限,調整為60000ms,避免因線程池不夠用,而導致請求被無限制掛起)

  

  3.DBUtil.java

package com.yuanziren;
import org.apache.commons.dbcp.BasicDataSource;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * 使用連接池技術管理資料庫連接
 */
public class DBUtil {
    
    //資料庫連接池
    private static BasicDataSource dbcp;
    
    //為不同線程管理連接
    private static ThreadLocal<Connection> tl;
    
    //通過配置文件來獲取資料庫參數
    static{
        try{
            Properties prop = new Properties();
            InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("db.properties");
            prop.load(is);
            is.close();
            //一、初始化連接池
            dbcp = new BasicDataSource();
            //設置驅動 (Class.forName())
            dbcp.setDriverClassName(prop.getProperty("jdbc.driver"));
            //設置url
            dbcp.setUrl(prop.getProperty("jdbc.url"));
            //設置資料庫用戶名
            dbcp.setUsername(prop.getProperty("jdbc.user"));
            //設置資料庫密碼
            dbcp.setPassword(prop.getProperty("jdbc.password"));
            //初始連接數量
            dbcp.setInitialSize(Integer.parseInt(prop.getProperty("initsize")));
            //連接池允許的最大連接數
            dbcp.setMaxActive(Integer.parseInt(prop.getProperty("maxactive")));
            //設置最大等待時間
            dbcp.setMaxWait(Integer.parseInt(prop.getProperty("maxwait")));
            //設置最小空閑數
            dbcp.setMinIdle(Integer.parseInt(prop.getProperty("minidle")));
            //設置最大空閑數
            dbcp.setMaxIdle(Integer.parseInt(prop.getProperty("maxidle")));
            //初始化線程本地
            tl = new ThreadLocal<Connection>();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    /**
     * 獲取資料庫連接
     * @return
     * @throws SQLException 
     */
    public static Connection getConnection() throws SQLException {
        /*
         * 通過連接池獲取一個空閑連接
         */
        Connection conn = dbcp.getConnection();
        tl.set(conn);
        return conn;
    }

    /**
     * 關閉資料庫連接
     */
    public static void closeConnection(){
        try{
            Connection conn = tl.get();
            if(conn != null){
                /*
                 * 通過連接池獲取的Connection
                 * 的close()方法實際上並沒有將
                 * 連接關閉,而是將該鏈接歸還。
                 */
                conn.close();
                tl.remove();
            }    
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    /**
     * 測試是否連接成功
     * @param args
     * @throws SQLException
     */
    public static void main(String[] args) throws SQLException {
        System.out.println(getConnection());
    }
}

    4.pom.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5   <modelVersion>4.0.0</modelVersion>
 6 
 7   <groupId>com.yuanziren</groupId>
 8   <artifactId>dbcp</artifactId>
 9   <version>1.0-SNAPSHOT</version>
10 
11   <name>dbcp</name>
12   <!-- FIXME change it to the project's website -->
13   <url>http://www.example.com</url>
14 
15   <properties>
16     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17     <maven.compiler.source>1.8</maven.compiler.source>
18     <maven.compiler.target>1.8</maven.compiler.target>
19   </properties>
20 
21   <dependencies>
22     <dependency>
23       <groupId>junit</groupId>
24       <artifactId>junit</artifactId>
25       <version>4.12</version>
26       <scope>test</scope>
27     </dependency>
28     <dependency>
29       <groupId>commons-dbcp</groupId>
30       <artifactId>commons-dbcp</artifactId>
31       <version>1.4</version>
32     </dependency>
33     <dependency>
34       <groupId>org.apache.commons</groupId>
35       <artifactId>commons-pool2</artifactId>
36       <version>2.6.2</version>
37     </dependency>
38     <dependency>
39       <groupId>org.apache.commons</groupId>
40       <artifactId>commons-collections4</artifactId>
41       <version>4.3</version>
42     </dependency>
43     <dependency>
44       <groupId>mysql</groupId>
45       <artifactId>mysql-connector-java</artifactId>
46       <version>8.0.16</version>
47     </dependency>
48   </dependencies>
49 
50   <build>
51   </build>
52 </project>

    4.運行結果

    5.代碼實現中遇到的Bug

      參考博客:

        JDBC連接MYSQL資料庫失敗:Loading class `com.mysql.jdbc.Driver'. This is deprecated.

        https://blog.csdn.net/weixin_42323802/article/details/82589743

        空指針問題:java.lang.NullPointerException at java.util.Properties$LineReader.readLine(Properties.java:434)問題

          https://blog.csdn.net/qq_41562136/article/details/83722473

        時區問題:

          https://blog.csdn.net/yongjiutongmi53151/article/details/86504546

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Centos7Yum安裝PHP7.21、安裝源 安裝php72w,是需要配置額外的yum源地址的,否則會報錯不能找到相關軟體包。 php高版本的yum源地址,有兩部分,其中一部分是epel-release,另外一部分來自webtatic。如果跳過epel-release的話,安裝webtatic的時 ...
  • rufus工具下載:下載鏈接 官方教程:官方教程鏈接 軟體界面預覽: 資源來源自網路,如果對您有幫助,請點擊推薦~。 我嘗試了這個方法可以用。電腦重啟時,選擇從U盤啟動,就能安裝系統。 參考鏈接: https://blog.csdn.net/xl_1851252/article/details/83 ...
  • [toc] centos7中好玩的命令 1.sl 此命令可以實現在屏幕上出現一個正在行駛的小火車 下載:yum install y sl 2.cowsay 此命令可以列印一個說話的小牛 下載:yum install y cowsay 3.boxes 此命令是列印一個ASCII的動畫 下載:yum i ...
  • 最近跟一個運維人員學了點新東西,感覺以前沒怎麼註意,但現在感覺很有用,特來記錄一下。 linux使用==ll==命令列出列表的時候,前面總是有一堆drwxr xr x ,這些代表什麼意思從來還沒有去在意過,只是找到自己的目錄然後一頓操作完事。但是這次在tomcat下部署項目的時候怎麼都不能啟動,後來 ...
  • 本文主要介紹ZooKeeper的快速部署安裝,更多信息請參考 "ZooKeeper" 概述 ZooKeeper 是一個分散式的,開放源碼的分散式應用程式協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。它是一個為分散式應用提供一致性服務的軟體,提供的功能包括 ...
  • 一、安裝編譯工具及庫文件 二、首先要安裝 PCRE PCRE 作用是讓 Nginx 支持 Rewrite 功能。 1、下載 PCRE 安裝包,下載地址: http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz ...
  • 鏈接:https://pan.baidu.com/s/1lnL3T8tc3ps2dp1zah1ZEA提取碼:wo5y Xshell 是一款強大的 SSH 客戶端 ,支持多種遠程協議,提供了很多功能與高級性能,中文界面也讓你輕鬆管理遠程伺服器。Xshell Plus 綠色版由NoCmd發佈! Xshe ...
  • 本文轉自: http://www.cnblogs.com/ggjucheng/archive/2012/01/14/2322659.html https://www.cnblogs.com/Jtianlin/p/4330723.html 簡介 用簡單的話來定義tcpdump,就是:dump the ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...