shinycssloaders本地正常,部署到Ubuntu服务器后失效的原因排查
问题分析与解决方案
你的Shiny应用在本地使用shinycssloaders的withSpinner功能正常,但部署到Ubuntu服务器后出现冻结,甚至仅加载library(shinycssloaders)就崩溃,以下是可能的原因及解决办法:
1. 包版本不兼容
本地与服务器的R包版本差异(尤其是shiny、shinycssloaders、htmlwidgets)可能引发冲突。比如服务器上的shiny版本过旧,无法适配新版shinycssloaders的API。
解决办法:
- 用
renv或packrat锁定本地包版本,然后在服务器上同步安装相同版本:# 本地初始化renv install.packages("renv") renv::init() # 生成锁定文件后,服务器上运行 renv::restore() - 若无法同步版本,尝试降级
shinycssloaders到兼容服务器shiny的版本:install.packages("devtools") devtools::install_version("shinycssloaders", version = "1.0.0", repos = "http://cran.us.r-project.org")
2. 服务器资源不足
加载未压缩.bin文件或渲染组件时,服务器内存/CPU不足导致应用冻结。Ubuntu服务器的默认配置可能无法支撑大文件加载+组件渲染的开销。
解决办法:
- 用
htop命令检查服务器实时资源使用,确认是否存在内存耗尽(OOM)情况; - 优化数据加载:用
data.table::fread替代read.csv提升加载速度,减少阻塞时间:library(data.table) granos_exportados <- fread('https://s3.us-east-2.amazonaws.com/ecotopia.today/Data/exports_summary_full2.csv') - 提前在本地预处理数据,将过滤后的小数据集部署到服务器,避免服务器端大量计算。
3. Shiny Server配置限制
Shiny Server的默认超时、进程数设置可能导致应用启动时卡住。
解决办法:
- 修改Shiny Server配置文件(通常位于
/etc/shiny-server/shiny-server.conf),增加初始化超时时间:server { listen 3838; location / { app_init_timeout 60; # 延长到60秒 site_dir /srv/shiny-server; log_dir /var/log/shiny-server; directory_index on; } } - 确保Shiny Server运行用户对应用目录、数据文件有读取权限。
4. 前端组件冲突
shinycssloaders的CSS/JS可能与shinythemes、leaflet、plotly的前端资源冲突,导致页面渲染阻塞。
替代方案:自定义加载动画
如果shinycssloaders无法正常使用,可以手动实现加载提示,避免依赖该包:
# UI部分修改 ui <- fluidPage( theme = shinytheme("cyborg"), tags$head( tags$style(HTML(' /* 自定义spinner样式 */ .spinner { border: 4px solid rgba(255,255,255,0.3); border-top: 4px solid white; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; position: absolute; top: 50%; left: 50%; margin: -20px 0 0 -20px; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .loading-container { position: relative; height: 440px; /* 对应plot的高度 */ } ')) ), column(4, align = "center", offset = 0, column(8, selectInput("year", "Select year", choices = c(2015, 2016, 2017, 2018, 2019), selected = 2019, width = "100%"), # 自定义加载容器 div(class = "loading-container", uiOutput("granos_exportados_container"))), id = "graph-title", "click trader (above) for sources (below)", br(), # Leaflet Map Section column(12, align = "center", div(class = "loading-container", style = "height:500px;", uiOutput("leaflet_map_container"))) ) ) # Server部分修改 server <- function(input, output, session) { query <- reactive({ parseQueryString(session$clientData$url_search) }) granos_exportados <- read.csv('https://s3.us-east-2.amazonaws.com/ecotopia.today/Data/exports_summary_full2.csv') pie_df <- reactive({ granos_exportados %>% filter(YEAR == input$year, COUNTRY == query()[['COUNTRY']], PORT == query()[['PORT']]) }) # 控制plot的加载状态 output$granos_exportados_container <- renderUI({ req(pie_df()) plotlyOutput("granos_exportados", width = "100%", height = "440px") }) # 控制地图的加载状态 output$leaflet_map_container <- renderUI({ req(df()) leafletOutput("leaflet_map", width = "100%", height = "500px") }) # 其余原有server代码保持不变... }
内容的提问来源于stack exchange,提问作者Brian Holmes
相关产品推荐
相关产品推荐

