【问题标题】:Access postgres DB from two applications从两个应用程序访问 postgres 数据库
【发布时间】:2014-11-11 05:35:01
【问题描述】:

我正在为我的应用程序执行负载平衡。我已经创建了两个应用服务器,比如 A 和 B。它们使用 Hibernate 访问同一个数据库 (Postgres)。

当系统从 A 移动到 B 时,问题就出现了。大部分工作正常,但在某些时候(从 db 读取数据时)系统会自动将用户注销。

这是因为与 db 同步吗?

当一个应用程序访问数据库时,数据库上是否存在某种锁定?

我需要做什么才能让它工作?

这将是一个很大的帮助。

【问题讨论】:

  • 您是否将负载均衡器设置为具有会话亲和性? (如果您不知道这是什么意思,请不要担心)
  • “系统自动将用户注销”是什么意思?你的意思是 Postgres 连接被关闭了吗?还是您的应用级登录?
  • @gerrytan:我没有使用任何负载平衡工具,我只是在应用服务器出现故障时立即切换应用服务器。而且,我也没有设置任何关于会话亲和力的东西,我不知道在哪里设置它。
  • @khampson:我指的是应用级登录,Postgres 连接可以自动关闭吗?因为应用程序一直在运行。只有它关闭用户会话。

标签: spring hibernate postgresql database-connection load-balancing


【解决方案1】:

虽然 Postgres 服务器可以出于各种原因终止连接(即如果管理员这样做),但通常这将是客户端的事情,在您的情况下可能是 Hiberate 作为 Spring DAO。如果您的应用级登录被关闭,则可能是您的应用在其他服务器上重新登录的方式存在问题。

很可能,您在每台服务器上都有完全独立的 DAO 实例,因此当从应用服务器 A 切换到 B 发生在 DB 读取中间时,它必须从头开始重新开始新服务器,包括身份验证等。

我假设每个都部署在自己的 WAR 中,并在运行时注入 DAO,此时连接到 Postgres制作。 (您可以在依赖注入代码中添加日志记录以确定更多信息。)

除了单独的数据库连接之外,它似乎不处理故障转移到另一台服务器而不需要重新登录。这不应该直接与 Postgres 相关,至少不连接。这将取决于您如何保持登录。即,如果它在本地缓存,那么每个应用程序中也会有两个单独的实例,并且需要重新进行身份验证。如果凭据存储在 Postgres 中,则需要先获取连接,然后再重新进行身份验证。

根据 OP 的评论进行编辑:

由于它们是两个独立的应用程序实例,因此仅靠负载均衡器是行不通的,因为这很可能取决于请求(大部分)是无状态的。如果您通过 URL 或标头中的令牌进行身份验证,则负载均衡器将起作用,因为身份验证令牌也将被重定向,并且虽然需要在后端进行重新身份验证,但如果令牌应授予身份验证是有效的,并且应用程序应该基本上保持登录状态。不过,这听起来不像您在使用身份验证令牌。

简而言之,这两个独立的实例,确实总是需要在每个请求上进行身份验证,但管理方式可能会有所不同。例如,您可以研究 OAuth 解决方案,但这可能对您的需求来说太过分了。

在任何情况下,您都应该避免直接从客户端获取状态,因为这可能会被篡改。如果服务器要干净地进行故障转移(例如,出于加载目的),您可以通过将安全上下文传播到另一个实例来控制应用逻辑中的安全切换,尽管这可能会有点笨拙。

但是,在 unclean 故障转移期间(例如,如果达到 JVM 堆限制),这是不可能的 - 您需要一个外部身份验证系统,其他应用可以使用该系统进行查询提供的凭据,确定请求已通过身份验证,并允许请求继续。

【讨论】:

  • 是的,你是对的。我在每台服务器上都有单独的 DAO 实例,这些实例包含在它们自己的 WAR 中。因此它正在尝试重新认证。但问题是如何避免它?我可以在代码级别做些什么吗?或者我必须配置我的负载平衡器设置?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
  • 2015-06-11
  • 1970-01-01
相关资源
最近更新 更多