Skip to content
On this page

Prisma 连接池

连接池是数据库性能优化的重要方面,它通过重用现有的数据库连接来提高应用程序的性能和资源利用率。

连接池基础概念

连接池是一组预先建立的数据库连接,应用程序可以从池中获取连接并在使用完毕后将其返回,而不是每次都创建新的连接。

Prisma 中的连接池配置

基础配置

在 Prisma schema 中配置连接池参数:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
  
  // 连接池大小
  directUrl = env("DIRECT_DATABASE_URL")
  
  // 在数据库连接字符串中配置连接池
  url = "postgresql://user:pass@host:port/db?connection_limit=10&pool_timeout=5"
}

环境变量配置

在连接字符串中配置连接池参数:

# PostgreSQL
DATABASE_URL="postgresql://user:pass@localhost:5432/db?connection_limit=20&pool_timeout=5"

# MySQL
DATABASE_URL="mysql://user:pass@localhost:3306/db?connection_limit=20&pool_timeout=5"

连接池参数详解

connection_limit

指定最大连接数:

DATABASE_URL="postgresql://user:pass@localhost:5432/db?connection_limit=20"

这个参数设置连接池的最大连接数量。根据应用程序的并发需求和数据库服务器的容量来调整。

pool_timeout

指定等待连接的最长时间:

DATABASE_URL="postgresql://user:pass@localhost:5432/db?pool_timeout=10"

如果所有连接都在使用中,新请求将等待指定的秒数,然后抛出错误。

statement_timeout

设置单个 SQL 语句的超时时间:

DATABASE_URL="postgresql://user:pass@localhost:5432/db?statement_timeout=30000"

连接池管理

初始化连接池

typescript
import { PrismaClient } from '@prisma/client'

// 连接池在第一次使用时自动初始化
const prisma = new PrismaClient({
  // 日志级别
  log: ['info', 'warn', 'error'],
})

连接池监控

typescript
// 监控连接池状态
async function monitorPool() {
  try {
    // 执行健康检查查询
    await prisma.$queryRaw`SELECT 1`
    console.log('Database connection is healthy')
  } catch (error) {
    console.error('Database connection failed:', error)
  }
}

连接池清理

typescript
// 应用关闭时清理连接池
process.on('beforeExit', async () => {
  await prisma.$disconnect()
})

连接池最佳实践

1. 合理设置连接池大小

typescript
// 根据应用并发需求和数据库能力设置
// 对于一般应用,10-20 个连接通常足够
const prisma = new PrismaClient({
  datasources: {
    db: {
      url: process.env.DATABASE_URL,
    }
  }
})

2. 使用环境变量管理配置

bash
# .env 文件
DATABASE_URL="postgresql://user:pass@localhost:5432/db?connection_limit=20&pool_timeout=5&statement_timeout=30000"

3. 实现连接健康检查

typescript
// 实现定期健康检查
setInterval(async () => {
  try {
    await prisma.$queryRaw`SELECT 1`
    console.log('✓ Database connection OK')
  } catch (error) {
    console.error('✗ Database connection failed:', error)
  }
}, 30000) // 每30秒检查一次

性能优化建议

1. 监控连接池使用情况

typescript
// 添加性能监控
const startTime = Date.now()
try {
  const result = await prisma.user.findMany()
  const endTime = Date.now()
  console.log(`Query took ${endTime - startTime}ms`)
  return result
} catch (error) {
  const endTime = Date.now()
  console.error(`Query failed after ${endTime - startTime}ms`, error)
  throw error
}

2. 避免连接泄漏

typescript
// 确保始终释放连接
try {
  const result = await prisma.user.findMany()
  // 处理结果
  return result
} finally {
  // 在 finally 块中确保资源清理
}

连接池故障排除

常见问题

  1. 连接超时:增加连接池大小或超时时间
  2. 连接泄漏:确保正确处理异常并释放连接
  3. 性能问题:监控慢查询并优化

诊断工具

typescript
// 添加详细的日志记录
const prisma = new PrismaClient({
  log: [
    { level: 'query', emit: 'event' },
    { level: 'info', emit: 'stdout' },
    { level: 'warn', emit: 'stdout' },
    { level: 'error', emit: 'stdout' },
  ],
})

prisma.$on('query', (e) => {
  console.log('Query: ' + e.query)
  console.log('Params: ' + e.params)
  console.log('Duration: ' + e.duration + 'ms')
})

总结

有效的连接池管理对于应用程序性能至关重要。通过合理配置连接池参数、监控连接使用情况和实施最佳实践,可以显著提高数据库访问性能和可靠性。