消息中间件相关(二)

如何保证消息的可靠性传输

rabbitMQ

1.生产者弄丢数据:可以选择使用rabbitMQ提供的事务功能,就是生产者在发送数据之前开启rabbitMQ事务channel.txSelect,如果没有消息没有被收到,生产者会抛出异常,此时就可以回滚事务channel.txRollback然后重试,如果收到了消息就可以提交事务了channe.txCommit.这种做法很耗费性能.

所以一般来说,如果你要确保说写rabbitmq的消息别丢,可以开启confirm模式,在生产者那里设置开启confirm模式之后,你每次写的消息都会分配一个唯一的id,然后如果写入了rabbitmq中,rabbitmq会给你回传一个ack消息,告诉你说这个消息ok了。如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息id的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发

事务机制和cnofirm机制最大的不同在于,事务机制是同步的,你提交一个事务之后会阻塞在那儿,但是confirm机制是异步的

2.rabbitmq弄丢了数据,这个就需要开启持久化,消息写入后会持久化到磁盘上,哪怕是rabbitMQ自己挂了,恢复之后会自动读取之前的数据

持久化分为两步

    1>创建queue的时候将消息持久化,可以保证rabbitMQ持久化queue里的元数据,但是不会持久化queue里的数据.

    2>将消息的deliveryMode设置为2就是将消息持久化

        注:以上两种持久化方式要同时进行

3.消费端弄丢了数据,刚消费的时候线程挂了,比如重启,rabbitMQ会认为你消费了,数据就丢失了.

解决方式是利用rabbitMQ的ack机制,可以通过api来调用.然后每次你自己代码里确保处理完的时候,再程序里ack一把。这样的话,如果你还没处理完,不就没有ack?那rabbitmq就认为你还没处理完,这个时候rabbitmq会把这个消费分配给别的consumer去处理

kafka

1.消费端弄丢了数据:

大家都知道kafka会自动提交offset,那么只要关闭自动提交offset,在处理完之后自己手动提交offset,就可以保证数据不会丢。但是此时确实还是会重复消费,比如你刚处理完,还没提交offset,结果自己挂了,此时肯定会重复消费一次,需要自己去保证数据的幂等性.

2.kafka弄丢了数据

kafka的leader机器宕机了,没有来的及将消息同步给follower,follower切换为leader之后,数据丢失.所以一般情况下需要设置以下几个参数:

    1>topic设置replication.factor参数:这个值必须大于1,要求每个partition必须有至少2个副本

    2>kafka服务端设置min.insync.replicas参数:这个值必须大于1,这个是要求一个leader至少感知到有至少一个follower还跟自己保持联系,没掉队

    3>producer端设置acks=all:这个是要求每条数据,必须是写入所有replica之后,才能认为是写成功了

    4>producer端设置retries=MAX(很大很大很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里了

3.生产者会不会丢数据呢?

上述的思路设置了ack=all,一定不会丢,要求是,你的leader接收到消息,所有的follower都同步到了消息之后,才认为本次写成功了。如果没满足这个条件,生产者会自动不断的重试,重试无限次。

消息中间件相关(三)

转载于:https://my.oschina.net/Pirvate/blog/3017887

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值