从这篇内容开始就是项目的正式过程了,接下来我将以思路和项目过程为主来进行讲解,部分过程我也会对代码部分内容进行讲解。

前提条件:

对应的hadoop集群要有,具体配置方法和版本见第一节内容;phoenix、clickhouse、springboot、redis等框架的使用,我会在用到的时候再介绍,也可以自己根据下载包里的文档内容进行了解,文章不做详细介绍。

第一部分 日志采集

日志生成这里采用模拟jar包的方式,参数调整在对应的application.yml中进行:

//以下为需要主要调整的内容,修改为当天的日期以及对应的地址,注意,需要和Springboot程序中的接收地址保持一致;
mock.date: "2021-07-22"
  #模拟数据发送模式
mock.type: "http"
  #http模式下,发送的地址
mock.url: "http://hadoop102/applog"

//以下内容可修改或者不修改都可以,可以根据自己的数据量要求来完成操作;
#启动次数
mock.startup.count: 1000
  #设备最大值
mock.max.mid: 20
  #会员最大值
mock.max.uid: 50
  #商品最大值
mock.max.sku-id: 10
  #页面平均访问时间
mock.page.during-time-ms: 20000
  #错误概率 百分比
mock.error.rate: 3
  #每条日志发送延迟 ms
mock.log.sleep: 100
  #商品详情来源  用户查询,商品推广,智能推荐, 促销活动
mock.detail.source-type-rate: "40:25:15:20"

#领取购物券概率
mock.if_get_coupon_rate: 75

#购物券最大id
mock.max.coupon-id: 3

  #搜索关键词  
mock.search.keyword: "图书,小米,iphone11,电视,口红,ps5,苹

接下来是日志采集Springboot程序的编写:

@RestController
@Slf4j
public class LoggerController {

    //KafkaTemplate是Spring提供对kafka操作的类

    @Autowired //注入,创建对应的对象;
    //KafkaTemplate是Spring框架提供的;
    KafkaTemplate kafkaTemplate;

    @RequestMapping("/applog") //与发送的请求保持一致;
    //jar包参数已经写死了,就叫param;这里接收到param的内容,然后传给jsonLog;
    //对应的windows地址为:10.242.151.3  //  开启cmd,输入ipconfig命令后,找到IPv4 地址 . . . . . . . . . . . . : 10.242.151.3(因人而异);
    //jar包输出数据的位置就为http://10.242.151.3/applog
    public String logger(@RequestParam("param") String jsonLog){
        //1.打印输出到控制台
        //System.out.println(jsonLog);
        //2.落盘   借助记录日志的第三方框架 log4j [logback]
        log.info(jsonLog);
        //3.将生成的日志发送到kafka对应的主题中
       kafkaTemplate.send("ods_base_log",jsonLog);
        return "success";
    }
}

//这是一个很简单的Springboot程序

//对应的application.properties文件内容:
# 应用名称
spring.application.name=gmall-logger
# 应用服务 WEB 访问端口
server.port=8081  //这里我推荐用8082端口,因为最后整个项目上传到Flink集群中运行时,8081端口会和Flink的端口号冲突;
//由于我的项目后续都是8081端口,所以这里我以8081端口来讲解;

#============== kafka ===================
# 指定kafka 代理地址,可以多个
spring.kafka.bootstrap-servers=hadoop102:9092

# 指定消息key和消息体的编解码方式
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer

//最后的lockback文件自己查看项目代码即可;
//需要注意的是:
    <property name="LOG_HOME" value="/opt/module/rt_gmall/gmall0709" />
//注意这里的value地址要在集群中对应位置创建目录来存放对应的log数据;

第一部分总结

这部分的主要目的是生成对应的日志文件,然后把日志数据发送到ods_base_log的kafka主题中,形成ods层的日志数据;

第二部分 Springboot程序部署和Nginx反向代理

首先将程序打包好,发送到集群中的3台服务器特定包下,比如/opt/module/rt_gmall包下,在此包下放入对应的打包好的程序;
开启测试:
开启zk、kafka,消费ods_base_log主题
开启rt_applog包下的日志生成jar包(自己提前创建好,jar包导入好,随便放在哪个服务器都行)
java -jar <你的包名> 运行jar包,如果主题中有数据,说明操作无误;

Nginx的一些配置说明

具体的配置过程自己参考文件即可,这里不做过多说明,唯一值得注意的点就是:

//在 server 外部配置做负载均衡
    //这个名字其实是可以随便定义的
    #gzip  on;

    upstream www.logserver.com{
        server hadoop102:8081 weight=1;
        server hadoop103:8081 weight=2;
        server hadoop104:8081 weight=3;
    }

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        location /applog {
            proxy_pass http://www.logserver.com;

//如果访问之前的listen的端口,就会跳转到对应的服务器内容上;
//注意配置文件中server的位置;

//注意加分号;
主要讲解一下Nginx在这里的作用:
这里Nginx是起到一个反向代理和负载均衡的作用,即代理服务器来接收数据,然后分发到不同的服务器上,这样就能有三台服务器来接收日志数据了;

Nginx和日志处理数据jar包群起群关脚本:

#!/bin/bash
JAVA_BIN=/opt/module/jdk1.8.0_212/bin/java
APPNAME=gmall-logger-0.0.1-SNAPSHOT.jar

case $1 in

"start"){
	for i in hadoop102 hadoop103 hadoop104
	do
		echo "========: $i==============="
		ssh $i "$JAVA_BIN -Xms32m -Xmx64m -jar /opt/module/rt_gmall/$APPNAME >/dev/null 2>&1 &"
 	done
	echo "========NGINX==============="
 	/opt/module/nginx/sbin/nginx
};;
 
"stop"){
    echo "======== NGINX==============="
 	/opt/module/nginx/sbin/nginx -s stop
 	for i in hadoop102 hadoop103 hadoop104
 	do
 		echo "========: $i==============="
 		ssh $i "ps -ef|grep $APPNAME |grep -v grep|awk '{print \$2}'|xargs kill" >/dev/null 2>&1
	done
};;
esac

通过log.sh start来启动脚本,注意我的脚本存放在/usr/local/bin目录下,个人电脑不尽不同,放到自己的环境变量目录下即可;

hadoop102上包括applog目录,这里存着的是数据生成jar包;

三台服务器上都有rt_gmall目录,保存着生成的log以及接收处理jar包;

都发送至102服务器的kafka节点来接收数据;

后续只要需要开启102的consumer、群起脚本和生成数据jar包即可,不用再去每台服务器单独启动脚本;

kafka可能故障处理

进入zookeeper中,bin/zkCli.sh开启zookeeper客户端;找到/brokers/ids文件,如果kafaka起不来但这里有数据,删除掉这里的数据;
再进入到kafka目录下的/opt/module/kafka/logs中,找到meta.properties文件,删除掉对应的文件再启动;

还不能启动看日志;处理不了再删除掉datas、logs目录和zookeeper中的brokers目录;

第三部分 业务数据的生成

业务数据这里同样采用jar包方式生成:

logging.level.root=info


spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://hadoop102:3306/gmall0709?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root

logging.pattern.console=%m%n


mybatis-plus.global-config.db-config.field-strategy=not_null

#这里唯一要注意的就是mysql的地址位置和数据库的名字,具体配置过程见参考文档,用户名和密码也可以自己定;

#建议把以下内容数据调下一点,否则运行起来会非常慢,不利于项目测试,在后续要多次运行该脚本;

但是如果直接这样做,数据就全部发送到了mysql上,而我们的目的是为了把数据发送到集群中以及kafka主题中,所以这里采用了maxwell工具;
Maxwell通过监控MySql中的binlog文件,当有数据变动时,Maxwell可以从MySql中去复制数据,从而保证数据同步,然后发送到kafka主题中,我的Maxwell配置如下(仅供参考):

Maxwell配置

//bin/maxwell-bootstrap可以采集历史数据;

首先复制一个config.properties.example文件为config.properties文件,修改config.properties内容:
    
producer=kafka
kafka.bootstrap.servers=hadoop102:9092,hadoop103:9092,hadoop104:9092
#需要添加
kafka_topic=ods_base_db_m
# mysql login info
host=hadoop102
user=maxwell
password=123456
#需要添加 后续初始化会用
client_id=maxwell_1
    
    //同步历史数据的时候会用到client_id=maxwell_1配置;后续还要再创建一个user=maxwell用户;
    
    接下来初始化Maxwell元数据库;
    
➢ 在 MySQL 中建立一个 maxwell 库用于存储 Maxwell 的元数据
[atguigu@hadoop202 module]$ mysql -uroot -p root
mysql> CREATE DATABASE maxwell ;
➢ 设置安全级别
mysql> set global validate_password_length=4;
mysql> set global validate_password_policy=0; //这里可能会报错;
➢ 分配一个账号可以操作该数据库
mysql> GRANT ALL ON maxwell.* TO 'maxwell'@'%' IDENTIFIED BY '123456';
//记住maxwell用户的密码是123456;
➢ 分配这个账号可以监控其他数据库的权限
mysql> GRANT SELECT ,REPLICATION SLAVE , REPLICATION CLIENT ON *.* TO maxwell@'%';


//kafka的分区都为4,这里要用到分区提高并行度的话,需要在maxwell的配置文件中的*** partitioning ***模块中添加内容:
producer_partition_by=primary_key
    
    //启动时指定配置文件:
    bin/maxwell --config config.properties
    //为了方便,这里写了一个脚本maxwell.sh
/opt/module/maxwell/bin/maxwell --config /opt/module/maxwell/config.properties >/dev/null 2>&1 &

Maxwell采集测试

//开启业务数据生成脚本;
//开启nginx脚本(包括了Springboot程序)
//开启consumer:
[@hadoop202 kafka]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic ods_base_db_m

//检测到数据说明配置成功

总结

在这一流程中,我们的工作详解如图所示:

Flink 搭建实时数仓 flink实时数仓项目实战_Flink 搭建实时数仓


通过这张图,可以很明显地看出我们是如何把数据保存在了对应的kafka主题中地;