Message发送之高级特性(二)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Message发送之高级特性(二)相关的知识,希望对你有一定的参考价值。

参考技术A

  若不希望消息马上被Broker发送给Comsumer,而是延迟1分钟发送给Comsumer,又或者需要消息每隔一定时间发送一次,一共发送N次。对于这样的需求,ActiveMQ提供了一种broker端消息定时调度机制。只需要在activemq.xml中配置schedulersupport属性值为true。

  提供了以下四种属性:

  以下是示例:
  (1) 延迟60秒

  (2) 延迟60秒,共投递10次,每次间隔10秒

  (3) 使用 CRON 表达式,每隔1小时发送一次

  ActiveMQ中提供了众多的“策略”(policy),它们可以在broker端为每个通道“定制”消息的管理方式。

  此策略表明Broker端消息转发给多个Consumer时,消息被发送的顺序性,这个顺序通常指Consumer的顺序,只对Topic有效,它有4种常用的类型:
  1) RoundRobinDispatchPolicy :“轮询”,消息将依次发送给每个“订阅者”。“订阅者”列表默认按照订阅的先后顺序排列,在转发消息时,对于匹配消息的第一个订阅者,将会被移动到“订阅者”列表的尾部,这也意味着“下一条”消息,将会较晚的转发给它。
   2) StrictOrderDispatchPolicy :严格有序,消息依次发送给每个订阅者,按照“订阅者”订阅的时间先后。它和RoundRobin最大的区别是,没有移动“订阅者”顺序的操作。
   3) PriorityDispatchPolicy : 基于“property”权重对“订阅者”排序。它要求开发者首先需要对每个订阅者指定priority,默认每个consumer的权重都一样。
  4) SimpleDispatchPolicy : 默认值,按照当前“订阅者”列表的顺序。其中 PriorityDispatchPolicy 是其子类。
  其中,轮询是比较常用的策略,示例如下:

   在非持久订阅者“失效”期间或一个新的Topic,broker可以保留的可追溯的消息量。前提是Topic必须是“retroactive”,我们可以在distination地址中指定此属性,例如:"order.topic?consumer.retroactive=true"。默认情况下,订阅者只能获取“订阅”开始之后的消息,如果retroactive=true,那么订阅者就可以获取其创建之前的消息列表。此Policy就是用来控制“retroactive”的消息量。
   (1) FixedSizedSubscriptionRecoveryPolicy : 保存一定size的消息,broker将为此Topic开辟定额的RAM用来保存最新的消息。

   (2) FixedCountSubscriptionRecoveryPolicy :保存一定条数的消息。

   (3) LastImageSubscriptionRecoveryPolicy :只保留最新的一条数据。
   (4) QueryBasedSubscriptionRecoveryPolicy :符合置顶selector的消息都将被保存,具体能够“恢复”多少消息,由底层存储机制决定;比如对于非持久化消息,只要内存中还存在,则都可以恢复。
   (5) TimedSubscriptionRecoveryPolicy :保留最近一段时间的消息。

   (6) NoSubscriptionRecoveryPolicy :关闭“恢复机制”。默认值。

  当消息过期后,或者“重发”几次之后仍然不能被正常消费,那么此消息将会被移除到DeadLetter队列中。此后,我们可以通过侦听死信队列,来获取相关通知或者对消息做额外的操作。
  (1) IndividualDeadLetterStrategy :把DeadLetter放入各自的死信通道中,对于Queue而言,死信通道的前缀默认为“ActiveMQ.DLQ.Queue.”,Topic为“ActiveMQ.DLQ.Topic.”。比如队列Order,那么它对应的死信通道为“ActiveMQ.DLQ.Queue.Order”。
   默认情况下,无论是Topic还是Queue,broker将使用Queue来保存DeadLeader,即死信通道通常为Queue;不过开发者也可以指定为Topic。

  (2) SharedDeadLetterStrategy :将所有的DeadLetter保存在一个共享的队列中,这是ActiveMQ broker端默认的策略。共享队列默认为“ActiveMQ.DLQ”,可以通过“deadLetterQueue”属性来设定。

  (3) SharedDeadLetterStrategy :broker将直接抛弃DeadLeatter。如果开发者不需要关心DeadLetter,可以使用此策略。AcitveMQ提供了一个便捷的插件:DiscardingDLQBrokerPlugin,来抛弃DeadLetter。

  此策略只对Topic有效,只对未持久化订阅者有效,当通道中有大量的消息积压时,broker可以保留的消息量。为了防止Topic中有慢速消费者,导致整个通道消息积压。
  (1) ConstantPendingMessageLimitStrategy :保留固定条数的消息,如果消息量超过limit,将使用 消息剔除策略 移除消息。

  (2) PrefetchRatePendingMessageLimitStrategy :保留prefetchSize倍数条消息。

  对于慢消费者,broker会启动一个后台线程用来检测所有的慢速消费者,并定期的关闭慢消费者。
  (1) AbortSlowConsumerStrategy abortConnection :中断慢速消费者,慢速消费将会被关闭。

  (2) AbortSlowConsumerStrategy maxTimeSinceLastAck :如果慢速消费者最后一个ACK距离现在的时间间隔超过阀值,则中断慢速消费者。

  对于多余的消息,ActiveMQ提供了以下策略来移除。
  (1) OldestMessageEvictionStrategy :移除旧消息,默认策略。
  (2) OldestMessageWithLowestPriorityEvictionStrategy :旧数据中权重较低的消息,将会被移除。
  (3) UniquePropertyMessageEvictionStrategy :移除具有指定property的旧消息。

  上述例子中,对于ORDER.WEIGHT Topic,只保留1000条消息,超出时,将ORDER值相同的消息列表中较旧的消息移除(只保留最新的一条消息)。

  当通道中存在大量的慢消费者时,此时便会产生大量的Pending Message(待消费消息)。对于这些Pending Message,ActiveMQ提供了几种Cursor来保存。
  (1) vmQueueCursor :将待转发消息保存在额外的内存(JVM linkeList)的存储结构中。是“非持久化消息”的默认设置,如果Broker不支持Persistent,它是任何类型消息的默认设置。有OOM风险。
  (2) fileQueueCursor :将消息保存到临时文件中。文件存储方式有broker的tempDataStore属性决定。是“持久化消息”的默认设置。
  (3) storeCursor :“综合”设置,对于非持久化消息,将采用vmQueueCursor存储,对于持久化消息采用fileQueueCursor。这是强烈推荐的策略,也是效率最好的策略。

springboot高级特性之邮件发送

我们平时经常会碰到email邮件发送的场景 如发送验证码,向客户发送邮件等等。
springboot中 整合了mail帮助我们更方便的发送邮件

平时我们发送邮件是通过 邮件的服务器发送出去的 比如qq邮件调用qq的邮件服务器 网易的邮件通过网易的服务器 我们使用邮件服务器发送邮件需要提前配置一些内容
我要以使用qq邮箱服务器发送邮件为例
我们登录qq邮箱 点击设置

进来之后点击账户

下拉 找到开启服务

发送一条短信之后即可开启 然后我们点击黄色框中的生成授权码 会给我们生成一个授权码 一会我们需要使用到这个授权码


复制记录好授权码

我们创建一个springboot工程

导入发送邮件的依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

然后我们编写配置文件 ssl的加密记得要配置 别删除

spring.mail.username=qq账号@qq.com
spring.mail.password=刚刚的授权码
#注解地址
spring.mail.host=smtp.qq.com
# 配置邮件编码
spring.mail.default-encoding=UTF-8
#开启ssl
#spring.mail.properties.mail.smtp.ssl.enable=true
# 配饰 SSL 加密工厂
spring.mail.properties.mail.smtp.socketFactoryClass=javax.net.ssl.SSLSocketFactory
# 表示开启 DEBUG 模式
spring.mail.properties.mail.debug=true

编写一个测试类
注入发送邮件的对象 这个是MailAutoConfiguration中配置好的


@SpringBootTest
class Springboot04TaskApplicationTests {

    @Autowired
    JavaMailSenderImpl javaMailSender; 
}

发送普通邮件 编写一个测试方法

 @Test
    void contextLoads() {
        SimpleMailMessage message = new SimpleMailMessage();
        //邮件设置  设置标题
        message.setSubject("通知--放假七天");
        //设置内容
        message.setText("今天开始放假放七天");
        //发给谁
        message.setTo("对方的qq@qq.com");
        //谁发的
        message.setFrom("你的qq要和配置文件中的一致@qq.com");
        //发送
        javaMailSender.send(message);
    }

发送测试


我们看到很多文件带有附件 图片或者文档等等 我们测试如何发送带附件的邮件

发送带附件的邮件 需要使用MimeMessage对象 但这个对象无法直接操作消息
我们需要另一个类帮助
MimeMessageHelper

 @Test
    public void test02(){
        //创建复杂的消息
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        //参数   参数一是 mimeMessage   参数二是  是否上传文件  布尔值
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
             helper.setSubject("今天开学");
             //Text兼容html片段    参数二 表示当前是否是html标签
             helper.setText("<b style='color:red'>今天开学啦!!</b>",true);
             //上传文件  参数文件名 参数二 文件位置 或一个流
            helper.addAttachment("bird.jpg",new File("C:\\\\Users\\\\Desktop\\\\v2-ae4216ed7f423bee2cc037198639dfda_r.jpg"));
             helper.setTo("对方@qq.com");
             helper.setFrom("你的qq@qq.com");
             javaMailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

测试发送

以上是关于Message发送之高级特性(二)的主要内容,如果未能解决你的问题,请参考以下文章

ActiveMQ(22):Consumer高级特性之消息分组(Message Groups)

ActiveMQ——Message高级特性

ActiveMQ(23):Consumer高级特性之Message dispatche asyncConsumer Priority与Message Selectors

springboot高级特性之邮件发送

RabbitMq高级特性之死信队列 通俗易懂 超详细 内含案例

ActiveMQ高级特性