精华内容
下载资源
问答
  • 精益生产如何推行才能气的快速持久成功.doc
  • 那么,我们怎样才能做到持久、高效的学习呢?我总结了下面几点,仅供大家参考。 首先,学习方法上存在的问题,追本溯源还是个人生活、学习工作、思考习惯的问题。多年来养成的坏习惯,就像我们的影子一

    学习方法讲了很多,听的过程中,我们心潮澎湃,热血沸腾,激情四射。我们悔不当初,痛定思痛之后,就决定要洗心革面,痛改前非,重新做人。而事后,我们却将那些山盟海誓抛诸脑后,继续走回了原来的老路。


    那么,我们怎样才能做到持久、高效的学习呢?我总结了下面几点,仅供大家参考。


    首先,学习方法上存在的问题,追本溯源还是个人生活、学习工作、思考习惯的问题。多年来养成的坏习惯,就像我们的影子一样如影随形。俗话说:百足之虫死而不僵。想要将这只坏虫子根除,需要足够的耐心与恒心,以及将其根除的决心。


    改变自己的习惯不是一敲板凳、一拍脑门的事儿。很多时候,尽管你想得很好,而你做起来总是自然而然的回到从前。我推荐几种个人认为比较好的方式:在谷歌日历上设置提醒。定期提醒自己写总结、定期提醒自己进行反思,距离上一次反思,自己又有哪些习惯将就了。不将就才是发现问题的源动力,培养自己良好的习惯。另外,需要注意的是,提醒来了,一定要不折不扣的执行。

    展开全文
  • Redis持久

    千次阅读 多人点赞 2019-09-27 11:45:31
    文章目录RDB 持久化(快照持久化)AOF 持久化重写/压缩AOFRedis 4.0 对持久化机制的优化如何选择合适的持久化方式 Redis 是内存型数据库,为了之后重用数据(比如重启机器、机器故障之后回复数据),或者是为了防止...

    Redis 是内存型数据库,为了之后重用数据(比如重启机器、机器故障之后回复数据),或者是为了防止系统故障而将数据备份到一个远程位置,需要将内存中的数据持久化到硬盘上。

    Redis 提供了RDB和AOF两种持久化方式。默认是只开启RDB,当Redis重启时,它会优先使用AOF文件来还原数据集。

    RDB 持久化(快照持久化)

    RDB 持久化:将某个时间点的所有数据都存放到硬盘上。

    可以将快照复制到其它服务器从而创建具有相同数据的服务器副本。如果系统发生故障,将会丢失最后一次创建快照之后的数据。如果数据量很大,保存快照的时间会很长。

    快照持久化是Redis默认采用的持久化方式,在redis.conf配置文件中默认有此下配置:

    #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
    save 900 1              
    
    #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
    save 300 10            
    
    #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
    save 60 10000        
    

    根据配置,快照将被写入dbfilename选项指定的文件里面,并存储在dir选项指定的路径上面。如果在新的快照文件创建完毕之前,Redis、系统或者硬件这三者中的任意一个崩溃了,那么Redis将丢失最近一次创建快照写入的所有数据。

    举个例子:假设Redis的上一个快照是2:35开始创建的,并且已经创建成功。下午3:06时,Redis又开始创建新的快照,并且在下午3:08快照创建完毕之前,有35个键进行了更新。如果在下午3:06到3:08期间,系统发生了崩溃,导致Redis无法完成新快照的创建工作,那么Redis将丢失下午2:35之后写入的所有数据。另一方面,如果系统恰好在新的快照文件创建完毕之后崩溃,那么Redis将丢失35个键的更新数据。

    创建快照的办法有如下几种:

    • BGSAVE命令 :客户端向Redis发送 BGSAVE命令 来创建一个快照。对于支持BGSAVE命令的平台来说(基本上所有平台支持,除了Windows平台),Redis会调用fork来创建一个子进程,然后子进程负责将快照写入硬盘,而父进程则继续处理命令请求。
    • SAVE命令 :客户端还可以向Redis发送 SAVE命令 来创建一个快照,接到SAVE命令的Redis服务器在快照创建完毕之前不会再响应任何其他命令。SAVE命令不常用,我们通常只会在没有足够内存去执行BGSAVE命令的情况下,又或者即使等待持久化操作执行完毕也无所谓的情况下,才会使用这个命令。
    • save选项 :如果用户设置了save选项(一般会默认设置),比如 save 60 10000,那么从Redis最近一次创建快照之后开始算起,当“60秒之内有10000次写入”这个条件被满足时,Redis就会自动触发BGSAVE命令。
    • SHUTDOWN命令 :当Redis通过SHUTDOWN命令接收到关闭服务器的请求时,或者接收到标准TERM信号时,会执行一个SAVE命令,阻塞所有客户端,不再执行客户端发送的任何命令,并在SAVE命令执行完毕之后关闭服务器。
    • 一个Redis服务器连接到另一个Redis服务器:当一个Redis服务器连接到另一个Redis服务器,并向对方发送SYNC命令来开始一次复制操作的时候,如果主服务器目前没有执行BGSAVE操作,或者主服务器并非刚刚执行完BGSAVE操作,那么主服务器就会执行BGSAVE命令

    如果系统真的发生崩溃,用户将丢失最近一次生成快照之后更改的所有数据。因此,快照持久化只适用于即使丢失一部分数据也不会造成一些大问题的应用程序。不能接受这个缺点的话,可以考虑AOF持久化。

    AOF 持久化

    AOF 持久化:将写命令添加到 AOF 文件(Append Only File)的末尾。

    与快照持久化相比,AOF持久化 的实时性更好,因此已成为主流的持久化方案。默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly参数开启:

    appendonly yes
    

    开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof。

    使用 AOF 持久化需要设置同步选项,从而确定写命令同步到磁盘文件上的时机。这是因为对文件进行写入并不会马上将内容同步到磁盘上,而是先存储到缓冲区,然后由操作系统决定什么时候同步到磁盘。在Redis的配置文件中存在三种同步方式

    选项同步频率
    always每个写命令都同步,这样会严重降低Redis的速度
    everysec每秒同步一次
    no让操作系统来决定何时同步

    appendfsync always 可以实现将数据丢失减到最少,不过这种方式需要对硬盘进行大量的写入而且每次只写入一个命令,十分影响Redis的速度。另外使用固态硬盘的用户谨慎使用appendfsync always选项,因为这会明显降低固态硬盘的使用寿命。

    appendfsync everysec 为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec选项 ,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。

    appendfsync no 选项一般不推荐,这种方案会使Redis丢失不定量的数据而且如果用户的硬盘处理写入操作的速度不够的话,那么当缓冲区被等待写入的数据填满时,Redis的写入操作将被阻塞,这会导致Redis的请求速度变慢。

    随着服务器写请求的增多,AOF 文件会越来越大。Redis 提供了一种将 AOF 重写的特性,能够去除 AOF 文件中的冗余写命令。

    虽然AOF持久化非常灵活地提供了多种不同的选项来满足不同应用程序对数据安全的不同要求,但AOF持久化也有缺陷——AOF文件的体积太大。

    重写/压缩AOF

    AOF虽然在某个角度可以将数据丢失降低到最小而且对性能影响也很小,但是极端的情况下,体积不断增大的AOF文件很可能会用完硬盘空间。另外,如果AOF体积过大,那么还原操作执行时间就可能会非常长。

    为了解决AOF体积过大的问题,用户可以向Redis发送 BGREWRITEAOF命令 ,这个命令会通过移除AOF文件中的冗余命令来重写(rewrite)AOF文件来减小AOF文件的体积。BGREWRITEAOF命令和BGSAVE创建快照原理十分相似,所以AOF文件重写也需要用到子进程,这样会导致性能问题和内存占用问题,和快照持久化一样。更糟糕的是,如果不加以控制的话,AOF文件的体积可能会比快照文件大好几倍。

    文件重写流程:

    文件重写流程
    和快照持久化可以通过设置save选项来自动执行BGSAVE一样,AOF持久化设置以下参数

    auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size
    

    选项自动执行BGREWRITEAOF命令。举例:假设用户对Redis设置了如下配置选项并且启用了AOF持久化。那么当AOF文件体积大于64mb,并且AOF的体积比上一次重写之后的体积大了至少一倍(100%)的时候,Redis将执行BGREWRITEAOF命令。

    auto-aof-rewrite-percentage 100  
    auto-aof-rewrite-min-size 64mb
    

    无论是AOF持久化还是快照持久化,将数据持久化到硬盘上都是非常有必要的,但除了进行持久化外,用户还必须对持久化得到的文件进行备份(最好是备份到不同的地方),这样才能尽量避免数据丢失事故发生。如果条件允许的话,最好能将快照文件和重新重写的AOF文件备份到不同的服务器上面。

    随着负载量的上升,或者数据的完整性变得越来越重要时,用户可能需要使用到复制特性。

    Redis 4.0 对持久化机制的优化

    Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 aof-use-rdb-preamble 开启)。

    如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的, AOF 里面的 RDB 部分就是压缩格式不再是 AOF 格式,可读性较差。

    如何选择合适的持久化方式

    • 一般来说, 如果想达到足以媲美PostgreSQL的数据安全性,你应该同时使用两种持久化功能。在这种情况下,当 Redis 重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。

    • 如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失,那么你可以只使用RDB持久化。

    • 有很多用户都只使用AOF持久化,但并不推荐这种方式,因为定时生成RDB快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比AOF恢复的速度要快,除此之外,使用RDB还可以避免AOF程序的bug。

    • 如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式。

    展开全文
  • Redis持久化概述 NOSQL和关系型数据库比较 NOSQL的优缺点 非关系型数据库的优势 关系型数据库的优势 主流的NOSQL产品 Redis概述 Redis的五种数据类型 字符串类型String 哈希类型hash 有序可重复列表类型list ...

    目录


    Redis持久化概述

    跳转到目录
    Redis高性能是由于其将所有数据存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。Redis支持两种方式的持久化,一种是 RDB方式,一种是 AOF方式。可以单独使用其中一种或将二者结合使用。

    • RDB持久化默认支持,无需配置)
      该机制是指在指定的时间间隔内将内存中的数据集快照写入磁盘。
    • AOF持久化
      该机制将以日志的形式记录服务器所处理的每一个写操作在Redis服务器启动之初会读取该文件来重新构建redis数据库,以保证启动后数据库中的数据是完整的。
    • 无持久化
      我们可以通过配置的方式禁用Redis服务器的持久化功能,这样我们就可以将Redis视为一个功能加强版的memcached了。
    • redis可以同时使用RDB和AOF

    快照(Snapshot)也称为RDB持久化方式

    跳转到目录

    1、RDB持久化特点

    • 这种方式可以将某一时刻所有数据都写入硬盘中,当然这也是redis的默认开启持久化方式,保存的文件是以.rdb形式结尾的文件因此这种方式也称之为RDB方式

    在这里插入图片描述

    2、快照生成方式

    跳转到目录

    • 客户端方式: BGSAVESAVE指令
    • 服务器配置自动触发
    2.1 客户端方式之BGSAVE (并行操作)
    • a. 客户端可以使用BGSAVE命令来创建一个快照,当redis服务器接收到客户端BGSAVE命令时,redis会调用fork¹创建一个子进程,然后子进程负责将快照写入磁盘中,而父进程则继续处理命令请求

      名词解释: fork,当一个进程创建子进程的时候,底层的操作系统会创建该进程的一个副本,在类unix系统中创建子进程的操作会进行优化:在刚开始(没有set操作)的时候,父子进程共享相同内存,直到父进程或子进程对内存进行了写(set操作)之后,对被写入的内存的共享才会结束服务

    在这里插入图片描述

    2.2 客户端方式之SAVE (串行操作)
    • b.客户端还可以使用SAVE命令来创建一个快照,接收到SAVE命令的redis服务器在快照创建完毕之前将不再响应任何其他的命令

    在这里插入图片描述

    • 注意: SAVE命令并不常用,使用SAVE命令在快照创建完毕之前,redis处于阻塞状态,无法对外服务(写操作)
    2.3 服务器配置方式之满足配置自动触发

    这里和MySQL的Redo机制很类似,它是用来持久化事务相关

    • 如果用户在redis.conf中设置了save配置选项,redis会在save选项条件满足之后自动触发一次BGSAVE命令, 如果设置多个save配置选项,当任意一个save配置选项条件满足,redis也会触发一次BGSAVE命令

    在这里插入图片描述

    • 表示 900S(15分钟), key发生1次变化, 就触发一次 bgsave命令, 持久化一次
    • 表示300S(5分钟), key发生10次变化, 就触发一次bgsave命令, 持久化一次
    • 表示60S(1分钟), key发生10000次变化, 就触发一次bgsave命令, 持久化一次

    上面自动触发的规则: 标明key改变的越频繁, 触发快照持久化到硬盘的时间就越短;

    2.4 服务器接收客户端shutdown指令
    • redis服务器接收到redis客户端发来的shutdown指令关闭服务器时,会执行一个save命令,阻塞所有的客户端,不再执行客户端执行发送的任何命令,并且在save命令执行完毕之后关闭服务器

    3、配置生成快照名称和位置

    跳转到目录

    1.修改生成快照名称
    • dbfilename dump.rdb
    2.修改生成位置
    • dir ./

    在这里插入图片描述

    4、RDB(快照)持久化的缺点:

    跳转到目录

    • 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在 定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。 (还没有到达指定时间作持久化)
      • 比如说, 我们设置5分钟修改了13+个key, 此时在2分钟的时候就修改了11个key, 但是此时还差3分钟, 才能作持久化操作, 此刻, redis服务器挂了, 那就代表, 前2分钟修改的那11个key, 数据就丢失

    其中,上面配置的是RDB方式数据持久化时机:

    关键字时间(秒)key修改数量解释
    save9001每900秒(15分钟)至少有1个key发生变化,则dump内存快照
    save30010每300秒(5分钟)至少有10个key发生变化,则dump内存快照
    save6010000每60秒(1分钟)至少有10000个key发生变化,则dump内存快照

    AOF 只追加日志文件

    跳转到目录

    1、AOF持久化的特点

    • 这种方式可以将所有客户端执行的(set)写命令记录到日志文件中,AOF持久化将被执行的写命令写到AOF的文件末尾,以此来记录数据发生的变化
    • 想要恢复内存中的数据, 只要redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复AOF文件的记录的数据集.(将写命令原封不动的写到aof的文件, 下次再从新执行就恢复了数据)
    • 该机制将以日志的形式记录服务器所处理的每一个写操作在Redis服务器启动之初会读取该文件来重新构建redis数据库,以保证启动后数据库中的数据是完整的。

    在这里插入图片描述

    2、开启AOF持久化

    跳转到目录
    在redis的默认配置(redis.conf)AOF持久化机制没有开启的,需要在配置中开启。

    开启AOF持久化
    • a. 修改 appendonly yes开启持久化
    • b. 修改 appendfilename "appendonly.aof" 指定生成文件名称

    在这里插入图片描述

    3、日志追加频率

    跳转到目录

    3.1、always (谨慎使用)
    • 说明: 每当我们执行(set)写操作, redis都要同步写入硬盘,严重降低redis速度
    • 解释: 如果用户使用了always选项,那么每个redis写命令都会被写入硬盘,从而将发生系统崩溃时出现的数据丢失减到最少; 遗憾的是,因为这种同步策略需要对硬盘进行大量的写入操作,所以redis处理命令的速度会受到硬盘性能的限制;
    • 注意: 转盘式硬盘在这种频率下200左右个命令/s ; 固态硬盘(SSD)几百万个命令/s;
    • 警告: 使用SSD用户请谨慎使用always选项,这种模式不断写入少量数据的做法有可能会引发严重的写入放大问题,导致将固态硬盘的寿命从原来的几年降低为几个月。
    3.2、everysec (推荐)
    • 说明: 每秒执行一次同步, 显式的将多个写命令同步到磁盘
    • 解释: 为了兼顾数据安全写入性能,用户可以考虑使用everysec选项,让redis每秒一次的频率对AOF文件进行同步,redis每秒同步一次AOF文件时性能和不使用任何持久化特性时的性能相差无几,而通过每秒同步一次AOF文件, redis可以保证,即使系统崩溃,用户 最多丢失一秒之内产生的数据。(因为下次在打开redis服务, 就会将aof中的所有写命令执行, 恢复数据, 由于每一秒都会将写命令同步aof中, 即使丢失, 也就丢失1s的数据)
    3.3、no (不推荐)
    • 说明: 由操作系统决定何时同步
    • 解释:最后使用no选项,将完全由操作系统决定什么时候同步AOF日志文件,这个选项不会对redis性能带来影响但是系统崩溃时,会丢失不定数量的数据,另外如果用户硬盘处理写入操作不够快的话,当缓冲区被等待写入硬盘数据填满时,redis会处于阻塞状态,并导致redis的处理命令请求的速度变慢。

    4.修改同步频率

    跳转到目录

    1.修改日志同步频率
    • 修改appendfsync everysec|always|no指定

    上述配置为aof持久化的时机,解释如下:

    关键字持久化时机解释
    appendfsyncalways每执行一次更新命令,持久化一次
    appendfsynceverysec每秒钟持久化一次
    appendfsyncno不持久化

    四、AOF文件的重写

    跳转到目录

    1、AOF(日志文件)持久化的缺点:

    • AOF的方式也同时带来了另一个问题, 持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条set test 100就够了。
    • 为了压缩aof的持久化文件Redis提供了AOF重写(ReWriter)机制

    2. AOF重写

    • 用来在一定程度上减小AOF文件的体积

    3. 触发重写方式

    跳转到目录

    3.1、客户端方式触发重写 bgrewriteaof命令
    • 执行BGREWRITEAOF命令 不会阻塞redis的服务
    3.2、服务器配置方式自动触发重写aof
    • 配置redis.conf中的auto-aof-rewrite-percentage选项 , 下图。
    • 如果设置auto-aof-rewrite-percentage值为100auto-aof-rewrite-min-size 64mb,并且启用的AOF持久化时,那么当AOF文件体积大于64M,并且AOF文件的体积比上一次重写之后体积大了至少一倍(100%)时,会自动触发,如果重写过于频繁,用户可以考虑将auto-aof-rewrite-percentage设置为更大
      在这里插入图片描述

    4、 重写原理

    跳转到目录

    • 注意:重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件, 替换原有的文件这点和快照有点类似。

    重写流程

    1. redis调用fork ,现在有父子两个进程, 子进程根据内存中的数据库快照往临时文件中写入重建数据库状态的命令
    2. 父进程继续处理client请求,除了把写命令写入到旧的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
    3. 当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。
    4. 现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加

    在这里插入图片描述
    在这里插入图片描述


    五、持久化总结

    跳转到目录

    • 两种持久化方案既可以同时使用(aof),又可以单独使用,在某种情况下也可以都不使用,具体使用那种持久化方案取决于用户的数据和应用决定

    • 无论使用AOF还是快照机制持久化,将内存中的数据持久化到硬盘都是有必要的,除了持久化外,用户还应该对持久化的文件进行备份(最好备份在多个不同地方)。

    RDB与AOF的选择之惑

    在这里插入图片描述

    • 对数据非常敏感,建议使用默认的AOF

      持久化方案

      • AOF持久化策略使用everysecond,每秒钟fsync一次。该策略redis仍可以保持很好的处理性能,当出现问题时,最多丢失0-1秒内的数据。
      • 注意:由于AOF文件存储体积较大,且恢复速度较慢
    • 数据呈现阶段有效性,建议使用RDB持久化方案

      • 数据可以良好的做到阶段内无丢失(该阶段是开发者或运维人员手工维护的),且恢复速度较快,阶段 点数据恢复通常采用RDB方案
      • 注意:利用RDB实现紧凑的数据持久化会使Redis降的很低
    • 综合比对

      • RDB与AOF的选择实际上是在做一种权衡,每种都有利有弊
      • 如不能承受数分钟以内的数据丢失,对业务数据非常敏感,选用AOF
      • 如能承受数分钟以内的数据丢失,且追求大数据集的恢复速度,选用RDB
      • 灾难恢复选用RDB
      • 双保险策略,同时开启 RDB 和 AOF,重启后,Redis优先使用 AOF 来恢复数据,降低丢失数据
    展开全文
  • activemq+spring 持久化发送消息

    千次阅读 2012-12-16 11:56:24
    最近有项目,需要用到 jms来提高性能。在网上查了下 ,发现 activeMQ 不错,...2、由于默认的activemq是日志文件的持久订阅,需要修改activemq的配置文件才能持久化到数据库里,在activemq的conf目录下的activemq.xml

    最近有项目,需要用到 jms来提高性能。在网上查了下 ,发现 activeMQ 不错,所以就在晚上搜了些资料。



    在网上找的资料如下(相当给力):大笑


    1、先是下载activeMq。

    2、由于默认的activemq是日志文件的持久订阅,需要修改activemq的配置文件才能持久化到数据库里,在activemq的conf目录下的activemq.xml,找到

     

    Xml代码   收藏代码
    1. <persistenceAdapter>  
    2.     <kahaDB directory="${activemq.base}/data/kahadb"/>  
    3. </persistenceAdapter>  

     

     把它注释掉换成

     

    Xml代码   收藏代码
    1. <persistenceAdapter>  
    2.      <jdbcPersistenceAdapter dataSource="#oracle-ds"/>  
    3. </persistenceAdapter>  

     

     还要在activemq.xml的<bean></beans>里面增加数据库的配置,并且把oracle的驱动jar包,复制到activemq下的lib目录里,由于我使用的是oracle我的配置如下:

     

     

    Xml代码   收藏代码
    1. <bean id="oracle-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
    2. <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>  
    3. <property name="url" value="jdbc:oracle:thin:@10.60.30.31:1521:orcl"/>  
    4. <property name="username" value="activemq"/>  
    5. <property name="password" value="activemq"/>  
    6. <property name="maxActive" value="200"/>  
    7. <property name="poolPreparedStatements" value="true"/>  
    8. ;/bean>  

     

     到此你的activemq发送消息就可以持久化了(注:前提是你在spring里配置activemq时要配置消息的持久化)

     

    3、接下来是spring+activemq 使用的jar包,都在activemq目录下的lib里

     

    4、下来是具体一些配置文件和类文件

     

    发送消息类

     

     

    Java代码   收藏代码
    1. /** 
    2.  * message sender 
    3.  * @description <p></p> 
    4.  * @author quzishen 
    5.  * @project NormandyPositionII 
    6.  * @class MessageSender.java 
    7.  * @version 1.0 
    8.  * @time 2011-1-11 
    9.  */  
    10. public class MessageSender {  
    11.     // ~~~ jmsTemplate  
    12.     public JmsTemplate jmsTemplate;  
    13.       
    14.     /** 
    15.      * send message 
    16.      */  
    17.     public void sendMessage(){  
    18.         jmsTemplate.convertAndSend("hello jms!");  
    19.     }  
    20.     public void setJmsTemplate(JmsTemplate jmsTemplate) {  
    21.         this.jmsTemplate = jmsTemplate;  
    22.     }  
    23. }  
     

     

    接收消息类

     

     

    Java代码   收藏代码
    1. /** 
    2.  * message receiver 
    3.  * @description <p></p> 
    4.  * @author quzishen 
    5.  * @project NormandyPositionII 
    6.  * @class MessageReceiver.java 
    7.  * @version 1.0 
    8.  * @time 2011-1-11 
    9.  */  
    10. public class MessageReceiver implements MessageListener {  
    11.     /* (non-Javadoc) 
    12.      * @see javax.jms.MessageListener#onMessage(javax.jms.Message) 
    13.      */  
    14.     public void onMessage(Message m) {  
    15.         System.out.println("[receive message]");  
    16.           
    17.         ObjectMessage om = (ObjectMessage) m;  
    18.         try {  
    19.             String key1 = om.getStringProperty("key1");  
    20.               
    21.             System.out.println(key1);  
    22.               
    23.             System.out.println("model:"+om.getJMSDeliveryMode());  
    24.             System.out.println("destination:"+om.getJMSDestination());  
    25.             System.out.println("type:"+om.getJMSType());  
    26.             System.out.println("messageId:"+om.getJMSMessageID());  
    27.             System.out.println("time:"+om.getJMSTimestamp());  
    28.             System.out.println("expiredTime:"+om.getJMSExpiration());  
    29.             System.out.println("priority:"+om.getJMSPriority());  
    30.         } catch (JMSException e) {  
    31.             e.printStackTrace();  
    32.         }  
    33.     }  
    34. }  

     

     

    在发送消息和接收消息前可以做一些自定的处理,就是这个类

     

     

    Java代码   收藏代码
    1. /** 
    2.  * message converter 
    3.  * @description <p></p> 
    4.  * @author quzishen 
    5.  * @project NormandyPositionII 
    6.  * @class MessageConvertForSys.java 
    7.  * @version 1.0 
    8.  * @time 2011-1-11 
    9.  */  
    10. public class MessageConvertForSys implements MessageConverter {  
    11.     /* (non-Javadoc) 
    12.      * @see org.springframework.jms.support.converter.MessageConverter#toMessage(java.lang.Object, javax.jms.Session) 
    13.      */  
    14.     public Message toMessage(Object object, Session session)  
    15.             throws JMSException, MessageConversionException {  
    16.         System.out.println("[toMessage]");  
    17.         ObjectMessage objectMessage = session.createObjectMessage();  
    18.           
    19.         objectMessage.setJMSExpiration(1000);  
    20.         objectMessage.setStringProperty("key1", object+"_add");  
    21.           
    22.         return objectMessage;  
    23.     }  
    24.     /* (non-Javadoc) 
    25.      * @see org.springframework.jms.support.converter.MessageConverter#fromMessage(javax.jms.Message) 
    26.      */  
    27.     public Object fromMessage(Message message) throws JMSException,  
    28.             MessageConversionException {  
    29.         System.out.println("[fromMessage]");  
    30.         ObjectMessage objectMessage = (ObjectMessage) message;  
    31.           
    32.         return objectMessage.getObjectProperty("key1");  
    33.     }  
    34. }  
     

     

    第一种,PTP方式的配置:

     

    Java代码   收藏代码
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
    4.     xmlns:context="http://www.springframework.org/schema/context"  
    5.     xmlns:aop="http://www.springframework.org/schema/aop"  
    6.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
    7.     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
    8.     http://www.springframework.org/schema/context   
    9.     http://www.springframework.org/schema/context/spring-context-2.5.xsd "  
    10.     default-autowire="byName">  
    11.       
    12.     <!-- JMS PTP MODEL -->  
    13.     <!-- PTP链接工厂 -->  
    14.     <bean id="queueConnectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">  
    15.         <property name="brokerURL" value="tcp://127.0.0.1:61616" />  
    16.         <!-- <property name="brokerURL" value="vm://normandy.notify" /> -->  
    17.         <property name="useAsyncSend" value="true" />  
    18.     </bean>  
    19.     <!-- 定义消息队列 -->  
    20.     <bean id="dest" class="org.apache.activemq.command.ActiveMQQueue">  
    21.         <constructor-arg value="queueDest" />  
    22.     </bean>  
    23.     <!-- PTP jms模板 -->  
    24.     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
    25.         <property name="connectionFactory" ref="queueConnectionFactory"></property>  
    26.         <property name="defaultDestination" ref="dest" />  
    27.         <property name="messageConverter" ref="messageConvertForSys" />  
    28.         <property name="pubSubDomain" value="false" />  
    29.     </bean>  
    30.       
    31.     <!-- 消息转换器 -->  
    32.     <bean id="messageConvertForSys" class="com.normandy.tech.test.MessageConvertForSys"></bean>  
    33.       
    34.     <!-- 消息发送方 -->  
    35.     <bean id="messageSender" class="com.normandy.tech.test.MessageSender"></bean>  
    36.     <!-- 消息接收方 -->  
    37.     <bean id="messageReceiver" class="com.normandy.tech.test.MessageReceiver"></bean>  
    38.       
    39.     <!-- 消息监听容器 -->  
    40.     <bean id="listenerContainer"    
    41.         class="org.springframework.jms.listener.DefaultMessageListenerContainer">    
    42.         <property name="connectionFactory" ref="queueConnectionFactory" />    
    43.         <property name="destination" ref="dest" />    
    44.         <property name="messageListener" ref="messageReceiver" />    
    45.     </bean>  
    46. </beans>  
     

     

     

    第二种:PUB/SUB方式的配置

    我们配置两个消息订阅者,分别订阅不同的消息,这样用于判断是否成功执行了消息的发布和消息的订阅

     

    Java代码   收藏代码
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
    4.     xmlns:context="http://www.springframework.org/schema/context"  
    5.     xmlns:aop="http://www.springframework.org/schema/aop"  
    6.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
    7.     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
    8.     http://www.springframework.org/schema/context   
    9.     http://www.springframework.org/schema/context/spring-context-2.5.xsd "  
    10.     default-autowire="byName">  
    11.       
    12.     <!-- JMS TOPIC MODEL -->  
    13.     <!-- TOPIC链接工厂 -->  
    14.     <bean id="topicSendConnectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">  
    15.         <property name="brokerURL" value="tcp://127.0.0.1:61616" />  
    16.         <property name="useAsyncSend" value="true" />  
    17.     </bean>  
    18.       
    19.     <bean id="topicListenConnectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">  
    20.         <property name="brokerURL" value="tcp://127.0.0.1:61616" />  
    21.     </bean>  
    22.       
    23.     <!-- 定义主题 -->  
    24.     <bean id="myTopic"  class="org.apache.activemq.command.ActiveMQTopic">  
    25.       <constructor-arg value="normandy.topic"/>  
    26.     </bean>  
    27.       
    28.     <bean id="myTopic2"  class="org.apache.activemq.command.ActiveMQTopic">  
    29.       <constructor-arg value="normandy.topic2"/>  
    30.     </bean>  
    31.       
    32.     <!-- 消息转换器 -->  
    33.     <bean id="messageConvertForSys" class="com.normandy.tech.test.MessageConvertForSys"></bean>  
    34.       
    35.     <!-- TOPIC send jms模板 -->  
    36.     <bean id="topicSendJmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
    37.         <property name="connectionFactory" ref="topicSendConnectionFactory"></property>  
    38.         <property name="defaultDestination" ref="myTopic" />  
    39.         <property name="messageConverter" ref="messageConvertForSys" />  
    40.         <!-- 开启订阅模式 -->  
    41.         <property name="pubSubDomain" value="true"/>  
    42.     </bean>  
    43.       
    44.     <!-- 消息发送方 -->  
    45.     <bean id="topicMessageSender" class="com.normandy.tech.test.MessageSender">  
    46.         <property name="jmsTemplate" ref="topicSendJmsTemplate"></property>  
    47.     </bean>  
    48.       
    49.     <!-- 消息接收方 -->  
    50.     <bean id="topicMessageReceiver" class="com.normandy.tech.test.MessageReceiver">  
    51.     </bean>  
    52.       
    53.     <!-- 主题消息监听容器 -->  
    54.     <bean id="listenerContainer"    
    55.         class="org.springframework.jms.listener.DefaultMessageListenerContainer">    
    56.         <property name="connectionFactory" ref="topicListenConnectionFactory" />    
    57.         <property name="pubSubDomain" value="true"/><!-- default is false -->  
    58.         <property name="destination" ref="myTopic" />  <!-- listen topic: myTopic -->  
    59.         <property name="subscriptionDurable" value="true"/>  
    60.         <property name="clientId" value="clientId_001"/><!---这里是设置接收客户端的ID,在持久化时,但这个客户端不在线时,消息就存在数据库里,知道被这个ID的客户端消费掉-->  
    61.         <property name="messageListener" ref="topicMessageReceiver" />    
    62.     </bean>  
    63.       
    64.     <!-- 主题消息监听容器2 -->  
    65.     <bean id="listenerContainer2"    
    66.         class="org.springframework.jms.listener.DefaultMessageListenerContainer">    
    67.         <property name="connectionFactory" ref="topicListenConnectionFactory" />    
    68.         <property name="pubSubDomain" value="true"/><!-- default is false -->  
    69.         <property name="destination" ref="myTopic2" />  <!-- listen topic: myTopic2 -->  
    70.         <property name="subscriptionDurable" value="true"/>  
    71.         <property name="clientId" value="clientId_002"/>!---这里是设置接收客户端的ID,在持久化时,但这个客户端不在线时,消息就存在数据库里,知道被这个ID的客户端消费掉-->  
    72.         <property name="messageListener" ref="topicMessageReceiver" />    
    73.     </bean>  
    74. </beans>  

     

    测试一下是否能发送和接收消息,我是在main方法里测试的

     

    Java代码   收藏代码
    1. public static void main(String[] args) throws HttpException, IOException {  
    2.     System.out.println("初始化spring!准备开始接收!");  
    3.     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-jms-topic-receiver.xml");  
    4.     MessageSender t=(MessageSender) context.getBean("topicMessageSender");  
    5.     t.sendMessage();  
    6. }  

     

     

     

     

     

    Activemq支持两种消息传送模式:PERSISTENT (持久消息)和 NON_PERSISTENT(非持久消息)

    从字面意思就可以了解,这是两种正好相反的模式。

    1、PERSISTENT 持久消息

    是activemq默认的传送方式,此方式下的消息在配合activemq.xml中配置的消息存储方式,会被存储在特定的地方,直到有消费者将消息消费或者消息过期进入DLQ队列,消息生命周期才会结束。

    此模式下可以保证消息只会被成功传送一次和成功使用一次,消息具有可靠性。在消息传递到目标消费者,在消费者没有成功应答前,消息不会丢失。所以很自然的,需要一个地方来持久性存储。

    如果消息消费者在进行消费过程发生失败,则消息会被再次投递。


    2、NON_PERSISTENT 非持久消息

    非持久的消息适用于不重要的,可以接受消息丢失的哪一类消息,这种消息只会被投递一次,消息不会在持久性存储中存储,也不会保证消息丢失后的重新投递。



    在spring提供的JmsTemplate中,同样提供了针对于当前功能的配置选项:

     

    Xml代码   收藏代码
    1. <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
    2.         <property name="connectionFactory" ref="cachingConnectionFactory"></property>  
    3.         <property name="defaultDestination" ref="dest" />  
    4.         <property name="messageConverter" ref="messageConverter" />  
    5.         <property name="pubSubDomain" value="false" />  
    6.         <property name="explicitQosEnabled" value="true" /> <!-- deliveryMode, priority, timeToLive 的开关,要生效,必须配置为true,默认false-->  
    7.         <property name="deliveryMode" value="1" /> <!-- 发送模式  DeliveryMode.NON_PERSISTENT=1:非持久 ; DeliveryMode.PERSISTENT=2:持久-->  
    8.     </bean>  
     

     

    消息的签收模式:

    客户端成功接收一条消息的标志是一条消息被签收,成功应答。

    消息的签收情形分两种:

    1、带事务的session

     如果session带有事务,并且事务成功提交,则消息被自动签收。如果事务回滚,则消息会被再次传送。

    2、不带事务的session

     不带事务的session的签收方式,取决于session的配置。

    Activemq支持一下三种模式:

      Session.AUTO_ACKNOWLEDGE  消息自动签收
      Session.CLIENT_ACKNOWLEDGE  客户端调用acknowledge方法手动签收
      Session.DUPS_OK_ACKNOWLEDGE 不必必须签收,消息可能会重复发送。在第二次重新传递消息的时候,消息头的JmsDelivered会被置为true标示当前消息已经传送过一次,客户端需要进行消息的重复处理控制。

    spring提供的JmsTemplate中的配置方式:

     

     

    Xml代码   收藏代码
    1. <!-- PTP jms模板 -->  
    2.     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
    3.         <property name="connectionFactory" ref="cachingConnectionFactory"></property>  
    4.         <property name="defaultDestination" ref="dest" />  
    5.         <property name="messageConverter" ref="messageConverter" />  
    6.         <property name="pubSubDomain" value="false" />  
    7.         <property name="sessionAcknowledgeMode" value="1" />   
    8. <!-- 消息应答方式  
    9.         Session.AUTO_ACKNOWLEDGE  消息自动签收  
    10.         Session.CLIENT_ACKNOWLEDGE  客户端调用acknowledge方法手动签收  
    11.         Session.DUPS_OK_ACKNOWLEDGE 不必必须签收,消息可能会重复发送  
    12.         -->  
    13.     </bean>  
     

     

    以上资料来自:

    http://blog.csdn.net/quzishen/article/details/6128781

    http://blog.csdn.net/quzishen/article/details/6131222


    如果你看到这里。基本已经掌握了 activeMQ的 基本用法


    ps: 我在弄持久化的时候, 碰到一个小小的尴尬的地方。因为我用的 是 异步发送 信息. 当我向 activeMQ服务器发送信息的时候。

    总是在我的 数据库里看不到我发送的信息记录。当时我就以为自己没有配好。。在网上又找了不少资料。发现可能是我已经

    消费了信息,所以可能没有,这点和 quartz框架差不多。所以我就已发送信息,就关闭服务器,怎奈还是没有计算器快,还是没有信息。

    后来我就自己写了个钩子程序,当一旦发送,我就关闭服务器,造成一个 down机 的假设环境。发现确实有用。呵呵。 

    JMS 才研究没有多久,但是感觉真的非常有用.


    展开全文
  • activemq持久订阅工作原理

    千次阅读 2018-08-16 15:05:15
    持久订阅consumer只能消费在该consumer激活状态时传送给对应topic的消息才能被该consumer消费,一旦该consumer 挂掉到下次启动期间发布到该topic的消息不能被该consumer重新恢复时使用!!! 持久订阅:订阅之后...
  • 数据持久

    千次阅读 2016-08-22 14:43:53
    1.为什么要进行数据持久化? 我们平时的浏览记录,qq的聊天记录,收藏夹等,每次打开程序的视乎都会存在,理论上每次关闭应用的时候,程序中使用的数据资源都应该被释放,将程序运行过程中或运行结束后的某些信息...
  • Redis持久化的两种方式

    千次阅读 2018-09-28 22:22:02
    一、引言 山高不辞土壤,才能成其高;...redis是一个支持持久化的内存数据库,也就是说redis可以将内存中的数据同步到硬盘,来实现持久化。 redis支持持久化的两种方式: 1、snapshotting(快照),这个是red...
  • 消息的可靠性是RabbitMQ的一大特色,那么RabbitMQ是如何保证消息可靠性的呢——消息持久化。  为了保证RabbitMQ在退出或者crash等异常情况下数据没有丢失,需要将queue,exchange和Message都持久化。 queue的...
  • RabbitMQ之消息持久

    万次阅读 多人点赞 2017-03-08 16:53:06
    消息的可靠性是RabbitMQ的一大特色,那么RabbitMQ是如何保证消息可靠性的呢——消息持久化。 为了保证RabbitMQ在退出或者crash等异常情况下数据没有丢失,需要将queue,exchange和Message都持久化。 queue的...
  • 什么是持久化? 为什么要持久化?

    千次阅读 2015-12-17 20:59:44
    1.什么是持久化? 狭义的理解: “持久化”仅仅指把域对象永久保存到数据库中;广义的理解,“持久化”包括和数据库相关的各种操作(持久化就是将有用的数据以某种技术保存起来,将来可以再次取出来应用,数据库技术,将...
  • Redis持久化策略

    千次阅读 2021-01-13 22:31:41
    Redis持久化策略RDBAOF注意优缺点 RDB RDB(Redis Database Backup file) 持久化策略采用的是快照模式,备份的是数据本身,redis默认的持久化策略。原理如图所示: 何时出发RDB文件的写入勒?有如下5中情形: 在...
  • jms1.1规范针对publisher/subscriber模型提出了持久订阅和非持久订阅者。我们用现实生活中的例子来说明,持久订阅和非持久订阅的区别。 1.非持久订阅  考虑学生听老师讲课的情景,大学老师讲课,一部分学生会去...
  • Akka 指南 之「持久化」

    千次阅读 2019-02-14 22:02:46
    文章目录持久化依赖示例项目简介体系结构事件源 持久化 依赖 为了使用 Akka 持久化(Persistence)功能,你必须在项目中添加如下依赖: &amp;amp;amp;amp;lt;!-- Maven --&amp;amp;amp;amp;gt; &...
  • RabbitMQ消息持久

    万次阅读 2020-06-03 19:56:02
    当RabbitMQ服务器挂了,它可能就丢失所有队列中的消息和任务。如果你想让RabbitMQ记住当前的状态和内容,就需要通过2...单单设置消息持久化而不设置队列的持久化显得毫无意义。 注意:已经定义的队列,再次定义是...
  • java对象持久

    千次阅读 2015-09-24 10:35:21
    简单地说,持久化就是把数据同步保存到数据库或某些存储设备中。在软件的分层体系结构中,持久化层是与数据库打交道的逻辑层。在数据库中对数据的增加、删除、查找和修改操作由持久化层来处理。最常见的操作是在ASP...
  • 持久化内存简介

    千次阅读 2019-05-16 10:33:52
    本文来自持久化内存文档,该文档上一次更新来自两个月前,也就是2019年3月,但是感觉内容应该还是比较老了,可能初版有两三年的历史了~ 一、持久化内存概述 在过去的几十年中,计算机系统已经实现了图1所示的...
  • java 持久

    千次阅读 2018-12-03 11:52:53
    JPA(Java Persistence API )中文名Java持久层API,JPA通过注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE...
  • 基本概念  持久连接:使用同一个TCP...持久连接的两种类型 keep-alive机制(http1.0) keep-alive握手过程如下: HTTP/1.0+支持keep-alive连接,但默认并未激活。客户端通过发送一个包含Connection: Keep-Aliv...
  • 主要介绍了Android持久化保存cookie的方法,在解析网页信息的时候,需要登录后才能访问,所以使用httpclient模拟登录,然后把cookie保存下来,以供下一次访问使用,感兴趣的小伙伴们可以参考一下
  • 解密Redis持久

    千次阅读 2013-02-28 18:18:01
    项目上经常用到redis进行持久化存储,却不知道redis持久化的原理,这里转载一篇博客,权当记读书笔记了,原文地址:http://blog.nosqlfan.com/html/3813.html 写操作的流程 首先我们来看一下,数据库在进行写...
  • 持久化API【JPA】完全掌握

    千次阅读 2019-10-03 16:44:15
    JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。 Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和...
  • 众所周知,Session对象的生命周期关闭浏览器之后就会销毁,那该如何...那就需要将session对象进行持久化的处理,这样浏览器才能通过session对象来“记住密码”。 ps:本人还是感觉用cookie对象去实现该功能比较好,这
  • Redis 的持久化机制

    2016-10-11 22:11:51
    Redis 的持久化机制
  • 消息持久化就是将消息保存到磁盘,这样的好处就是如果服务挂了,则消息还保存在磁盘不会丢失,服务起来后还能找到消息并在此发送,消息的持久化和消息的发送模型是没有关系的。 消息持久化的配置很方便的,所以...
  • 一.前言 Redis的所有数据都是保存在内存中...由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁 盘上,当redis重启后,可以从磁盘中...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 201,444
精华内容 80,577
关键字:

怎么才能持久