数据库连接池管理 logo

数据库连接池管理

Organization
microwind
数据库连接池管理

当设计数据库连接池时,分析连接池策略,优化性能配置,解决连接泄漏。验证连接池架构,设计监控方案,和最佳实践。

Overview

Publishermicrowind
Repositoryai-skills
Skill name数据库连接池管理
Stars
93
Forks
25
Bundled files
2
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 2 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by microwind on GitHub. Read the source before you install it.

Installation

Install the 数据库连接池管理 AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/microwind/ai-skills/tree/main/database/connection-pooling
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/microwind/ai-skills.git /tmp/ai-skills
mkdir -p .claude/skills
cp -r /tmp/ai-skills/database/connection-pooling .claude/skills/microwind-19
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable 数据库连接池管理 in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads 数据库连接池管理 on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so 数据库连接池管理 is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

数据库连接池管理技能

概述

数据库连接池是管理数据库连接的重要技术,通过复用数据库连接来提高应用性能和资源利用率。合理的连接池配置可以显著减少连接建立和销毁的开销,提高系统的并发处理能力。不当的连接池设计会导致连接泄漏、性能瓶颈和系统不稳定。

核心原则: 好的连接池应该合理配置大小、及时回收空闲连接、有效处理连接泄漏、提供监控指标。坏的连接池会导致资源浪费、性能下降、系统崩溃。

何时使用

始终:

  • 设计高并发数据库应用时
  • 优化数据库访问性能时
  • 处理大量数据库连接时
  • 构建微服务架构时
  • 实现数据库负载均衡时
  • 处理数据库连接超时时

触发短语:

  • "如何设计连接池?"
  • "数据库连接优化"
  • "连接池配置最佳实践"
  • "连接泄漏处理"
  • "连接池监控"
  • "高并发数据库访问"

数据库连接池管理技能功能

连接池配置

  • 初始连接数
  • 最大连接数
  • 最小空闲连接数
  • 最大空闲连接数
  • 连接超时时间
  • 空闲连接超时时间

连接生命周期管理

  • 连接创建
  • 连接验证
  • 连接复用
  • 连接回收
  • 连接销毁
  • 连接泄漏检测

性能优化

  • 连接预热
  • 连接池扩容
  • 连接池缩容
  • 连接复用策略
  • 批量操作优化
  • 异步连接获取

监控与诊断

  • 连接池状态监控
  • 连接使用统计
  • 性能指标收集
  • 异常情况告警
  • 连接泄漏检测
  • 资源使用分析

常见问题

❌ 连接池配置不当

  • 最大连接数过小导致等待
  • 最小连接数过大浪费资源
  • 超时时间设置不合理
  • 连接验证策略过于频繁

❌ 连接泄漏

  • 连接使用后未正确释放
  • 异常情况下连接未回收
  • 长时间事务占用连接
  • 连接池监控缺失

❌ 性能问题

  • 连接池竞争激烈
  • 连接创建开销过大
  • 连接验证耗时过长
  • 连接池扩容不及时

❌ 资源管理

  • 连接池大小与数据库不匹配
  • 多个连接池资源冲突
  • 连接池关闭不彻底
  • 内存泄漏和资源浪费

代码示例

基础连接池实现

java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class BasicConnectionPool {
    private final String url;
    private final String username;
    private final String password;
    private final int maxSize;
    private final int initSize;
    private final BlockingQueue<Connection> connectionPool;
    private final AtomicInteger activeConnections = new AtomicInteger(0);
    
    public BasicConnectionPool(String url, String username, String password, 
                            int initSize, int maxSize) throws SQLException {
        this.url = url;
        this.username = username;
        this.password = password;
        this.maxSize = maxSize;
        this.initSize = initSize;
        this.connectionPool = new LinkedBlockingQueue<>(maxSize);
        
        // 初始化连接池
        initializePool();
    }
    
    private void initializePool() throws SQLException {
        for (int i = 0; i < initSize; i++) {
            Connection connection = createNewConnection();
            connectionPool.offer(connection);
        }
    }
    
    private Connection createNewConnection() throws SQLException {
        return DriverManager.getConnection(url, username, password);
    }
    
    public Connection getConnection() throws SQLException, InterruptedException {
        Connection connection = connectionPool.poll(5, TimeUnit.SECONDS);
        
        if (connection == null) {
            if (activeConnections.get() < maxSize) {
                connection = createNewConnection();
                activeConnections.incrementAndGet();
            } else {
                // 等待可用连接
                connection = connectionPool.take();
            }
        }
        
        // 验证连接是否有效
        if (!isConnectionValid(connection)) {
            connection = createNewConnection();
        }
        
        return connection;
    }
    
    public void releaseConnection(Connection connection) {
        if (connection != null) {
            try {
                if (!connection.isClosed()) {
                    connectionPool.offer(connection);
                } else {
                    activeConnections.decrementAndGet();
                }
            } catch (SQLException e) {
                activeConnections.decrementAndGet();
            }
        }
    }
    
    private boolean isConnectionValid(Connection connection) {
        try {
            return connection != null && !connection.isClosed() && 
                   connection.isValid(1); // 1秒超时验证
        } catch (SQLException e) {
            return false;
        }
    }
    
    public int getActiveConnections() {
        return activeConnections.get();
    }
    
    public int getIdleConnections() {
        return connectionPool.size();
    }
    
    public void close() {
        for (Connection connection : connectionPool) {
            try {
                connection.close();
            } catch (SQLException e) {
                // 记录日志
            }
        }
        connectionPool.clear();
        activeConnections.set(0);
    }
}

HikariCP高性能连接池配置

java
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;

public class HikariCPManager {
    private HikariDataSource dataSource;
    
    public DataSource createDataSource(String url, String username, String password) {
        HikariConfig config = new HikariConfig();
        
        // 基本配置
        config.setJdbcUrl(url);
        config.setUsername(username);
        config.setPassword(password);
        config.setDriverClassName("com.mysql.cj.jdbc.Driver");
        
        // 连接池配置
        config.setMinimumIdle(5);           // 最小空闲连接数
        config.setMaximumPoolSize(20);        // 最大连接池大小
        config.setConnectionTimeout(30000);  // 连接超时时间(ms)
        config.setIdleTimeout(600000);        // 空闲超时时间(ms)
        config.setMaxLifetime(1800000);       // 连接最大生命周期(ms)
        config.setLeakDetectionThreshold(60000); // 连接泄漏检测阈值(ms)
        
        // 性能优化配置
        config.setAutoCommit(true);           // 自动提交
        config.setConnectionTestQuery("SELECT 1"); // 连接测试查询
        config.setValidationTimeout(5000);     // 验证超时时间
        config.setPoolName("MyHikariCP");      // 连接池名称
        
        // 监控配置
        config.setRegisterMbeans(true);        // 注册JMX MBean
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        
        dataSource = new HikariDataSource(config);
        return dataSource;
    }
    
    public void close() {
        if (dataSource != null) {
            dataSource.close();
        }
    }
    
    // 获取连接池状态
    public String getPoolStatus() {
        if (dataSource == null) {
            return "DataSource not initialized";
        }
        
        HikariPoolMXBean poolProxy = dataSource.getHikariPoolMXBean();
        return String.format(
            "Active: %d, Idle: %d, Waiting: %d, Total: %d",
            poolProxy.getActiveConnections(),
            poolProxy.getIdleConnections(),
            poolProxy.getThreadsAwaitingConnection(),
            poolProxy.getTotalConnections()
        );
    }
}

连接池监控和管理

java
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.HikariPoolMXBean;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ConnectionPoolMonitor {
    private final HikariDataSource dataSource;
    private final ScheduledExecutorService scheduler;
    private final MetricsCollector metricsCollector;
    
    public ConnectionPoolMonitor(HikariDataSource dataSource) {
        this.dataSource = dataSource;
        this.scheduler = Executors.newScheduledThreadPool(1);
        this.metricsCollector = new MetricsCollector();
        
        startMonitoring();
    }
    
    private void startMonitoring() {
        scheduler.scheduleAtFixedRate(this::collectMetrics, 0, 30, TimeUnit.SECONDS);
    }
    
    private void collectMetrics() {
        HikariPoolMXBean poolProxy = dataSource.getHikariPoolMXBean();
        
        PoolMetrics metrics = PoolMetrics.builder()
            .activeConnections(poolProxy.getActiveConnections())
            .idleConnections(poolProxy.getIdleConnections())
            .waitingThreads(poolProxy.getThreadsAwaitingConnection())
            .totalConnections(poolProxy.getTotalConnections())
            .timestamp(System.currentTimeMillis())
            .build();
        
        metricsCollector.record(metrics);
        
        // 检查告警条件
        checkAlerts(metrics);
    }
    
    private void checkAlerts(PoolMetrics metrics) {
        // 检查连接池使用率
        double usageRate = (double) metrics.getActiveConnections() / 
                          metrics.getTotalConnections();
        
        if (usageRate > 0.8) {
            sendAlert("连接池使用率过高: " + String.format("%.1f%%", usageRate * 100));
        }
        
        // 检查等待线程数
        if (metrics.getWaitingThreads() > 10) {
            sendAlert("连接池等待线程过多: " + metrics.getWaitingThreads());
        }
        
        // 检查空闲连接数
        if (metrics.getIdleConnections() < 2) {
            sendAlert("空闲连接数过低: " + metrics.getIdleConnections());
        }
    }
    
    private void sendAlert(String message) {
        // 发送告警通知
        System.err.println("[ALERT] " + message);
        // 可以集成邮件、短信、Slack等通知方式
    }
    
    public void shutdown() {
        scheduler.shutdown();
        try {
            if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
                scheduler.shutdownNow();
            }
        } catch (InterruptedException e) {
            scheduler.shutdownNow();
        }
    }
    
    // 连接池指标数据类
    @lombok.Data
    @lombok.Builder
    public static class PoolMetrics {
        private int activeConnections;
        private int idleConnections;
        private int waitingThreads;
        private int totalConnections;
        private long timestamp;
    }
    
    // 指标收集器
    public static class MetricsCollector {
        private final List<PoolMetrics> metricsHistory = new ArrayList<>();
        
        public void record(PoolMetrics metrics) {
            synchronized (metricsHistory) {
                metricsHistory.add(metrics);
                // 保留最近1000条记录
                if (metricsHistory.size() > 1000) {
                    metricsHistory.remove(0);
                }
            }
        }
        
        public List<PoolMetrics> getMetricsHistory() {
            return new ArrayList<>(metricsHistory);
        }
        
        public PoolMetrics getLatestMetrics() {
            synchronized (metricsHistory) {
                return metricsHistory.isEmpty() ? null : 
                       metricsHistory.get(metricsHistory.size() - 1);
            }
        }
    }
}

Spring Boot连接池配置

java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.jdbc.DataSourceBuilder;
import javax.sql.DataSource;

@Configuration
public class DatabaseConfig {
    
    @Bean
    @ConfigurationProperties(prefix = "app.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create()
            .type(com.zaxxer.hikari.HikariDataSource.class)
            .build();
    }
}

# application.yml
app:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: ${DB_USERNAME:user}
    password: ${DB_PASSWORD:pass}
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      minimum-idle: 5
      maximum-pool-size: 20
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
      leak-detection-threshold: 60000
      pool-name: SpringHikariCP
      connection-test-query: SELECT 1

连接池使用示例

java
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UserRepository {
    private final DataSource dataSource;
    
    public UserRepository(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    
    public User findById(Long id) throws SQLException {
        String sql = "SELECT * FROM users WHERE id = ?";
        
        try (Connection connection = dataSource.getConnection();
             PreparedStatement statement = connection.prepareStatement(sql)) {
            
            statement.setLong(1, id);
            
            try (ResultSet resultSet = statement.executeQuery()) {
                if (resultSet.next()) {
                    return mapRowToUser(resultSet);
                }
            }
        }
        
        return null;
    }
    
    public void save(User user) throws SQLException {
        String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
        
        try (Connection connection = dataSource.getConnection();
             PreparedStatement statement = connection.prepareStatement(sql)) {
            
            statement.setString(1, user.getName());
            statement.setString(2, user.getEmail());
            
            statement.executeUpdate();
        }
    }
    
    private User mapRowToUser(ResultSet resultSet) throws SQLException {
        User user = new User();
        user.setId(resultSet.getLong("id"));
        user.setName(resultSet.getString("name"));
        user.setEmail(resultSet.getString("email"));
        return user;
    }
}

最佳实践

连接池配置

  • 合理设置大小: 根据并发量和数据库能力设置最大连接数
  • 设置超时时间: 避免无限等待,设置合理的连接和查询超时
  • 启用连接验证: 定期验证连接有效性,避免使用失效连接
  • 配置生命周期: 设置连接最大生命周期,定期刷新连接

性能优化

  • 连接预热: 应用启动时预先创建一定数量的连接
  • 批量操作: 使用批量SQL减少连接使用次数
  • 事务管理: 合理控制事务范围,及时释放连接
  • 连接复用: 尽量复用连接,减少连接创建开销

监控告警

  • 实时监控: 监控连接池使用率、等待时间等关键指标
  • 告警机制: 设置合理的告警阈值,及时发现问题
  • 日志记录: 记录连接池操作日志,便于问题排查
  • 性能分析: 定期分析连接池性能数据,优化配置

异常处理

  • 连接泄漏检测: 启用连接泄漏检测,及时发现未释放的连接
  • 优雅降级: 连接池满时提供降级策略
  • 重试机制: 连接获取失败时实现重试逻辑
  • 资源清理: 应用关闭时正确释放连接池资源

相关技能

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the 数据库连接池管理 AI skill do?

当设计数据库连接池时,分析连接池策略,优化性能配置,解决连接泄漏。验证连接池架构,设计监控方案,和最佳实践。

Why use 数据库连接池管理 on TypingMind?

Because you install it once and use it with any model. 数据库连接池管理 is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install 数据库连接池管理 in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/microwind/ai-skills/tree/main/database/connection-pooling. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use 数据库连接池管理?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with 数据库连接池管理?

As many as you like. As long as a model supports skills, you can use 数据库连接池管理 with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the 数据库连接池管理 AI skill free?

Yes. It is published on GitHub by microwind under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇