基于dubbo+RocketMQ+springboot的简单埋点系统

2023-11-17

1:整体架构流程

2:目录详情

  • consumer 消息消费者项目
  • provider 方法提供者项目
  • mq RocketMQ项目
  • point 打点接口项目

3:关键代码详解

3.1:mq项目

mq.properties

mq.defaultmqgroup=xd-mq-group   //默认消息组名称
mq.namesrvaddr=localhost:9876   //rocketMQ地址,这里我用的是window docker启用的,具体说明在下面
mq.instancename=xd-rmq-instance 
复制代码

PdBaseMqService

用于初始化RocketMQ 服务 和 提供生成消息方法

// 从配置文件中获取
Resource resource = new ClassPathResource("mq.properties");
Properties p = new Properties();

try {
   p.load(resource.getInputStream());
} catch (IOException e) {
   logger.error("配置文件异常");
}

producer = new DefaultMQProducer(String.valueOf(p.getProperty("mq.defaultmqgroup")));
producer.setNamesrvAddr(String.valueOf(p.getProperty("mq.namesrvaddr")));
producer.setInstanceName(String.valueOf(p.getProperty("mq.instancename")));

try {
   producer.start();
   producer.setRetryTimesWhenSendAsyncFailed(2);
   logger.info("MQ生产者,Producer Started...");
} catch (Exception e) {
   logger.error("MQ生产者,异常:" + e.getMessage(), e);
}
复制代码
try {

   Message message = new Message(topic, tags, JSON.toJSONString(object).getBytes());
   logger.info("MQ生产者,【异步】发送消息:topic=" + topic + ",tags=" + tags);

   // 异步发送
   producer.send(message, new SendCallback() {
      @Override
      public void onSuccess(SendResult sendResult) {
         //logger.info("消息发送结果:result=" + sendResult.getSendStatus().name() + ",msgId=" + sendResult.getMsgId());
      }

      @Override
      public void onException(Throwable e) {
         logger.error("消息发送结果,异常了:" + e.getMessage(), e);
      }
   }, TIMEOUT);

} catch (Exception e) {
   logger.error("MQ生产者,发送消息,异常:" + e.getMessage(), e);
   return false;
}
复制代码

ProducerMqService

定义 RocketMQ的Topic 和 Tag 及发送消息的方法

// 定义主题,一般一个项目,使用同一个
public static String TOPIC = "XdTopic";

//================================
// 定义Tag,实际业务
//================================
/**
 *  应用事件打点
 */
public static String TAG_DOT_APP_EVENT_HIS = "tagDotAppEventHis";

public boolean sendDotAppEventHis(DotAppEventHisVo dotAppEventHisVo);
复制代码

ProducerMqServiceImpl

执发送消息的方法

@Override
public boolean sendDotAppEventHis(DotAppEventHisVo dotAppEventHisVo) {
   try {
      return PdBaseMqService.sendMsg(ProducerMqService.TOPIC, ProducerMqService.TAG_DOT_APP_EVENT_HIS, dotAppEventHisVo);
   } catch (Exception e) {
      logger.error("mq异步化:应用事件打点异常:" + e.getMessage(), e);
      return false;
   }
}
复制代码

3.2:provider方法提供者

ProducerMqServiceImpl

providers.xml dubbo xml方式封装方法

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

   <!-- 配置可参考 http://dubbo.io/User+Guide-zh.htm -->
   <!-- 服务提供方应用名,用于计算依赖关系 -->
   <dubbo:application name="dubbo-provider" owner="dubbo-provider" />

   <!-- 定义 zookeeper 注册中心地址及协议 -->
   <dubbo:registry protocol="zookeeper" address="localhost:2181" client="zkclient" />

   <!-- 定义 Dubbo 协议名称及使用的端口,dubbo 协议缺省端口为 20880,如果配置为 -1 或者没有配置 port,则会分配一个没有被占用的端口 -->
   <dubbo:protocol name="dubbo" port="-1" />

   <!-- 实际业务 -->
   <dubbo:service interface="com.xd.mq.service.ProducerMqService" ref="producerMqService" timeout="10000" />
   <bean id="producerMqService" class="com.xd.mq.service.impl.ProducerMqServiceImpl" />

</beans>
复制代码

**注意:zookeeper 我用的是本地环境,换为你们的zookeeper即可 **

3.3:point打点项目

ProducerMqServiceImpl

consumers.xml 注册使用dubbo的方法

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
       
   <!-- 配置可参考 http://dubbo.io/User+Guide-zh.htm -->
   <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
   <dubbo:application name="md-webapi-dus" owner="md-webapi-dus" />
   
   <!-- 定义 zookeeper 注册中心地址及协议 -->
   <dubbo:registry protocol="zookeeper" address="localhost:2181" client="zkclient" />
   
   <!-- 实际业务 -->
   <dubbo:reference id="producerMqService" interface="com.xd.mq.service.ProducerMqService" />
   
</beans>
复制代码

3.2:consumer消费者

ConsumerMqServiceImpl 订阅消息

package com.xd.consumer.service.impl;

![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b7f657ba58ad4eeb981a4471acd14122~tplv-k3u1fbpfcp-watermark.image?)
import com.google.gson.Gson;
import com.xd.consumer.base.CmBaseMqService;
import com.xd.mq.service.ProducerMqService;
import com.xd.mq.vo.DotAppEventHisVo;
import com.xd.consumer.service.ConsumerMqService;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * MQ消费者
 *
 * @author Minbo
 */
@Service
public class ConsumerMqServiceImpl implements ConsumerMqService {

    protected static Logger logger = LoggerFactory.getLogger(com.xd.consumer.service.impl.ConsumerMqServiceImpl.class);

    @Override
    public boolean consume() {
        try {
            DefaultMQPushConsumer consumer = CmBaseMqService.getConsumer();
            // 订阅所有消息
            consumer.subscribe(ProducerMqService.TOPIC, "*");
            logger.info("消费者,订阅所有消息");

            consumer.registerMessageListener(new MessageListenerConcurrently() {
                public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                                                                ConsumeConcurrentlyContext context) {
                    for (MessageExt msg : msgs) {
                        Gson gson = new Gson();

                        logger.info("消费者,准备消费消息:tag= " + msg.getTags());

                        // 区分不同Tag,不同处理方式
                        switch (msg.getTags()) {
                            // 应用事件打点
                            case ProducerMqService.TAG_DOT_APP_EVENT_HIS:
                                DotAppEventHisVo dotAppEventHisVo = gson.fromJson(new String(msg.getBody()),
                                        DotAppEventHisVo.class);
                                logger.info("消费消息:得到内容为:" + dotAppEventHisVo.toString());
                                break;
                            default:
                                logger.error("无处理类型,请检查。tag=" + msg.getTags(), new RuntimeException("未知Tag类型"));
                                break;
                        }
                    }
                    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                }
            });

            consumer.start();
            logger.info("消费者,启动成功...");

        } catch (Exception e) {
            logger.error("消费者,启动异常:" + e.getMessage(), e);
        }
        return true;
    }
}
复制代码

注意事项: 需要自己备好 RocketMQ 和 zookeeper的调用地址,我是window用docker运行的打包镜像运行的,这两个地址需要更换成自己的 本次工程也已上传到 github,看这里:dus-system

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于dubbo+RocketMQ+springboot的简单埋点系统 的相关文章

随机推荐

  • 求n边形周长的k等分点坐标(今日头条)

    题目 本题来自今天头条的笔试 有一个n边形 P0 P1 Pn 每一条边皆为垂直或水平线段 现给定数值k 以P0为起点将n边形的周长分为k段 每段的长度相等 请打印出k等分点的坐标 T0 T1 Tk 的坐标 分析 1 可以计算出从第0个点 到
  • 线程池ExecutorService

    1 线程池创建方式 1 通过Executors创建线程池 import java util concurrent ExecutorService import java util concurrent Executors public cl
  • Ubuntu18.04未安装Qt报qt.qpa.plugin could not load the Qt platform plugin xcb问题的解决方法

    在Ubuntu 18 04开发机上安装了Qt 5 14 2 当将其可执行程序拷贝到另一台未安装Qt的Ubuntu 18 04上报错 拷贝可执行程序前 使用ldd将此执行程序依赖的动态库也一起拷贝过去 包括Qt5 14 2 5 14 2 gc
  • JS ES6 单链表2种插入尾部方式

    一种是类里加一个指向尾部最后一个元素指针 通过他添加一个元素到队列最后 一种是每次增一个元素都从头开始遍历直到最后一个 然后添加 打开出来有单链表结构是一样的 除了上面的 多了一个队尾指针 class Node 单个结点 data next
  • Cadence 生成gerber文件,嘉立创下单助手解析不了PCB板的问题

    概述 最近由于公司的原因 使用Cadence EDA工具绘制一块 TMC2300电机驱动板 遇到一些问题 在这记录一下坑 也方便遇到这个问题的硬件攻城狮得到解决 1 EDA Cadence 17 4 在生成gerber文件时 使用CAM35
  • type_traits技术与C++

    引言 一个方法实现过程中 业务逻辑很多都是相似的 但是与具体的特化类型的不同有一定的差异 这个时候可以采用特化模板的方式实现 不同的类型使用不同的特化实现 但是这种情况造成一定的业务逻辑的冗余 而trait技术可以将特化类型通过封装 以一个
  • windows10进行Colmap配置

    colmap下载 https demuc de colmap 新的colmap按照官网的编译方式仅需要预装好CMake Boost QT5 CUDA和CGAL 1 CMake CMake安装最简单 去官网下载好压缩包解压即可 建议下载新版
  • 使用sentencepiece模型替换词表

    最近在用DeBERTa模型跑一些下游任务 了解到了sentencepiece模型 用于替代预训练模型中的词表 sentencepiece 是google开源的文本Tokenzier工具 本身提供四种切分方法 包括 char word byt
  • Python爬虫三国演义

    爬取三国全篇内容 定位目标 https www shicimingju com book sanguoyanyi html 在这里插入代码片import requests from bs4 import BeautifulSoup f op
  • 100天精通Python(可视化篇)——第86天:matplotlib绘制不同种类炫酷热力图参数说明+代码实战

    文章目录 专栏导读 一 热力图介绍 1 介绍 2 参数说明 二 绘制热力图 1 普通热力图 2 添加坐标轴和标题 3 添加热力标尺 4 添加色块数值
  • 虚析构和纯虚析构

    问题 多态使用时 如果子类中有属性开辟到堆区 那么父类指针在释放时无法调用到子类的析构代码 解决方式 将父类的析构改为虚析构或纯虚析构 可以解决父类指针释放子类对象 都需要具体的实现函数 虚析构和纯虚析构的区别 如果是纯虚析构 该类属于抽象
  • 【踩坑】解决maven的编译报错Cannot connect to the Maven process. Try again later

    背景 新公司新项目 同事拷给我maven的setting配置文件 跑项目编译发现maven报 Cannot connect to the Maven process Try again later If the problem persis
  • 你了解Spring BeanFactoryAware嘛

    其实再写这篇文章之前呢 我是看Spring IOC源码 可是老师啃不动 那么就从外围开始吧 在Spring生命周期的探索当中 其中网上主流的做法就是让我们的Bean实现一大波接口 到目前为止 这些接口的名称一个也没有记住 Spring的这个
  • Redis分片

    目录 一 Redis为什么要分片 二 分布式存储的特性 三 分片方案 1 范围分片 优点 缺点 2 hash节点取余分区 3 一致性hash分区 一 Redis为什么要分片 一般你系统核心缓存的命中率需维持在99 甚至99 9 哪怕下降1
  • JavaScript函数 - 简介与示例代码

    JavaScript是一种广泛应用于Web开发的脚本语言 它具备强大的函数功能 函数是JavaScript中的一个核心概念 它允许您封装可重复使用的代码块 并通过调用函数来执行特定的操作 本文将介绍JavaScript函数的基本概念 并提供
  • java程序员经典错误,请速速收藏

    大家好 我是鱼尾 作为一名 java 开发程序员 不知道大家有没有遇到过一些匪夷所思的bug 有时候在我们碰到错误的时候 可能会花几个小时才能解决 然而当你找到它们的时候 你可能会默默地骂自己是个傻瓜 因为这些可笑的 bug 基本上都是你忽
  • Entry输入框实现登录用户名冷却验证小案例(Tkinter)

    本篇讲一下Entry冷却验证的用法 其实我们在登录注册的时候用户名是否存在的验证一般不能等到全部都填写完后 点击注册再进行判断 最好的办法是在输入用户名时就立刻判断是否存在 这篇内容是在上一篇合法性验证的基础上的升级版 点击查看上一篇 实现
  • XSS数据接收平台——蓝莲花(BlueLotus)

    文章目录 一 前言 二 安装 三 使用 1 我的JS创建一个模板 2 使用创建的模板攻击 3 打开攻击的目标 这里选择pikachu靶场的存储型XSS模块测试 4 查看返回的数据 一 前言 蓝莲花平台是清华大学曾经的蓝莲花战队搭建的平台 该
  • 适合教孩子编码的 7 款免费编程语言

    21CTO导读 计算机编程是一项需求旺盛且欣欣向荣的事业 所以这些日子父母们可能都希望他们的孩子长大后也能成为一名软件程序员 如果想教小孩如何编程 该从哪儿开始呢 可以尝试以下列表中这些对儿童友好的编程语言以及工具 Scratch 海风教育
  • 基于dubbo+RocketMQ+springboot的简单埋点系统

    1 整体架构流程 2 目录详情 consumer 消息消费者项目 provider 方法提供者项目 mq RocketMQ项目 point 打点接口项目 3 关键代码详解 3 1 mq项目 mq properties mq defaultm