TwoRavens配置的完整过程及异常处理方法

TowRavens是开源项目Dataverse用到的数据可视化统计的API, 其主界面很简单,就是一个html,数据的可视化实现依赖javascript的可视化数据库d3.js,数据的进一步处理则依赖R语言。

其主要工作流程如下:
1.在Dataverse客户端上传带处理的指定类型的数据文件,服务器讲数据初步解析后放入临时文件中。
(Dataverse由glassfish支持)
2.用户通过Dataverse的入口调用TwoRavens应用,同时将数据的路径传入TwoRavens。
(TwoRavens由apache支持)
3.TwoRavens通过js将数据解析,运用d3数据库将数据图形化,并解析成json对象。
4.数据的进一步统计则通过ajax机制,将json对象发送(POST)到Rserve端。
5.Rserve将数据统计完毕后返回到TwoRavens,再通过d3将数据图形化展示出来。
同时TwoRavens还提供许多数据统计的模型处理,也都是依赖于Rserve完成的。

TwoRavens提供的功能非常强大,其中运用到了d3,ajax,rserve等多方面的功能。虽然是开源的,Dataverse的官方指南也有TwoRavens的详细配置过程(点击这里查看)。可是将整个应用完整的配置到自己的服务器上还是一个比较艰巨的任务,其中会遇到不少关卡。

1.首先,遇到的第一个问题就是在Dataverse客户端找不到进入TwoRavens的入口。
正常情况下,当一个数据类型的文件上传之后,在其文件管理列表旁边会有对应文件的操作按钮Explore,点击该按钮就可以进入TwoRavens将对于数据做可视化分析。
查看Explore按钮的html样式之后发现

<ui:fragment rendered="#{ twoRavensHelper.canSeeTwoRavensExploreButtonFromPage(fileMetadata) and !worldMapPermissionHelper.canUserSeeExploreWorldMapButtonFromPage(fileMetadata)}"><!-- TwoRavens Explore button ONLY ... not WorldMap --><h:commandLink rendered="#{!downloadPopupRequired}"type="button" styleClass="btn btn-default #{fileMetadata.dataFile.ingestInProgress ? 'disabled' : ''}"disabled="#{fileMetadata.dataFile.ingestInProgress ? 'disabled' : ''}"action="#{fileDownloadService.startExploreDownloadLink( guestbookResponse, fileMetadata )}" target="_blank"><span class="glyphicon glyphicon-equalizer"/> <span class="ladda-label">#{bundle.explore}</span></h:commandLink><p:commandLink rendered="#{downloadPopupRequired}"type="button" styleClass="btn btn-default"action="#{guestbookResponseService.modifyDatafileAndFormat(guestbookResponse, fileMetadata, 'explore' )}"update="@widgetVar(downloadPopup)"oncomplete="PF('downloadPopup').show();handleResizeDialog('downloadPopup');"><span class="glyphicon glyphicon-equalizer"/> #{bundle.explore}</p:commandLink>
</ui:fragment>

Explore按钮的渲染条件是twoRavensHelper.canSeeTwoRavensExploreButtonFromPage(fileMetadata),再根据这段判定找到java方法,再打开glassfish的服务器日志,会发现是Rserve connection refused. Rserve是配置在6311端口的,可是命令行查看6311端口
$netstat -npl | grep 6311
原来,按照Dataverse官方给的Rserve安装启动脚本启动rserve是没有效果的。
后来参考了网络博客使用命令:
RCMDRserve R CMD Rserve netstat -npl | grep 6311
接着就能看到Rserve已正常启动。
然后刷新Dataverse的文件管理界面,就能看到对应的Explore按钮出现了。

2.但是,点击Explore按钮之后,页面并没有跳转到TwoRavens界面,而且服务器端无法响应。因为TwoRavens依赖的是apache,于是找到了apache的错误日志,发现是apache在启动的时候出错,因为apache中还导入了R_module用来支持R语言面向网络的接口实现,所以apache在启动的时候还会加载相应的R依赖包,错误正是由于R的依赖包没有安装完整。这是因为网络不稳定,资源镜像服务也不稳定而导致的,这个只能花时间一点一点把依赖的包一个一个下载安装好。等一切依赖都准备就绪了,Apache启动成功,然后TwoRavens的页面就正常的跳转出来了。

3.正常跳转到了TwoRavens主界面,然而数据完全没有加载进来,这时候查看apache日志,没有异常,那么问题就出在TwoRavens解析数据的js脚本上了。通过浏览器的开发者工具,可以找到js发生异常的具体位置,原来是在解析数据的环节上没有读取到相应的变量,然后根据json规则,修改了js解析数据的规则,最后数据解析成功。再重启服务器,清空浏览器缓存(不清除缓存,浏览器会继续使用缓存中的js脚步,发布的新js版本无效)重新进入TwoRavens,d3数据图形都正常加载出来了。

4.d3图形加载出来了并不是最后一步,因为浏览器又弹出了error,json对象无法解析。
查看开发者工具,找到了js段发生异常的代码,问题出在了访问http://dataexpolore/cunstom/dataapp这个地址上。在apache的文件目录下按照路径找到了dataexplore/custom/,但是在custom目录下并没有dataapp,那么这个dataapp到底是怎么回事呢?一个临时文件夹还是一个api入口呢?后来想起来,在安装apache的时候,在其配置文件/conf/httpd.conf文件里添加了如下配置语句:

RSourceOnStartup "/var/www/html/dataexplore/rook/rooksource.R"

这句设置了apache启动过程中会编译运行rooksource.R,该脚本对Rserve做了初始化,并且导入了后续R脚本处理数据时依赖的R包,因为一开始依赖包没有安装完整,所以脚本运行失败,导致apache启动失败,也就是问题二出现的原因。

...
<Location /custom/transformapp>SetHandler r-handlerRFileEval /var/www/html/dataexplore/rook/rooktransform.R:Rook::Server$call(transform.app)
</Location>
<Location /custom/dataapp>SetHandler r-handlerRFileEval /var/www/html/dataexplore/rook/rookdata.R:Rook::Server$call(data.app)
</Location>
...

原来apache把/custom/dataapp这条路径指向了/var/www/html/dataexplore/rook/rookdata.R:Rook::Server$call(data.app)
于是我们找到了/dataexplore/rook/目录下的rookdata.R文件,看到原来js的ajax请求被apache转到了rookdata.R,rookdata.R里面有相应的Request对象和Response对象的处理。
首先,我们尝试打印出dataapp从Request中读取出的json对象,可是查看apache的日志,发现没有任何内容被打印出来,request是空的。我们在想,是不是r语言读取json对象出了什么问题,有可能还是R的依赖包问题。接着在rookdata.R中自定义了一个json变量,然后尝试用r语句打印出来(中间也是不断的尝试,因为自定义的json对象直接用print语句打印出来,会自动在变量值最后自动填充换行符‘\n’,后来利用jsonlit::toJson方法才成功解决了这个问题),查看日志,发现json对象是可以正常打印的。
那么问题就应该是Request对象上。然后我们查看了Rook,rapache的官方文档,其中对rook和rapache的主要变量方法做了介绍。

Rook: A web server interface and package for R

A Rook application is an R reference class object that implements a ‘call’ method or an R closure that takes exactly one argument, an environment, and returns a list with three named elements: ‘status’, ‘headers’, and ‘body’.

rApache is a project supporting web application development using the R statistical language and environment and the Apache web server.

Rook is an R package that defines a specification and set of convenience objects for running R web applications on various web servers without the need to modify your code. Thus, you can write and run Rook apps within R using the built-in Rhttpd web server and deploy them on rApache.

至此,我们才搞清楚了apache,rapache,rserve,rook之间是什么关系。
apache提供网络服务
rapache提供R语言的网络服务,是apache的一个模块
rserve是R语言的运行环境
rook是R语言的网络服务包和接口,一个rook应用是一个R对象,通常用call(enviroment)方法来调用
如apache配置文件中的调用:

<Location /custom/dataapp>SetHandler r-handlerRFileEval /var/www/html/dataexplore/rook/rookdata.R:Rook::Server$call(data.app)
</Location>

说明http://custom/dataapp指向的就是R的一个Rook类服务
rookdata.R中的脚本如下:

data.app <- function(env){result <- list()request <- Request$new(env)response <- Response$new(headers = list( "Access-Control-Allow-Origin"="*"))...result<-jsonlite:::toJSON(result)response$write(result)response$finish()
}

R脚本可以打印出json对象,那么说明Rserve的功能是没有问题的,R的依赖包也都正常载入了。我们猜测,是不是rapache没有把Request传递进来呢?我们按照rapache文档描述的步骤,一步步检查rapache在apache中的配置,module和路径配置,handler设置都是没有问题的,那么会不会是apache版本的问题呢?因为apache目前是2.2.x和2.4.x并行的,确实经常会有版本问题出现。于是又在系统重新安装了2.2版本的apache,然后把rapache相关的model和路径都配置好,发现apache服务器无法正常启动。因为rapache的依赖应用都是apache2.4版本的,2.2版本不兼容。那么说明不是apache版本问题。
于是问题又回到了Rserve,rookdata.R脚本,rapache的配置都是正常的,ajax请求在开发者工具中抓取,可以看到完全符合标准的请求和json对象,并且custom/dataapp路径确实已经指向了rookdata.R,data.app也被调用了,因为浏览器访问custom/dataapp地址后,在apache日志里可以看到rookdata.R脚本运行的部分打印输出。那么问题还是在Request的解析上。于是我们用postman自定义了一些简单的参数,访问http://custom/dataapp,然后根据参考重新编写了打印Reuqest参数的脚本,发现,原来Reuqest是可以被正常解析的,那么R脚本也没有问题,可是当我们在请求端,把参数设置成中文字符,那么R脚本运行就会发生异常。所以,json对象无法解析的原因找到了,是中文字符传递的问题。

5.但是问题并没有结束,因为R脚本中出现了permission denied权限问题,原因是R脚本在处理数据时会在custom的log_dir目录下创建一个临时文件,而R脚本在/dataexplore/rook目录下。我们尝试修改两个目录的分组和权限,两个目录放在同一用户同一分组,同时权限都设置为777,然而依然出现了permission denied。于是再百度,发现是SELinux强制访问权限设置,使用命令setenforce 0关闭SELinux服务即可。

至此,TwoRavens的功能已全部在本机实现。

回顾整个部署过程,其实出现问题的原因很简单,可是排查问题解决问题却花费了很多的精力,走了不少弯路,但也对Dataverse和TwoRavens两套应用的流程都有了深入理解。

-1.由于Rserve没有启动,导致Explore按钮无法显示,但实际上找到Explore按钮的配置及渲染的判断,需要阅读Dataverse的代码以及查看glassfish日志,逐步分析,才找到Rserve的原因。-2.R依赖包没有安装完整,导致apache启动失败-3.js解析数据时逻辑有误,导致d3数据图形无法显示-4.R脚本无法读取中文字符,导致无法解析json对象。原因很简单,但是找到原因这个过程中绕了不少弯路。但也因此对apache的运行机制有了进一步了解。-5.SELinux安全设置,默认安装在 Fedora 和 Red Hat Enterprise Linux系统中,这算是额外的计算机安全知识补充

查找原因解决异常是考察和提升计算机能力的一个过程,过程很痛苦,可最终也获益良多。

TwoRavens配置的完整过程及异常处理方法相关推荐

  1. 云耀服务器 NumPy安装 完整过程

    背景 安装torch报错 基础环境配置 云耀服务器 python 配置 sentencepiece 完整过程 wget 源码获取 NumPy官方:https://pypi.org/project/nu ...

  2. 三,vagrant配置Docker完整教程

    配置Docker完整过程记录分享

  3. Ubuntu上snmp安装、配置、启动及远程测试完整过程

    0.说明 关于一个完整的教程,还是那句话,国内的要么不完整,要么就太旧了,而且思路也不清晰,所以这里写一篇完整的给大家分享一下. 虽然对于Linux主机的监控可以通过执行特定的命令来完成,但是相比之后 ...

  4. Qt最新版5.13在Windows环境静态编译安装和部署的完整过程(VS 2017/VS 2019)

    文章目录 为什么要静态编译 1.源码下载 2. 编译工具下载 ActivePerl Python Ruby 编译环境选择 3.编译 1.修改源码里的qtbase\mkspecs\common\msvc ...

  5. SAP变式配置的完整指南(中英文双语版)

    A Complete Guide of SAP Variant Configuration SAP变式配置的完整指南 Variant configuration is for manufacturin ...

  6. caffe学习笔记18-image1000test200数据集分类与检索完整过程

    image1000test200数据集分类与检索完整过程: 1.准备数据:数据集图片分10个类,每个类有100个train图片(train文件夹下,一共1000),20个test图片(val文件夹下, ...

  7. 虚拟机安装windows ghost版本系统记录完整过程

    重点 1.磁盘一定要分成2个 2.直接安装第一个盘   就是进入CD后选1  自动安装 https://blog.csdn.net/hanzl1/article/details/79298787 虚拟 ...

  8. Spring MVC 原理 - DispatcherServlet调用完整过程

    本篇主要讲解了Spring mvc的调用过程,通过这个过程来了解Spring的原理. 进入web.xml中配置的Spring拦截(调度)器: 调用堆栈信息: 开始拦截,这一步主要是根据request获 ...

  9. 源码级剖析了 Naive UI 的 Button 完整过程

    注意:为了让篇幅尽可能简洁一丢丢,在有些地方贴源码时,我尽可能贴最能反映要讲解内容的源码,其他重复性的代码就略去了,所以如果你自己尝试去阅读源码时,可能会发现和文章里的代码有出入.文章跑通 Naive ...

最新文章

  1. one-hot encoding不是万能的,这些分类变量编码方法你值得拥有
  2. 对 VR 项目开发流程的调研
  3. nexus3下载地址
  4. (21)FPGA面试题D触发器表示方法
  5. cdh官方文档看后小结(含优化项)001
  6. tomcat 原理与使用资料
  7. MySQL-快速入门(14)MySQL性能优化
  8. KMP复习之poj 3461 Oulipo
  9. 机器学习数学篇—基础数学知识清单
  10. 如何运用MATLAB实现K-MEANS聚类分析
  11. php doctrine,php – Doctrine上的复杂SQL查询
  12. 百度小程序怎么添加到主屏幕将百度小程序放到手机桌面?
  13. 解决 java.lang.RuntimeException: Method i in android.util.Log not mocked. See http://g.co/androidstudi
  14. Android+CS6:工业动画之变速变方向旋转齿轮
  15. 计算机技术培训需要资质证书吗,计算机软考是职业证书还是执业证书
  16. UG\NX二次开发 调用NX命令 PostMessage
  17. 苹果上网本报价_1小时一个价,iPhone12 加价300元起!果粉上网买收到蓝色真机,感叹“真香”...
  18. AI + 医疗的下一个十年:从公共卫生预警到人类基因密码破解| AI TIME
  19. FFmpeg批量转换视频格式
  20. ps画图匹配Android机不同分辨率屏幕

热门文章

  1. 前端项目结构设计精细方案
  2. (设计模式十三)java设计模式之观察者模式
  3. 【Unity Shader】Special Effects(四)Dissolve 溶解(UI)
  4. Android(数据存储:文件存储、SharedPreferences)验证QQ密码
  5. 【蓝桥软件学院】Android中五大Manager详解及使用技巧
  6. 《花开半夏》--4 苏彤(2)
  7. 【win7/win10】虚拟机安装与简单配置教程
  8. 一图看懂SAP仓储单位SU的应用
  9. 编写一个程序,读取雇员信息,然后打印一个工资表。
  10. 『Reprint』转载