11.亿级流量电商详情页系统实战--lua发送访问量到kafka,strom进行统计

新建eshop-strom项目

1、kafka consumer spout

单独的线程消费,写入队列

nextTuple,每次都是判断队列有没有数据,有的话再去获取并发射出去,不能阻塞

2、日志解析bolt

3、商品访问次数统计bolt

基于LRUMap完成统计

1、storm task启动的时候,基于分布式锁将自己的taskid累加到一个znode中

2、开启一个单独的后台线程,每隔1分钟算出top3热门商品list

3、每个storm task将自己统计出的热数据list写入自己对应的znode中

1.服务启动的时候,进行缓存预热
2.从zk中读取taskid列表
3.一次遍历每个taskid,尝试获取分布式锁,如果获取不到,快速报错,不要等待,因为说明已经其他服务实例在预热了
4.直接尝试获取下一个taskid的分布式锁
5.即时获取到了分布式锁,也要检查一下这个taskid的预热状态,如果已经被预热过了,就不要再预热
6,执行预热操作,遍历productid列表,查询数据,然后写ehcache和redis
7.预热完成后,设置taskid对应的预热状态

在这里插入图片描述
将项目eshop-storm mvn package,打包产生

storm jar eshop-storm-0.0.1-SNAPSHOT.jar com.example.eshop.storm.HotProductTopology HotProductTopology

停止

storm kill HotProductTopology

执行zkCli.sh进入到zk客户端中

执行命令get

[zk: localhost:2181(CONNECTED) 0] get
ZooKeeper -server host:port cmd args
        stat path [watch]
        set path data [version]
        ls path [watch]
        delquota [-n|-b] path
        ls2 path [watch]
        setAcl path acl
        setquota -n|-b val path
        history 
        redo cmdno
        printwatches on|off
        delete path [version]
        sync path
        listquota path
        rmr path
        get path [watch]
        create [-s] [-e] path data acl
        addauth scheme auth
        quit 
        getAcl path
        close 
        connect host:port
[zk: localhost:2181(CONNECTED) 1] 


查看/taskid-list节点

[zk: localhost:2181(CONNECTED) 1] get /taskid-list
4,5   ---- 发现节点是4和5
cZxid = 0x700000785
ctime = Wed Aug 24 21:07:59 CST 2022
mZxid = 0x7000007a0
mtime = Wed Aug 24 21:08:09 CST 2022
pZxid = 0x700000785
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0

在这里插入图片描述

执行步骤 1

1.启动三台节点的zk集群
2.启动三台节点的kafka集群

我的启动脚本是放在了node1上

sh start-zk.sh
sh start-kafka.sh

在node1上执行

storm nimbus >/dev/null 2>&1 &

然后在node1、node2、node3上执行

storm supervisor >/dev/null 2>&1 &

然后为了查看三个节点的日志输出,需要在node1、node2、node3上执行

storm logviewer >/dev/null 2>&1 &

然后在node1节点上启动界面

storm ui >/dev/null 2>&1 &

执行步骤2

将eshop-strom 编译打包产生jar,并将jar上传到node1的/usr/local下

[root@node1 local]# cd /usr/local/
[root@node1 local]# ll |grep storm
-rw-r--r--.  1 root root  27941176 8月  26 11:26 eshop-storm-0.0.1-SNAPSHOT.jar
drwxr-xr-x. 13 root root       268 8月  10 14:22 storm
[root@node1 local]# 
将jar丢入到storm中
[root@node1 local]# storm jar eshop-storm-0.0.1-SNAPSHOT.jar com.example.eshop.storm.HotProductTopology HotProductTopology

启动以后,访问界面

http://10.1.218.22:8080/index.html
在这里插入图片描述
点击HotProductTopology进去
在这里插入图片描述在这里插入图片描述

在node1上,登录zkCli.sh

[zk: localhost:2181(CONNECTED) 0] get /taskid-list
4,5
cZxid = 0x800000d3b
ctime = Fri Aug 26 12:16:41 CST 2022
mZxid = 0x800000d45
mtime = Fri Aug 26 12:16:43 CST 2022
pZxid = 0x800000d3b
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0

如果之前已经启动过storm,运行过jar程序,那么/staskid-list会有历史数据 在启动jar程序以前,可以删除该节点

rmr /taskid-list
退出zkCli 用命令quit

正常情况,应该是访问nginx请求,由nginx的lua脚本发送访问产品的消息到kafka的topic :access-log中,lua发送出来的消息格式为:
在这里插入图片描述
,但是由于我本地lua脚本发送的消息,无法到达kafka,所以,改为手动发送模拟消息到kafka上

   public static void main(String[] args) throws IOException {
        Properties props = new Properties();

        props.put("serializer.class", "kafka.serializer.StringEncoder");
        props.put("metadata.broker.list", "10.1.218.22:9092");

        ProducerConfig producerConfig = new ProducerConfig(props);

        Producer kafkaProducer = new Producer(producerConfig);


        // Use random partitioner. Don't need the key type. Just set it to Integer.
        // The message is of type String.

        JSONObject message = new JSONObject();
        JSONObject productId = new JSONObject();
        productId.put("productId", 2);
        message.put("uri_args", productId);


        kafkaProducer.send(new KeyedMessage("access-log", JSONObject.toJSONString(message)));

        kafkaProducer.close();
        System.in.read();

    }

查看storm日志,发现已经开始统计了
在这里插入图片描述 业务流程: 1.请求发送到nginx,nginx的lua脚本发送请求商品的消息,到kafka,strom消费kafka中消息,并统计每个商品的访问次数,将热门商品id保存到zk中
2.storm的ProductCountBolt任务,每个任务启动,都会将自己的任务id追加添加到zk的/taskid-list节点中,例如我们设置了2个ProductCountBolt任务,则/taskid-list 保存为[4,5],每个ProductCountBolt任务zk中创建热门商品节点/ask-hot-product-list-{taskid}
例如:/task-hot-product-list-4 [3,5,7]
/task-hot-product-list-5 [2,4,6]
3.通过controller的方式,预热处理/task-hot-product-list-4、/task-hot-product-list-5节点的热门商品,将产品信息保存到redis和local cache中

git地址

https://gitee.com/yanweiling/redis-eshop-struct.git
预热入口 CacheTestController .prewarm()
热门商品统计 strom程序:eshop-storm

shell脚本


start-zk.sh内容
#!/bin/bash
for I in {node1,node2,node3}
do
echo "$I 上的zk 正在启动"
ssh root@$I "source /etc/profile; /usr/local/zk/bin/zkServer.sh start"
echo "$I 上的zk 启动成功"
done

--------------------------------------
 start-kafka.sh内容
#!/bin/bash
KAFKA_HOME=/usr/local/kafka
for number in {1..3}
do
   host=node${number}
   echo ${host}
    /usr/bin/ssh ${host} "cd ${KAFKA_HOME};source /etc/profile;${KAFKA_HOME}/bin/kafka-server-start.sh ${KAFKA_HOME}/config/server.properties >>/dev/null 2>&1 &"
        echo "${host} started"
done


stop-zk.sh

#!/bin/bash
for I in {node1,node2,node3}
do
echo "$I 上的kafka 正在关闭"
ssh root@$I "source /etc/profile;  /usr/local/zk/bin/zkServer.sh stop"
echo "$I 上的kafka 关闭完成"
done

stop-kafka.sh

#!/bin/bash
KAFKA_HOME=/usr/local/kafka
for number in {1..3}
do
   host=node${number}
   echo ${host}
    /usr/bin/ssh ${host} "cd ${KAFKA_HOME};source /etc/profile;${KAFKA_HOME}/bin/kafka-server-stop.sh"
   echo "${host} stoped"
done

start-redis-cluster.sh

#!/bin/bash
for number in {1..3}
do
echo "关闭 node${number}上的redis port 6379"
 server=node${number}
declare -i num1=$number*2-1
declare -i num2=$number*2
port1="700$num1"
port2="700$num2"
echo "${server}"
echo $port1 $port2
ssh root@$server "redis-cli -p 6379 -a 123456 shutdown"
ssh root@$server "cd /etc/init.d;./redis_$port1 start;./redis_$port2 start "
done

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值