sparkstreaming实时流处理项目(七)

1.搭建springboot

先选择spring initializr -> next在这里插入图片描述
创建项目名称
在这里插入图片描述
选择web版本
在这里插入图片描述
选择目录
在这里插入图片描述
因为自定义maven,删除了关于的文件目录结构
在这里插入图片描述
编写一个helloworld:

package com.qianliu.spark.web;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

//@RestController注解表示HelloBoot的生命周期交给RestController来管理
@RestController
public class HelloBoot {

    //@RequestMapping映射该方法
    //value = "/hello"表示访问的链接是:/hello
    //method = RequestMethod.GET表示请求的方法是:get
    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    public String sayHello(){
        return "hello spring boot!";
    }
}

运行该程序:
在这里插入图片描述
访问:http://localhost:8080/hello
在这里插入图片描述

2.使用echarts

五分钟上手官方教程:
https://www.echartsjs.com/tutorial.html#5 分钟上手 ECharts

将下载好的echart包引入到springboot中
在这里插入图片描述
在application.properties中设置相关的配置
在这里插入图片描述

编写test.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Echarts</title>
    <!-- 引入 echarts.js -->
    <script src="echarts/echarts.common.min.js"></script>
</head>
<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="main" style="width: 600px;height:400px;"></div>
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));

        // 指定图表的配置项和数据
        var option = {
            title: {
                text: 'ECharts 入门示例'
            },
            tooltip: {},
            legend: {
                data:['销量']
            },
            xAxis: {
                data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
            },
            yAxis: {},
            series: [{
                name: '销量',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20]
            }]
        };

        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
    </script>
</body>
</html>

在这里插入图片描述
引入thymeleaf模板化语言:
在这里插入图片描述
在hellospringboot下加入:

@RequestMapping(value = "/test",method = RequestMethod.GET)
    public ModelAndView getindex(){
        return new ModelAndView("test"); //test表示的是resources/templates/test.html
    }

启动WebApplication下的main函数来启动springboot:
在这里插入图片描述

3.调整springboot

test.html改为如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Echarts</title>
    <!-- 引入 echarts.js -->
    <script src="echarts/echarts.common.min.js"></script>
</head>
<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="main" style="width: 600px;height:400px;position: absolute;top: 50%;left: 50%;margin-top: -200px;margin-left: -300px;"></div>
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));

        option = {
            title : {
                text: '慕课网课程浏览量实时统计',
                subtext: '实施课程访问次数',
                x:'center'
            },
            tooltip : {
                trigger: 'item',
                formatter: "{a} <br/>{b} : {c} ({d}%)"
            },
            legend: {
                orient: 'vertical',
                left: 'left',
                data: ['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
            },
            series : [
                {
                    name: '访问来源',
                    type: 'pie',
                    radius : '55%',
                    center: ['50%', '60%'],
                    data:[
                        {value:335, name:'直接访问'},
                        {value:310, name:'邮件营销'},
                        {value:234, name:'联盟广告'},
                        {value:135, name:'视频广告'},
                        {value:1548, name:'搜索引擎'}
                    ],
                    itemStyle: {
                        emphasis: {
                            shadowBlur: 10,
                            shadowOffsetX: 0,
                            shadowColor: 'rgba(0, 0, 0, 0.5)'
                        }
                    }
                }
            ]
        };

        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
    </script>
</body>
</html>

com.qianliu下的包如图所示:
备注:springboot扫描器扫描的时候会扫描WebApplication平级的目录,为了使spark,dao,domain,utils与其平级,故放在一同一级目录下。

在这里插入图片描述

4.编写访问hbase的配置文件

引入hbase的包:

<!-- HBase 依赖-->
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-client</artifactId>
            <version>${hbase.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-server</artifactId>
            <version>${hbase.version}</version>
        </dependency>

在服务器上启动hbase

#启动zookeeper
zkServer.sh start
#启动hdfs
start-dfs.sh
#启动hbase
start-hbase.sh

改写以前写好的hbase的工具包:

package com.qianliu.dao;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.PrefixFilter;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * HBase操作工具类:Java工具类建议采用单例模式封装
 */
public class HBaseUtils {


    HBaseAdmin admin = null;
    Configuration configuration = null;


    /**
     * 私有改造方法
     */
    private HBaseUtils(){
        configuration = new Configuration();
        configuration.set("hbase.zookeeper.quorum", "192.168.48.138:2181");
        configuration.set("hbase.rootdir", "hdfs://192.168.48.138:8020/hbase");

        try {
            admin = new HBaseAdmin(configuration);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static HBaseUtils instance = null;

    public  static synchronized HBaseUtils getInstance() {
        if(null == instance) {
            instance = new HBaseUtils();
        }
        return instance;
    }


    /**
     * 根据表名获取到HTable实例
     */
    public HTable getTable(String tableName) {

        HTable table = null;

        try {
            table = new HTable(configuration, tableName);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return table;
    }

    /**
     * 添加一条记录到HBase表
     * @param tableName HBase表名
     * @param rowkey  HBase表的rowkey
     * @param cf HBase表的columnfamily
     * @param column HBase表的列
     * @param value  写入HBase表的值
     */
    public void put(String tableName, String rowkey, String cf, String column, String value) {
        HTable table = getTable(tableName);

        Put put = new Put(Bytes.toBytes(rowkey));
        put.add(Bytes.toBytes(cf), Bytes.toBytes(column), Bytes.toBytes(value));

        try {
            table.put(put);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * @author qianliu on 2019/3/27 20:50
     * @param tablename 表名
     * @param rowkey 列名,此处是课程的编号
     * @return 返回列名的查询出来的结果,返回的是课程的浏览记录
     * @Discription:
     */
    public Map<String,Long> query(String tablename,String rowkey) throws IOException {
        Map<String,Long> map = new HashMap<String,Long>();
        HTable table = getTable(tablename);
        String cf = "info";//列族
        String qualifier = "click_count";//列族中的列名

        Scan scan = new Scan();

        //获取过滤器
        Filter filter = new PrefixFilter(Bytes.toBytes(rowkey));
        scan.setFilter(filter);

        //table中加入scan
        ResultScanner rs = table.getScanner(scan);


        //获取结果转化为java中的string和long类型
        for (Result result : rs){
            String row = Bytes.toString(result.getRow());
            Long count = Bytes.toLong(result.getValue(cf.getBytes(),qualifier.getBytes()));
            map.put(row,count);
        }
        return map;
    }

    public static void main(String[] args) {

        //HTable table = HBaseUtils.getInstance().getTable("imooc_course_clickcount");
        //System.out.println(table.getName().getNameAsString());

        /*
        String tableName = "imooc_course_clickcount" ;
        String rowkey = "20171111_88";
        String cf = "info" ;
        String column = "click_count";
        String value = "2";

        HBaseUtils.getInstance().put(tableName, rowkey, cf, column, value);
        */
    }

}

开发一个DAO层讲hbase中的信息获取之后格式化为map<k,v>类型

package com.qianliu.dao;

import com.qianliu.domain.CourseClickCount;
import com.qianliu.utils.HBaseUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/*
* 课程点击访问的DAO
* */
public class CourseClickDAO {

    public static List<CourseClickCount> query(String day) throws Exception{
        List<CourseClickCount> list = new ArrayList<>();

        //取hbase中获取day中的所有课程以及课程访问量
        Map<String,Long> map = HBaseUtils.getInstance().query("imooc_course_clickcount","20190309");
        for (Map.Entry<String,Long> entry: map.entrySet()){
            CourseClickCount courseClickCount = new CourseClickCount();
            courseClickCount.setName(entry.getKey());
            courseClickCount.setValue(entry.getValue());
            list.add(courseClickCount);
        }

        return list;
    }

    public static void main(String[] args) throws Exception {
        CourseClickDAO dao = new CourseClickDAO();
        List<CourseClickCount> list = dao.query("20171022");
        for(CourseClickCount model : list) {
            System.out.println(model.getName() + " : " + model.getValue());
        }
    }
}

根据慕课网的实例,返回的参数为name和value构造一个CourseClickCount 来存放

package com.qianliu.domain;
/*
* 课程点击量
* */
public class CourseClickCount {
    private String name;
    private Long value;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getValue() {
        return value;
    }

    public void setValue(Long value) {
        this.value = value;
    }
}

写一个类来完成课程编号到课程名称的映射,异步请求“/course_clickcount_dynamic”获取hbase中的信息返回为json串,访问“/echarts”可以获取test.html网页。

package com.qianliu.spark;

import com.qianliu.dao.CourseClickDAO;
import com.qianliu.domain.CourseClickCount;
import org.codehaus.jettison.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * web层
 */
@RestController
public class ImoocStatApp {

    private static Map<String, String> courses = new HashMap<>();
    static {
        courses.put("112","Spark SQL慕课网日志分析");
        courses.put("128","10小时入门大数据");
        courses.put("145","深度学习之神经网络核心原理与算法");
        courses.put("146","强大的Node.js在Web开发的应用");
        courses.put("131","Vue+Django实战");
        courses.put("130","Web前端性能优化");
    }

    //@Autowired
    CourseClickDAO courseClickDAO;


    /*@RequestMapping(value = "/course_clickcount_dynamic", method = RequestMethod.GET)
    public ModelAndView courseClickCount() throws Exception {

        ModelAndView view = new ModelAndView("index");

        List<CourseClickCount> list = courseClickDAO.query("20171022");
        for(CourseClickCount model : list) {
            model.setCourse(courses.get(model.getCourse().substring(9)));
        }
        JSONArray json = new JSONArray(list);

        view.addObject("data_json", json);

        return view;
    }*/

    @RequestMapping(value = "/course_clickcount_dynamic", method = RequestMethod.POST)
    @ResponseBody
    public List<CourseClickCount> courseClickCount() throws Exception {

        List<CourseClickCount> list = courseClickDAO.query("20171022");
        for(CourseClickCount model : list) {
            model.setName(courses.get(model.getName().substring(9)));
        }

        return list;
    }

    @RequestMapping(value = "/echarts", method = RequestMethod.GET)
    public ModelAndView echarts(){
        return new ModelAndView("test");
    }

}

因为要加入json异步请求,pom.xml中

<!--使用json传值-->
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>

网页test.html中异步请求数据库中的信息

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Echarts</title>
    <!-- 引入 echarts.js -->
    <script src="echarts/echarts.min.js"></script>
    <!--引入jquery:因为此处用到了json传值-->
    <script src="echarts/jquery.js"></script>
</head>
<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="main" style="width: 800px;height:400px;position: absolute;top: 50%;left: 50%;margin-top: -200px;margin-left: -400px;"></div>
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));

        option = {
            title : {
                text: '慕课网课程浏览量实时统计',
                subtext: '实施课程访问次数',
                x:'center'
            },
            tooltip : {
                trigger: 'item',
                formatter: "{a} <br/>{b} : {c} ({d}%)"
            },
            legend: {
                orient: 'vertical',
                left: 'left',
                data: ['Spark SQL慕课网日志分析','10小时入门大数据','深度学习之神经网络核心原理与算法',
                    '强大的Node.js在Web开发的应用','Vue+Django实战','Web前端性能优化']
            },
            series : [
                {
                    name: '访问来源',
                    type: 'pie',
                    radius : '55%',
                    center: ['50%', '60%'],
                    data:(function(){
                        var datas = [];
                        $.ajax({
                            type: "POST",
                            url: "/course_clickcount_dynamic",
                            dataType: 'json',
                            async: false,
                            success: function(result) {
                                for(var i=0; i<result.length; i++) {
                                    datas.push({"value":result[i].value, "name":result[i].name})
                                }
                            }
                        })
                        return datas;

                    })(),
                    itemStyle: {
                        emphasis: {
                            shadowBlur: 10,
                            shadowOffsetX: 0,
                            shadowColor: 'rgba(0, 0, 0, 0.5)'
                        }
                    }
                }
            ]
        };

        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
    </script>
</body>
</html>

启动springboot
在这里插入图片描述

项目上传至:
1.sparkstreaming处理实时流: https://github.com/LUK-qianliu/sparktrain
2.springboot+echarts可视化: https://github.com/LUK-qianliu/springboot1

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值