用数据说话 - 数据库连接池真的香吗?

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 用数据说话 - 数据库连接池真的香吗?

什么是连接池


数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。


为什么要使用连接池


一次数据库的步骤


  1. TCP建立连接的三次握手


  1. MySQL认证的三次握手


  1. 真正的SQL执行


  1. MySQL的关闭


  1. TCP的四次握手关闭


利用连接池后



连接池优点


  • 较少了网络开销


  • 系统的性能会有一个实质的提升


  • 没了麻烦的TIME_WAIT状态


连接池实战


预备1:模拟并发处理


由于只有并发处理才能体现连接池的价值。所以要试验连接池前我们先搞一个并发函数。


要求如下:


  1. 可以设置并发量


  1. 可以设置总执行次数


  1. 可以打印每次执行的耗时和总耗时


const sleep = delay => new Promise(resolve => setTimeout(resolve, delay))
const asyncFun = async (fun, curMax = 4, sum = 200) => {
    let num = 0
    let curNum = 0
    console.time('总耗时');
    console.log('beginTime:' + new Date().toLocaleString())
    const result = []
    while (num !== sum) {
        if (curNum <= curMax) {
            result.push(new Promise(async resolve => {
                console.log(`Process Run 并发数:${curNum} 完成:${num}/${sum} `)
                res = await fun()
                curNum--
                resolve(res)
            }))
            num++
            curNum++
        } else {
            await sleep(10)
        }
    }
    console.log('endTime:' + new Date().toLocaleString())
    console.timeEnd('总耗时');
}
module.exports = { asyncFun }
// 测试
const test = async () => {
    const delay = (Math.random() * 1000).toFixed()
    await sleep(delay)
}
setTimeout(() => asyncFun(test, 4, 20))



预备2:mysql查看连接数


mysqladmin -uroot -pexample processlist



未使用连接池


(async () => {
    // get the client
    const mysql = require('mysql2/promise');
    // 连接配置
    const cfg = {
        host: "localhost",
        user: "root",
        password: "example", // 修改为你的密码
        database: "shop", // 请确保数据库存在
        connectionLimit : 5,
    }
    // 非连接池
    const query = async () => {
        const connection = await mysql.createConnection(cfg)
        const [rows, fields] = await connection.execute(`SELECT * FROM users`)
        // console.log('select:', rows)
        connection.destroy()
    }
    const { asyncFun } = require('./async')
    await asyncFun(query, 20, 1000)
})()


执行耗时



数据库的连接数



使用连接池


下面我们改用连接池方式


// 设置连接池
    const pool = await mysql.createPool(cfg)
    // 连接池
    const query = async () => {
        const connection = await pool.getConnection()
        const [rows, fields] = await connection.execute(`SELECT * FROM users`)
        // console.log('select:', rows)
        connection.release()
    }


执行耗时



数据库的连接数



数据对比与总结


非连接池 连接池
总耗时 7.043 1.459s
连接数 20(等于并发数) 5(连接池连接数)


在处理中只使用了五个连接有效的节省了系统资源,并且提升了性能总耗时只有原来的大约五分之一。


数据库中间件中的连接池设置


(async () => {
    const Sequelize = require("sequelize");
    // 建立连接
    const sequelize = new Sequelize("kaikeba", "root", "example", {
        host: "localhost",
        dialect: "mysql",
        // operatorsAliases: false,
        pool: {
            max: 10,
            min: 0,
            idle: 30000
        }
    });
    // 定义模型
    const Fruit = sequelize.define("Fruit", {
        name: { type: Sequelize.STRING(20), allowNull: false },
        price: { type: Sequelize.FLOAT, allowNull: false },
        stock: { type: Sequelize.INTEGER, defaultValue: 0 }
    });
    // 同步数据库,force: true则会删除已存在表
    let ret = await Fruit.sync({ force: true })
    console.log('sync', ret)
    ret = await Fruit.create({
        name: "香蕉",
        price: 3.5
    })
    // console.log('create', ret)
    const find = async () => {
        Fruit.findAll()
        // console.log('findAll', JSON.stringify(ret, '', '\t'))
    }
    // await find()
    const { asyncFun } = require('./async')
    asyncFun(find,20,100)
})()


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
10天前
|
领域建模 微服务
死磕-领域驱动模型(一)
死磕-领域驱动模型(一)
|
2月前
|
存储 Java 数据库连接
那些年,我与JDBC的“甜蜜”回忆
那些年,我与JDBC的“甜蜜”回忆
27 4
|
5月前
|
JavaScript Java 关系型数据库
流浪动物救助|基于Springboot的流浪动物救助平台设计与实现(源码+数据库+文档)
流浪动物救助|基于Springboot的流浪动物救助平台设计与实现(源码+数据库+文档)
51 0
|
5月前
|
JavaScript Java 关系型数据库
宠物救助系统|基于Springboot和vue的流浪猫狗救助救援系统设计与实现(源码+数据库+文档)
宠物救助系统|基于Springboot和vue的流浪猫狗救助救援系统设计与实现(源码+数据库+文档)
80 0
|
存储 SQL 缓存
收好这份武林秘籍,让你分库分表再无烦恼
互联网发展至今,各个公司企业的数据量都大幅增长,分库分表越来越多的被我们用到,那么我们应该如何针对我们自己的业务场景,对数据进行合理的划分,用最小的代价解决掉性能瓶颈。
277 0
|
安全 NoSQL Java
如果让ChatGPT对线面试官会怎么样
如果让ChatGPT对线面试官会怎么样
80 0
|
存储 前端开发
【面试造火箭,入职拧螺丝】万字详解如何从0开始手写一个Promise
手写Promise现在已经成了面试的热门内容,但在实际开发中基本都不会去手写一个Promise,但是在面试中各种手写题可能就会遇到一个手写Promise,我们可以尽量提高我们的上限,从而获取更多的工作机会。
111 0
【面试造火箭,入职拧螺丝】万字详解如何从0开始手写一个Promise
下一篇
无影云桌面