消息机制

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

岁酱吖の 提交于 2019-12-02 14:52:05
RabbitMQ 生产者弄丢了数据   生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了,因为网络问题什么的,都有可能。   此时可以选择用 RabbitMQ 提供的事务功能,就是生产者发送数据之前开启 RabbitMQ 事务channel.txSelect,然后发送消息,如果消息没有成功被 RabbitMQ 接收到,那么生产者会收到异常报错,此时就可以回滚事务channel.txRollback,然后重试发送消息;如果收到了消息,那么可以提交事务channel.txCommit。 但问题是,RabbitMQ 事务机制(同步)一搞,基本上吞吐量会降下来,因为太耗性能。   所以一般来说,如果要确保写 RabbitMQ 的消息别丢,可以开启 confirm 模式,在生产者那里设置开启 confirm 模式之后,你每次写的消息都会分配一个唯一的 id,然后如果写入了 RabbitMQ 中,RabbitMQ 会给你回传一个 ack 消息,告诉你说这个消息 ok 了。如果 RabbitMQ 没能处理这个消息,会回调你的一个 nack 接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息 id 的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发。   事务机制和 confirm 机制最大的不同在于,事务机制是同步的

Linux进程间通信 --- IPC机制(转)

余生颓废 提交于 2019-12-02 12:27:58
在linux下的多个进程间的通信机制叫做IPC(Inter-Process Communication),它是多个进程之间相互沟通的一种方法。在linux下有多种进程间通信的方法:半双工管道、命名管道、消息队列、信号、信号量、共享内存、内存映射文件,套接字等等。使用这些机制可以为linux下的网络服务器开发提供灵活而又坚固的框架。 1. 管道 (PIPE) 管道实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另一进程就可以从管道的另一端将其读取出来。 管道的特点: 1、管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道; 2、只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。比如fork或exec创建的新进程,在使用exec创建新进程时,需要将管道的文件描述符作为参数传递给exec创建的新进程。当父进程与使用fork创建的子进程直接通信时,发送数据的进程关闭读端,接受数据的进程关闭写端。 3、单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。 4、数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾

zookeeper知识点总结

醉酒当歌 提交于 2019-12-01 19:29:30
1.ZooKeeper是一个开放源码的分布式协调服务,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。 分布式应用程序可以基于Zookeeper实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。 Zookeeper保证了如下分布式一致性特性: 顺序一致性 原子性 单一视图 可靠性 实时性(最终一致性) 客户端的读请求可以被集群中的任意一台机器处理, 如果读请求在节点上注册了监听器,这个监听器也是由所连接的zookeeper机器来处理 。对于写请求,这些请求会同时发给其他zookeeper机器并且达成一致后,请求才会返回成功。因此,随着zookeeper的集群机器增多,读请求的吞吐会提高但是写请求的吞吐会下降。 有序性是zookeeper中非常重要的一个特性,所有的更新都是全局有序的,每个更新都有一个唯一的时间戳,这个时间戳称为zxid(Zookeeper Transaction Id)。而读请求只会相对于更新有序,也就是读请求的返回结果中会带有这个zookeeper最新的zxid。 Zookeeper提供了文件系统和通知机制。Zookeeper提供一个多层级的节点命名空间(节点称为znode)。与文件系统不同的是

浏览器 HTTP 协议缓存机制详解

孤者浪人 提交于 2019-12-01 15:06:05
最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control、为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag,有时又没有带?等等。。。 后来查了一些资料以及同事亲自验证,总算对这些问题有了个清晰的理解,现在整理出来以备忘。 1、缓存的分类 缓存分为服务端侧(server side,比如 Nginx、Apache)和客户端侧(client side,比如 web browser)。 服务端缓存又分为 代理服务器缓存 和 反向代理服务器缓存(也叫网关缓存,比如 Nginx反向代理、Squid等),其实广泛使用的 CDN 也是一种服务端缓存,目的都是让用户的请求走”捷径“,并且都是缓存图片、文件等静态资源。 客户端侧缓存一般指的是浏览器缓存,目的就是加速各种静态资源的访问,想想现在的大型网站,随便一个页面都是一两百个请求,每天 pv 都是亿级别,如果没有缓存,用户体验会急剧下降、同时服务器压力和网络带宽都面临严重的考验。 2、 浏览器缓存机制 详解 浏览器缓存控制机制有两种:HTML Meta标签 vs. HTTP头信息 2.1 HTML Meta标签控制缓存 浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制(如: Expires; Cache-control等)

SpringCloud之RabbitMQ安装

◇◆丶佛笑我妖孽 提交于 2019-12-01 10:11:01
  本篇章讲解RabbitMQ的用途、原理以及配置,RabbitMQ的安装请查看 SpringCloud之RabbitMQ安装 一、MQ用途   1、同步变异步消息   场景:用户下单完成后,发送邮件和短信通知。   运用消息队列之后,用户下单完之后,下单信息写入数据库,再写入消息队列,发送邮件和发送短信各自去消息队列进行读取,节省时间,提高效率。          2、应用解耦   场景:用户下单后,订单系统需要多渠道通知用户。   下单服务系统:用户使用下单服务后,将下单信息写入数据库,下单成功。   短信服务系统:用户下单后,将短信信息写入消息队列,以发送短信信息通知用户交易信息。   邮件服务系统:用户下单后,将邮件信息写入消息队列,以发送邮件信息通知用户交易信息。   这样,如果微信通知不能正常使用,也不影响用户下单,用户下单后,只用把下单通知信息写入消息队列,不用关心后续操作,实现了订单系统和通知系统的解耦。                3、流量削峰   一般在秒杀或者团购活动中使用。   场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。针对这个问题,一般需要在应用前端加入消息队列。     a.可以控制活动的人数     b.可以缓解短时间内高流量压垮应用   用户的请求,服务器接收后,首先写入消息队列,如果消息队列的数量大于最大的数量

android的消息处理机制——Looper,Handler,Message

牧云@^-^@ 提交于 2019-12-01 04:10:59
这篇文章有一半是copy别人的,站在巨人的肩膀上,我们才能看得更高更远...... 在开始讨论android的消息处理机制前,先来谈谈一些基本相关的术语。 通信的同步 (Synchronous):指向客户端发送请求后,必须要在服务端有回应后客户端才继续发送其它的请求,所以这时所有请求将会在服务端得到同步,直到服务端返回请求。 通信的异步 (Asynchronous):指客户端在发送请求后,不必等待服务端的回应就可以发送下一个请求。 所谓同步调用,就是在一个函数或方法调用时,没有得到结果之前,该调用就不返回,直到返回结果。异步调用和同步是相对的,在一个异步调用发起后,被调用者立即返回给调用者,但是调用者不能立刻得到结果,被调用都在实际处理这个调用的请求完成后,通过状态、通知或回调等方式来通知调用者请求处理的结果。 android的消息处理有三个核心类:Looper,Handler和Message。其实还有一Message Queue(消息队列),但是 MQ被封装到Looper里面了,我们不会直接与MQ打交道,所以它不算是个核心类。 1. 消息类:Message类 android.os.Message的主要功能是进行消息的封装,同时可以指定消息的操作形式,Message类定义的变量和常用方法如下: (1)public int what:变量,用于定义此Message属于何种操作 (2

消息中间件常见问题

人走茶凉 提交于 2019-12-01 02:55:11
高可用,重复消费,幂等,可靠性传输,消息丢失 1、 kafka,rabbitMQ,activemq,rocketMQ使用场景及区别技术选型 吞吐量、topic数量对吞吐量的影响、时效性、可用性、可靠性、核心特点、优劣势总结 activemq:吞吐量万级 非常成熟,功能比较强大,大量的公司再项目中有应用 偶尔会有低概消息丢失,近些年应用越来越少 官方社区维护越来越少,而且确实主要基于解耦和异步来用的,较少在大规模吞吐的场景下使用 rabbitMQ: 吞吐量万级 跟服务器有关系 基于erlang开发,性能较好 延时低,而且提供开源的管理界面 社区比较活跃,近些年互联网公司用rabbitmq的比较多,因为基于erlang语言 不懂源码,比较难进行定制和掌控; rocketMQ:单机吞吐量10w,topic可以达到几百或者上千级别 topic越多吞吐量会有较小幅度的下降,阿里大规模使用,比较可靠、日处理消息上百亿、拓展方便、社区维护可以,只会复杂MQ业务场景 kafka:功能简单,主要支持简单的mq功能,ms级延迟 极高的可用性和可靠性不过有消息重复消费 在大数据领域的实时计算以及日志采集被大规模使用。 中小型公司:rabbitMQ,技术实力一般 挑战不是很高 社区比较活跃; 大型公司:rocketMQ 基础架构研发实力较强 如果是大数据领域的实时计算、日志采集等场景

RabbitMQ实战(三)-高级特性

旧城冷巷雨未停 提交于 2019-11-30 21:16:06
0 相关源码 1 你将学到 如何保证消息百分百投递成功 幂等性 如何避免海量订单生成时消息的重复消费 Confirm确认消息、Return返回消息 自定义消费者 消息的ACK与重回队列 限流 TTL 死信队列 2 保证消息的百分百投递成功 2.1 Producer 的可靠性投递 2.1.1 要求 保证消息的成功发出 保证MQ节点的成功接收 发送端收到MQ节点(Broker) 确认应答 完善的消息补偿机制 在实际生产中,很难保障前三点的完全可靠,比如在极端的环境中,生产者发送消息失败了,发送端在接受确认应答时突然发生网络闪断等等情况,很难保障可靠性投递,所以就需要有第四点完善的消息补偿机制。 2.1.2 解决方案 2.1.2.1 方案一:消息信息落库,对消息状态进行打标(常见方案) 将消息持久化到DB并设置状态值,收到Consumer的应答就改变当前记录的状态. 再轮询重新发送没接收到应答的消息,注意这里要设置重试次数. 方案流程图 方案实现流程 比如我下单成功 step1 - 对订单数据入BIZ DB订单库,并对因此生成的业务消息入MSG DB消息库 此处由于采用了两个数据库,需要两次持久化操作,为了保证数据的一致性,有人可能就想着采用分布式事务,但在大厂实践中,基本都是采用补偿机制! 这里一定要保证step1 中消息都存储成功了,没有出现任何异常情况,然后生产端再进行消息发送

微服务架构中的进程间通信

爱⌒轻易说出口 提交于 2019-11-30 18:09:41
简介 在单体应用中,各模块之间的调用是通过编程语言级别的方法或者函数来实现的。而基于微服务的分布式应用是运行在多台机器上的;一般来说,每个服务实例都是一个进程。 因此,如下图所示,服务之间的交互必须通过进程间通信(IPC)来实现。 后面我们将会详细介绍 IPC 技术,现在我们先来看下设计相关的问题。 交付模式 当为某个服务选择 IPC 时,首先需要考虑服务之间的交互问题。客户端和服务器之间有很多的交互模式,我们可以从两个维度进行归类。第一个维度是一对一还是一对多: • 一对一:每个客户端请求有一个服务实例来响应。 • 一对多:每个客户端请求有多个服务实例来响应。 第二个维度是这些交互式是同步还是异步: • 同步模式:客户端请求需要服务端即时响应,甚至可能由于等待而阻塞。 • 异步模式:客户端请求不会阻塞进程,服务端的响应可以是非即时的。 下表显示了不同交互模式: 一对一的交互模式有以下几种方式: 请求/响应:一个客户端向服务器端发起请求,等待响应,客户端期望此响应即时到达。在一个基于线程的应用中,等待过程可能造成线程阻塞。 通知(也就是常说的单向请求):一个客户端请求发送到服务端,但是并不期望服务端响应。 请求/异步响应:客户端发送请求到服务端,服务端异步响应请求。客户端不会阻塞,而且被设计成默认响应不会立刻到达。 一对多的交互模式有以下几种方式: 发布/ 订阅模式

OC:浅析Runtime中消息转发机制

℡╲_俬逩灬. 提交于 2019-11-30 16:28:53
一、介绍 OC是一门动态性语言,其实现的本质是利用runtime机制。在runtime中,对象调用方法,其实就是给对象发送一个消息,也即objc_msgSend()。在这个消息发送的过程中,系统会进行一系列的操作,最终实现消息的成功转发或者异常的抛出。这个传递的过程就是消息的转发。 消息转发过程:1、动态解析 2、快转发(接收者重定向) 3、慢转发(完整转发,方法重定向) 二、示例 在Person类中.h文件中声明了一个吃的方法: eat ,但是.m中没有具体的实现。 @interface Person : NSObject -(void)eat; @end 然后在控制器中创建Person对象调用eat,发现crash了。 - (void)viewDidLoad { [super viewDidLoad]; Person *person = [[Person alloc] init]; [person eat]; } 实现结果和原因如下 crash: '-[Person eat]: unrecognized selector sent to instance 0x60000366f310 reason: methodSignatureForSelector方法中,返回了一个空的对应方法签名,最终导致程序报错崩溃 此时,针对这种情况,消息就进入了转发流程