桌面应用数万用户访问PostgreSQL无需单独建角色的最优方案咨询
通用角色并发连接数问题解答
PostgreSQL的并发连接上限默认由全局配置参数max_connections控制,默认值为100,该限制对所有数据库角色生效,和使用哪个角色建立连接没有关系。
除非你手动执行ALTER ROLE usership CONNECTION LIMIT <数值>;给usership角色单独设置了连接上限,否则该角色本身没有额外的并发连接约束,只要全局连接数未被占满,都可以正常创建连接。
如果后续需要支撑大量并发客户端,可以部署pgBouncer这类连接池工具,通过连接复用机制大幅降低数据库的实际连接开销,可支撑数千级的并发客户端请求。
该场景的最优实现方案
你不想为每个终端用户创建独立数据库角色的判断是正确的,PostgreSQL的角色系统本身是为数据库权限管理设计的,并不适合面向大量外部终端用户做账号管理,增删角色的操作成本、权限维护成本都很高,完全不匹配这类面向外部用户的产品场景。
结合你的需求,推荐两种实现方案,按优先级排序如下:
方案1:增加业务后端做数据库访问代理(推荐)
这个方案和常规多用户网站的架构完全一致,安全性、可维护性最高:
- 数据库不对公网开放,仅允许你的业务后端服务访问,后端使用统一的
usership角色连接数据库 - 桌面端所有数据请求都先发送到业务后端,后端先校验用户的登录状态、操作权限,再执行对应的数据库操作,将结果返回给桌面端
- 所有用户账号信息存在独立的用户表中,密码做哈希加盐存储,无需和PostgreSQL的角色系统挂钩
- 优势:完全避免数据库凭证泄露到客户端的风险,权限控制逻辑完全在业务层实现,灵活度最高,后续迭代功能不需要调整数据库权限配置
方案2:端侧直连数据库+行级安全策略(RLS)
如果你的业务逻辑必须在端侧执行数据库操作,无法增加后端代理层,可以用该方案:
- 保留
usership通用角色,给它配置最小必要权限:公共数据表授予只读权限,个人设置、测量值表授予读写权限,同时开启这些个人数据表的行级安全(RLS)策略 - 所有用户账号信息存储在独立的用户表中,密码做哈希加盐存储,不依赖PostgreSQL的角色鉴权
- 用户打开桌面端后,首先向你的账号服务提交用户名密码做登录校验,校验通过后返回用户唯一ID及签名信息
- 客户端使用
usership角色建立数据库连接后,首先执行SET app.current_user_id = '当前用户ID';设置会话级变量,RLS策略基于该变量做行权限控制:只允许用户读写user_id与会话变量匹配的行,公共数据的读操作不受RLS限制 - 注意:该方案需要避免
usership凭证被客户端逆向提取,建议对凭证做加壳混淆,同时配置数据库IP白名单、限制usership的操作权限,避免恶意用户拖库或篡改数据
内容的提问来源于stack exchange,提问作者Gedankenpolizei
相关产品推荐
相关产品推荐

