Shiny App使用secureserver后出现服务端断开连接及不稳定问题
问题原因与解决方案
可能的触发原因
- shinymanager与会话超时配置冲突:shinymanager默认自带会话有效期校验逻辑,若未显式配置超时时间,其触发逻辑和shinyapps.io的闲置超时机制冲突,会导致进程无响应被平台强制关闭,不会抛出常规错误日志。
- 身份凭据存储冲突:你的应用同时使用googlesheets4的Google身份验证和shinymanager的用户验证,两者默认都会把token/验证信息存在R会话的临时缓存或者全局环境中,出现变量名/存储路径冲突时会直接导致R进程崩溃。
- shinymanager版本bug:1.0.400以下的shinymanager版本存在已知的内存泄漏问题,部署在shinyapps.io上时用户登录后内存占用会持续升高,达到实例内存上限后会被平台直接kill进程,因此日志中无报错信息。
- 凭据校验逻辑异常:你当前直接将credentials变量传入
check_credentials,若该变量包含特殊字符、或者shinymanager后台定时校验时读取会话变量异常,会触发未捕获的错误直接终止服务进程。
另外请注意你给出的问题代码存在笔误,正确写法应为result_auth <- secure_server(check_credentials = check_credentials(credentials)),函数名用下划线连接。
可行解决方案
- 显式对齐会话超时配置:在调用
secure_server时显式设置timeout参数,和你shinyapps.io后台配置的闲置超时时间保持一致,避免两个超时逻辑冲突:
result_auth <- secure_server( check_credentials = check_credentials(credentials), timeout = 1800 # 单位为秒,可根据你的平台配置调整 )
- 隔离googlesheets4的身份缓存:在应用初始化阶段就指定googlesheets4的token存储路径,和shinymanager的缓存路径隔离开,避免存储冲突:
library(googlesheets4) # 提前将服务账号token存在.secrets目录下,部署时一起上传 gs4_auth(cache = ".secrets", email = "你的应用服务账号邮箱")
- 升级shinymanager到最新版本:安装官方开发版修复已知的内存泄漏问题:
remotes::install_github("datastorm-open/shinymanager")
- 改用加密数据库存储用户凭据:不要直接把用户凭据作为变量传入校验函数,提前将凭据写入加密sqlite数据库,调用时读取数据库,避免会话变量读取异常:
# 首次运行生成凭据数据库,后续可注释该段 # shinymanager::create_db( # credentials_data = credentials, # sqlite_path = "credentials.sqlite", # passphrase = "自定义加密密码" # ) # 服务端调用替换为以下代码 result_auth <- secure_server( check_credentials = check_credentials( db_path = "credentials.sqlite", passphrase = "你设置的加密密码" ) )
- 开启全量错误日志捕获:在应用代码最开头加入错误日志配置,将所有未捕获的错误写入本地文件,方便后续定位问题:
options(shiny.error = function() { sink("shiny_error_log.txt", append = TRUE) print(paste0("错误时间:", Sys.time())) print(sys.calls()) sink() })
内容的提问来源于stack exchange,提问作者reidj
相关产品推荐
相关产品推荐

