在 Dokploy 中為 PostgreSQL 搭建 PgBouncer 數據庫連接池(圖文)

前言:為什么你需要一個連接池?

如果你正在使用 Node.js (尤其是像 Next.js 這樣的框架) 配合 Prisma 操作 PostgreSQL 數據庫,你很可能在某個階段會遇到那個令人頭疼的錯誤:“Error: Too many clients already”。這通常發生在應用并發量上升,或者在 Next.js 的構建 (next build) 階段,因為它會嘗試并行渲染多個頁面,瞬間創建大量數據庫連接。

雖然最直接的反應是增加 PostgreSQL 的 max_connections,但這只是一個臨時的“創可貼”,它會消耗更多寶貴的服務器內存,并且無法從根本上解決連接風暴的問題。

一個更專業、更具擴展性的解決方案是在你的應用和數據庫之間引入一個中間件——連接池工具PgBouncer 正是此領域的王者,它輕量、高效,能以極小的資源消耗管理成千上萬的連接。

本指南將詳細記錄我們如何在 Dokploy 平臺上,為一個正在運行的 PostgreSQL 數據庫和一個需要進行靜態站點生成 (SSG) 的 Next.js 應用,成功搭建并配置 PgBouncer 服務。我們將這個過程中的每一步、遇到的每一個坑、以及最終的解決方案都毫無保留地分享出來。

核心架構:我們要做什么?

我們的目標非常明確:將應用架構從“直連”模式升級為通過 PgBouncer 連接池管理的“中間人”模式。

部署前架構 (直連模式):

[Next.js App] —> [PostgreSQL Database]

  • 問題: 應用的每一次數據庫操作都可能創建一個新的連接,在高并發或構建時極易耗盡數據庫資源。

部署后架構 (連接池模式):

[Next.js App] —> [PgBouncer Pooler] —> [PostgreSQL Database]

  • 優勢: Next.js 應用將所有連接請求都發送給 PgBouncer。PgBouncer 維護一個與 PostgreSQL 之間的小而穩定的連接池,高效地復用這些連接來處理大量請求。數據庫本身將得到極大的保護。

Step 1: 創建 PgBouncer 服務骨架

我們的第一步是在 Dokploy 中創建一個新的應用,用于承載 PgBouncer。

  1. 在 Dokploy 儀表盤,點擊 “Add new” -> “Application”。
  2. 在 “Provider” 部分,選擇 Docker 作為來源。
  3. Docker Image 輸入框中,填入鏡像名稱:edoburu/pgbouncer
  4. 此時先不要部署,直接進入下一步配置。
    在這里插入圖片描述

Step 2: 暴露所需端口

為了讓服務之間可以通過網絡互相訪問,我們需要將 PostgreSQL 和 PgBouncer 的端口都映射到宿主機上。

  1. 暴露 PostgreSQL 端口:

    • 進入你的 PostgreSQL 數據庫服務的配置頁面。
    • 導航到 Advanced -> Ports
    • 添加一條規則,將數據庫的真實端口(例如 5633)映射出來。
      • Published Port: 5633
      • Published Port Mode: Host
      • Target Port: 5633
    • 保存并 Redeploy PostgreSQL 服務。
  2. 暴露 PgBouncer 端口:

    • 回到我們剛剛創建的 PgBouncer 服務的配置頁面。
    • 導航到 Advanced -> Ports
    • 添加一條規則,將 PgBouncer 的監聽端口 6432 映射出來。
      • Published Port: 6432
      • Published Port Mode: Host
      • Target Port: 6432
    • 保存設置。

[圖片占位符:Dokploy 中為 PgBouncer 服務配置端口映射的彈窗界面]
在這里插入圖片描述

Step 3: 準備并掛載 PgBouncer 配置文件

現在,我們需要為 PgBouncer 提供它的“靈魂”——配置文件。

1. 在本地準備配置文件

在這里插入圖片描述
在這里插入圖片描述

  • pgbouncer.ini (主配置文件): 創建一個文本文件,填入以下內容。

    [databases]
    # 定義數據庫連接。這里的 key (YOUR_DATABASE_NAME) 最好和真實的 dbname 保持一致。
    # host 設置為你的服務器公網IP,port 設置為你的 PostgreSQL 真實端口。
    YOUR_DATABASE_NAME = host=YOUR_SERVER_PUBLIC_IP port=YOUR_POSTGRES_PORT dbname=YOUR_DATABASE_NAME[pgbouncer]
    # 監聽所有網絡接口,允許來自 Docker 外部和內部的連接
    listen_addr = *
    # PgBouncer 自身的監聽端口,給 Next.js 應用連接
    listen_port = 6432# 認證方式必須是 md5,并且需要指定用戶列表文件
    auth_type = md5
    auth_file = /etc/pgbouncer/userlist.txt# 定義哪些用戶擁有管理和查看統計的權限
    admin_users = YOUR_DATABASE_USERNAME
    stats_users = YOUR_DATABASE_USERNAME# 連接池模式。transaction 是對大多數應用最安全、最推薦的模式
    pool_mode = transaction# 池大小等性能配置
    default_pool_size = 20
    max_client_conn = 1000# pgbouncer 進程的 pid 文件路徑
    pidfile = /var/run/pgbouncer/pgbouncer.pid
    
  • userlist.txt (認證文件): 創建第二個文本文件,定義允許連接的用戶名和密碼。

    # 格式: "用戶名" "密碼"
    # 必須使用英文雙引號將用戶名和密碼括起來,中間用一個空格隔開。
    "YOUR_DATABASE_USERNAME" "YOUR_DATABASE_PASSWORD"
    
2. 在 Dokploy 中掛載配置文件
  • 回到 PgBouncer 服務Advanced -> Volumes 設置區域。
  • 添加兩個 File Mount 類型的掛載:
    • 第一個: 將 pgbouncer.ini全部內容粘貼進去,Mount Path 設置為 /etc/pgbouncer/pgbouncer.ini
    • 第二個: 將 userlist.txt全部內容粘貼進去,Mount Path 設置為 /etc/pgbouncer/userlist.txt

Step 4: 配置啟動命令并部署 PgBouncer

  1. PgBouncer 服務Advanced -> Run Command 區域,明確告訴容器如何啟動。
    • Command: pgbouncer /etc/pgbouncer/pgbouncer.ini
  2. 完成所有配置后,點擊頁面右上角的 Deploy 按鈕部署 PgBouncer 服務。
  3. 檢查 PgBouncer 的日志,確保它已正常啟動,并且沒有 broken auth fileconnect failed 等錯誤。

在這里插入圖片描述
最后回到 General 中點擊 Deploy 就可以部署成功了:

在這里插入圖片描述

Step 5: 更新 Next.js 應用配置(決勝一步)

現在 PgBouncer 服務已經通過公網 IP 和指定端口(6432)完全就緒,我們可以直接讓 Next.js 應用連接這個公開的地址。這個方法可以同時解決構建和運行時的連接問題。

  1. 進入你的 Next.js 應用在 Dokploy 的配置頁面。

  2. 導航到 Environment 標簽頁。

  3. 找到 DATABASE_URL 這個環境變量(如果沒有就新建一個)。

  4. 將其值設置為指向 PgBouncer 的公網地址

    postgresql://YOUR_DATABASE_USERNAME:YOUR_DATABASE_PASSWORD@YOUR_SERVER_PUBLIC_IP:6432/YOUR_DATABASE_NAME?pgbouncer=true
    

    重要: 請確保這里的 YOUR_SERVER_PUBLIC_IP 是您服務器的公網 IP,端口是 PgBouncer 的端口 6432

[圖片占位符:Next.js 應用中配置 DATABASE_URL 環境變量的截圖]

  1. 確認構建命令為默認值:在 “General” 標簽頁,確保 “Build Command” 是簡單的 pnpm run buildnpm run build,不帶任何 DATABASE_URL= 的前綴。
  2. 保存所有修改,然后點擊 Deploy 部署你的 Next.js 應用。
  3. ?pgbouncer=true 是一個專門的 “兼容模式”開關,你用它來明確地告知 Prisma:“注意,你現在連接的不是一個真正的 PostgreSQL 數據庫,而是一個 PgBouncer 連接池!請調整你的行為模式。”

總結

恭喜你!如果一切順利,你的應用現在應該已經成功構建并運行起來了。

通過這次實踐,我們不僅解決了一個棘手的數據庫連接問題,還掌握了在類 PaaS 平臺(如 Dokploy)上進行復雜服務編排的關鍵技能。我們學會了如何:

  • 使用 PgBouncer 管理連接池。
  • 通過端口映射和服務名進行服務間通信。
  • 利用文件掛載注入自定義配置。
  • 通過統一使用公網地址,快速解決在 CI/CD 流程中訪問數據庫的難題。

現在,你的應用架構變得更加健壯、高效且具備彈性,能夠從容應對未來的流量挑戰。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/89982.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/89982.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/89982.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Mac獲取終端歷史

在 macOS 中,歷史記錄文件的位置取決于你使用的 shell。以下是針對不同 shell 的歷史記錄文件的默認位置:對于 Bash 用戶: 歷史記錄文件通常位于 ~/.bash_history。對于 Zsh 用戶(macOS Catalina及以后版本默認使用的shell&#x…

高頻交易服務器篇

在 Binance 進行高頻交易(HFT)時,服務器的低延遲、高穩定性和快速網絡是關鍵。亞馬遜云(AWS) 提供了多種適合高頻交易的方案,以下是推薦的配置和優化策略:1. 選擇 AWS 區域(Region&a…

MVC與MVVM架構模式詳解:原理、區別與JavaScript實現

Hi,我是布蘭妮甜 !在當今復雜的前端開發領域,如何組織代碼結構一直是開發者面臨的核心挑戰。MVC和MVVM作為兩種經典的架構模式,為前端應用提供了清晰的責任劃分和可維護的代碼組織方案。本文將深入探討這兩種模式的原理、實現差異…

從小白到進階:解鎖linux與c語言高級編程知識點嵌入式開發的任督二脈(2)

【硬核揭秘】Linux與C高級編程:從入門到精通,你的全棧之路! 第三部分:Shell腳本編程——自動化你的Linux世界,讓效率飛起來! 嘿,各位C語言的“卷王”們! 在Linux的世界里&#xf…

鎖和事務的關系

事務的4大特性(ACID) 原子性(Atomicity):事務被視為一個單一的、不可分割的工作單元一致性(Consistency):事務執行前后,數據庫從一個一致狀態轉變為另一個一致狀態,并且強制執行所有…

電動車信用免押小程序免押租賃小程序php方案

電動車信用免押租賃小程序,免押租小程序,信用免押接口申請、對接開發,可源碼搭建,可二開或定制。開發語言后端php,前端uniapp。可二開定制 在線選擇門店,選擇車輛類型,選擇租賃方式&#xff08…

機器學習在智能安防中的應用:視頻監控與異常行為檢測

隨著人工智能技術的飛速發展,智能安防領域正經歷著一場深刻的變革。智能安防通過整合先進的信息技術,如物聯網(IoT)、大數據和機器學習,能夠實現從傳統的被動防御到主動預防的轉變。機器學習技術在智能安防中的應用尤為…

MySQL中DROP、DELETE與TRUNCATE的深度解析

在MySQL數據庫操作中,DROP、DELETE和TRUNCATE是三個常用的數據操作命令,它們都可以用于刪除數據,但在功能、執行效率、事務處理以及對表結構的影響等方面存在顯著差異。本文將從多個維度對這三個命令進行詳細對比和解析,幫助讀者更…

一條 SQL 語句的內部執行流程詳解(MySQL為例)

當執行如下 SQL: SELECT * FROM users WHERE id 1;在數據庫內部,其實會經歷多個復雜且有序的階段。以下是 MySQL(InnoDB 引擎)中 SQL 查詢語句從發送到結果返回的完整執行流程。 客戶端連接階段 客戶端(如 JDBC、My…

超詳細yolo8/11-detect目標檢測全流程概述:配置環境、數據標注、訓練、驗證/預測、onnx部署(c++/python)詳解

文章目錄 一、配置環境二、數據標注三、模型訓練四、驗證預測五、onnx部署c 版python版本 一、配置環境 我的都是在Linux系統下,訓練部署的;模型訓練之前,需要配置好環境,Anaconda、顯卡驅動、cuda、cudnn、pytorch等&#xff1b…

阿里云Flink:開啟大數據實時處理新時代

走進阿里云 Flink 在大數據處理的廣袤領域中,阿里云 Flink 猶如一顆璀璨的明星,占據著舉足輕重的地位。隨著數據量呈指數級增長,企業對數據處理的實時性、高效性和準確性提出了前所未有的挑戰 。傳統的數據處理方式逐漸難以滿足這些嚴苛的需…

【Linux】基礎開發工具(1)

1. 軟件包管理器 1.1 什么是軟件包 在Linux下安裝軟件, ?個常用的辦法是下載到程序的源代碼, 并進行編譯, 得到可執行程序. 但是這樣太麻煩了, 于是有些人把?些常?的軟件提前編譯好, 做成軟件包(可以理解成windows上 的安裝程序)放在?個服務器上, 通過包管理器可以很?便…

藍橋杯51單片機設計

#超聲波原理# ①超聲波測距原理:聲波反射原理 聲波分類: 超聲波測距原理 超聲波頻率越高,波長越短,反身性越強,衍射性越弱 ②超聲波模塊原理 發射原理 跳線帽 接收原理 問題: 1.超聲波發射模塊需…

【LeetCode 熱題 100】240. 搜索二維矩陣 II——排除法

Problem: 240. 搜索二維矩陣 II 編寫一個高效的算法來搜索 m x n 矩陣 matrix 中的一個目標值 target 。該矩陣具有以下特性: 每行的元素從左到右升序排列。 每列的元素從上到下升序排列。 文章目錄 整體思路完整代碼時空復雜度時間復雜度:O(M N)空間復…

Android Input 系列專題【inputflinger事件的讀取與分發】

Android輸入系統在native中的核心工作就是,從Linux驅動設備節點中讀取事件,然后將這個事件進行分發,這兩項工作分別交給了InputReader和InputDispatcher來做。 他們的源碼都屬于native層inputflinger里面的一部分,如下架構&#…

【大模型LLM】GPU計算效率評估指標與優化方法:吞吐率

GPU計算效率評估指標與優化方法:吞吐率 一、核心效率指標二、大模型吞吐率(Large Model Throughput)三、關鍵性能瓶頸分析四、實際測量工具五、優化策略總結 一、核心效率指標 吞吐率(Throughput) 定義:單位…

Nestjs框架: 集成 Prisma

概述 在 NestJS 的官方文檔中,有兩處對數據庫進行了介紹 第一處位于左側“Techniques(技術)”部分下的“數據庫”板塊,中文文檔里同樣有這個位置。 Database 第二處是下面的“Recipes (秘籍)”板塊,這里有多個部分都與…

CppCon 2018 學習:What Do We Mean When We Say Nothing At All?

提供的內容深入探討了C編程中的一些關鍵概念,特別是如何編寫清晰、易維護的代碼,并展示了一些C17的新特性。我將對這些內容做中文的解釋和總結。 1. 良好的代碼設計原則 什么是“良好的代碼”? 能工作:代碼實現了預期功能。能在…

C語言中的輸入輸出函數:構建程序交互的基石

在C語言的世界里,輸入輸出(I/O)操作是程序與用戶或外部數據源進行交互的基本方式。無論是從鍵盤接收用戶輸入,還是將處理結果顯示到屏幕上,亦或是讀寫文件,都離不開C語言提供的輸入輸出函數。本文將深入探討…

高速信號眼圖

橫軸體系時域的抖動大小;縱軸體現電壓的噪聲。 噪聲越大,眼高越小。 抖動越大,眼寬越窄。 眼圖的模板是定義好的最大jitter和噪聲的模板范圍。就是信號的不可觸碰區域。信號波形不能夠觸碰到模板或者進行模板中。也就是眼圖中的線軌跡要在眼…