1 数据可视化接口
1.1 设计思路
之前把轻度聚合的结果都保存到了ClickHouse中,主要目的就是提供即时的数据查询、统计、分析服务。这些统计服务一般会用两种形式展示,一种是为专业的数据分析人员的BI工具,另一种是为非专业人员提供更加直观的数据大屏。
下面主要是面向百度的sugar的数据大屏服务的接口开发。
1.2 需求梳理
1.2.1 最终效果
1.2.2 分析可视化大屏
组件名称 | 组件 | 查询指标 | 对应的数据表 |
---|---|---|---|
总成交金额 | 数字翻牌 | 订单总金额 | product_stats |
省市热力图查询 | 热力图 | 省市分组订单金额 | province_stats |
分时流量 | 折线图 | UV分时数 PV分时数 新用户分时数 | visitor_stats |
品牌TopN | 水平柱状图 | 按品牌分组订单金额 | product_stats |
品类分布 | 饼状图 | 按品类分组订单金额 | product_stats |
热词字符云 | 字符云 | 关键词分组计数 | keyword_stats |
流量表格 | 交叉透视表 | UV数(新老用户) PV数(新老用户) 跳出率(新老用户) 平均访问时长 (新老用户) 平均访问页面数(新老用户) | visitor_stats |
热门商品 | 轮播表格 | 按SPU分组订单金额 | product_stats |
1.1.3 接口执行过程
2 Sugar数据大屏
Sugar是百度云退出的敏捷BI和数据可视化平台,目标是解决报表和大屏的数据 BI分析和可视化问题,解决数据可视化系统的开发人力。
2.1 使用入口
https://cloud.baidu.com/product/sugar.html
Sugar目前是免费使用1个月,DataV是免费使用7天
2.2 创建数据大屏
步骤1:点击【立即使用】后,登录百度账号
步骤2:然后首先创建组织
步骤3:创建中选择产品【大屏尝鲜版】,首次使用有一个月的试用期
步骤4:新建好组织后选择【进入组织】
步骤5:进入默认的【第一个空间】
步骤6:在空间中选择【待创建大屏】后的新建
步骤7:选择大屏的模板
步骤8:选择空模板,也可以根据现有的模板进行修改
步骤9:进入大屏的编辑窗口
3 总成交金额接口
3.1 需求分析与设计思路
-- mapper接口
定义selectGMV()方法,需要在注解上添加@Select注解
从ClickHouse中的product_stats_2021表中查询sum(payment_amount)
-- service接口
定义getGMV()方法
-- serviceImpl实现类
实现Service接口中的方法,注入Mapper对象,Mapper的方法中获取数据
-- Controller类
注入ServiceImpl对象
定义getGMV()方法,接收请求,返回从ServiceImpl中获取的结果
分层结构:SpringBoot项目,三层结构
-- 分层 -- 类 --处理内容
控制层 Controller 负责接收请求,返回结果
服务层 Service 负责业务处理
数据映射层 Mapper 负责和数据库之间的交互
本项目中的分层结构:
数据映射层:Mapper 编写SQL查询商品统计表 从ClickHouse中查询数据(需要传入参数date)
服务层:Service 接收调用Mapper中的方法,查询商品统计数据
控制层:Controller 查询交易额接口 接收访问路径的请求,返回结果给页面
public interface Mapper(){} Mapper定义为接口
public interface Service(){} Service定义为接口
public class ServiceImpl(){} 定义Service的实现类
public class Controller(){} 定义Controller为类
-- Mapper作为一个接口,需要在GmallPublisherApplication主类中 添加@MapperScan("包路径")注解,加载主类的时候,会去指定的包路径下,寻找接口,为其创建实现类。
-- Service作为一个接口,定义ServiceImpl实现类;ServiceImpl实现类上需要添加@Service注解,这样SSM就会通过IOC容器,帮助我们去创建对象;创建什么类型的对象,需要在将该类型定义为属性,并在属性上面添加@Autowired注解。
-- Controller作为一个类,需要接收请求,所以需要添加@Controller注解;还需要使用@ResponseBody注解,标注返回值不是页面跳转,是返回String;@RestController = @Controller + @ResponseBody
-- @RequestMapping注解,可以放在类上,也可以放在方法上,定义了访问路径的命名空间。
-- 面向接口编程
3.2 Sugar组件:数字翻牌器
3.1.1 添加组件
从大屏的编辑器上方选择【指标】 --> 【数字翻牌器】
3.1.2 查询组件需要的数据格式
在数据绑定方式选择【静态JSON】
3.1.3 配置组件
点击组件,在右侧的菜单中选择【数据】,绑定方式改为【API拉取】下面的路径填写:
$API_HOST/api/sugar/gmv
其中这个$API_HOST为API宏,需要自己配置,使用到了内网穿透。后面介绍。在这个数据接口后面可以接收请求参数:比如:
$API_HOST/api/sugar/gmv?date=20210226
3.1.4 数据接口访问路径
-
访问数据接口:用来接收请求Request
/api/sugar/gmv
-
返回数据格式:根据sugar组件的静态JSON数据格式
{ "status": 0, "msg": "", "data": 1201081.1632389291 }
3.3 数据接口实现
3.2.1 创建数据接口模块,并添加依赖
在gmall-realtime-flink工程下创建gmall-publisher的SpringBoot模块。
在pom.xml文件中添加依赖
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
<dependency>
<groupId>ru.yandex.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.1.55</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.2.2 代码实现
(1)修改SpringBoot核心配置文件application.properties
- 修改tomcat的端口号
- 添加JDBC驱动:ClickHouse驱动,以及URL
server.port=8070
#配置ClickHouse驱动以及URL
spring.datasource.driver-class-name=ru.yandex.clickhouse.ClickHouseDriver
spring.datasource.url=jdbc:clickhouse://hadoop102:8123/default
(2)在Application中添加@MapperScan注解
添加@MapperScan的注解的作用是:加载Application的时候,会给注解指定的路径下的 接口 创建实现类。
@SpringBootApplication
//TODO MapperScan 注解会为当前包中的类 提供实现接口的 实现类
// 会去这个包路径去找接口,提供实现类,接口中有抽象方法,那么需要怎么实现呢? --> 在接口中的发给发上使用Select Insert 等注解,注解()内是sql语句
@MapperScan(basePackages = "com.codejiwei.mapper")
public class GmallPublisherApplication {
public static void main(String[] args) {
SpringApplication.run(GmallPublisherApplication.class, args);
}
}
(3)Mapper层:创建ProductStatsMapper接口
从ClickHouse中查询数据:查询sql为:
select sum()
/**
* Author: codejiwei
* Date: 2021/2/27
* Desc: 编写SQL查询商品统计表 接口:ssm帮助创建实现类
* TODO mapper就和数据库打交道
**/
public interface ProductStatsMapper {
//获取某一天商品的交易额
//TODO SSM底层 通过@Select实现抽象方法 sql语句中有抽象方法传入的参数 使用#{参数名} 的方式使用参数
@Select("select sum(order_amount) from product_stats_2021 where toYYYYMMDD(stt)=#{date};")
BigDecimal getGMV(int date);
}
(4)Service层:创建ProductStatsService接口
/**
* Author: codejiwei
* Date: 2021/2/27
* Desc: 商品统计的service接口
* TODO Service做业务处理
**/
public interface ProductStatsService {
//获取某一天交易总额
BigDecimal getGMV(int date);
}
(5)Service层:创建ProductStatsServiceImpl实现类
/**
* Author: codejiwei
* Date: 2021/2/27
* Desc: 商品统计service接口实现类
*
* TODO IOC 容器 创建对象一开始是程序员创建对象,现在对对象的控制交给IOC容器控制
* 控制反转
* IOC帮我们创建对象,通过添加一个@Service注解
**/
@Service //标识是Spring的Service层组件,将对象的创建交给Spring的IOC容器
public class ProductStatsServiceImpl implements ProductStatsService{
//TODO 在容器中,寻找ProductStatsMapper类型的对象,赋值给当前属性
// TODO 通过IOC创建对象,使用Autowired进行注入
@Autowired
ProductStatsMapper productStatsMapper; //调整IDEA的提醒等级为Warn
@Override
public BigDecimal getGMV(int date) {
return productStatsMapper.getGMV(date);
}
}
(6)Controller层:创建SugarController类
/**
* Author: codejiwei
* Date: 2021/2/27
* Desc: 查询交易额接口以及返回参数处理
* TODO 大屏展示的控制层
* 接收客户端的请求Request,对请求进行处理,并给客户端响应Response
*
* @RestController = @ResponseBody + @Controller
* 仅用Controller的话,方法的返回值,会认为是页面跳转;如果想返回一个jsonString的话,就不对了
* 不做页面跳转 仅仅做String返回 那么就需要再加上 ResponseBody
*
* @RequestMapping 可以加在方法上,
* 也可以放在类上,相当于指定了访问路径的命名空间
*
**/
@RequestMapping("/api/sugar")
@RestController
public class SugarController {
@Autowired
ProductStatsService productStatsService;
/*
* 请求路径:/api/sugar/gmv
*
* 返回值类型:
{
"status": 0,
"msg": "",
"data": 1201001.961568421
}
*
* */
@RequestMapping("/gmv")
public String getGMV(@RequestParam(value = "date", defaultValue = "0") Integer date) {
if (date == 0) {
date = now();
}
BigDecimal gmv = productStatsService.getGMV(date);
return "{" +
"\"status\": 0," +
"\"data\": " + gmv +
"}";
}
private Integer now() {
String yyyyMMdd = DateFormatUtils.format(new Date(), "yyyyMMdd");
// System.out.println(">>>>>>>>>>>>>" + yyyyMMdd);
return Integer.valueOf(yyyyMMdd);
}
@RequestMapping("/clickCt")
public String m2() {
return "success";
}
}
3.2.3 测试本地接口
(1)启动SpringBoot应用程序
(2)用浏览器访问http://localhost:8070/api/sugar/gmv
(3)输出结果
则个时候输出的结果,默认是当前日期的数据。没有数据,可以指定查看某一天的数据:
localhost:8070/api/sugar/gmv?date=20210226
3.4 内网穿透
3.4.1 作用
通过个人电脑无论是连接WiFi上网还是网线上网,都是属于局域网内的,外网无法直接访问到你的电脑,内网穿透可以让局域网中的电脑实现外网访问的可能。
3.4.2 工具
- 网云穿:http://www.neiwangchuantou.net/
- 花生壳:https://hsk.oray.com
- Ngrok:http://www.ngrok.cc
3.4.3 配置使用步骤
步骤1:注册花生壳
步骤2:登录个人版,配置隧道
步骤3:通过外网地址访问
3.5 配置Sugar大屏
3.5.1 配置服务器全局Host
回到Sugar的空间管理,在【空间设置】中添加$API_HOST
3.5.2 大屏刷新数据
回到大屏中,设置数据绑定方式:API拉取,填写数据接口