1、整合Eureka
基于之前的edu实战项目,把服务注册到eureka进行服务治理,已有的服务如下
工程名称(服务名称) | 说明 |
---|---|
jude-edu-parent | 版本管理 |
jude-edu-edu | 主要业务模块 |
jude-edu-admin-login | 后台登录注销模块 |
jude-edu-common | 公共模块 |
jude-edu-oss | 阿里云存储模块 |
jude-edu-vod | 阿里云视频点播模块 |
服务注册中心 edu-eureka
新建module maven工程 edu-eureka , parent选择edu-parent
1、导入依赖
edu-parent的pom.xml添加
<!--Spring Cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
edu-eureka的pom.xml添加
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、配置文件,edu-eureka的application.yaml 添加
server:
port: 8220
spring:
application:
name: jude-edu-eureka
profiles:
active: dev
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
3、edu-eureka的启动类添加注解@EnableEurekaServer开启服务注册
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
服务注册到edu-eureka
1、添加依赖,edu-admin-login的pom.xml 添加
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、配置文件,edu-admin-login.application.yaml 添加
# 服务注册中心
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8220/eureka/
3、edu-admin-login的启动类增加注解@EnableEurekaClient
@SpringBootApplication
@EnableEurekaClient
public class AdminLoginApplication {
public static void main(String[] args) {
SpringApplication.run(AdminLoginApplication.class,args);
}
}
启动edu-eureka,edu-admin-login,浏览器访问http://localhost:8220/
可以看到edu-admin-login 服务已经注册到eureka了,其他服务同样配置。
Eureka server 自我保护机制失效配置,不建议关闭
# 关闭自我保护机制, 不可用的微服务就会自动剔除,默认开启
# eureka.server.enable-self-preservation=false
# 清理失效的时间 5s,默认60秒
# eureka.server.eviction-interval-timer-in-ms=5000
Eureka client 的心跳配置,保持默认
# 每5s发送一个心跳!默认30秒
# eureka.instance.lease-renewal-interval-in-seconds=5
# 如果10s 之后,服务端没有收到心跳,就代表微服务挂了!默认90秒
# eureka.instance.lease-expiration-duration-in-seconds=10
生产环境中,集群至少两台,合理的是3台,尽量单数。
2、用户中心微服务
新建数据库coding_ucenter
新建module maven工程edu-ucenter,parent选择edu-parent,一个微服务与一个数据库对应,使用myabtis-plus的代码生成器,自动生成mapper\service\controller
参考edu-admin-login把 edu-ucenter 注册到Eureka中
web层接口-统计用户今日注册数
web层接口的定义MemberAdminController
@ApiOperation(value = "统计用户今日注册数")
@GetMapping(value = "count-register/{day}")
public R registerCount(
@ApiParam(name = "day",value = "统计日期")
@PathVariable("day") String day){
Integer count = memberService.countRegister(day);
return R.ok().data("countRegister",count);
}
3、统计中心微服务
新建数据库coding_statistics,
新建module maven工程edu-statistics,parent选择edu-parent,一个微服务与一个数据库对应,使用myabtis-plus的代码生成器,自动生成mapper\service\controller
参考edu-admin-login把 edu-ucenter 注册到Eureka中
4、Feign调用
Feign总结:
- 声明式、模板化、Http客户端
- 默认集成Ribbon结合实现负载均衡,
- 默认集成HyStrix,实现服务降级!
任务:edu-statistics 通过feign调用edu-ucenter 的web层接口-统计用户今日注册数,获取注册数,生成今日统计记录
1、edu-statistics的pom.xml添加依赖
<!--添加feign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
2、edu-statistics的主启动类添加 Feign的支持注解@EnableFeignClients
@SpringBootApplication
@ComponentScan(basePackages = {"com.jude.statistics","com.jude.common"})
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class StatisticsApplication {
public static void main(String[] args) {
SpringApplication.run(StatisticsApplication.class,args);
}
}
3、edu-statistics的feign接口UcenterClient
@FeignClient("edu-ucenter")
public interface UcenterClient {
@GetMapping("/admin/ucenter/member/count-register/{day}")
R countRegister(@PathVariable String day);
}
4、edu-statistics的业务层接口实现类DailyServiceImpl
@Autowired
UcenterClient ucenterClient;
@Override
public void saveStatisticsByDay(String day) {
// 删除已存在的统计
QueryWrapper<Daily> dailyQueryWrapper = new QueryWrapper<>();
dailyQueryWrapper.eq("date_calculated",day);
baseMapper.delete(dailyQueryWrapper);
// 获取统计信息
Integer registerNum = (Integer) ucenterClient.countRegister(day).getData().get("countRegister");
// TODO 作业:这里的数据也可以远程调用,根据实际情况来操作
Integer loginNum = RandomUtils.nextInt(100,200); // 登录数
Integer videoViewNum = RandomUtils.nextInt(100,200); // 视频播放数
Integer courseNum = RandomUtils.nextInt(100,200); // 每日课程新增个数
// 添加到统计表中
Daily daily = new Daily();
daily.setRegisterNum(registerNum);
daily.setLoginNum(loginNum);
daily.setVideoViewNum(videoViewNum);
daily.setCourseNum(courseNum);
daily.setDateCalculated(day);
this.save(daily);
}
5、edu-statistics的web层接口的定义DailyAdminController
@ApiOperation(value = "新增每日统计数据记录")
@GetMapping("{day}")
public R createStatisticsByDay(@ApiParam(name = "day",value = "日期",example = "2020-05-08",required = true)
@PathVariable String day){
dailyService.saveStatisticsByDay(day);
return R.ok();
}
启动edu-eureka、edu-ucenter、edu-statistics,使用swagger测试
成功,edu-statistics通过feign请求edu-ucenter的count-register获取注册数,保存到数据库
4、前端配置统计分析
前端后台vue工程web-admin,
1、/src/router/index.js增加菜单路由
{
path: '/statistics/daily',
component: Layout,
meta: { title: '统计分析', icon: 'chart' },
name: 'statisticsDaily',
children: [
{
path: 'create',
component: () => import('@/views/statistics/create'),
name: 'StatisticsDailyCreate',
meta: { title: '生成统计', icon: 'form' }
}
]
},
2、/src/api/statistics/daily.js 接口函数
import request from '@/utils/request'
const api_name = '/admin/statistics/daily'
export default{
createStatistics(day) {
return request({
url: `${api_name}/${day}`,
method: 'get'
})
}
}
3、/src/views/statistics/create.vue 模版页面
<template>
<div class="app-container">
<el-form :inline="true">
<!-- 日期 -->
<el-form-item label="日期">
<el-date-picker
v-model="day"
type="date"
placeholder="选择日期"
value-format="yyyy-MM-dd"/>
</el-form-item>
<el-button
:disabled="btnDisabled"
type="primary"
@click="create()">生成统计</el-button>
</el-form>
</div>
</template>
<script>
import daily from '@/api/statistics/daily'
export default {
data() {
return {
day: '',
btnDisabled: false
}
},
methods: {
create() {
this.btnDisabled = true
daily.createStatistics(this.day).then(response => {
this.btnDisabled = false
this.$message({
type: 'success',
message: '生成成功'
})
})
}
}
}
</script>
启动edu-eureka、edu-admin-login、edu-ucenter、edu-statistics ,登录测试:
5、Echarts 图表
ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。
官网示例:https://echarts.apache.org/examples/zh/index.html
集成到项目中
前端后台vue工程web-admin,安装echarts
npm install echarts --save
1、/src/router/index.js 增加菜单路由统计图表
{
path: '/statistics/daily',
component: Layout,
meta: { title: '统计分析', icon: 'dashboard' },
name: 'statisticsDaily',
children: [
{
path: 'create',
component: () => import('@/views/statistics/create'),
name: 'StatisticsDailyCreate',
meta: { title: '生成统计' }
},
{
path: 'chart',
component: () => import('@/views/statistics/chart'),
name: 'StatisticsDailyChart',
meta: { title: '统计图表'}
}
]
}
2、/src/api/statistics/daily.js 增加接口函数
// 获取统计数据
showChart(searchObj) {
return request({
url: `${api_name}/show-chart/${searchObj.begin}/${searchObj.end}/${searchObj.type}`,
method: 'get'
})
}
3、/src/views/statistics/chart.vue 模版页面
<template>
<div class="app-container">
<!--表单-->
<el-form :inline="true" class="demo-form-inline">
<!-- 根据不同的规则,生成不同的图表 -->
<el-form-item>
<el-select v-model="searchObj.type" clearable placeholder="请选择">
<el-option label="学员登录数统计" value="login_num"/>
<el-option label="学员注册数统计" value="register_num"/>
<el-option label="课程播放数统计" value="video_view_num"/>
<el-option label="每日课程数统计" value="course_num"/>
</el-select>
</el-form-item>
<el-form-item>
<el-date-picker
v-model="searchObj.begin"
type="date"
placeholder="选择开始日期"
value-format="yyyy-MM-dd" />
</el-form-item>
<el-form-item>
<el-date-picker
v-model="searchObj.end"
type="date"
placeholder="选择截止日期"
value-format="yyyy-MM-dd" />
</el-form-item>
<el-button
:disabled="btnDisabled"
type="primary"
icon="el-icon-search"
@click="showChart()">查询</el-button>
</el-form>
<!-- 图表 -->
<div class="chart-container">
<div id="chart" class="chart" style="height:500px;width:100%" />
</div>
</div>
</template>
<script>
import echarts from 'echarts'
import daily from '@/api/statistics/daily'
export default {
data() {
return {
// 查询条件
searchObj: {
type: '',
begin: '',
end: ''
},
btnDisabled: false,
// 图表数据
chart: null,
title: '',
xData: [],
yData: []
}
},
methods: {
showChart() {
this.initChartData()
// this.setChart()//放在initChartData回调中执行
},
// 准备图表数据
initChartData() {
daily.showChart(this.searchObj).then(response => {
// 数据
this.yData = response.data.dataList
// 横轴时间
this.xData = response.data.dateList
// 当前统计类别
switch (this.searchObj.type) {
case 'register_num':
this.title = '学员注册数统计'
break
case 'login_num':
this.title = '学员登录数统计'
break
case 'video_view_num':
this.title = '课程播放数统计'
break
case 'course_num':
this.title = '每日课程数统计'
break
}
this.setChart()
})
},
// 设置图标参数
setChart() {
// 基于准备好的dom,初始化echarts实例
this.chart = echarts.init(document.getElementById('chart'))
// console.log(this.chart)
// 指定图表的配置项和数据
var option = {
title: {
text: this.title
},
// x轴是类目轴(离散数据),必须通过data设置类目数据
xAxis: {
type: 'category',
data: this.xData// -------绑定数据
},
// y轴是数据轴(连续数据)
yAxis: {
type: 'value'
},
// 系列列表。每个系列通过 type 决定自己的图表类型
series: [{
// 系列中的数据内容数组
data: this.yData, // -------绑定数据
// 折线图
type: 'line'
}],
dataZoom: [{
show: true,
height: 30,
xAxisIndex: [
0
],
bottom: 30,
start: 10,
end: 80,
handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
handleSize: '110%',
handleStyle: {
color: '#d3dee5'
},
textStyle: {
color: '#fff'
},
borderColor: '#90979c'
},
{
type: 'inside',
show: true,
height: 15,
start: 1,
end: 35
}]
}
this.chart.setOption(option)
}
}
}
</script>
后端接口
1、edu-statistics 统计中心服务的业务层接口实现类DailyServiceImpl
@Override
public Map<String, Object> getChartData(String begin, String end, String type) {
List<Daily> dayList = this.list(new QueryWrapper<Daily>().select(type,"date_calculated")
.between("date_calculated",begin,end));
Map<String, Object> map = new HashMap<>();
List<Integer> dataList = new ArrayList<Integer>();
List<String> dateList = new ArrayList<String>();
map.put("dataList", dataList);
map.put("dateList", dateList);
for (int i = 0; i < dayList.size(); i++) {
Daily daily = dayList.get(i);
dateList.add(daily.getDateCalculated());
switch (type) {
case "register_num":
dataList.add(daily.getRegisterNum());
break;
case "login_num":
dataList.add(daily.getLoginNum());
break;
case "video_view_num":
dataList.add(daily.getVideoViewNum());
break;
case "course_num":
dataList.add(daily.getCourseNum());
break;
default:
break;
}
}
return map;
}
2、edu-statistics 统计中心服务的web层接口定义DailyAdminController
@ApiOperation(value = "查询统计报表数据")
@GetMapping("show-chart/{begin}/{end}/{type}")
public R showChart(@ApiParam(name = "begin",value = "开始日期",required = true) @PathVariable String begin,
@ApiParam(name = "end",value = "截止日期",required = true) @PathVariable String end,
@ApiParam(name = "type",value = "报表类型",required = true) @PathVariable String type){
Map<String, Object> map = dailyService.getChartData(begin, end, type);
return R.ok().data(map);
}
启动测试,获取后端数据渲染图表
拓展:L7 地理空间数据可视化
旧版本官网:http://antv-2018.alipay.com/zh-cn/l7/1.x/index.html
新版本官网:https://antv.gitee.io/zh
好炫酷!