开发者学堂课程【大数据实战项目:反爬虫系统(Lua+Spark+Redis+Hadoop框架搭建):数据处理-链路统计-数据库到前端展现】学习笔记与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/670/detail/11638
数据处理-链路统计-数据库到前端展现
内容介绍
一、 回顾
二、 如何使数据库展现到前端
三、 效果
一、 回顾
通过 web 界面的后台当中有一个程序,程序做了定时任务,定时去拉取将 redis 里面的数据写到 mysql,数据写完以后 redis 中的 activeUserNumber 活跃的用户连接数以及近几天的数和前面的数据是如何展现到前端的呢?前端的代码是什么样的?
二、 如何使数据库展现到前端
1. web 项目展现
此页是 web 项目展现过程,项目 web 先要来到代码当中,在提供的代码中找到web app,有一个 pages,pages 中有一个 common,common 中有一个 top.jsp,
打开 top.jsp 是一个传智播客反爬虫界面,也就是首页面里的传智播客反爬虫平台,
< div class =" top ">
< div class =" top - logo ">
传智播客反爬虫< div >
< div class =" top - user ">
< div class =" top -user1">
< div class ="user1">
< img src ="$( ctx }/ themes / default / images / user - portrait . png ”/></ div >
< div class ="user1-accounts" title =""><%= usercnName %></ div >
< div class ="user1-Triangle"></ div >
< div style ="" class =" none ">
< div class ="user1-Triangle1">/ div >
< a id =" mofityPassWord ” href ="#”>
修改密码</ a >< a
href ="$ fctx }/ auth /1ogout">
退出く/ a >
</ div ></ div >
2. 数据采集
在向后看前端展现是数据管理模块中的数据采集,数据采集模块得到的是下图的效果,找到数据管理模块中的数据采集,数据采集就是按钮,按钮调用的 id 是dataCollect,提供了一个 dataCollect的jsp
く/ div >
< ul class =" dwei ">
< li class =" dwei -1i">
< a class =" active ”
id =" indexFlage ” href ="$ ctx }/ pages / index . jsp ">
首页</ a >
<1i>
< li class =" dwei -1i">く a id =" dataManage ">
数据管理</ a >
< ul class " dwei - yinc ">
< li >く a id =" dataCollect ” href =“#”>
数术采集 k / a >く/1i>
< li ンく a id =" dataHandle " href ="#”>
数据处理</ a ン/1i>
</ ul >く/1i>
< li class =" dwei - li ">く a id =" dataVisualize ” href =”#”>
数据可视化</ a >く/ li >< li class =" dwei -11">く a id =" processManage " href ="#”>
流程管理</ a ></1i>< li class =" dwei - li "ン< a id =" sysManage ">
系统管理</ a >
< ul class =" dwei - yinc ">
< li ン< a id =" useranage ">
用户管理</ a ></ li >
< li >< a 1d=" roleManage ">
角色管理</ a >/ li >< li ンく a id =" persManage ">
权限管理</ a >/ li ></ ul ></ li >
</ ul >
</ div >
3.jsp
dataCollect 的 jsp,其中有部署的服务器名称,当前活跃连接数,最近三天采集数据量,就是前端展现出来的数据库,此 jsp 加载的是 script dataCollect的 js,< body >
< article class =" dataCollect ”>
< div class =" table - responsive ">
< table class =" table ">
< thead >
< tr >
< th >
部署服务器</ th >
< th >
当前活跃连接数</ th >
< th >
最近三天采集数据量</ th >
<!--< th width ="200" style =" text - align : center ;">
脚
</ tr >
</ thead >
< tbody id =" datacollect ”>
< tr >
< td class =" server - img ”>
< p >
服务器1</ p >
</ td >
4.js
在找一下这个js,js在all里面查找。点击dataCollect的js,我们要展示昨天前天前三天的数据情况。ajax是做异步查询的,前端到后端的异步查询到后台去访问数据,后台在 dataCollect 里面有一个 getDataCollect。
loadserver : function (
$. ajax (
url : ctx +"/ dataCollect / getDataCollect ',
type : get ,
dataType :‘ json ,
success : function ( data )
var datacollectHtml ='';
for ( var i =0; icdata . length ; i ++)
dat aCollctHtml +=‘< tr >< td class =" server - img ">< p >+ data [ i ]. serverName +'</ p ></ td >'+‘< td >< p >+ data [ i ] activeNum + Sp >く/ td >'+
‘< td >< p class =" fontsize ">く span
昨天;</ span >く span >+ data [ i ]. yesterdayNum +*
行</ span ></ p >+
< p class =" fontsize ">く span >
前:</ span >く span >+ data [ i ]. beforeYesterdayNum +'
行</ span >く/ p >'+
' p class =" fontSize ">く span >
前三天:</ span >く span >+ data [ i ]. lastThreeDaysNum +行</ span ></ p ></ td ></ tr >;
’ ctd class =" operation - img ">く img src =“$[ ctx }/ themes / default / images / ico -095.png” onclick =” window . dataColLec
$(" Hdatacollect ').htm1(datacollectHtm1);
error : function ( data )
alert ("
系统错误”);
5.DataCollect
找一下 DataCollect,在controller中,打开 controller 找 DataCollect controller双击,下面这段代码就是通过前端ajax来到程序后台去查询数据,如何查询数据?
首先初始化 datacollectviewList,是一个 list 类型里面是一个 datacollect 的 view是一个为前端展现提供的bean包括id服务器名称,包括昨天前天近三天数据链以及activeNum(当前活跃用户连接数),这个bean就是用来封装这个结果的,将bean数据封装后返回前端界面数据就是展现了。如何封装bean?首先实例化bean的一个list,如果有多个值就封装datacollectviewList。继续向后看代码,先实例化一个redis 集群。
esponseBody
public List < Datacollectview > getDataCollect ( HttpServletRequest request )
List < Datacollectview > datacollectviewList = new ArrayList く~>();
tryt
//实例化 redis 集群
Jediscluster jediscluster = JedisConnectionUtil . getJediscluster ();
//从数据库表 dataColLect 中拿出所有数招
List く Datacollect > datacollectList = datacollectservice . getDataCollect ();
for ( Datacollect datacollect : datacollectList ){
//遍历 mysqL 中所有 servername
//redis服务器 获取正在运行的服务器( CSANTI MONITOR _ LP *)
// Last 类似 CSANTI MONITOR _LP1553088805099
String last = JedisConnectionUtil . keys ( jediscluster , pattern : Constants . cSANTI _ MONITOR _ LP +”*”). last ();
//获取到key 对应的value {" serversCountMap ”:"192.168.2.141”:30)," activeNumMap ":"192.168.2.141”:"5" string value = jediscluster . get ( last );
//将【" serversCountNap ":"192.168.2.141”:30]," activeNumMap ":{"192.168.2.141”:"5"
月)转换成 L ink ] sonvo LinkJsonvO resolveLinkJson = JsonResolveUtil . resolveLinkJson ( value );
//获取到 bean 中的" activeNumMap "也就是"192.168.2.141":“5"
//< String , Integer >就是("192.168.2.141":"5
Map < String , Integer >map2= resolveLinkJson . getActiveNumap ();
//可能会有多个 keySet , keySet 是 IP (192.168.2.141)
getDataCollect 是做什么的?from Datacollect 然后 find 去执行这个代码,也就是在数据库中Datacollect的表里直接把数据查找没有任何条件,有一个就查找一个,有多个就查找多个,查找以后返回了一个 dataCollectDao 到这里就从数据库中拿到了所有的数据,Datacollect中可能会有多个值那就遍历每一个值
@override
public List < Datacollect > getDatacollect (){
//查询所有的数据
String hql =" from Datacollect ";
return dataColl,ectDao . find (hq1);
}
@Override
public void deleteServer ( String id ){
Datacollect datacollect = new Datacollect ( id ); dataCollectDao . delete ( datacollect );
@ Override
public void modifyData ( string id , string newScript )
前面是在数据库中将数据库表里所有的数据都查到,先拿到第一个在向后走,在向后走是一个redis的JedisConnectionutil . keys,keys里面又传了一个redis集群和CSANTI MONITOR _前缀,
// 在redis 服务器获取正在运行的服务器( CSANTI MONITOR _ LP *)// Last
类似 CSANTI _ MONITOR _LP1553088805099
String last = JedisConnectionutil . keys ( jediscluster , pater : Constants . cSANTI _ MONITOR _ LP +”*"). last ();
/获取 key 对应的 value "
serversCountMap ":(“192.168.2.141":30),"
activeNumMap ":{"192.168.2.141":“5
string value = jediscluster . get ( last );
/将{" serversCountMap ":{"192.168.2.141”:30),"
activeNumMap ":("192.168.2.141”:“5"}
转换成
LinkJsonVo LinkJsonvo resolveLinkJson = JsonResolveUtil . resolveLinkJson ( value );
/获取到 bean 中的" activeNumMap "也就是
“192.168.2.141";"5")
/< string , Integer >
就是{"192.168.2.141":"5"
Map < String , Integer >map2= resolveLinkJson . getActiveNumap ();
//可能会有多个 keySet , key Set 是 TP (192.168.2,141) Set < String > keySet =map2. keySet ();
/遍历每一个 IP , key 当前正在服务的服务监 ip ,在 iredis 数据库获取的
for ( String key : keySet ){
获取my5qL中,当前正在服务的servername当前服务 IP在 mysql 存的数摺
if( key . equals ( datacollect . getServerName ()){
//实例化前端展现的bean
JedisConnectionutil 是什么?还是刚才的代码把在这个集群当中所有这个前缀的数据全部都 jedis.keys 中,拿到了所有的key塞到 keys 里面然后返回了 keys。public static TreeSet < String > keys ( JedisCluster jc , string pattern ){
Treeset < String > keys = new Treeset く>();
Map < String , JedisPool > clusterNodes = jc . getclusterNodes (); for ( Stringk : clusterNodes . keyset ()
JedisPooljp = clusterNodes . get ( k ); Jedis jedis = jp . getResource ();
try
keys ,addAl1( jedis . keys ( pattern ));
catch ( Exception e ){
e . printStackTrace (); finallyf
//用完一定要 cLose 这个链接!!!
jedis . close ();
}
return Keys
6.key
这就拿到了redis里面所有的key,所有的key拿到以后只要最后一个,然后get key就拿到了对应的value,value对应的是这个格式 serversCountMap ":(“192.168.2.141":30),"
activeNumMap ":{"192.168.2.141":“5的数据,返回的是LinkJsonVo,与前面所讲一致,也就是将字符串类型的转化完bean并且做了返回。继续看,将redis同步到 mysl 里 get 的是 ServerCountMap,现在获取的是 get activeMap,这样就拿到了一个 map 这个 map 前面是 ip 后面是 ip 所对应的值。
然后在keySet,拿到了里面所有的key。当前是一台服务器所以这里面只有一个值,如果有多台服务器就有多个值map2.keySet就拿到了这个值也是一个set值,这个值有可能是多个,对每一个值都要进行遍历。
这就从redis数据库中读取出来的值又获得activeNumMap,又通过key拿到了对应的值。key是对应的ip。datacollect是刚刚在数据库中读到的所有的数据,先遍历其中一个,然后循环找到最后一个获取到keyset。key的真正来源是先从redis里面读取所有的拿到最后一个经过数据转化成linkJsonVo的bean,转化成bean以后拿到所有的key.遍历其中某一个key redis里的ip等于数据库查出来的结果。数据库里的getServerName也就是server_name。
redis里面生成的最后一条数据里面的key ip等于数据库中的key ip,在这个前提下进行获取数据获取的是为了前端展现数据的bean,先实例化bean在进行封装,封装的是setActiveNum,当前活跃用户连接数,活跃用户连接数的值在map2中get key,key就是ip,map2是刚刚从jsonvo中获得的。
也就拿到了这个ip当前所对应的用户活跃连接数,并且给他设置到了datacollect里的ativenum里面。这个bean的数据来源于redis,而下面设置的setBeforeYesterdayNum将redis同步到mysql的数据读出来时意味着dataCollect获得到了
setBeforeYesterdayNum,数据库里面前天的数据获取到给到当前这个bean的前天的数据,再把ip获取出来,在将数据库中的近三天的数据读取出来,设置给这个setLastThreeDaysNum bean近三天的数据,服务器的名称servername读取出来给到当前bean的服务器名称,数据库当中的yesterday读取出来给到bean里面的昨天数据。
这就把bean封装完美了,封装完毕以后才准备好一个,如果多个服务器用dataCollectviewList也就是前面刚计算好的list,它就是来封装多个值的先把一个封装好,一个值就添加一个,多个就通过数据库里面的循环遍历多次然后读取出来写入到list里面。
如果没有if( key . equals ( datacollect . getServerName这句话就会很尴尬,数据库中有十个前端界面就展现十个,加了这句话以后数据库里面有十个但是现在当前redis里面活跃的只有一个,那list里面就只有一个值。返回返到了ajax中ajac返回到data中,data再去获取。这就是从后端展现到前端的一个过程
// 在redis 服务器获取正在运行的服务器( CSANTI MONITOR _ LP *)// Last 类似 CSANTI _ MONITOR _LP1553088805099
String last = JedisConnectionutil . keys ( jediscluster , pater : Constants . cSANTI _ MONITOR _ LP +”*"). last ();
/获取 key 对应的value "
serversCountMap ":(“192.168.2.141":30),"
activeNumMap ":{"192.168.2.141":“5
string value = jediscluster . get ( last );
/将{" serversCountMap ":{"192.168.2.141”:30)," activeNumMap ":("192.168.2.141”:“5"}
转换成
LinkJsonVo LinkJsonvo resolveLinkJson = JsonResolveUtil . resolveLinkJson ( value );
/获取到 bean 中的" activeNumMap "也就是
“192.168.2.141";"5")
/< string , Integer >
就是{"192.168.2.141":"5"
Map < String , Integer >map2= resolveLinkJson . getActiveNumap ();
//可能会有多个 keySet , key Set 是 TP (192.168.2,141) Set < String > keySet =map2. keySet ();
/遍历每一个 IP , key 当前正在服务的服务监 ip ,在 iredis 数据库获取的
for ( String key : keySet ){
获取my5qL中,当前正在服务的servername当前服务 IP在 mysql 存的数摺
if( key . equals ( datacollect . getServerName ()){
//实例化前端展现的bean
DatacollectView datacollectview = new DatacollectView ();
//将当前最新的活跃还接数封装到 bean くくく数据来源/ redis >>>
datacollectview . setActiveNum (map2.get( key ));
datacollectView . setBeforeYesterdayNum ( datacollect . getBeforeYesterdayNum ()); datacollectview , setId (datac1lect. getId ());
datacollectview . setLastThreeDaysNum ( datacollect . getLastThreeDaysNum ());
datacollectview . setServerName ( datacollect . getServerName ());
datacollectview , setYesterdayNum ( datacollect . getYesterdayNum ());
dataCollectviewList . add ( datacollectview );
//将其他信息封装进 bean
//封装 server name ( server IP ) bean 添加到 bean 的l ist 内
}
三、效果
流程当中服务器名称近三天的数据来源于MySQL,当前活跃用户连接数来源于redis,检测一下效果,在dataCollectController中看,dataCollectViewList就是写入的list,list添加实例化首先当前dataCollectView,当前活跃用户连接数来自于map2,map2来自于linkJsonVo,来源于value,value来源于redis集群里面获取出的最后一个值,也就是从redis里面读取的所以说当前的活跃用户连接数来源于map2来源于redis.而其他的服务器名称servername来源于datacollect的getservename,数据库中的名字昨天前面近三天数据也来源于数据库中的值,也就是来源于mysql。
也就是服务器名称近三天的数据来源于MySQL,当前活跃用户连接数来源于redis
// 在redis 服务器获取正在运行的服务器( CSANTI MONITOR _ LP *)// Last 类似 CSANTI _ MONITOR _LP1553088805099
String last = JedisConnectionutil . keys ( jediscluster , pater : Constants . cSANTI _ MONITOR _ LP +”*"). last ();
/获取 key 对应的value "
serversCountMap ":(“192.168.2.141":30),"
activeNumMap ":{"192.168.2.141":“5
string value = jediscluster . get ( last );
/将{" serversCountMap ":{"192.168.2.141”:30)," activeNumMap ":("192.168.2.141”:“5"}
转换成 LinkJsonVo LinkJsonvo resolveLinkJson = JsonResolveUtil . resolveLinkJson ( value );
/获取到 bean 中的" activeNumMap "也就是“192.168.2.141";"5")
/< string , Integer >就是{"192.168.2.141":"5"
Map < String , Integer >map2= resolveLinkJson . getActiveNumap ();
//可能会有多个 keySet , key Set 是 TP (192.168.2,141) Set < String > keySet =map2. keySet ();
/遍历每一个 IP , key 当前正在服务的服务监 ip ,在 iredis 数据库获取的
for ( String key : keySet ){
获取my5qL中,当前正在服务的servername当前服务 IP在 mysql 存的数摺
if( key . equals ( datacollect . getServerName ()){
//实例化前端展现的 bean
DatacollectView datacollectview = new DatacollectView ();
//将当前最新的活跃还接数封装到 bean くくく数据来源/ redis >>>
datacollectview . setActiveNum (map2.get( key ));
datacollectView . setBeforeYesterdayNum ( datacollect . getBeforeYesterdayNum ()); datacollectview , setId (datac1lect. getId ());
datacollectview . setLastThreeDaysNum ( datacollect . getLastThreeDaysNum ());
datacollectview . setServerName ( datacollect . getServerName ());
datacollectview , setYesterdayNum ( datacollect . getYesterdayNum ());
dataCollectviewList . add ( datacollectview );
//将其他信息封装进 bean
//封装 server name ( server IP ) bean 添加到 bean 的l ist 内
}