报错的原因是在配置spring-rabbitmq.xml文件时的connectionFactory与redis的connectionFactory的Id命名冲突
改好之后有报错:
spring报错org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
原因:对应要注入的实现类没有 加注解,如dao层 @Repository 如service层 @Service
解决:在相应的实现类加上注解即可
将MQProducer接口和MQProducerImpl放在Service层,并且加上@Service注解即可
另外,因为代码的问题,加到队列中的消息,一直没有消费掉,然后每次运行程序的时候,都是自动就跑到消费者队列中,进行消费(即进行商品的秒杀),但是这并不是我想要的,想要的是秒杀的时候才进入队列
查看http://localhost:15672/#/queues的时候看到,运行的时候
业务执行失败的场景,这条消息不会ack,在Queues中一直处于Unacked状态,直到我关闭控制台程序,它才会自动将所有的Unacked的消息全部切换成Ready(虽然不知道它是怎么实现的),从而保证,下一次重启消费端时可继续尝试消费那些"失败"的消息。
当关闭掉IDEA之后,真的就自动的从unacked状态切换到ready状态了,很神奇。
RabbitMQ消息确认机制
为了保证消息从队列可靠地到达消费者,RabbitMQ提供消息确认机制(message acknowledgment)。消费者在声明队列时,可以指定noAck参数,当noAck=false时,RabbitMQ会等待消费者显式发回ack信号后才从内存(和磁盘,如果是持久化消息的话)中移去消息。否则,RabbitMQ会在队列中消息被消费后立即删除它。
采用消息确认机制后,只要令noAck=false,消费者就有足够的时间处理消息(任务),不用担心处理消息过程中消费者进程挂掉后消息丢失的问题,因为RabbitMQ会一直持有消息直到消费者显式调用basicAck为止。
当noAck=false时,对于RabbitMQ服务器端而言,队列中的消息分成了两部分:一部分是等待投递给消费者的消息;一部分是已经投递给消费者,但是还没有收到消费者ack信号的消息。如果服务器端一直没有收到消费者的ack信号,并且消费此消息的消费者已经断开连接,则服务器端会安排该消息重新进入队列,等待投递给下一个消费者(也可能还是原来的那个消费者)。
RabbitMQ不会为未ack的消息设置超时时间,它判断此消息是否需要重新投递给消费者的唯一依据是消费该消息的消费者连接是否已经断开。这么设计的原因是RabbitMQ允许消费者消费一条消息的时间可以很久很久。
RabbitMQ管理平台界面上可以看到当前队列中Ready状态和Unacknowledged状态的消息数,分别对应上文中的等待投递给消费者的消息数和已经投递给消费者但是未收到ack信号的消息数。
也可以通过命令行查看上述信息:
来源:oschina
链接:https://my.oschina.net/u/4385912/blog/3910218