3.10服务发布流程详情及清理方案
背景: 1、用户的服务发布之后会一直占用online的内存资源。online资源有限,用户占用的资源需要更多的限制,根据当前的现状及未来情况预测,吃紧的主要是内存资源,所以需要对内存资源占用进行优化;
2、当前服务发布使用iserver完成,iserver的服务发布之后会一直占用内存资源而不会释放。优化资源占用主要方式为将免费用户长期不使用的服务取消发布;任务要求:
- 只针对免费版个人用户
- 能自动化执行释放
- 能自动化执行释放
- 释放周期为7天(讨论)
- 释放后删除服务,保留数据,页面上的保留现在的状态为“休眠”
3.pg数据库清理,关系型存储
上传数据-服务发布流程
上传数据配置
配置:
http://support.supermap.com.cn/DataWarehouse/WebDocHelp/iPortal/index.htm
####容量限制
<uploadSetting>
- <userMaxCapacity>:用于设置用户允许上传的最大数据容量默认值,单位:MB;默认值:2048,即用户可上传的最大数据容量为 2048 MB。
- <fileSuffixBlackList>:用于设置不允许上传的数据文件的后缀格式,支持设置多个后缀格式黑名单,后缀名称需分别包含在不同的<string>节点中
配置文件:$\color{blue}{iportal.xml}$
online的配置: 限制为500M <!-- iportal上传设置 -->
<uploadSetting>
<!-- 用户上传数据容量上限,单位:MB -->
<userMaxCapacity>500</userMaxCapacity>
<!-- 上传文件后缀黑名单,即不允许上传此后缀格式的文件 -->
<fileSuffixBlackList>
<!-- <string>jsp</string> -->
</fileSuffixBlackList>
</uploadSetting>数据类型
数据文件及发布服务类型的对应关系
托管数据存储配置
配置文件:$\color{blue}{iportal-storage.xml }$
二进制存储方式
OSS存储为online独有扩展功能
$\color{red}{需要确定OSS中的数据}$
关系型存储
启用关系型存储后,数据将优先存储到关系型存储中。
iPortal 可以提供将上传的 Excel、CSV、GeoJSON 等数据发布为服务的能力,具体可发布的服务类型,请参见数据
需要注意的是,在启用关系型存储之前,请确保您的 iServer 托管服务器关联了 iServer DataStore (关联时需要勾选“关系型数据”选项),或者已经在 iServer 托管服务器中注册了 HBase、PostgreSQL、PostGIS、HDFS 等空间数据库(注册时需要勾选“允许编辑”选项)。
iportal——icn环境:(iserver——iServer DataStore(数据目录服务) —— postgreSql)
上传代码
选择数据文件
web/mycontent/datas/capacity.json
DatasContentResource.java
//获取当前用户数据容量
getUserDataCapacity()
->
DataItemComPonentImpl
getUserDataCapacity(){
//先获取userExtension数据容量信息
//1.从shiro中拿到用户name昵称
//2.根据name从数据库userextension表查询当前用户的存储容量,如果没有数据,则默认一个maxCaoacity=214743648
//3.从数据库dataItems表根据username获取size字段(已使用的容量)
}得到可用容量及可使用容量
点击上传
2个接口
/web/mycontent/datas.json 接口 post
参数:
重启项目;会把dataitem表 状态serviceStatus为DELETE的删掉
DatasContentResource.java
addDataItem接口{
//各种判断
doAddDataItem(req,dataItem参数);
}
->
IportalDatasResourceBase.java
doAddDataItem(){
//1.获取当前登录用户
//2.各种判断
//3.从配置文件中创建二进制存储对象(file,ftp,datacatalog、oss),online配置的oss并创建数据存储唯一标记(oss的唯一标记为随机字符串)
// 添加dataItem
doAddDataItem();
}
->
DataItemComponentImpl.java
doAddDataItem(){
//1.dataItem对象插入数据库dataItem表
//2.tags表插入
//2.插入资源权限新版 permissions表,一般是‘user’类型,还有group、role、iportalgroup、department
//3.新增资源快照。放入线程池,(没太看懂)
//4.dataItem对象放入es
}返回值:
childID是dataItem表的id,dataitem.id是插入是随机生成的
dataitem表
tag表
permission表/web/mycontent/datas/1079564216/upload.json 上传接口
DatasContentResource.java
//数据上传接口
uploadData(){
if(是否是断点续传){
走断点续传,不支持datacatalog,数据目录存储
}
普通上传
}
->
IportalDatasResourceBase.java
//普通上传
doUploadData(){
// 1.通过url上参数id从数据库dataItems表查询dataItems对象
// 2.判断容量,剩余容量 与 上传容量 对比
// 1.先获取userExtension表信息可用容量根据用户
// 2.在获取dataitem表 已使用容量
// 3. 即将上传数据,将数据状态标位正在更新,dataItem表status为'MODUFYING'
// 4.上传
//1. 用户的session设置-10000L,防止过去
//2. 进入上传类 UploadDatacontentResource
.. 下面的流程
}
===============================================
UploadDatacontentResource.java
uoload(){
helper.add()
}
->
HttpServletFileStreamStorageHelperImol.java
add(){
// 1.判断事发后是文件流,还是数据流
// 2.checkUploadDataValid() 返回null,真不知道online是不是也判断为null
// 3. 根据不同的存储类型存储:datastore,relationship,tilestoragge,online是关系型存储(不对,后面发现应该走的是 dataFile == null路线,走的是二进制存储,online是oss)
// 进入关系型存储
// 实时进度条,6 StorageOperation doTransform common-io的IOUtis 的copyLarge实现
..
}
->
RelationshipStorageImpl.java
add(){
// 读写锁
//1. 获取关系型存储服务地址
//httpclient MultipartEntity类型访问服务,把流传过去
// 读写锁结束
}
=========================================
//3. 更新dataitem的size
//4. 进入onUploadCompelete()
//1. 将数据状态标位成功,dataItem表status为'OK'
//2.添加dataitem表md5
_________________________________
//3.数据发布预检测,如果需要预检测,online配置了预检测
->
PrecheckEnableDataPublisherImpl.java
checkData(){
// 1.得到datatem的id和MD5的hash值,存入concurrentHashmap中
// 2.执行预处理类,开启线程执行
...
}
SchedulableDataPreChecker.java
call(){
// 1. 获取节点,空闲的机器节点,各种线程操作,ku
// 2.进入doPrecheck(){
// 再次获取dataitem对象根据id
// 3.进入CommandExecutor,极其复杂,循环通过各种command类,具体研究代码
}
}
_________________________________
===================================================
//4.预检测完后,判断是否需要导入datastore中,online独有逻辑,工作空间不导入datastore地图
获取数据
/web/maps/{id}/map.json
IportalMapsResource
getIportalMapsResource()
IportalMapsResource
getWebMapResponse()
getViewerMap()
// 得到整个webmap表
getWebMapContent(){
// 得到整个webmap表,注意!!!!:会多设置一个"rootUrl"
webComponent.load();
doGetCheck(){
// maps表
viewerMapComponent.getViewerMapById()
}
}/(id)/content
id是dataid
前端解析了webmap,拿到dataid,多次调用该接口
IportalDatasResource
getDataContent(){
// 引用的数据
getDataItemByIdWithDownloadOrManagePermission(){
-> IportalDatasResourceBase
getDataItem()
}
// 地图数据
getDataContent()
}
->
DataItemComponentImpl
getDataContent(){
// 1 校验只支持json、geojson、cdv、excel、shp
// 2.校验storageId,helper 不为null
// 3.从数据存储 输入到临时文件中
// 得到数据文件的内容
}保存地图
webmap
/web/maps/{id}/map.json
id:mapid
参数:
前端传下来的webmap数据
IportalMapResource
updateWebContent(){
save(){
viewerMapComponent.updateViewMap
}
}/web/maps/{id}.json
WebMapComponentImpl
save(){
viewerMapDao.updateAttributesToSyncWithWebMap()
webMapDao.save()
}另存为地图
/web/maps.json
IportalMapsRource
ctreateViewerMap(){
viewerMapComponent.addViewerMap(){
// 新增maps表
// 新增tags表
// 新增perssion表
// 新增es
// 新增
}
}/web/maps/{id}/map.json 同保存
/thunbnail 更新缩略图
