数据处理-链路统计-数据库到前端展现|学习笔记

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 快速学习数据处理-链路统计-数据库到前端展现

开发者学堂课程【大数据实战项目:反爬虫系统(Lua+Spark+Redis+Hadoop框架搭建):数据处理-链路统计-数据库到前端展现】学习笔记与课程紧密联系,让用户快速学习知识

课程地址https://developer.aliyun.com/learning/course/670/detail/11638


数据处理-链路统计-数据库到前端展现

 

内容介绍

一、 回顾

二、 如何使数据库展现到前端

三、 效果

 

一、 回顾

通过 web 界面的后台当中有一个程序,程序做了定时任务,定时去拉取将 redis 里面的数据写到 mysql,数据写完以后 redis 中的 activeUserNumber 活跃的用户连接数以及近几天的数和前面的数据是如何展现到前端的呢?前端的代码是什么样的?

 

二、 如何使数据库展现到前端

1. web 项目展现

image.png

此页是 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 内

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
存储 SQL 关系型数据库
Mysql学习笔记(二):数据库命令行代码总结
这篇文章是关于MySQL数据库命令行操作的总结,包括登录、退出、查看时间与版本、数据库和数据表的基本操作(如创建、删除、查看)、数据的增删改查等。它还涉及了如何通过SQL语句进行条件查询、模糊查询、范围查询和限制查询,以及如何进行表结构的修改。这些内容对于初学者来说非常实用,是学习MySQL数据库管理的基础。
122 6
|
1月前
|
SQL Ubuntu 关系型数据库
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
本文为MySQL学习笔记,介绍了数据库的基本概念,包括行、列、主键等,并解释了C/S和B/S架构以及SQL语言的分类。接着,指导如何在Windows和Ubuntu系统上安装MySQL,并提供了启动、停止和重启服务的命令。文章还涵盖了Navicat的使用,包括安装、登录和新建表格等步骤。最后,介绍了MySQL中的数据类型和字段约束,如主键、外键、非空和唯一等。
69 3
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
|
1月前
|
Web App开发 前端开发 安全
前端研发链路之测试
本文由前端徐徐撰写,介绍了前端测试的重要性及其主要类型,包括单元测试、E2E测试、覆盖率测试、安全扫描和自动化测试。文章详细讲解了每种测试的工具和应用场景,并提供了选择合适测试策略的建议,帮助开发者提高代码质量和用户体验。
31 3
前端研发链路之测试
|
1月前
|
资源调度 前端开发 JavaScript
前端研发链路之脚手架
本文首发于微信公众号“前端徐徐”。文章介绍了前端开发中脚手架工具的重要性及其工作原理。脚手架工具能够大幅提升开发效率,确保代码质量和项目一致性。文章详细探讨了脚手架的历史、工作原理、常见工具及其优势与潜在问题,并展望了其未来发展方向,帮助开发者更好地理解和应用脚手架工具。
31 4
前端研发链路之脚手架
|
1月前
|
负载均衡 前端开发 JavaScript
前端研发链路之开发
本文首发于微信公众号“前端徐徐”,作者徐徐。文章介绍了前端研发链路中的开发部分,重点探讨了开发服务器(dev-server)、热更新(hot-reload)、数据模拟(mock)和代理(proxy)等关键技术,帮助开发者理解其基本原理和应用场景,提升开发效率和代码质量。
34 2
前端研发链路之开发
|
1月前
|
敏捷开发 前端开发 Devops
前端研发链路之 CI/CD
本文首发于微信公众号“前端徐徐”,作者徐徐介绍了前端研发链路中的CI/CD。文章从CI/CD的背景、意义、运作方式及常用工具等方面进行了详细探讨,帮助读者理解如何在前端开发中有效应用CI/CD,提升开发效率和产品质量。
36 1
前端研发链路之 CI/CD
|
1月前
|
前端开发 JavaScript 编译器
前端研发链路之构建
本文首发于微信公众号“前端徐徐”,作者徐徐探讨了前端研发链路中的构建过程。文章介绍了构建器、JavaScript编译器和CSS编译器的作用及常见工具,详细解析了它们如何协同工作,提高开发效率和项目可维护性。适合前端开发者阅读,帮助理解现代前端构建体系。
17 1
前端研发链路之构建
|
1月前
|
前端开发 JavaScript 测试技术
前端研发链路之代码规范
大家好,我是徐徐。本文将探讨前端研发链路中的代码规范,包括业界流行规范、CSS命名规范和相关工具。通过保持代码整洁和一致性,不仅能提高团队协作效率,还能减少错误,提升开发质量。文中详细对比了几种常见的代码规范和工具,如 Airbnb Style Guide、BEM、Eslint 和 Prettier,并展望了未来代码规范的发展趋势。希望对大家有所帮助。
72 1
前端研发链路之代码规范
|
23天前
|
NoSQL 前端开发 MongoDB
前端的全栈之路Meteor篇(三):运行在浏览器端的NoSQL数据库副本-MiniMongo介绍及其前后端数据实时同步示例
MiniMongo 是 Meteor 框架中的客户端数据库组件,模拟了 MongoDB 的核心功能,允许前端开发者使用类似 MongoDB 的 API 进行数据操作。通过 Meteor 的数据同步机制,MiniMongo 与服务器端的 MongoDB 实现实时数据同步,确保数据一致性,支持发布/订阅模型和响应式数据源,适用于实时聊天、项目管理和协作工具等应用场景。
|
24天前
|
缓存 前端开发 JavaScript
前端架构思考:代码复用带来的隐形耦合,可能让大模型造轮子是更好的选择-从 CDN 依赖包被删导致个站打不开到数年前因11 行代码导致上千项目崩溃谈谈npm黑洞 - 统计下你的项目有多少个依赖吧!
最近,我的个人网站因免费CDN上的Vue.js包路径变更导致无法访问,引发了我对前端依赖管理的深刻反思。文章探讨了NPM依赖陷阱、开源库所有权与维护压力、NPM生态问题,并提出减少不必要的依赖、重视模块设计等建议,以提升前端项目的稳定性和可控性。通过“left_pad”事件及个人经历,强调了依赖管理的重要性和让大模型代替人造轮子的潜在收益