SpringBoot整合阿里云RocketMQ对接,商业版

news2024/11/15 21:37:06

1.需要阿里云开通商业版RocketMQ

普通消息新建普通主题,普通组,延迟消息新建延迟消息主题,延迟消息组

2.结构目录

在这里插入图片描述

3.引入依赖

<!--阿里云RocketMq整合-->
        <dependency>
            <groupId>com.aliyun.openservices</groupId>
            <artifactId>ons-client</artifactId>
            <version>1.8.8.5.Final</version>
        </dependency>

4.延迟消息配置

import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.batch.BatchMessageListener;
import com.aliyun.openservices.ons.api.bean.BatchConsumerBean;
import com.aliyun.openservices.ons.api.bean.Subscription;
import com.atkj.devicewx.config.MqConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 延迟消息配置类
 */
@Configuration
public class BatchConsumerClient {

    @Autowired
    private MqConfig mqConfig;

    @Autowired
    private BatchDemoMessageListener messageListener;

    @Bean(initMethod = "start", destroyMethod = "shutdown")
    public BatchConsumerBean buildBatchConsumer() {
        BatchConsumerBean batchConsumerBean = new BatchConsumerBean();
        //配置文件
        Properties properties = mqConfig.getMqPropertie();
        properties.setProperty(PropertyKeyConst.GROUP_ID, mqConfig.getDelayGroupId());
        //将消费者线程数固定为20个 20为默认值
        properties.setProperty(PropertyKeyConst.ConsumeThreadNums, "20");
        batchConsumerBean.setProperties(properties);
        //订阅关系
        Map<Subscription, BatchMessageListener> subscriptionTable = new HashMap<Subscription, BatchMessageListener>();
        Subscription subscription = new Subscription();
        subscription.setTopic(mqConfig.getDelayTopic());
        subscription.setExpression(mqConfig.getDelayTag());
        subscriptionTable.put(subscription, messageListener);
        //订阅多个topic如上面设置
        batchConsumerBean.setSubscriptionTable(subscriptionTable);
        return batchConsumerBean;
    }

}

import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.batch.BatchMessageListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 延迟消息消费者
 */
@Slf4j
@Component
public class BatchDemoMessageListener implements BatchMessageListener {

    @Override
    public Action consume(final List<Message> messages, final ConsumeContext context) {
        log.info("消费者收到消息大小:"+messages.size());
        for (Message message : messages) {
            byte[] body = message.getBody();
            String s = new String(body);
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String formatTime = sdf.format(date);
            System.out.println("接收到消息时间:"+formatTime);
            log.info("接收到消息内容:"+s);
        }
        try {
            //do something..
            return Action.CommitMessage;
        } catch (Exception e) {
            //消费失败
            return Action.ReconsumeLater;
        }
    }
}

5.MQ配置类


import com.aliyun.openservices.ons.api.PropertyKeyConst;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

@Data
@Configuration
@ConfigurationProperties(prefix = "rocketmq")
public class MqConfig {

    private String accessKey;
    private String secretKey;
    private String nameSrvAddr;
    private String topic;
    private String groupId;
    private String tag;
    private String orderTopic;
    private String orderGroupId;
    private String orderTag;
    private String delayTopic;
    private String delayGroupId;
    private String delayTag;

    public Properties getMqPropertie() {
        Properties properties = new Properties();
        properties.setProperty(PropertyKeyConst.AccessKey, this.accessKey);
        properties.setProperty(PropertyKeyConst.SecretKey, this.secretKey);
        properties.setProperty(PropertyKeyConst.NAMESRV_ADDR, this.nameSrvAddr);
        return properties;
    }

}

6.YML配置

## 阿里云RocketMQ配置
rocketmq:
  accessKey: laskdfjlaksdjflaksjdflaksdjflakdjf
  secretKey: asdfasdlfkasjdlfkasjdlfkajsdlkfjkalksdfj
  nameSrvAddr: rmq..rmq.acs.com:8080
  topic: topic_lsdjf_test
  groupId: Glskdfjalsdkfjalksdjflaksdfj_push
  tag: "*"
  orderTopic: XXX
  orderGroupId: XXX
  orderTag: "*"
  delayTopic: topic_alskdjfalksdjflksdjfkla_delay
  delayGroupId: GIlaskdjflkasdjflkajsdkf_delay
  delayTag: "*"

7.普通消息配置

import com.aliyun.openservices.ons.api.MessageListener;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.bean.ConsumerBean;
import com.aliyun.openservices.ons.api.bean.Subscription;
import com.atkj.devicewx.config.MqConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;


/**
 * 普通消息配置类
 */
@Configuration
public class ConsumerClient {

    @Autowired
    private MqConfig mqConfig;

    @Autowired
    private DemoMessageListener messageListener;

    @Bean(initMethod = "start", destroyMethod = "shutdown")
    public ConsumerBean buildConsumer() {
        ConsumerBean consumerBean = new ConsumerBean();
        //配置文件
        Properties properties = mqConfig.getMqPropertie();
        properties.setProperty(PropertyKeyConst.GROUP_ID, mqConfig.getGroupId());
        //将消费者线程数固定为20个 20为默认值
        properties.setProperty(PropertyKeyConst.ConsumeThreadNums, "20");
        consumerBean.setProperties(properties);
        //订阅关系
        Map<Subscription, MessageListener> subscriptionTable = new HashMap<Subscription, MessageListener>();
        Subscription subscription = new Subscription();
        subscription.setTopic(mqConfig.getTopic());
        subscription.setExpression(mqConfig.getTag());
        subscriptionTable.put(subscription, messageListener);
        //订阅多个topic如上面设置

        consumerBean.setSubscriptionTable(subscriptionTable);
        return consumerBean;
    }

}


import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 普通主题消费者
 */
@Component
@Slf4j
public class DemoMessageListener implements MessageListener {

    @Override
    public Action consume(Message message, ConsumeContext context) {

        log.info("接收到消息: " + message);
        try {
            byte[] body = message.getBody();
            String s = new String(body);
            log.info("接收到消息字符串:"+s);
            //Action.CommitMessag 进行消息的确认
            return Action.CommitMessage;
        } catch (Exception e) {
            //消费失败
            return Action.ReconsumeLater;
        }
    }
}

import com.aliyun.openservices.ons.api.bean.ProducerBean;
import com.atkj.devicewx.config.MqConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 普通消息生产者配置类
 */
@Configuration
public class ProducerClient {

    @Autowired
    private MqConfig mqConfig;

    @Bean(initMethod = "start", destroyMethod = "shutdown")
    public ProducerBean buildProducer() {
        ProducerBean producer = new ProducerBean();
        producer.setProperties(mqConfig.getMqPropertie());
        return producer;
    }

}

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.SendResult;
import com.aliyun.openservices.ons.api.bean.ProducerBean;
import com.aliyun.openservices.ons.api.exception.ONSClientException;
import com.atkj.devicewx.config.MqConfig;
import org.springframework.stereotype.Component;

/**
 * 普通消息生产者
 *
 **/
@Component
public class RocketMessageProducer {
 
    private static ProducerBean producer;
    private static MqConfig mqConfig;
 
    public RocketMessageProducer(ProducerBean producer, MqConfig mqConfig) {
        this.producer = producer;
        this.mqConfig = mqConfig;
    }
 
    /**
     * @Description: <h2>生产 普通 消息</h2>
     * @author: LiRen
     */
    public  static void producerMsg(String tag, String key, String body) {
        Message msg = new Message(mqConfig.getTopic(), tag, key, body.getBytes());
        long time = System.currentTimeMillis();
        try {
            SendResult sendResult = producer.send(msg);
            assert sendResult != null;
            System.out.println(time
                    + " Send mq message success.Topic is:" + msg.getTopic()
                    + " Tag is:" + msg.getTag() + " Key is:" + msg.getKey()
                    + " msgId is:" + sendResult.getMessageId());
        } catch (ONSClientException e) {
            e.printStackTrace();
            System.out.println(time + " Send mq message failed. Topic is:" + msg.getTopic());
        }
    }
 
}
import com.aliyun.openservices.ons.api.*;
import com.atkj.devicewx.config.MqConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;

import java.util.Properties;

/**
 * 普通消息消费者
 */
//效果和 DemoMessageListener 一致
//@Component
public class RocketMQConsumer {
 
    @Autowired
    private MqConfig rocketMQConfig;
 
 
    /**
     * 1、普通订阅
     *
     * @param
     */
    @Bean //不加@Bean Spring启动时没有注册该方法,就无法被调用
    public void normalSubscribe( ) {
 
        Properties properties = rocketMQConfig.getMqPropertie();
 
        properties.put(PropertyKeyConst.GROUP_ID,rocketMQConfig.getGroupId());
 
        Consumer consumer = ONSFactory.createConsumer(properties);
        consumer.subscribe(rocketMQConfig.getTopic(), rocketMQConfig.getTag(), new MessageListener() {
            @Override
            public Action consume(Message message, ConsumeContext context) {
                System.out.println("Receive: " + new String(message.getBody()));
 
                //把消息转化为java对象
                //JSONObject jsonObject=JSONObject.parseObject(jsonString);
                //Book book= jsonObject.toJavaObject(Book.class);

                return Action.CommitMessage;
            }
        });
 
        consumer.start();
    }
}

7.order没用到


import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.bean.OrderConsumerBean;
import com.aliyun.openservices.ons.api.bean.Subscription;
import com.aliyun.openservices.ons.api.order.MessageOrderListener;
import com.atkj.devicewx.config.MqConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

//项目中加上 @Configuration 注解,这样服务启动时consumer也启动了
public class OrderConsumerClient {

    @Autowired
    private MqConfig mqConfig;

    @Autowired
    private OrderDemoMessageListener messageListener;

    @Bean(initMethod = "start", destroyMethod = "shutdown")
    public OrderConsumerBean buildOrderConsumer() {
        OrderConsumerBean orderConsumerBean = new OrderConsumerBean();
        //配置文件
        Properties properties = mqConfig.getMqPropertie();
        properties.setProperty(PropertyKeyConst.GROUP_ID, mqConfig.getOrderGroupId());
        orderConsumerBean.setProperties(properties);
        //订阅关系
        Map<Subscription, MessageOrderListener> subscriptionTable = new HashMap<Subscription, MessageOrderListener>();
        Subscription subscription = new Subscription();
        subscription.setTopic(mqConfig.getOrderTopic());
        subscription.setExpression(mqConfig.getOrderTag());
        subscriptionTable.put(subscription, messageListener);
        //订阅多个topic如上面设置

        orderConsumerBean.setSubscriptionTable(subscriptionTable);
        return orderConsumerBean;
    }

}


import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.order.ConsumeOrderContext;
import com.aliyun.openservices.ons.api.order.MessageOrderListener;
import com.aliyun.openservices.ons.api.order.OrderAction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class OrderDemoMessageListener implements MessageOrderListener {
    @Override
    public OrderAction consume(final Message message, final ConsumeOrderContext context) {
        log.info("接收到消息: " + message);
        try {
            //do something..
            return OrderAction.Success;
        } catch (Exception e) {
            //消费失败,挂起当前队列
            return OrderAction.Suspend;
        }
    }
}

import com.aliyun.openservices.ons.api.bean.OrderProducerBean;
import com.atkj.devicewx.config.MqConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 生产者配置类
 */
@Configuration
public class OrderProducerClient {

    @Autowired
    private MqConfig mqConfig;

    @Bean(initMethod = "start", destroyMethod = "shutdown")
    public OrderProducerBean buildOrderProducer() {
        OrderProducerBean orderProducerBean = new OrderProducerBean();
        orderProducerBean.setProperties(mqConfig.getMqPropertie());
        return orderProducerBean;
    }

}

8.事务消息没用到

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.transaction.LocalTransactionChecker;
import com.aliyun.openservices.ons.api.transaction.TransactionStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 事务消息
 */
@Slf4j
@Component
public class DemoLocalTransactionChecker implements LocalTransactionChecker {
    @Override
    public TransactionStatus check(Message msg) {
        log.info("开始回查本地事务状态");
        return TransactionStatus.CommitTransaction; //根据本地事务状态检查结果返回不同的TransactionStatus
    }
}

import com.aliyun.openservices.ons.api.bean.TransactionProducerBean;
import com.atkj.devicewx.config.MqConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 事务消息配置类
 */
@Configuration
public class TransactionProducerClient {

    @Autowired
    private MqConfig mqConfig;

    @Autowired
    private DemoLocalTransactionChecker localTransactionChecker;

    @Bean(initMethod = "start", destroyMethod = "shutdown")
    public TransactionProducerBean buildTransactionProducer() {
        TransactionProducerBean producer = new TransactionProducerBean();
        producer.setProperties(mqConfig.getMqPropertie());
        producer.setLocalTransactionChecker(localTransactionChecker);
        return producer;
    }

}

9.测试类


import com.aliyun.openservices.ons.api.*;
import com.aliyun.openservices.ons.api.exception.ONSClientException;
import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON;
import com.atkj.devicewx.config.MqConfig;
import com.atkj.devicewx.normal.RocketMessageProducer;
import com.atkj.devicewx.service.TestService;
import com.atkj.devicewx.vo.MetabolicVo;
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.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

/**
 * @Author: albc
 * @Date: 2024/07/12/10:22
 * @Description: good good study,day day up
 */
@RequestMapping("/api/v1/mq/test")
@RestController
public class TestController {


    @Autowired
    private TestService testService;


    @Autowired
    private MqConfig mqConfig;

    @RequestMapping("/one")
    public String testOne(){
        Integer count = testService.testOne();
        return "发送成功:"+count;
    }

    /**
     * 普通消息测试
     * @return
     */
    @RequestMapping("/useRocketMQ")
    public String useRocketMQ() {


        MetabolicVo metabolicVo = new MetabolicVo();
        metabolicVo.setAge(123);
        metabolicVo.setName("测试名字");
        metabolicVo.setWeight(75);
        RocketMessageProducer.producerMsg("123","666", JSON.toJSONString(metabolicVo));
        return "请求成功!";
    }

    /**
     * 发送延迟消息测试
     * @return
     */
    @RequestMapping("/delayMqMsg")
    public String delayMqMsg() {
        Properties producerProperties = new Properties();
        producerProperties.setProperty(PropertyKeyConst.AccessKey, mqConfig.getAccessKey());
        producerProperties.setProperty(PropertyKeyConst.SecretKey, mqConfig.getSecretKey());
        producerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, mqConfig.getNameSrvAddr());
        //注意!!!如果访问阿里云RocketMQ 5.0系列实例,不要设置PropertyKeyConst.INSTANCE_ID,否则会导致收发失败
        Producer producer = ONSFactory.createProducer(producerProperties);
        producer.start();
        System.out.println("生产者启动..........");

        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formatTime = sdf.format(date);

        String meg = formatTime + "发送延迟消息测试";
        Message message = new Message(mqConfig.getDelayTopic(), mqConfig.getDelayTag(), meg.getBytes());
        // 延时时间单位为毫秒(ms),指定一个时刻,在这个时刻之后才能被消费,这个例子表示 3秒 后才能被消费
        long delayTime = 3000;
        message.setStartDeliverTime(System.currentTimeMillis() + delayTime);
        try {
            SendResult sendResult = producer.send(message);
            assert sendResult != null;
            System.out.println(new Date() + "发送mq消息主题:" + mqConfig.getDelayTopic() + "消息id: " + sendResult.getMessageId());
        } catch (ONSClientException e) {
            // 消息发送失败,需要进行重试处理,可重新发送这条消息或持久化这条数据进行补偿处理
            System.out.println(new Date() + "重试发送mq消息主题:" + mqConfig.getDelayTopic());
            e.printStackTrace();
        }
        return "请求成功!";

    }

}

优化部分

每次发送消息都要创建生产者,效率低下
使用单例优化

import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Properties;

/**
 * 生产者单例
 * @Author: albc
 * @Date: 2024/07/15/15:49
 * @Description: good good study,day day up
 */
@Component
@Slf4j
public class ProducerSingleton {

    private volatile static Producer producer;

    private static String accessKey;
    private static String secretKey;
    private static String nameSrvAddr;

    private ProducerSingleton() {

    }

    @Value("${rocketmq.accessKey}")
    private void setAccessKey(String accessKey) {
        ProducerSingleton.accessKey = accessKey;
    }

    @Value("${rocketmq.secretKey}")
    private void setSecretKey(String secretKey) {
        ProducerSingleton.secretKey = secretKey;
    }

    @Value("${rocketmq.nameSrvAddr}")
    private void setNameSrvAddr(String nameSrvAddr) {
        ProducerSingleton.nameSrvAddr = nameSrvAddr;
    }

    /**
     * 创建生产者
     * @return
     */
    public static Producer getProducer(){
        if (producer == null){
            synchronized(ProducerSingleton.class){
                if (producer == null){
                    Properties producerProperties = new Properties();
                    producerProperties.setProperty(PropertyKeyConst.AccessKey, accessKey);
                    producerProperties.setProperty(PropertyKeyConst.SecretKey, secretKey);
                    producerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, nameSrvAddr);
                    //注意!!!如果访问阿里云RocketMQ 5.0系列实例,不要设置PropertyKeyConst.INSTANCE_ID,否则会导致收发失败
                    producer = ONSFactory.createProducer(producerProperties);
                    producer.start();
                    log.info("生产者启动........");
                }
            }
        }
        return producer;
    }

}


import com.aliyun.openservices.ons.api.*;
import com.aliyun.openservices.ons.api.exception.ONSClientException;
import com.atkj.devicewx.level.config.MqConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


/**
 * 延迟消息生产者
 *
 * @Author: albc
 * @Date: 2024/07/15/14:11
 * @Description: good good study,day day up
 */
@Slf4j
@Component
public class BatchMessageProducer {


    @Autowired
    private MqConfig mqConfig;


    /**
     * 发送消息
     * @param msg 发送消息内容
     * @param delayTime 延迟时间,毫秒
     */
    public void sendDelayMeg(String msg,Long delayTime) {
        Producer producer = ProducerSingleton.getProducer();
        Message message = new Message(mqConfig.getDelayTopic(), mqConfig.getDelayTag(), msg.getBytes());
        message.setStartDeliverTime(System.currentTimeMillis() + delayTime);
        try {
            SendResult sendResult = producer.send(message);
            assert sendResult != null;
            log.info( "发送mq消息主题:" + mqConfig.getDelayTopic() + "消息id: " + sendResult.getMessageId());
        } catch (ONSClientException e) {
            // 消息发送失败,需要进行重试处理,可重新发送这条消息或持久化这条数据进行补偿处理
            log.error("重试发送mq消息主题:" + mqConfig.getDelayTopic());
            e.printStackTrace();
        }finally {
            message = null;
        }
    }


}


其他不变

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1928612.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C language】扫雷

目录 1.概要2.实现核心思想3.实现过程3.1游戏框架3.2游戏逻辑初始化棋盘 MineInit打印棋盘 MinePrint设置雷 SetMines扫雷 ClearMines 4.总结 1.概要 为了提高C初学者对C语言基本语法的掌控能力&#xff0c;一个极简版的扫雷游戏是十分适合锻炼代码能力的。下面分享仅用数组、…

14_Shell重定向输入输出

14_Shell重定向输入输出 输出重定向&#xff1a;一般情况&#xff0c;输出是在终端直接显示&#xff0c;改变输出位置&#xff0c;改变到文件中&#xff0c;这就是输出重定向 输入重定向&#xff1a;一般情况&#xff0c;输入是读取用户终端输入&#xff0c;改变输入位置&#…

026-GeoGebra中级篇-曲线(2)_极坐标曲线、参数化曲面、分段函数曲线、分形曲线、复数平面上的曲线、随机曲线、非线性动力系统的轨迹

除了参数曲线、隐式曲线和显式曲线之外&#xff0c;还有其他类型的曲线表示方法。本篇主要概述一下极坐标曲线、参数化曲面、分段函数曲线、分形曲线、复数平面上的曲线、随机曲线、和非线性动力系统的轨迹&#xff0c;可能没有那么深&#xff0c;可以先了解下。 目录 1. 极坐…

VScode:前端项目中yarn包的安装和使用

一、首先打开PowerShell-管理员身份运行ISE 输入命令&#xff1a; set-ExecutionPolicy RemoteSigned 选择“全是”&#xff0c;表示允许在本地计算机上运行由本地用户创建的脚本&#xff0c;没有报错就行了 二、接着打开VScode集成终端 输入 npm install -g yarn 再次输入以下…

IoT数据采集网关在企业应用中扮演的角色-天拓四方

随着物联网&#xff08;IoT&#xff09;技术的不断发展&#xff0c;越来越多的企业开始利用IoT技术实现智能化、自动化的生产和管理。在这个过程中&#xff0c;Iot数据采集网关作为连接物理世界与数字世界的桥梁&#xff0c;发挥着至关重要的作用。 IoT数据采集网关是一种硬件…

4.定时器

原理 时钟源&#xff1a;定时器是内部时钟源&#xff08;晶振&#xff09;&#xff0c;计数器是外部计时长度&#xff1a;对应TH TL计数器初值寄存器(高八位,低八位)对应的中断触发函数 中断源中断处理函数Timer0Timer0_Routine(void) interrupt 1Timer1Timer1_Routine(void) …

c++初阶知识——类和对象(中)

目录 1.类的默认成员函数 2.构造函数 3.析构函数 4.拷贝构造函数 5.运算符重载 5.1 赋值运算符重载 5.2 使用运算符重载等特性实现日期类 6.取地址运算符重载 6.1 const成员函数 6.2 取地址运算符重载 1.类的默认成员函数 默认成员函数就是⽤⼾没有显式实现&#…

网站开发:使用VScode安装yarn包和运行前端项目

一、首先打开PowerShell-管理员身份运行ISE 输入命令&#xff1a; set-ExecutionPolicy RemoteSigned 选择“全是”&#xff0c;表示允许在本地计算机上运行由本地用户创建的脚本&#xff0c;没有报错就行了 二、接着打开VScode集成终端 输入 npm install -g yarn 再次输入以…

防火墙双机热备带宽管理综合实验

拓扑图和要求如下&#xff1a; 之前的步骤可以去到上次的实验 1.步骤一&#xff1a; 首先在FW3防火墙上配置接口IP地址&#xff0c;划分区域 创建心跳线&#xff1a; 下面进行双机热备配置&#xff1a; 步骤二&#xff1a; 先将心跳线连接起来 注意&#xff1a;一定要将心跳…

Django select_related()方法

select_related()的作用 select_related()是Django ORM&#xff08;对象关系映射&#xff09;中的一种查询优化方法&#xff0c;主要用于减少数据库查询次数&#xff0c;提高查询效率。当你在查询一个模型实例时&#xff0c;如果这个实例有ForeignKey关联到其他模型&#xff0…

Hadoop-29 ZooKeeper集群 Watcher机制 工作原理 与 ZK基本命令 测试集群效果 3台公网云服务器

章节内容 上节我们完成了&#xff1a; ZNode的基本介绍ZNode节点类型的介绍事务ID的介绍ZNode实机测试效果 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机上搭建过一次&#xff…

Python JSON处理:兼容性与高级应用

JSON&#xff08;JavaScript Object Notation&#xff09;作为当前最流行的数据传输格式&#xff0c;在Python中也有多种实现方式。由于JSON的跨平台性和简便易用性&#xff0c;它在数据交互中被广泛应用。本文将重点讨论如何熟练应用Python的JSON库&#xff0c;将JSON数据映射…

【区块链 + 智慧政务】中国铁塔区块链委托代征开票应用 | FISCO BCOS应用案例

中国铁塔是全球规模最大的通信铁塔基础设施服务提供者。通信塔站址点多面广&#xff0c;业主构成复杂&#xff0c;因此产生海量税务、合同、票据等信息。为进一步提高场租或供电取票的及时性和规范性&#xff0c;严格遵循税务相关的要求&#xff0c;中国铁塔采用国产开源联盟链…

python--实验12

目录 知识点 第一部分&#xff1a;文件概述 第二部分&#xff1a;文件的基本操作 第三部分&#xff1a;目录管理 第四部分&#xff1a;CSV文件读写 第五部分&#xff1a;openpyxl等模块 小结 实验 知识点 第一部分&#xff1a;文件概述 文件标识&#xff1a;找到计算机…

尚硅谷大数据技术-数据湖Hudi视频教程-笔记03【Hudi集成Spark】

大数据新风口&#xff1a;Hudi数据湖&#xff08;尚硅谷&Apache Hudi联合出品&#xff09; B站直达&#xff1a;https://www.bilibili.com/video/BV1ue4y1i7na 尚硅谷数据湖Hudi视频教程百度网盘&#xff1a;https://pan.baidu.com/s/1NkPku5Pp-l0gfgoo63hR-Q?pwdyyds阿里…

【ARM】MDK-服务器与客户端不同网段内出现卡顿问题

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 记录不同网段之间的请求发送情况以及MDK网络版license文件内设置的影响。 2、 问题场景 客户使用很久的MDK网络版&#xff0c;在获取授权时都会出现4-7秒的卡顿&#xff0c;无法对keil进行任何操作&#xff0c;彻底…

Mac 如何安装vscode

Mac 电脑/ 苹果电脑如何安装 vscode 下载安装包 百度搜索vscode&#xff0c;即可得到vscode的官方下载地址&#xff1a;https://code.visualstudio.com/ 访问网页&#xff0c;点击下载即可。 下载完成后&#xff0c;得到下图所示的app。 将该 app 文件&#xff0c;放入到…

CV11_模型部署pytorch转ONNX

如果自己的模型中的一些算子&#xff0c;ONNX内部没有&#xff0c;那么需要自己去实现。 1.1 配置环境 安装ONNX pip install onnx -i https://pypi.tuna.tsinghua.edu.cn/simple 安装推理引擎ONNX Runtime pip install onnxruntime -i https://pypi.tuna.tsinghua.edu.cn/si…

基于STM32设计的超声波测距仪(微信小程序)(186)

基于STM32设计的超声波测距仪(微信小程序)(186) 文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】ESP8266工作模式配置1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献1.4 开发工具的选择1.5 系统框架图…

WebSocket、服务器推送技术

WebSocket 是一种在单个 TCP 连接上进行 全双工 通信的协议&#xff0c;它可以让客户端和服务器之间进行实时的双向通信&#xff0c;且不存在同源策略限制 WebSocket 使用一个长连接&#xff0c;在客户端和服务器之间保持持久的连接&#xff0c;从而可以实时地发送和接收数据…