我正在为我的应用程序执行负载平衡。我已经制作了两个应用服务器,比如A和B.使用Hibernate访问同一个数据库(Postgres)。
当系统从A移动到B时出现问题。大多数工作正常,但在某些时候(从db读取数据时)系统会自动将用户注销。
这是因为与db的同步吗?
当一个应用程序访问数据库时,数据库是否存在某种锁定?
为了让它正常工作,我需要做些什么?
这将是一个很好的帮助。
答案 0 :(得分:0)
虽然 Postgres 服务器可以出于各种原因终止连接(例如,如果管理员这样做),通常这将是客户端的事情,在您的情况下可能 Hiberate < / em>作为 Spring DAO 。如果您的应用级登录正在关闭,则可能是您的应用在其他服务器上重新登录的问题。
最有可能的是,您在每台服务器上都有完全独立的 DAO 实例,因此当从app-server A切换到B时,在DB读取时,它必须从头开始重新启动新服务器,包括身份验证等,
我假设每个都部署在自己的 WAR 中并且在运行时注入 DAO ,此时连接到 Postgres 制作完成。 (您可以在依赖注入代码中添加日志记录以确定更多内容。)
除了单独的数据库连接外,它似乎无法在不需要重新登录的情况下处理到其他服务器的故障转移。这不应该直接与 Postgres相关 ,至少不是连接。这取决于您如何持久登录。即,如果它在本地缓存,那么每个应用程序中也会有两个独立的实例,并且需要重新进行身份验证。如果凭据存储在 Postgres 中,则首先需要在重新进行身份验证之前获取连接。
根据OP的评论进行编辑:
由于它们是两个独立的应用程序实例,因此单独的负载均衡器不起作用,因为这很可能取决于(主要)无状态的请求。如果您通过URL或标头中的令牌进行身份验证,则负载均衡器可以正常工作,因为身份验证令牌也会被重定向,并且虽然需要在后端进行重新身份验证,但如果令牌需要进行身份验证是有效的,应用程序应该基本上保持登录状态。但是,听起来你并没有使用auth令牌。
简而言之,这两个独立的实例,身份验证确实总是需要在每个请求上进行,但管理的方式可能会有所不同。例如,您可以查看 OAuth 解决方案,但这可能会因您的需求而过度。
在任何情况下,您应该避免直接从客户端获取状态,因为这可能会被篡改。如果服务器干净地进行故障转移(例如,出于加载目的),您可以通过将安全上下文传播到另一个实例来控制应用程序逻辑中的安全切换,尽管这可能有点笨拙。
但是,在 unclean 故障转移期间(例如,如果达到了JVM堆限制),那是不可能的 - 您需要一个外部身份验证系统,其他应用程序可以使用提供的凭据进行查询,确定请求已通过身份验证,并允许请求继续。