RabbitM

    RabbitMQ是一个消息代理,从“生产者”接收消息并传递消息至“消费者”,期间可根据规则路由、缓存、持久化消息。“生产者”也即message发送者以下简称P,相对应的“消费者”乃message接收者以下简称C,message通过queue由P到C,queue存在于RabbitMQ,可存储尽可能多的message,多个P可向同一queue发送message,多个C可从同一个queue接收message。

  • 简单示例
-- =============connection====================
ConnectionFactory factory=new ConnetionFactory();
factory.setHost("ip");
factory.setPort(5672)
factory.setVirtualHost("/vhost_app1");
factory.setUserName("userName");
factory.setPassword("password");
-- =============send==========================
//获取通道
Channel channel=connection.createChannel();
//声明队列
channel.queueDeclare("队列name",false,false,false,null);
//发送消息
channel.basicPublish("","队列name",null,"消息内容msg");
//close
channel.close();
connection.close();

-- =============receive 轮询模式==========================
QueueingConsumer consumer=new QueueingConsumer(channel);
channel.basicConsume("队列名称",true,consumer);
//无限轮询
while(true){
	Delivery delivery=consumer.nextDelivery();
	String msg=new String (delivery.getBody());\	
}
-- =============receive监听模式================
DefaultConsumer consumer=new DefualtConsumer(channel){
	@Override
	public void handleDelivery(Strong consumerTag,Envelope envelope,
		BasicProperties properties,byte[] body) throws IOException{
		String msg=new String(body,"utf-8");		
	}
}
work queues

将耗时的消息处理通过队列分配给多个consumer来处理,我们称此处的consumer为worker,我们将此处的queue称为Task Queue,其目的是为了避免资源密集型的task的同步处理,也即立即处理task并等待完成。相反,调度task使其稍后被处理。也即把task封装进message并发送到task queue,worker进程在后台运行,从task queue取出task并执行job,若运行了多个worker,则task可在多个worker间分配。


 #若存在多个consumer每个consumer的负载可能不同,有些处理的快有些处理的慢  
#RabbitMQ并不管这些,只是简单的以round-robin的方式分配message  
#这可能造成某些consumer积压很多任务处理不完而一些consumer长期处于饥饿状态  
#可以使用prefetch_count=1的basic_qos方法可告知RabbitMQ只有在consumer处理并确认了上一个message后才分配新的message给他  #否则分给另一个空闲的consumer  
channel.basic_qos(prefetch_count=1) 
 
执行一个任务可能需要花费几秒钟,你可能会担心如果一个消费者在执行任务过程中挂掉了。一旦RabbitMQ将消息分发给了消费者,就会从内存中删除。在这种情况下,如果正在执行任务的消费者宕机,会丢失正在处理的消息和分发给这个消费者但尚未处理的消息。

但是,我们不想丢失任何任务,如果有一个消费者挂掉了,那么我们应该将分发给它的任务交付给另一个消费者去处理。

为了确保消息不会丢失,RabbitMQ支持消息应答。消费者发送一个消息应答,告诉RabbitMQ这个消息已经接收并且处理完毕了。RabbitMQ就可以删除它了。

如果一个消费者挂掉却没有发送应答,RabbitMQ会理解为这个消息没有处理完全,然后交给另一个消费者去重新处理。这样,你就可以确认即使消费者偶尔挂掉也不会丢失任何消息了。

没有任何消息超时限制;只有当消费者挂掉时,RabbitMQ才会重新投递。即使处理一条消息会花费很长的时间。

消息应答是默认打开的。我们通过显示的设置autoAsk=true关闭这种机制现即自动应答开,一旦我们完成任务,消费者会自动发送应答通知RabbitMQ消息已被处理,可以从内存删除。如果消费者因宕机或链接失败等原因没有发送ACK(不同于ActiveMQ,在RabbitMQ里,消息没有过期的概念),则RabbitMQ会将消息重新发送给其他监听在队列的下一个消费者。



-- =============receive woker队列模式================
channel.queueDeclare("队列name",false,false,false,null);
channel.basicQos(1);//告诉mq服务处理完再分配下一个mq
Consumer consumer=new DefaultConsumer(channel){
	@Override
	public void handleDelivery(Strong consumerTag,Envelope envelope,
		BasicProperties properties,byte[] body) throws IOException{
		try{
			String msg=new String(body,"utf-8");	
			channel.basicAck(envelope.getDeliveryTag(),false);//处理完成回调应答
		}cath(Exception e){
			
		}
			
	}
}
channel.basicConsumer("队列name","autoAck|false",consumer);//监听队列关闭自动应答



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值