pythonamqp
① 消息中间件(一)MQ详解及四大MQ比较
一、消息中间件相关知识
1、概述
消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、扮信最终一致性等一系列功能,成为异步RPC的主要手段之一。当今市面上有很多主流的消息中间件,如老牌的ActiveMQ、RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发RocketMQ等。
2、消息中间件的组成
2.1 Broker
消息服务器,作为server提供消息核心服务
2.2 Procer
消息生产者,业务的发起方,负责生产消息传输给broker,
2.3 Consumer
消息消费者,业务的处理方,负责从broker获取消息并进行业务逻辑处理
2.4 Topic
2.5 Queue
2.6 Message
消息体,根据不同通信协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输
3 消息中间件模式分类
3.1 点对点
PTP点对点:使用queue作为通信载体
说明:
消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费消息。
消息被消费以后,queue中不再存储,所以消息消费者不可能消费到已经被消费的消息。 Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。
说明:
queue实现了负载均衡,将procer生产的消息发送到消息队列中,由多个消费者消费。但一个消息只能被一个消费者接受,当没有消费者可用时,这个消息会被保存直到有一个可用的消费者厅谨轮。
4 消息中间件的优势
4.1 系统解耦
交互系统之间没有直接的调用关系,只是通过消息传输,故系统侵入性不强,耦合度低。
4.2 提高系统响应时间
例如原来的一套逻辑,完成支付可能涉及先修改订单状态、计算会员积分、通知物流配送几个逻辑才能完成;通过MQ架构设计,就可将紧急重要(需要立刻响应晌键)的业务放到该调用方法中,响应要求不高的使用消息队列,放到MQ队列中,供消费者处理。
4.3 为大数据处理架构提供服务
通过消息作为整合,大数据的背景下,消息队列还与实时处理架构整合,为数据处理提供性能支持。
4.4 java消息服务——JMS
Java消息服务(Java Message Service,JMS)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
5 消息中间件应用场景
5.1 异步通信
有些业务不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
5.2 解耦
降低工程间的强依赖程度,针对异构系统进行适配。在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。通过消息系统在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口,当应用发生变化时,可以独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
5.3 冗余
有些情况下,处理数据的过程会失败。除非数据被持久化,否则将造成丢失。消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的”插入-获取-删除”范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。
5.4 扩展性
因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可。不需要改变代码、不需要调节参数。便于分布式扩容。
5.5 过载保护
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量无法提取预知;如果以为了能处理这类瞬间峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
5.6 可恢复性
系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
5.7 顺序保证
在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。
5.8 缓冲
在任何重要的系统中,都会有需要不同的处理时间的元素。消息队列通过一个缓冲层来帮助任务最高效率的执行,该缓冲有助于控制和优化数据流经过系统的速度。以调节系统响应时间。
5.9 数据流处理
分布式系统产生的海量数据流,如:业务日志、监控数据、用户行为等,针对这些数据流进行实时或批量采集汇总,然后进行大数据分析是当前互联网的必备技术,通过消息队列完成此类数据收集是最好的选择。
6 消息中间件常用协议
6.1 AMQP协议
AMQP即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制。
优点:可靠、通用
6.2 MQTT协议
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。
优点:格式简洁、占用带宽小、移动端通信、PUSH、嵌入式系统
6.3 STOMP协议
STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。STOMP提供一个可互操作的连接格式,允许客户端与任意STOMP消息代理(Broker)进行交互。
优点:命令模式(非topicqueue模式)
6.4 XMPP协议
XMPP(可扩展消息处理现场协议,Extensible Messaging and Presence Protocol)是基于可扩展标记语言(XML)的协议,多用于即时消息(IM)以及在线现场探测。适用于服务器之间的准即时操作。核心是基于XML流传输,这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同。
优点:通用公开、兼容性强、可扩展、安全性高,但XML编码格式占用带宽大
6.5 其他基于TCP/IP自定义的协议
有些特殊框架(如:redis、kafka、zeroMq等)根据自身需要未严格遵循MQ规范,而是基于TCPIP自行封装了一套协议,通过网络socket接口进行传输,实现了MQ的功能。
7 常见消息中间件MQ介绍
7.1 RocketMQ
阿里系下开源的一款分布式、队列模型的消息中间件,原名Metaq,3.0版本名称改为RocketMQ,是阿里参照kafka设计思想使用java实现的一套mq。同时将阿里系内部多款mq产品(Notify、metaq)进行整合,只维护核心功能,去除了所有其他运行时依赖,保证核心功能最简化,在此基础上配合阿里上述其他开源产品实现不同场景下mq的架构,目前主要多用于订单交易系统。
具有以下特点:
官方提供了一些不同于kafka的对比差异:
https://rocketmq.apache.org/docs/motivation/
7.2 RabbitMQ
使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP,STOMP,也正是如此,使的它变的非常重量级,更适合于企业级的开发。同时实现了Broker架构,核心思想是生产者不会将消息直接发送给队列,消息在发送给客户端时先在中心队列排队。对路由(Routing),负载均衡(Load balance)、数据持久化都有很好的支持。多用于进行企业级的ESB整合。
7.3 ActiveMQ
Apache下的一个子项目。使用Java完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,少量代码就可以高效地实现高级应用场景。可插拔的传输协议支持,比如:in-VM, TCP, SSL, NIO, UDP, multicast, JGroups and JXTA transports。RabbitMQ、ZeroMQ、ActiveMQ均支持常用的多种语言客户端 C++、Java、.Net,、python、 Php、 Ruby等。
7.4 Redis
使用C语言开发的一个Key-Value的NoSQL数据库,开发维护很活跃,虽然它是一个Key-Value数据库存储系统,但它本身支持MQ功能,所以完全可以当做一个轻量级的队列服务来使用。对于RabbitMQ和Redis的入队和出队操作,各执行100万次,每10万次记录一次执行时间。测试数据分为128Bytes、512Bytes、1K和10K四个不同大小的数据。实验表明:入队时,当数据比较小时Redis的性能要高于RabbitMQ,而如果数据大小超过了10K,Redis则慢的无法忍受;出队时,无论数据大小,Redis都表现出非常好的性能,而RabbitMQ的出队性能则远低于Redis。
7.5 Kafka
Apache下的一个子项目,使用scala实现的一个高性能分布式Publish/Subscribe消息队列系统,具有以下特性:
7.6 ZeroMQ
号称最快的消息队列系统,专门为高吞吐量/低延迟的场景开发,在金融界的应用中经常使用,偏重于实时数据通信场景。ZMQ能够实现RabbitMQ不擅长的高级/复杂的队列,但是开发人员需要自己组合多种技术框架,开发成本高。因此ZeroMQ具有一个独特的非中间件的模式,更像一个socket library,你不需要安装和运行一个消息服务器或中间件,因为你的应用程序本身就是使用ZeroMQ API完成逻辑服务的角色。但是ZeroMQ仅提供非持久性的队列,如果down机,数据将会丢失。如:Twitter的Storm中使用ZeroMQ作为数据流的传输。
ZeroMQ套接字是与传输层无关的:ZeroMQ套接字对所有传输层协议定义了统一的API接口。默认支持 进程内(inproc) ,进程间(IPC) ,多播,TCP协议,在不同的协议之间切换只要简单的改变连接字符串的前缀。可以在任何时候以最小的代价从进程间的本地通信切换到分布式下的TCP通信。ZeroMQ在背后处理连接建立,断开和重连逻辑。
特性:
二、主要消息中间件的比较
② 为什么大数据用python
Python 已经成为较受欢迎的程序设计语言之一。自从2004年以后,python的使用率呈线性增长。2011年1月,它被TIOBE编程语言排行榜评为2010年度语言。由于Python语言的简洁性、易读性以及可扩展性,在国外用Python做科学计算的研究机构日益增多,一些知名大学已经采用Python来教授程序设计课程。
数据就是资产。大数据工程师是现在十分火热、高薪的职位。做大数据开发和分析不仅要用到Java,Python也是较重要的语言。
那么,今天我们就来分析一下,Python之于大数据的意义和作用。
相关推荐:《Python入门教程》
什么是大数据?
大数据(big data),指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。
为什么是python大数据?
从大数据的网络介绍上看到,大数据想要成为信息资产,需要有两步,一是数据怎么来,二是数据处理。
数据怎么来:
在数据怎么来这个问题上,数据挖掘无疑是很多公司或者个人的优选,毕竟大部分公司或者个人是没有能力产生这么多数据的,只能是挖掘互联网上的相关数据。
网络爬虫是Python的传统强势领域,较流行的爬虫框架Scrapy,HTTP工具包urlib2,HTML解析工具beautifulsoup,XML解析器lxml,等等,都是能够独当一面的类库。
当然,网络爬虫并不仅仅只是打开网页,解析HTML怎么简单。高效的爬虫要能够支持大量灵活的并发操作,常常要能够同时几千甚至上万个网页同时抓取,传统的线程池方式资源浪费比较大,线程数上千之后系统资源基本上就全浪费在线程调度上了。
Python由于能够很好的支持协程(Coroutine)操作,基于此发展起来很多并发库,如Gevent,Eventlet,还有Celery之类的分布式任务框架。被认为是比AMQP更高效的ZeroMQ也是较早就提供了Python版本。有了对高并发的支持,网络爬虫才真正可以达到大数据规模。
数据处理:
有了大数据,那么也需要处理,才能找到适合自己的数据。而在数据处理方向,Python也是数据科学家较喜欢的语言之一,这是因为Python本身就是一门工程性语言,数据科学家用Python实现的算法,可以直接用在产品中,这对于大数据初创公司节省成本是非常有帮助的。
正是因为这些原因,才让python语言成为很多公司处理大数据的优选。加之python本身具有简单、易学、库多等原因,让越来越多的人选择转行python开发。
③ 从 0 到 1:全面理解 RPC 远程调用
作者 | Python编程时光
责编 | 胡巍巍
什么是RPC呢?网络给出的解释是这样的:“RPC(Remote Procere Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议”。
这个概念听起来还是比较抽象,没关系,继续往后看,后面概念性的东西,我会讲得足够清楚,让你完全掌握 RPC 的基础内容。
在 OpenStack 里的进程间通信方式主要有两种,一种是基于HTTP协议的RESTFul API方式,另一种则是RPC调用。
那么这两种方式在应用场景上有何区别呢?
有使用经验的人,就会知道:
首先,给你提两个问题,带着这两个问题再往下看:
1、RPC 和 REST 区别是什么?2、为什么要采用RPC呢?
首先,第一个问题:RPC 和 REST 区别是什么?
你一定会觉得这个问题很奇怪,是的,包括我,但是你在网络上一搜,会发现类似对比的文章比比皆是,我在想可能很多初学者由于基础不牢固,才会将不相干的二者拿出来对比吧。既然是这样,那为了让你更加了解陌生的RPC,就从你熟悉得不能再熟悉的 REST 入手吧。
01、所属类别不同
REST,是Representational State Transfer 的简写,中文描述表述性状态传递(是指某个瞬间状态的资源数据的快照,包括资源数据的内容、表述格式(XML、JSON)等信息。)
REST 是一种软件架构风格。这种风格的典型应用,就是HTTP。其因为简单、扩展性强的特点而广顷肢受开发者的青睐。
而RPC 呢,是 Remote Procere Call Protocol 的简写,中文描述是远程过程调用,它可以实现客户端像调用本地服务(方法)一样调用服务器的服务(方法)。
而 RPC 可以基于 TCP/UDP,也可以基于 HTTP 协议进行传输的,按理说它和REST不是一个层面意义上的东西,不应该放在一起讨论,但是谁让REST这么流行呢,它是目前最流行的一套互联网应用程序的API设计标准,某种意义下,我们说 REST 可以其实就是指代 HTTP 协议。
02、使用方式不同
03、面向对象不同
从设计上来看,RPC,所谓的远程过程调用 ,是面向方法的 ,REST:所谓的 Representational state transfer ,是面向资源的,除此之外,还有一种叫做 SOA,所谓的面向服务的架构,它是面向消息的,这个接触不多,就不多说了。
04、序列化协议不同
接口调用通常包含两个部分,序列化和通信协议。
通信协议,上面已经提及了,REST 是 基于 HTTP 协议,而 RPC 可以基于 TCP/UDP,也可以基于 HTTP 协议进行传输的。
常见的序列化协议,有:json、xml、hession、protobuf、thrift、text、bytes等,REST 通常使用的是 JSON或者XML,而 RPC 使用的是渣历 JSON-RPC,或者 XML-RPC。
通过以上几点,我们知道了 REST 和 RPC 之间有很明显的差异。
然后第二个问题:为什么要采用RPC呢?
那到底为何要使用 RPC,单纯的依靠RESTful API不可以吗?为什么要搞这么多复杂的协议,渣渣表示真的学不过来了。
关于这一点,以下几点仅是我的个人猜想,仅供交流哈:
说了这么多,我们该如何选择这两者呢?我总结了如下两点,供你参考:
“远程调用”意思就是:被调用方法的具体实现不在程序运行本地,而是在别的某个地方(分布到各个服务器),调用者只想要函数运算的结果,却不需要实现函数的具体细节。
光说不练嘴把式,接下来,我将分别用三种不同的方式全面地让你搞明白 rpc 远程调用是如何实现的。
01、基于 xml-rpc
Python实现 rpc,可以使用标准库里的 SimpleXMLRPCServer,它是基于XML-RPC 协议的。
有了这个模块,开如乎搜启一个 rpc server,就变得相当简单了。执行以下代码:
有了 rpc server,接下来就是 rpc client,由于我们上面使用的是 XML-RPC,所以 rpc clinet 需要使用xmlrpclib 这个库。
然后,我们通过 server_proxy 对象就可以远程调用之前的rpc server的函数了。
SimpleXMLRPCServer是一个单线程的服务器。这意味着,如果几个客户端同时发出多个请求,其它的请求就必须等待第一个请求完成以后才能继续。
若非要使用 SimpleXMLRPCServer 实现多线程并发,其实也不难。只要将代码改成如下即可。
02、基于json-rpc
SimpleXMLRPCServer 是基于 xml-rpc 实现的远程调用,上面我们也提到 除了 xml-rpc 之外,还有 json-rpc 协议。
那 python 如何实现基于 json-rpc 协议呢?
答案是很多,很多web框架其自身都自己实现了json-rpc,但我们要独立这些框架之外,要寻求一种较为干净的解决方案,我查找到的选择有两种
第一种是 jsonrpclib
第二种是 python-jsonrpc
先来看第一种 jsonrpclib
它与 Python 标准库的 SimpleXMLRPCServer 很类似(因为它的类名就叫做 SimpleJSONRPCServer ,不明真相的人真以为它们是亲兄弟)。或许可以说,jsonrpclib 就是仿照 SimpleXMLRPCServer 标准库来进行编写的。
它的导入与 SimpleXMLRPCServer 略有不同,因为SimpleJSONRPCServer分布在jsonrpclib库中。
服务端
客户端
再来看第二种python-jsonrpc,写起来貌似有些复杂。
服务端
客户端
调用过程如下
还记得上面我提到过的 zabbix API,因为我有接触过,所以也拎出来讲讲。zabbix API 也是基于 json-rpc 2.0协议实现的。
因为内容较多,这里只带大家打个,zabbix 是如何调用的:直接指明要调用 zabbix server 的哪个方法,要传给这个方法的参数有哪些。
03、基于 zerorpc
以上介绍的两种rpc远程调用方式,如果你足够细心,可以发现他们都是http+rpc 两种协议结合实现的。
接下来,我们要介绍的这种(zerorpc),就不再使用走 http 了。
zerorpc 这个第三方库,它是基于TCP协议、 ZeroMQ 和 MessagePack的,速度相对快,响应时间短,并发高。zerorpc 和 pyjsonrpc 一样,需要额外安装,虽然SimpleXMLRPCServer不需要额外安装,但是SimpleXMLRPCServer性能相对差一些。
调用过程如下
客户端除了可以使用zerorpc框架实现代码调用之外,它还支持使用“命令行”的方式调用。
客户端可以使用命令行,那服务端是不是也可以呢?
是的,通过 Github 上的文档几个 demo 可以体验到这个第三方库做真的是优秀。
比如我们可以用下面这个命令,创建一个rpc server,后面这个 time Python 标准库中的 time 模块,zerorpc 会将 time 注册绑定以供client调用。
经过了上面的学习,我们已经学会了如何使用多种方式实现rpc远程调用。
通过对比,zerorpc 可以说是脱颖而出,一支独秀。
为此,我也做了一番思考:
OpenStack 组件繁多,在一个较大的集群内部每个组件内部通过rpc通信频繁,如果都采用rpc直连调用的方式,连接数会非常地多,开销大,若有些 server 是单线程的模式,超时会非常的严重。
OpenStack 是复杂的分布式集群架构,会有多个 rpc server 同时工作,假设有 server01,server02,server03 三个server,当 rpc client 要发出rpc请求时,发给哪个好呢?这是问题一。
你可能会说轮循或者随机,这样对大家都公平。这样的话还会引出另一个问题,倘若请求刚好发到server01,而server01刚好不凑巧,可能由于机器或者其他因为导致服务没在工作,那这个rpc消息可就直接失败了呀。要知道做为一个集群,高可用是基本要求,如果出现刚刚那样的情况其实是很尴尬的。这是问题二。
集群有可能根据实际需要扩充节点数量,如果使用直接调用,耦合度太高,不利于部署和生产。这是问题三。
引入消息中间件,可以很好的解决这些问题。
解决问题一:消息只有一份,接收者由AMQP的负载算法决定,默认为在所有Receiver中均匀发送(round robin)。
解决问题二:有了消息中间件做缓冲站,client 可以任性随意的发,server 都挂掉了?没有关系,等 server 正常工作后,自己来消息中间件取就行了。
解决问题三:无论有多少节点,它们只要认识消息中间件这一个中介就足够了。
既然讲到了消息队列,如果你之前没有接触过这块内容,最好花几分钟的时间跟我好好过下关于消息队列的几个基础概念。
首先,RPC只是定义了一个通信接口,其底层的实现可以各不相同,可以是 socket,也可以是今天要讲的 AMQP。
AMQP(Advanced Message Queuing Protocol)是一种基于队列的可靠消息服务协议,作为一种通信协议,AMQP同样存在多个实现,如Apache Qpid,RabbitMQ等。
以下是 AMQP 中的几个必知的概念:
Publisher:消息发布者
Queue:用来保存消息的存储空间,消息没有被receiver前,保存在队列中。
Exchange:用来接收Publisher发出的消息,根据Routing key 转发消息到对应的Message Queue中,至于转到哪个队列里,这个路由算法又由exchange type决定的。
Exchange type:主要四种描述exchange的类型。
direct:消息路由到满足此条件的队列中(queue,可以有多个):routing key = binding key
topic:消息路由到满足此条件的队列中(queue,可以有多个):routing key 匹配 binding pattern. binding pattern是类似正则表达式的字符串,可以满足复杂的路由条件。
fanout:消息路由到多有绑定到该exchange的队列中。
binding :binding是用来描述exchange和queue之间的关系的概念,一个exchang可以绑定多个队列,这些关系由binding建立。前面说的binding key /binding pattern也是在binding中给出。
为了让你明白这几者的关系,我画了一张模型图。
关于AMQP,有几下几点值得注意:
前面铺垫了那么久,终于到了讲真实应用的场景。在生产中RPC是如何应用的呢?
其他模型我不太清楚,在 OpenStack 中的应用模型是这样的
至于为什么要如此设计,前面我已经给出了自己的观点。
接下来,就是源码解读 OpenStack ,看看其是如何通过rpc进行远程调用的。如若你对此没有兴趣(我知道很多人对此都没有兴趣,所以不浪费大家时间),可以直接跳过这一节,进入下一节。
目前Openstack中有两种RPC实现,一种是在oslo messaging,一种是在openstack.common.rpc。
openstack.common.rpc是旧的实现,oslo messaging是对openstack.common.rpc的重构。openstack.common.rpc在每个项目中都存在一份拷贝,oslo messaging即将这些公共代码抽取出来,形成一个新的项目。oslo messaging也对RPC API 进行了重新设计,对多种 transport 做了进一步封装,底层也是用到了kombu这个AMQP库。(注:Kombu 是Python中的messaging库。Kombu旨在通过为AMQ协议提供惯用的高级接口,使Python中的消息传递尽可能简单,并为常见的消息传递问题提供经过验证和测试的解决方案。)
关于oslo_messaging库,主要提供了两种独立的API:
因为 notify 实现是太简单了,所以这里我就不多说了,如果有人想要看这方面内容,可以收藏我的博客(http://python-online.cn) ,我会更新补充 notify 的内容。
OpenStack RPC 模块提供了 rpc.call,rpc.cast, rpc.fanout_cast 三种 RPC 调用方法,发送和接收 RPC 请求。
rpc.call 和 .rpc.cast 从实现代码上看,他们的区别很小,就是call调用时候会带有wait_for_reply=True参数,而cast不带。
要了解 rpc 的调用机制呢,首先要知道 oslo_messaging 的几个概念主要方法有四个:
transport:RPC功能的底层实现方法,这里是rabbitmq的消息队列的访问路径
transport 就是定义你如何访连接消息中间件,比如你使用的是 Rabbitmq,那在 nova.conf中应该有一行transport_url的配置,可以很清楚地看出指定了 rabbitmq 为消息中间件,并配置了连接rabbitmq的user,passwd,主机,端口。
target用来表述 RPC 服务器监听topic,server名称和server监听的exchange,是否广播fanout。
rpc server 要获取消息,需要定义target,就像一个门牌号一样。
rpc client 要发送消息,也需要有target,说明消息要发到哪去。
endpoints:是可供别人远程调用的对象
RPC服务器暴露出endpoint,每个 endpoint 包涵一系列的可被远程客户端通过 transport 调用的方法。直观理解,可以参考nova-conctor创建rpc server的代码,这边的endpoints就是 nova/manager.py:ConctorManager
dispatcher:分发器,这是 rpc server 才有的概念
只有通过它 server 端才知道接收到的rpc请求,要交给谁处理,怎么处理?
在client端,是这样指定要调用哪个方法的。
而在server端,是如何知道要执行这个方法的呢?这就是dispatcher 要干的事,它从 endpoint 里找到这个方法,然后执行,最后返回。
Serializer:在 python 对象和message(notification) 之间数据做序列化或是反序列化的基类。
主要方法有四个:
每个notification listener都和一个executor绑定,来控制收到的notification如何分配。默认情况下,使用的是blocking executor(具体特性参加executor一节)
模仿是一种很高效的学习方法,我这里根据 OpenStack 的调用方式,抽取出核心内容,写成一个简单的 demo,有对 OpenStack 感兴趣的可以了解一下,大部分人也可以直接跳过这章节。
注意以下代码不能直接运行,你还需要配置 rabbitmq 的连接方式,你可以写在配置文件中,通过 get_transport 从cfg.CONF 中读取,也可以直接将其写成url的格式做成参数,传给 get_transport 。而且还要nova或者其他openstack组件的环境中运行(因为需要有ctxt这个环境变量)
简单的 rpc client
简单的 rpc server
【End】
热 文 推 荐
☞Facebook 发币 Libra;谷歌十亿美金为穷人造房;第四代树莓派 Raspberry Pi 4 发布 | 开发者周刊
☞WebRTC 将一统实时音视频天下?
☞小米崔宝秋:小米 AIoT 深度拥抱开源
☞华为在美研发机构 Futurewei 意欲分家?
☞老司机教你如何写出没人敢维护的代码!
☞Python有哪些技术上的优点?比其他语言好在哪儿?
☞上不了北大“图灵”、清华“姚班”,AI专业还能去哪上?
☞公链史记 | 从鸿蒙初辟到万物生长的十年激荡……
☞边缘计算容器化是否有必要?
☞马云曾经偶像,终于把阿里留下的1400亿败光了!
你点的每个“在看”,我都认真当成了喜欢
④ 为什么从事大数据行业,一定要学习Python
你好,这主要是因为Python在处理大数据方面有着得天独厚的优势。
以后您如果再遇到类似的问题,可以按照下面的思路去解决:
1、发现问题:往往生活在世界中,时时刻刻都处在这各种各样的矛盾中,当某些矛盾放映到意识中时,个体才发现他是个问题,并要求设法去解决它。这就是发现问题的阶段。从问题的解决的阶段性看,这是第一阶段,是解决问题的前提。
2、分析问题:要解决所发现的问题,必须明确问题的性质,也就是弄清楚有哪些矛盾、哪些矛盾方面,他们之间有什么关系,以明确所要解决的问题要达到什么结果,所必须具备的条件、其间的关系和已具有哪些条件,从而找出重要的矛盾、关键矛盾之所在。
3、提出假设:在分析问题的基础上,提出解决问题的假设,即可采用的解决方案,其中包括采取什么原则和具体的途径和方法,但所有这些往往不是简单现成的,而且有多种多样的可能。但提出假设是问题解决的关键阶段,正确的假设引导问题顺利得到解决,不正确不恰当的假设则使问题的解决走弯路或导向歧途。
4、校验假设:假设只是提出n种可能解决方案,还不能保证问题必定能获得解决,所以问题解决的最后一步是对假设进行检验。不论哪种检验如果未能获得预期结果,必须重新另提出假设再进行检验,直至获得正确结果,问题才算解决。
⑤ OpenStack璇︾粏璧勬枡澶у叏
OpenStack鏄涓涓鐢盢ASA锛堢编锲藉浗瀹惰埅绌鸿埅澶╁眬锛夊拰Rackspace钖堜綔镰斿彂骞跺彂璧风殑锛屼互Apache璁稿彲璇佹巿𨱒幂殑镊鐢辫蒋浣揿拰寮鏀惧师濮嬬爜椤圭洰銆
OpenStack鏄涓涓寮婧愮殑浜戣$畻绠$悊骞冲彴椤圭洰锛岀敱鍑犱釜涓昏佺殑缁勪欢缁勫悎璧锋潵瀹屾垚鍏蜂綋宸ヤ綔銆侽penStack鏀鎸佸嚑涔庢墍链夌被鍨嬬殑浜戠幆澧冿纴椤圭洰鐩镙囨槸鎻愪緵瀹炴柦绠鍗曘佸彲澶ц勬ā镓╁𪾢銆佷赴瀵屻佹爣鍑嗙粺涓镄勪簯璁$畻绠$悊骞冲彴銆侽penStack阃氲繃钖勭崭簰琛ョ殑链嶅姟鎻愪緵浜嗗熀纭璁炬柦鍗虫湇锷★纸IaaS锛夌殑瑙e喅鏂规堬纴姣忎釜链嶅姟鎻愪緵API浠ヨ繘琛岄泦鎴愩
OpenStack鏄涓涓镞ㄥ湪涓哄叕鍏卞强绉佹湁浜戠殑寤鸿句笌绠$悊鎻愪緵杞浣撶殑寮婧愰”鐩銆傚畠镄勭ぞ鍖烘嫢链夎秴杩130瀹朵紒涓氩强1350浣嶅紑鍙戣咃纴杩欎簺链烘瀯涓庝釜浜洪兘灏哋penStack浣滀负锘虹璁炬柦鍗虫湇锷★纸IaaS锛夎祫婧愮殑阃氱敤鍓岖銆侽penStack椤圭洰镄勯栬佷换锷℃槸绠鍖栦簯镄勯儴缃茶繃绋嫔苟涓哄叾甯︽潵镩濂界殑鍙镓╁𪾢镐с傛湰鏂囧笇链涢氲繃鎻愪緵蹇呰佺殑鎸囧间俊鎭锛屽府锷╁ぇ瀹跺埄鐢∣penStack鍓岖𨱒ヨ惧畾鍙婄$悊镊宸辩殑鍏鍏变簯鎴栫佹湁浜戙
OpenStack浜戣$畻骞冲彴锛屽府锷╂湇锷″晢鍜屼紒涓氩唴閮ㄥ疄鐜扮被浼间簬 Amazon EC2 鍜 S3 镄勪簯锘虹鏋舵瀯链嶅姟(Infrastructure as a Service, IaaS)銆侽penStack 鍖呭惈涓や釜涓昏佹ā缁勶细Nova 鍜 Swift锛屽墠钥呮槸 NASA 寮鍙戠殑铏氭嫙浼烘湇鍣ㄩ儴缃插拰涓氩姟璁$畻妯$粍锛涘悗钥呮槸 Rackspace寮鍙戠殑鍒嗘暎寮忎簯瀛桦偍妯$粍锛屼袱钥呭彲浠ヤ竴璧风敤锛屼篃鍙浠ュ垎寮鍗旷嫭鐢ㄣ侽penStack闄や简链 Rackspace 鍜 NASA 镄勫ぇ锷涙敮鎸佸栵纴杩樻湁鍖呮嫭 Dell銆丆itrix銆 Cisco銆 Canonical绛夐吨閲忕骇鍏鍙哥殑璐$尞鍜屾敮鎸侊纴鍙戝𪾢阃熷害闱炲父蹇锛屾湁鍙栦唬鍙︿竴涓涓氱晫棰嗗厛寮婧愪簯骞冲彴 Eucalyptus 镄勬佸娍銆
锘烘湰浠嬬粛
- 涓鏂囧悕 锛歄penStack浜戣$畻绠$悊骞冲彴
- 澶栨枃钖 锛歄penStack
- 寮鍙戣 锛歂ASA锛孯ackspace
- 绋嫔纺璇瑷 锛歅ython
- 阆靛惊镙囧嗳 锛歄pen 銆丄MQP銆丼QLAlchemy
杩愮敤锣冨洿
OpenStack鏄疘aaS(锘虹璁炬柦鍗虫湇锷)缁勪欢锛岃╀换浣曚汉閮藉彲浠ヨ嚜琛屽缓绔嫔拰鎻愪緵 浜戠杩愮畻 链嶅姟銆 姝ゅ栵纴OpenStack涔熺敤浣滃缓绔 阒茬伀澧 鍐呯殑钬 绉佹湁浜 钬濓纸Private Cloud锛夛纴鎻愪緵链烘瀯鎴栦紒涓氩唴钖勯儴闂ㄥ叡浜璧勬簮銆铡傚晢鏀鎻
缇庡浗锲藉惰埅绌鸿埅澶╁眬镄凬ebula杩愮畻骞冲彴銆 缇庡浗锲藉惰埅绌鸿埅澶╁眬镄凬ebula杩愮畻骞冲彴銆 鐜版椂宸茶〃绀烘敮鎸丱penStack椤圭洰镄勫ぇ鍨嬬‖浣揿巶鍟嗗寘𨰾锛欼BM銆丄MD銆両ntel鍜屾埓灏旂瓑銆 寰杞鍦2010骞10链堣〃绀烘敮鎸丱penStack涓嶹indows Server 2008 R2镄勬暣钖堛 2011骞2链堬纴镐濈戠郴缁熸e纺锷犲叆OpenStack椤圭洰锛岄吨镣圭爷鍒禣penStack镄勭绣璺链嶅姟銆 Ubuntu链𨱒ュ湪鍫嗗彔鏂归溃镄勪簯缃戣矾鍖栨柟妗堛 2012骞4链堬纴IBM瀹e竷锷犲叆OpenStack椤圭洰锛屽苟浣滀负涓昏佽禐锷╁晢銆 2012骞10链堬纴Viacloud浜掕仈浜戝钩鍙板姞鍏OpenStack椤圭洰锛岀爷鍒禣penStack鍏链変簯骞冲彴鍜岀佹湁浜戝钩鍙般 IBM鍦2013骞翠妇琛岀殑 IBM Pulse澶т细瀹e竷灏嗗熀浜嶰penStack鎻愪緵绉佹湁浜戞湇锷′互鍙婄浉鍏冲楃敤銆鎶链璧勬枡
浠Python绋嫔纺璇瑷缂栧啓 鏁村悎Tornado 缃戦〉浼烘湇鍣ㄣ丯ebula杩愮畻骞冲彴 浣跨敤Twisted杞浣撴嗘灦 阆靛惊Open Virtualization Format銆丄MQP銆丼QLAlchemy绛夋爣鍑 铏氭嫙链哄櫒杞浣撴敮鎸佸寘𨰾锛欿VM銆乆en銆乂irtualBox銆丵EMU銆 LXC 绛夈椤圭洰
镙稿绩椤圭洰
OpenStack瑕嗙洊浜嗙绣璺銆佽櫄𨰾熷寲銆佷綔涓氱郴缁熴佷己链嶅櫒绛夊悇涓鏂归溃銆傚畠鏄涓涓姝e湪寮鍙戜腑镄勪簯璁$畻骞冲彴椤圭洰锛屾牴鎹鎴愮啛鍙婇吨瑕佺▼搴︾殑涓嶅悓锛岃鍒呜В鎴愭牳蹇冮”鐩銆佸靛寲椤圭洰锛屼互鍙婃敮鎸侀”鐩鍜岀浉鍏抽”鐩銆傛疮涓椤圭洰閮芥湁镊宸辩殑濮斿憳浼氩拰椤圭洰鎶链涓荤★纴钥屼笖姣忎釜椤圭洰閮戒笉鏄涓鎴愪笉鍙樼殑锛屽靛寲椤圭洰鍙浠ユ牴鎹鍙戝𪾢镄勬垚镡熷害鍜岄吨瑕佹э纴杞鍙树负镙稿绩椤圭洰銆傛埅姝㈠埌Icehouse鐗堟湰锛屼笅闱㈠垪鍑轰简10涓镙稿绩椤圭洰锛埚嵆OpenStack链嶅姟锛夈 璁$畻锛圕ompute锛夛细Nova銆备竴濂楁带鍒跺櫒锛岀敤浜庝负鍗曚釜鐢ㄦ埛鎴栦娇鐢ㄧ兢缁勭$悊铏氭嫙链哄疄渚嬬殑鏁翠釜鐢熷懡锻ㄦ湡锛屾牴鎹鐢ㄦ埛闇姹傛潵鎻愪緵铏氭嫙链嶅姟銆傝礋璐h櫄𨰾熸満鍒涘缓銆佸紑链恒佸叧链恒佹寕璧枫佹殏锅溿佽皟鏁淬佽縼绉汇侀吨钖銆侀攒姣佺瓑镎崭綔锛岄厤缃瓹PU銆佽板繂浣撶瓑淇℃伅瑙勬牸銆傝嚜Austin鐗堟湰闆嗘垚鍒伴”鐩涓銆 瀵硅薄瀛桦偍锛圤bject Storage锛夛细Swift銆备竴濂楃敤浜庡湪澶ц勬ā鍙镓╁𪾢绯荤粺涓阃氲繃鍐呯疆鍐椾綑鍙婇珮瀹归敊链哄埗瀹炵幇瀵硅薄瀛桦偍镄勭郴缁燂纴鍏佽歌繘琛屽瓨鍌ㄦ垨钥呮绱㈡。妗堛傚彲涓篏lance鎻愪緵闀滃儚瀛桦偍锛屼负Cinder鎻愪緵鍗峰囦唤链嶅姟銆傝嚜Austin鐗堟湰闆嗘垚鍒伴”鐩涓 闀滃儚链嶅姟锛圛mage Service锛夛细Glance銆备竴濂楄櫄𨰾熸満闀滃儚镆ユ垒鍙婃绱㈢郴缁燂纴鏀鎸佸氱嶈櫄𨰾熸満闀滃儚镙煎纺锛圆KI銆丄MI銆丄RI銆両SO銆丵COW2銆丷aw銆乂DI銆乂HD銆乂MDK锛夛纴链夊垱寤轰笂浼犻暅镀忋佸垹闄ら暅镀忋佺紪杈戦暅镀忓熀链淇℃伅镄勫姛鑳姐傝嚜Bexar鐗堟湰闆嗘垚鍒伴”鐩涓銆 韬浠芥湇锷★纸Identity Service锛夛细Keystone銆备负OpenStack鍏朵粬链嶅姟鎻愪緵韬浠介獙璇併佹湇锷¤勫垯鍜屾湇锷′护鐗岀殑锷熻兘锛岀$悊Domains銆丳rojects銆乁sers銆丢roups銆丷oles銆傝嚜Essex鐗堟湰闆嗘垚鍒伴”鐩涓銆 缃戣矾&鍦板潃绠$悊锛圢eork锛夛细Neutron銆傛彁渚涗簯璁$畻镄勭绣璺铏氭嫙鍖栨妧链锛屼负OpenStack鍏朵粬链嶅姟鎻愪緵缃戣矾杩炵嚎链嶅姟銆备负鐢ㄦ埛鎻愪緵鎺ュ彛锛屽彲浠ュ畾涔垲eork銆丼ub銆丷outer锛岄厤缃瓺HCP銆丏NS銆佽礋杞藉潎琛°丩3链嶅姟锛岀绣璺鏀鎸丢RE銆乂LAN銆傚栨寕绋嫔纺鏋舵瀯鏀鎸佽稿氢富娴佺殑缃戣矾铡傚跺拰鎶链锛屽侽penvSwitch銆傝嚜Folsom鐗堟湰闆嗘垚鍒伴”鐩涓銆 鍧楀瓨鍌 (Block Storage)锛欳inder銆备负杩愯屽疄渚嬫彁渚涚ǔ瀹氱殑鏁版嵁鍧楀瓨鍌ㄦ湇锷★纴瀹幂殑澶栨寕绋嫔纺椹卞姩鏋舵瀯链夊埄浜庡潡璁惧囩殑鍒涘缓鍜岀$悊锛屽傚垱寤哄嵎銆佸垹闄ゅ嵎锛屽湪瀹炰緥涓婃寕杞藉拰鍗歌浇鍗枫傝嚜Folsom鐗堟湰闆嗘垚鍒伴”鐩涓銆 UI 鐣岄溃 (Dashboard)锛欻orizon銆侽penStack涓钖勭嶆湇锷$殑Web绠$悊闂ㄦ埛锛岀敤浜庣亩鍖栫敤鎴峰规湇锷$殑镎崭綔锛屼緥濡傦细钖锷ㄥ疄渚嬨佸垎閰岻P浣嶅潃銆侀厤缃璁块梾鎺у埗绛夈傝嚜Essex鐗堟湰闆嗘垚鍒伴”鐩涓銆 娴嬮噺 (Metering)锛欳eilometer銆傚儚涓涓婕忔枟涓镙凤纴鑳芥妸OpenStack鍐呴儴鍙戠敓镄勫嚑涔庢墍链夌殑浜嬩欢閮芥敹闆呜捣𨱒ワ纴铹跺悗涓鸿¤垂鍜岀洃鎺т互鍙婂叾瀹冩湇锷℃彁渚涙暟鎹鏀鎾戙傝嚜Havana鐗堟湰闆嗘垚鍒伴”鐩涓銆 閮ㄧ讲缂栨帓 (Orchestration)锛欻eat銆傛彁渚涗简涓绉嶉氲繃妯℃澘瀹氢箟镄勫岗钖岄儴缃叉柟寮忥纴瀹炵幇浜戝熀纭璁炬柦杞浣撹繍琛岀幆澧冿纸璁$畻銆佸瓨鍌ㄥ拰缃戣矾璧勬簮锛夌殑镊锷ㄥ寲閮ㄧ讲銆傝嚜Havana鐗堟湰闆嗘垚鍒伴”鐩涓銆 璧勬枡搴撴湇锷★纸Database Service锛夛细Trove銆备负鐢ㄦ埛鍦∣penStack镄勭幆澧冩彁渚涘彲镓╁𪾢鍜屽彲闱犵殑鍏崇郴鍜岄潪鍏崇郴璧勬枡搴揿紩镎庢湇锷°傝嚜Icehouse鐗堟湰闆嗘垚鍒伴”鐩涓銆绀惧尯椤圭洰
锛14涓锛 璐熻浇鍧囱锛欰tlas-LB锛圧ackspace锛 璁鎭浼鍒楋细Burrow锛圥iston锛 浜戠$悊宸ュ叿锛欳lanavi锛图rupal锛 镊锷ㄩ儴缃诧细Crowbar锛图ell锛 链嶅姟閮ㄧ讲锛钦uju锛圲buntu锛 鍏崇郴鍨嬭祫鏂椤簱锛歊edDwarf锛圧ackspace锛 ...甯傚満瓒嫔悜
Rackspace浠OpenStack涓哄熀纭镄勭佹湁浜戜笟锷℃疮骞磋惀鏀7浜跨编鍏冿纴澧为暱鐜囱秴杩囦简20%銆 OpenStack铏界劧链変簺鏂归溃杩树笉澶鎴愮啛锛岀劧钥屽畠链夊叏鐞冨ぇ閲忕殑缁勭粐鏀鎸侊纴澶ч噺镄勫紑鍙戜汉锻桦弬涓庯纴鍙戝𪾢杩呴熴傚浗闄呬笂宸茬粡链夊緢澶氢娇鐢∣penStack鎼寤虹殑鍏链変簯銆佺佹湁浜戙佹贩钖堜簯锛屼緥濡傦细RackspaceCloud銆佹儬鏅浜戙丮ercadoLibre镄処T锘虹璁炬柦浜戙丄T&T镄凛loudArchitec銆佹埓灏旂殑OpenStack瑙e喅鏂规堢瓑绛夈傝屽湪锲藉唴OpenStack镄勭儹搴︿篃鍦ㄩ愭笎鍗囨俯锛屽崕鑳滃ぉ鎴愩侀珮寰峰湴锲俱佷含涓溿侀樋閲屽反宸淬佺栌搴︺佷腑鍏淬佸崕涓虹瓑閮藉筄penStack浜х敓浜嗘禄铡氱殑鍏磋叮骞跺弬涓庡叾涓銆傝嚜2010骞村垱绔嬩互𨱒ワ纴宸插彂甯10涓鐗堟湰銆傚叾涓琏cehouse鐗堟湰链120涓缁勭粐銆1202钖崭唬镰佽础鐚钥呭弬涓庯纴钥屾渶鏂扮殑鏄疛uno鐗堟湰銆侽penStack寰埚彲鑳藉湪链𨱒ョ殑锘虹璁炬柦鍗虫湇锷★纸IaaS锛夎祫婧愮$悊鏂归溃鍗犳嵁棰嗗间綅缃锛屾垚涓哄叕链変簯銆佺佹湁浜戝强娣峰悎浜戠$悊镄勨滀簯浣滀笟绯荤粺钬濇爣鍑澶у瀷鐢ㄦ埛
缇庡浗锲藉惰埅绌鸿埅澶╁眬 锷犳嬁澶у崐瀹樻柟链烘瀯CANARIE缃戣矾镄凞AIR锛图igital Aelerator for Innovation and Research锛夐”鐩锛屽悜澶у︿笌涓灏忓瀷浼佷笟鎻愪緵镰旂┒鍜屽紑鍙戜簯绔杩愮畻鐜澧冿绂DAIR鐢ㄦ埛鍙浠ユ寜闇瑕佸揩阃熷缓绔嬬绣璺𨰾撴墤銆 𨱍犳櫘浜戯纸浣跨敤Ubuntu Linux锛 MercadoLibre镄処T锘虹璁炬柦浜戯纴鐜版椂浠OpenStack绠$悊瓒呰繃6000 鍙拌櫄𨰾熸満鍣ㄣ AT&T镄勨淐loud Architect钬濓纴灏嗗湪缇庡浗镄勮揪𨰾夋柉銆佸湥鍦颁筜鍝ュ拰鏂版辰瑗垮窞瀵瑰栨彁渚涗簯绔链嶅姟銆鍐呭硅﹁В
鍒涘缓铏氭嫙链猴纸VM锛夐渶瑕佸悇绉嶆湇锷$殑浜掑姩鍜岄厤钖埚伐浣溿备笅锲惧𪾢绀轰简OpenStack鍏稿瀷鐜澧冩灦鏋勶纴钖勪釜链嶅姟涔嬮棿镄勪簰锷ㄥ拰镵岃兘銆 OpenStack鍏稿瀷鐜澧冩灦鏋 OpenStack锲燨pen钥屽紑鏀撅纴锲犵粍浠惰岀伒娲伙纴锲犲寘瀹硅屽崥澶с傛湁璁$畻銆佺绣璺銆佸硅薄瀛桦偍銆佸潡瀛桦偍銆佽韩浠姐侀暅镀忔湇锷°侀棬鎴枫佹祴閲忋侀儴缃茬紪鎺掋佽祫鏂椤簱链嶅姟绛夌瓑缁勪欢锛屾湁镄勭粍浠跺彲浠ユ牴鎹闇瑕侀夋嫨瀹夎咃纴缁勭绣缁撴瀯涔熷緢𨱔垫椿銆佸氭牱銆傚疄鐜颁简鏀鎸佹帴鍏ュ氱崭富娴佽櫄𨰾熸満杞浣掳细KVM銆丩XC銆丵EMU銆丠yper-V銆乂Mware銆乆enServer锛屼篃鍙浠ヨ嚜琛屽紑鍙戝栨寕绋嫔纺鎺ュ叆鍏朵粬镄勮櫄𨰾熷寲杞浣撱 OpenStack Compute (Nova)鏄涓濂楁带鍒跺櫒锛岀敤浜庝负鍗曚釜鐢ㄦ埛鎴栦娇鐢ㄧ兢缁勫惎锷ㄨ櫄𨰾熸満瀹炰緥銆傚畠钖屾牱鑳藉熺敤浜庝负鍖呭惈镌澶氢釜瀹炰緥镄勭壒瀹氶”鐩璁惧畾缃戣矾銆侽penStack Compute鍦ㄥ叕鍏变簯澶勭悊鏂归溃鍫涓峣mazon EC2鐩告彁骞惰猴绂钥屽湪绉佹湁浜戞柟闱涔熸涓嶉婅壊浜嵘Mware镄勪骇鍝併傚湪鍏鍏变簯涓锛岃繖濂楃$悊链哄埗灏嗘彁渚涢勫埗镄勯暅镀忔垨鏄涓虹敤鎴峰垱寤虹殑闀滃儚鎻愪緵瀛桦偍链哄埗锛岃繖镙风敤鎴峰氨鑳藉熷皢闀滃儚浠ヨ櫄𨰾熸満镄勫舰寮忓惎锷ㄣ OpenStack 瀵硅薄瀛桦偍(Swift)鏄涓濂楃敤浜庡湪澶ц勬ā鍙镓╁𪾢绯荤粺涓阃氲繃鍐呯疆鍐椾綑鍙婂归敊链哄埗瀹炵幇瀵硅薄瀛桦偍镄勭郴缁熴傝繖浜涘硅薄鑳藉熼氲繃涓涓猂EST API鎴栨槸镀廋yberck杩欐牱鍙浠ュ规帴瀵硅薄瀛桦偍API镄勫㈡埛绔锷犱互鎭㈠嶃 OpenStack闀滃儚链嶅姟 (Glance)鏄涓濂楄櫄𨰾熸満闀滃儚镆ユ垒鍙婃绱㈢郴缁熴傚畠鑳藉熶互涓夌嶅舰寮忓姞浠ラ厤缃锛氩埄鐢∣penStack瀵硅薄瀛桦偍链哄埗𨱒ュ瓨鍌ㄩ暅镀忥绂鍒╃敤Amazon镄勭亩鍗曞瓨鍌ㄨВ鍐虫柟妗堬纸绠绉癝3锛夌洿鎺ュ瓨鍌ㄤ俊鎭锛涙垨钥呭皢S3瀛桦偍涓庡硅薄瀛桦偍缁揿悎璧锋潵锛屼綔涓篠3璁块梾镄勮繛绾垮櫒銆侽penStack闀滃儚链嶅姟鏀鎸佸氱嶈櫄𨰾熸満闀滃儚镙煎纺锛屽寘𨰾琕Mware锛圴MDK锛夈丄mazon闀滃儚锛圆KI銆丄RI銆丄MI锛変互鍙奦irtualBox镓鏀鎸佺殑钖勭岖佺熸牸寮忋傞暅镀忓厓鏁版嵁镄勫瑰櫒镙煎纺鍖呮嫭Amazon镄𪞝KI銆丄RI浠ュ强AMI淇℃伅锛屾爣鍑哋VF镙煎纺浠ュ强浜岃繘鍒跺ぇ鍨嬫暟鎹銆 OpenStack镄勫紑鍙戝懆链熸槸姣忓勾锲哄畾鍙戝竷涓や釜鏂扮増链锛屽苟涓旀疮涓涓鏂扮増杞浣揿彂甯冩椂锛屽紑鍙戣呬笌椤圭洰鎶链棰嗗艰呭凡缁忓湪瑙勫垝涓嬩竴涓鐗堟湰镄勭粏鑺伞傝繖浜涘紑鍙戣呮潵镊鍏ㄧ悆70澶氢釜缁勭粐锛岃秴杩1600浜恒备粬浠閲囩敤楂樼骇镄勫伐鍏蜂笌寮鍙戞柟寮忥纴杩涜屼唬镰佹煡鐪嬨佹寔缁镄勯泦鎴愩佹祴璇曚笌寮鍙戞灦鏋勶纴璁╃増链鍦ㄥ揩阃熸垚闀跨殑钖屾椂涔熻兘纭淇濈ǔ瀹氭с鏋勫缓绉佹湁浜
绗涓姝ユ槸璁惧畾姝g‘镄勭‖浣揿拰缃戣矾鐜澧冦傚敖绠OpenStack鍏佽稿湪涓涓鍗曚竴镄勫钩闱㈢绣璺涓婇儴缃蹭竴鍒囷纴浠庡畨鍏ㄧ殑瑙掑害𨱒ョ湅骞朵笉瀹夊叏銆傚彇鍐充簬浣犳墍浣跨敤镄勭$悊绋嫔纺浠ュ强铏氭嫙缃戣矾鎺ュ彛锛屽畠浼氩厑璁竒uest铏氭嫙链哄梾鎺㈢$悊娴侀噺銆傚缓璁镊冲皯浣跨敤涓や釜缃戣矾锛氢竴涓鐢ㄦ潵绠$悊娴侀噺锛屼竴涓鐢ㄦ潵杩涜岃櫄𨰾熸満涔嬮棿镄勫硅瘽銆傝繖镒忓懗镌镓链夌殑浜戣$畻缁撶偣涓浣犻渶瑕佷袱涓缃戝崱锛堜竴涓杩愯屽疄渚嬶级鍜岀绣璺绠$悊钥呫傝繖浜涘簲璇ヨ繍琛屽湪涓嶅悓镄処P锣冨洿涓銆傝$畻缁撶偣鍜屽疄渚嬬殑缃戣矾涔熼渶瑕佹敮鎸乂LAN镙囱帮纴锲犱负杩欐槸鍦ㄢ滈”鐩钬濅箣闂撮殧缁濇祦閲忔墍浣跨敤镄勬満鍒躲备竴涓椤圭洰绛変环浜庝綘镄勪筜椹阃奅C2璐︽埛锛岄櫎浜嗕綘涓嶈兘鎸夌収浣犳墍甯屾湜镄勬暟鐩鍒涘缓鍜屽垎閰崭箣澶栥傛疮涓涓椤圭洰閮芥湁镊宸辩殑绠$悊锻桦拰鐢ㄦ埛锛屽湪镞㈠畾椤圭洰涓镄勬墍链夊疄渚嫔彲浠ュ郊姝ら氢俊銆傞氲繃鎸囨淳姣忎竴涓椤圭洰镊宸辩殑VLAN浠ュ强鍐呴儴鍜屽栭儴镄処P浣嶅潃姹犳潵镓ц屻 涓镞︾‖浣揿拰缃戣矾璁惧畾濂斤纴涓嬩竴姝ュ氨鏄纭瀹氩湪鍝閲岄儴缃叉墍链夌殑OpenStack缁勪欢銆傛爣鍑嗛儴缃插簲链変竴涓鎺у埗鍣ㄥ拰涓绯诲垪璁$畻缁撶偣銆傛带鍒跺櫒杩愯岃鎭浼烘湇鍣锛岃祫鏂椤簱鍜屽叾浠栫殑缁勪欢𨱒ョ紪鎺掍簯锛屽悓镞惰$畻缁撶偣杩愯屽疄渚嬨备絾鏄浣犱篃鍙浠ュ垎瑙f带鍒跺櫒涓哄湴鐞嗙殑閮ㄥ垎锛屼粠钥屾敼锽勬ц兘锛屽儚鎶奙ySQL鏀惧湪涓嶅悓镄勭墿鐞嗙洅涓銆傚逛簬瀹夊叏钥岃█锛屾渶鍏抽敭镄勬槸纭淇濇疮涓閮ㄥ垎閮藉畨瑁呭湪瀹夊叏镄勪富链轰笂锛屼綘鍙闇瑕佸皢鍏堕梼锷犲湪缃戣矾涓婏纴璁╀簯杩愯浆鍗冲彲銆 鍙链変袱閮ㄥ垎闇瑕佹毚闇茬粰澶栭溃镄勪笘鐣岋纸鍗充娇闾e彧鏄浣犵殑浼佷笟缃戣矾锛夛细API浼烘湇鍣/Web 鎺у埗鍙帮纸濡傛灉寮钖锛夊拰缃戣矾绠$悊钥呫傝繖浜涗己链嶅櫒闇瑕佽繃纭锛屼綘鐢氲呖鍙浠ヤ娇鐢ㄧ涓夋柟缃戣矾鎺ュ彛𨱒ラ殧绂诲悗绔绠$悊鐢ㄦ埛杩炵嚎浜х敓镄勬祦閲忋 濡傛灉浣犻伒寰榛樿ゅ畨瑁呰存槑涔︼纴鍙鑳借繖浜涢儴鍒嗗苟涓嶅备粬浠搴旇ョ殑闾f牱瀹夊叏銆备笅闱㈡槸涓浜涘叿浣撶殑鏀瑰彉锛 * MySQL浼烘湇鍣ㄤ娇鐢ㄦ寚瀹氱殑鐢ㄦ埛璐︽埛锛屼笉鏄镙筂ySQL绠$悊璐︽埛銆傝繖涓璐︽埛鍜屽瘑镰佸皢浼氭毚闇插湪姣忎竴涓浜戠粨镣逛笂锛屽嵆浣夸娇鐢ㄥ熀浜庤瘉涔︾殑璁よ瘉锛屽洜姝ゆ墍链夌粨镣归渶瑕佽块梾杩欎釜璧勬枡搴扑己链嶅櫒銆 * MySQL閰岖疆妗f堜腑锛岄檺鍒惰块梾浼烘湇鍣锛孙penStack鐢ㄦ埛璐︽埛涓哄敮涓鎺堟潈IP浣嶅潃銆 * 绉婚櫎浠讳綍涓嶉渶瑕佺殑OS缁勪欢骞剁‘淇濅綘镓璁惧畾镄勪己链嶅櫒鍙鏀鎸侀氲繃SSH镄勫熀浜庡瘑阍ョ殑锏诲叆銆 * 榛樿MySQL鍜孯abbitMQ锛堣鎭浼烘湇鍣锛夋祦閲忎笉锷犲瘑銆傚傛灉浣犻殧绂讳简绠$悊缃戣矾鍜屽潥锲虹殑涓绘満锛岃繖灏变笉搴旇ユ槸涓涓寰堢碂绯旷殑椋庨橹銆傚傛灉浣犵殑浜戠绣璺鏄扑簬鍡呮帰锛堜緥濡傦纴瀹冨拰鍏朵粬浼烘湇鍣ㄥ叡浜缃戣矾锛夛纴浣犻渶瑕佸姞瀵嗘祦閲忋备綘鍙浠ヤ娇鐢∣penSSL𨱒ヨ繘琛孧ySQL 鍜孯abbitMQ澶勭悊銆傦纸鎴戜釜浜鸿缮娌¤繘琛屾祴璇曪纴锲犳ら厤缃鍙鑳芥湁镣归毦銆傦级 涓嬩竴姝ワ纴璁颁綇濡傛灉鏀鎸乄eb绠$悊鎺у埗鍙帮纴榛樿や笉阃傜敤SSL銆链嶅姟涓蹇
涓锲绊penStack链嶅姟涓蹇姒傝堪
2013骞6链18镞ュ湪鍗椾含鍙寮浜嗏滀腑锲戒簯璁$畻浜т笟淇冭繘澶т细𨱌ㄤ腑锲绊penStack链嶅姟涓蹇冨彂甯冧细钬濓纴鍗庤儨澶╂垚鍦ㄤ细涓婃e纺瀹e竷鎺ㄥ嚭涓锲介栧禣penStack链嶅姟涓蹇冦侽penStack鏄鍏ㄧ悆寮鍙戣呭叡钖屽弬涓庣殑涓涓寮婧愰”鐩锛屾棬鍦ㄥ疄鐜扳滀簯浣滀笟绯荤粺钬濓纴鍗充竴涓鍏锋湁閮ㄧ讲鍜岀$悊鍏链変簯銆佺佹湁浜戜互鍙婃贩钖堜簯锘虹鏋舵瀯鑳藉姏镄勫钩鍙般 1銆佸缓璁惧苟杩愯惀涓锲界涓涔熷彲鑳芥槸鍞涓镄凮penstack鏀鎸佷腑蹇冦 2銆佷负Openstack镄勭爷绌惰咃纴寮鍙戣呭拰浣跨敤钥呮彁渚涗赴瀵岀殑绾夸笂鍙婄幇鍦轰笓涓氭敮鎸佹湇锷″拰鍜ㄨ㈡湇锷★纴娑堥櫎瀹㈡埛浣跨敤寮婧愯蒋浣撶殑钖庨【涔嫔咖銆 3銆佹彁楂桦浗鍐呬簯璁$畻浠庝笟浜哄憳鏁伴噺鍜岀礌璐锛屾櫘鍙婂紑婧愯蒋浣撶簿绁炰笌鎶链銆 4銆佹墦镰翠簯璁$畻寤鸿剧殑鍨勬柇锛屽ぇ澶ч檷浣庝簯璁$畻骞冲彴寤鸿句笌杩愯惀鎴愭湰锛屾帹锷ㄥ苟淇濋㱩锲藉唴浜戣$畻骞冲彴寤鸿捐摤鍕冨彂灞曘绯荤粺鏋勬垚
800鐢佃瘽鏀鎸佷腑蹇冿纸100鍧愬腑锛 Web绾夸笂鏀鎸佸钩鍙帮纸100鍧愬腑锛 链嶅姟鐢靛瓙阌鍞骞冲彴 鐭ヨ瘑搴 CRM绯荤粺 涓扑笟鍜ㄨ㈠洟阒燂纸10浜猴级 涓扑笟鐜板満鎶链鏀鎸佸洟阒燂纸50浜猴级 涓扑笟瀹㈡埛鍖栧紑鍙戝洟阒燂纸100浜猴级 涓扑笟杩愮淮绠$悊锲㈤槦锛300浜猴级 鍏ㄧ悆瀹为獙瀹ょ骇鏀鎸佸洟阒燂纸2涓锲介檯椤剁骇镙稿绩浠g爜瀹为獙瀹わ级链嶅姟鍐呭
鎻愪緵瀹屽杽镄凩1锛孡2浠ュ强L3瀹为獙瀹ょ骇鍒绾夸笂涓庣幇鍦烘湇锷 24*7鐢佃瘽鍜ㄨ/鏀鎸佹湇锷★纴Web绾夸笂鍜ㄨ㈡湇锷/鏀鎸佹湇锷 鐗堟湰鍙戝竷涓庡崌绾ф湇锷 娴嬭瘯链嶅姟 鐜板満瀹夎咃纴鍗囩骇/璋冧紭链嶅姟 瀹氩埗寮鍙戞湇锷 锘硅链嶅姟 鐭ヨ瘑搴揿叡浜链嶅姟 杩愮淮链嶅姟 鐢靛瓙浜ゆ槗链嶅姟浣挞獙
1銆佸㈡埛鍙浠24灏忔椂阃氲繃鐢佃瘽鎴栫绣璺鍦ㄦ敮鎸佷腑蹇冭幏寰楀府锷╋纴鍖呮嫭浜戞妧链鍜ㄨ锛岃祫鏂欑储鍙栵纴璐涔版湇锷″寘銆 2銆佹敹璐规湇锷″寘鍒嗕负绾у埆锛堜緥锛 锘烘湰链嶅姟鍖咃纸5*8 鐢佃瘽鏀鎸佹湇锷★级 镙囧嗳链嶅姟鍖咃纸7*24鐢佃瘽鏀鎸佹湇锷+鐜板満链嶅姟锛 楂樼骇链嶅姟鍖咃纸7*24*6骞冲彴淇澶崭缭璇侊级 3銆佷笓涓氭湇锷¢夐”锛堜緥锛 绯荤粺闆嗘垚链嶅姟 涓扑汉鍊煎畧链嶅姟 绯荤粺璋冧紭链嶅姟 绯荤粺杩佺Щ链嶅姟 宸℃链嶅姟 杩愮淮绠$悊链嶅姟 搴旀ュ洖鍝嶆湇锷 锘硅链嶅姟链嶅姟浠峰
1銆佸瑰紑婧愪簯璁$畻镄勭敤鎴峰拰娼滃湪鐢ㄦ埛 鎻愪緵浜嗕竴涓銮峰缑鐭ヨ瘑锛屾寚瀵煎拰鎶链鏀鎸佺殑娓犻亾锛岃В鍐充简濂楃敤寮婧愪簯鎶链镓句笉鍒版妧链钖庣浘镄勫按灏灞闱銆 鎻愪緵浜嗕竴涓楂樻按骞崇殑鎶链锲㈤槦瀵圭敤鎴疯繘琛屽畨瑁咃纴閰岖疆锛屽紑鍙戯纴链浣冲寲锛岃繍缁存湇锷★纴浣夸簯璁$畻骞冲彴鍙浠ユg‘镄勮閮ㄧ讲鍜屼娇鐢锛岀湡姝d骇鐢熸晥鐩娿 2銆佸逛簬Openstack浜т笟阈 淇冭繘Openstack鍦ㄤ腑锲界殑钀藉湴鐢熸牴锛屽紑鑺辩粨鏋溿傝В鍐充简Openstack闆鹃噷鐪嬭姳镄勫按灏銆 3銆佸逛簬鏀鎸佷腑蹇冩湰韬 銮峰缑澶ч噺镄勫㈡埛淇℃伅鍜岄”鐩链轰细锛岃幏寰楅珮鍒╂鼎镄勬湇锷′笟锷°傝仛钖埚ぇ閲忎笟鍐呮妧链璧勬簮锛屽舰鎴愭妧链璧勬簮姹狅纴骞堕氲繃镵氩悎鏁埚簲浣夸骇涓氶摼鍏卞悓鎴愰暱銆 4銆佸圭ぞ浼 澶уぇ淇冭繘浜戝缓璁炬ヤ紣锛岄檷浣嶪T杩愯惀鎴愭湰锛屾彁楂树笟锷℃晱鎹峰害锛岃妭鑳藉噺鎺掞纴淇冭繘浜т笟鍗囩骇銆鎴愬憳浼佷笟
鍗庤儨澶╂垚 Intel Canonical Rackspace 涓锲藉紑婧愪簯镵旂洘
⑥ 消息队列原理及选型
消息队列(Message Queue)是一种进程间通信或同一进程的不同线程间的通信方式。
Broker(消息服务器)
Broker的概念来自与Apache ActiveMQ,通俗的讲就是MQ的服务器。
Procer(生产者)
业务的发起方,负责生产消息传输给broker
Consumer(消费者)
业务的处理方,负责从broker获取消息并进行业务逻辑处理
Topic(主题)
发布订阅模式下的消息统一汇集地,不同生产者向topic发送消息,由MQ服务器分发到不同的订阅 者,实现消息的广播
Queue(队列)
PTP模式下,特定生产者向特定queue发送消息,消费者订阅特定的queue完成指定消息的接收。
Message(消息体)
根据不同通信协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输
点对点模型用于消息生产者和消息消费者之间点到点的通信。
点对点模式包含三个角色:
每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,可以放在内存 中也可以持久化,直到他们被消费或超时。
特点:
发布订阅模型包含三个角色:
多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。
特点:
AMQP即Advanced Message Queuing Protocol,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。AMQP 的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。
优点:可靠、通用
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。
优点:格式简洁、占用带宽小、移动端通信、PUSH、嵌入式系统
STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。STOMP提供一个可互操作的连接格式,允许客户端与任意STOMP消息代理(Broker)进行交互。
优点:命令模式(非topicqueue模式)
XMPP(可扩展消息处理现场协议,Extensible Messaging and Presence Protocol)是基于可扩展标记语言(XML)的协议,多用于即时消息(IM)以及在线现场探测。适用于服务器之间的准即时操作。核心是基于XML流传输,这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同。
优点:通用公开、兼容性强、可扩展、安全性高,但XML编码格式占用带宽大
RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。 RabbitMQ 主要是为了实现系统之间的双向解耦而实现的。当生产者大量产生数据时,消费者无法快速消费,那么需要一个中间层。保存这个数据。
RabbitMQ 是一个开源的 AMQP 实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP 等,支持 AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
Channel(通道)
道是两个管理器之间的一种单向点对点的的通信连接,如果需要双向交流,可以建立一对通道。
Exchange(消息交换机)
Exchange类似于数据通信网络中的交换机,提供消息路由策略。
RabbitMq中,procer不是通过信道直接将消息发送给queue,而是先发送给Exchange。一个Exchange可以和多个Queue进行绑定,procer在传递消息的时候,会传递一个ROUTING_KEY,Exchange会根据这个ROUTING_KEY按照特定的路由算法,将消息路由给指定的queue。和Queue一样,Exchange也可设置为持久化,临时或者自动删除。
Exchange有4种类型:direct(默认),fanout, topic, 和headers。
不同类型的Exchange转发消息的策略有所区别:
Binding(绑定)
所谓绑定就是将一个特定的 Exchange 和一个特定的 Queue 绑定起来。Exchange 和Queue的绑定可以是多对多的关系。
Routing Key(路由关键字)
exchange根据这个关键字进行消息投递。
vhost(虚拟主机)
在RabbitMq server上可以创建多个虚拟的message broker,又叫做virtual hosts (vhosts)。每一个vhost本质上是一个mini-rabbitmq server,分别管理各自的exchange,和bindings。vhost相当于物理的server,可以为不同app提供边界隔离,使得应用安全的运行在不同的vhost实例上,相互之间不会干扰。procer和consumer连接rabbit server需要指定一个vhost。
假设P1和C1注册了相同的Broker,Exchange和Queue。P1发送的消息最终会被C1消费。
基本的通信流程大概如下所示:
Consumer收到消息时需要显式的向rabbit broker发送basic。ack消息或者consumer订阅消息时设置auto_ack参数为true。
在通信过程中,队列对ACK的处理有以下几种情况:
即消息的Ackownledge确认机制,为了保证消息不丢失,消息队列提供了消息Acknowledge机制,即ACK机制,当Consumer确认消息已经被消费处理,发送一个ACK给消息队列,此时消息队列便可以删除这个消息了。如果Consumer宕机/关闭,没有发送ACK,消息队列将认为这个消息没有被处理,会将这个消息重新发送给其他的Consumer重新消费处理。
消息的收发处理支持事务,例如:在任务中心场景中,一次处理可能涉及多个消息的接收、处理,这应该处于同一个事务范围内,如果一个消息处理失败,事务回滚,消息重新回到队列中。
消息的持久化,对于一些关键的核心业务来说是非常重要的,启用消息持久化后,消息队列宕机重启后,消息可以从持久化存储恢复,消息不丢失,可以继续消费处理。
fanout 模式
模式特点:
direct 模式
任何发送到Direct Exchange的消息都会被转发到routing_key中指定的Queue。
如果一个exchange 声明为direct,并且bind中指定了routing_key,那么发送消息时需要同时指明该exchange和routing_key。
简而言之就是:生产者生成消息发送给Exchange, Exchange根据Exchange类型和basic_publish中的routing_key进行消息发送 消费者:订阅Exchange并根据Exchange类型和binding key(bindings 中的routing key) ,如果生产者和订阅者的routing_key相同,Exchange就会路由到那个队列。
topic 模式
前面讲到direct类型的Exchange路由规则是完全匹配binding key与routing key,但这种严格的匹配方式在很多情况下不能满足实际业务需求。
topic类型的Exchange在匹配规则上进行了扩展,它与direct类型的Exchage相似,也是将消息路由到binding key与routing key相匹配的Queue中,但这里的匹配规则有些不同。
它约定:
以上图中的配置为例,routingKey=”quick.orange.rabbit”的消息会同时路由到Q1与Q2,routingKey=”lazy.orange.fox”的消息会路由到Q1,routingKey=”lazy.brown.fox”的消息会路由到Q2,routingKey=”lazy.pink.rabbit”的消息会路由到Q2(只会投递给Q2一次,虽然这个routingKey与Q2的两个bindingKey都匹配);routingKey=”quick.brown.fox”、routingKey=”orange”、routingKey=”quick.orange.male.rabbit”的消息将会被丢弃,因为它们没有匹配任何bindingKey。
RabbitMQ,部署分三种模式:单机模式,普通集群模式,镜像集群模式。
普通集群模式
多台机器部署,每个机器放一个rabbitmq实例,但是创建的queue只会放在一个rabbitmq实例上,每个实例同步queue的元数据。
如果消费时连的是其他实例,那个实例会从queue所在实例拉取数据。这就会导致拉取数据的开销,如果那个放queue的实例宕机了,那么其他实例就无法从那个实例拉取,即便开启了消息持久化,让rabbitmq落地存储消息的话,消息不一定会丢,但得等这个实例恢复了,然后才可以继续从这个queue拉取数据, 这就没什么高可用可言,主要是提供吞吐量 ,让集群中多个节点来服务某个queue的读写操作。
镜像集群模式
queue的元数据和消息都会存放在多个实例,每次写消息就自动同步到多个queue实例里。这样任何一个机器宕机,其他机器都可以顶上,但是性能开销太大,消息同步导致网络带宽压力和消耗很重,另外,没有扩展性可言,如果queue负载很重,加机器,新增的机器也包含了这个queue的所有数据,并没有办法线性扩展你的queue。此时,需要开启镜像集群模式,在rabbitmq管理控制台新增一个策略,将数据同步到指定数量的节点,然后你再次创建queue的时候,应用这个策略,就会自动将数据同步到其他的节点上去了。
Kafka 是 Apache 的子项目,是一个高性能跨语言的分布式发布/订阅消息队列系统(没有严格实现 JMS 规范的点对点模型,但可以实现其效果),在企业开发中有广泛的应用。高性能是其最大优势,劣势是消息的可靠性(丢失或重复),这个劣势是为了换取高性能,开发者可以以稍降低性能,来换取消息的可靠性。
一个Topic可以认为是一类消息,每个topic将被分成多个partition(区),每个partition在存储层面是append log文件。任何发布到此partition的消息都会被直接追加到log文件的尾部,每条消息在文件中的位置称为offset(偏移量),offset为一个long型数字,它是唯一标记一条消息。它唯一的标记一条消息。kafka并没有提供其他额外的索引机制来存储offset,因为在kafka中几乎不允许对消息进行“随机读写”。
Kafka和JMS(Java Message Service)实现(activeMQ)不同的是:即使消息被消费,消息仍然不会被立即删除。日志文件将会根据broker中的配置要求,保留一定的时间之后删除;比如log文件保留2天,那么两天后,文件会被清除,无论其中的消息是否被消费。kafka通过这种简单的手段,来释放磁盘空间,以及减少消息消费之后对文件内容改动的磁盘IO开支。
对于consumer而言,它需要保存消费消息的offset,对于offset的保存和使用,有consumer来控制;当consumer正常消费消息时,offset将会"线性"的向前驱动,即消息将依次顺序被消费。事实上consumer可以使用任意顺序消费消息,它只需要将offset重置为任意值。(offset将会保存在zookeeper中,参见下文)
kafka集群几乎不需要维护任何consumer和procer状态信息,这些信息有zookeeper保存;因此procer和consumer的客户端实现非常轻量级,它们可以随意离开,而不会对集群造成额外的影响。
partitions的设计目的有多个。最根本原因是kafka基于文件存储。通过分区,可以将日志内容分散到多个server上,来避免文件尺寸达到单机磁盘的上限,每个partiton都会被当前server(kafka实例)保存;可以将一个topic切分多任意多个partitions,来消息保存/消费的效率。此外越多的partitions意味着可以容纳更多的consumer,有效提升并发消费的能力。(具体原理参见下文)。
一个Topic的多个partitions,被分布在kafka集群中的多个server上;每个server(kafka实例)负责partitions中消息的读写操作;此外kafka还可以配置partitions需要备份的个数(replicas),每个partition将会被备份到多台机器上,以提高可用性。
基于replicated方案,那么就意味着需要对多个备份进行调度;每个partition都有一个server为"leader";leader负责所有的读写操作,如果leader失效,那么将会有其他follower来接管(成为新的leader);follower只是单调的和leader跟进,同步消息即可。由此可见作为leader的server承载了全部的请求压力,因此从集群的整体考虑,有多少个partitions就意味着有多少个"leader",kafka会将"leader"均衡的分散在每个实例上,来确保整体的性能稳定。
Procers
Procer将消息发布到指定的Topic中,同时Procer也能决定将此消息归属于哪个partition;比如基于"round-robin"方式或者通过其他的一些算法等。
Consumers
本质上kafka只支持Topic。每个consumer属于一个consumer group;反过来说,每个group中可以有多个consumer。发送到Topic的消息,只会被订阅此Topic的每个group中的一个consumer消费。
如果所有的consumer都具有相同的group,这种情况和queue模式很像;消息将会在consumers之间负载均衡。
如果所有的consumer都具有不同的group,那这就是"发布-订阅";消息将会广播给所有的消费者。
在kafka中,一个partition中的消息只会被group中的一个consumer消费;每个group中consumer消息消费互相独立;我们可以认为一个group是一个"订阅"者,一个Topic中的每个partions,只会被一个"订阅者"中的一个consumer消费,不过一个consumer可以消费多个partitions中的消息。kafka只能保证一个partition中的消息被某个consumer消费时,消息是顺序的。事实上,从Topic角度来说,消息仍不是有序的。
Kafka的设计原理决定,对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,否则将意味着某些consumer将无法得到消息。
Guarantees
Kafka就比较适合高吞吐量并且允许少量数据丢失的场景,如果非要保证“消息可靠传输”,可以使用JMS。
Kafka Procer 消息发送有两种方式(配置参数 procer.type):
对于同步方式(procer.type=sync)?Kafka Procer 消息发送有三种确认方式(配置参数 acks):
kafka的设计初衷是希望作为一个统一的信息收集平台,能够实时的收集反馈信息,并需要能够支撑较大的数据量,且具备良好的容错能力。
持久性
kafka使用文件存储消息,这就直接决定kafka在性能上严重依赖文件系统的本身特性。且无论任何OS下,对文件系统本身的优化几乎没有可能。文件缓存/直接内存映射等是常用的手段。因为kafka是对日志文件进行append操作,因此磁盘检索的开支是较小的;同时为了减少磁盘写入的次数,broker会将消息暂时buffer起来,当消息的个数(或尺寸)达到一定阀值时,再flush到磁盘,这样减少了磁盘IO调用的次数。
性能
需要考虑的影响性能点很多,除磁盘IO之外,我们还需要考虑网络IO,这直接关系到kafka的吞吐量问题。kafka并没有提供太多高超的技巧;对于procer端,可以将消息buffer起来,当消息的条数达到一定阀值时,批量发送给broker;对于consumer端也是一样,批量fetch多条消息。不过消息量的大小可以通过配置文件来指定。对于kafka broker端,似乎有个sendfile系统调用可以潜在的提升网络IO的性能:将文件的数据映射到系统内存中,socket直接读取相应的内存区域即可,而无需进程再次和交换。 其实对于procer/consumer/broker三者而言,CPU的开支应该都不大,因此启用消息压缩机制是一个良好的策略;压缩需要消耗少量的CPU资源,不过对于kafka而言,网络IO更应该需要考虑。可以将任何在网络上传输的消息都经过压缩。kafka支持gzip/snappy等多种压缩方式。
生产者
负载均衡: procer将会和Topic下所有partition leader保持socket连接;消息由procer直接通过socket发送到broker,中间不会经过任何“路由层“。事实上,消息被路由到哪个partition上,有procer客户端决定。比如可以采用“random““key-hash““轮询“等,如果一个topic中有多个partitions,那么在procer端实现“消息均衡分发“是必要的。
其中partition leader的位置(host:port)注册在zookeeper中,procer作为zookeeper client,已经注册了watch用来监听partition leader的变更事件。
异步发送:将多条消息暂且在客户端buffer起来,并将他们批量的发送到broker,小数据IO太多,会拖慢整体的网络延迟,批量延迟发送事实上提升了网络效率。不过这也有一定的隐患,比如说当procer失效时,那些尚未发送的消息将会丢失。
消费者
consumer端向broker发送“fetch”请求,并告知其获取消息的offset;此后consumer将会获得一定条数的消息;consumer端也可以重置offset来重新消费消息。
在JMS实现中,Topic模型基于push方式,即broker将消息推送给consumer端。不过在kafka中,采用了pull方式,即consumer在和broker建立连接之后,主动去pull(或者说fetch)消息;这中模式有些优点,首先consumer端可以根据自己的消费能力适时的去fetch消息并处理,且可以控制消息消费的进度(offset);此外,消费者可以良好的控制消息消费的数量,batch fetch。
其他JMS实现,消息消费的位置是有prodiver保留,以便避免重复发送消息或者将没有消费成功的消息重发等,同时还要控制消息的状态。这就要求JMS broker需要太多额外的工作。在kafka中,partition中的消息只有一个consumer在消费,且不存在消息状态的控制,也没有复杂的消息确认机制,可见kafka broker端是相当轻量级的。当消息被consumer接收之后,consumer可以在本地保存最后消息的offset,并间歇性的向zookeeper注册offset。由此可见,consumer客户端也很轻量级。
对于JMS实现,消息传输担保非常直接:有且只有一次(exactly once)。
在kafka中稍有不同:
at most once: 消费者fetch消息,然后保存offset,然后处理消息;当client保存offset之后,但是在消息处理过程中出现了异常,导致部分消息未能继续处理。那么此后"未处理"的消息将不能被fetch到,这就是"at most once"。
at least once: 消费者fetch消息,然后处理消息,然后保存offset。如果消息处理成功之后,但是在保存offset阶段zookeeper异常导致保存操作未能执行成功,这就导致接下来再次fetch时可能获得上次已经处理过的消息,这就是"at least once",原因offset没有及时的提交给zookeeper,zookeeper恢复正常还是之前offset状态。
exactly once: kafka中并没有严格的去实现(基于2阶段提交,事务),我们认为这种策略在kafka中是没有必要的。
通常情况下“at-least-once”是我们首选。(相比at most once而言,重复接收数据总比丢失数据要好)。
kafka高可用由多个broker组成,每个broker是一个节点;
创建一个topic,这个topic会划分为多个partition,每个partition存在于不同的broker上,每个partition就放一部分数据。
kafka是一个分布式消息队列,就是说一个topic的数据,是分散放在不同的机器上,每个机器就放一部分数据。
在0.8版本以前,是没有HA机制的,就是任何一个broker宕机了,那个broker上的partition就废了,没法写也没法读,没有什么高可用性可言。
0.8版本以后,才提供了HA机制,也就是就是replica副本机制。每个partition的数据都会同步到其他的机器上,形成自己的多个replica副本。然后所有replica会选举一个leader出来,那么生产和消费都跟这个leader打交道,然后其他replica就是follower。
写的时候,leader会负责把数据同步到所有follower上去,读的时候就直接读leader上数据即可。
kafka会均匀的将一个partition的所有replica分布在不同的机器上,从而提高容错性。
如果某个broker宕机了也没事,它上面的partition在其他机器上都有副本的,如果这上面有某个partition的leader,那么此时会重新选举一个新的leader出来,大家继续读写那个新的leader即可。这就有所谓的高可用性了。
写数据的时候,生产者就写leader,然后leader将数据落地写本地磁盘,接着其他follower自己主动从leader来pull数据。一旦所有follower同步好数据了,就会发送ack给leader,leader收到所有follower的ack之后,就会返回写成功的消息给生产者。
消息丢失会出现在三个环节,分别是生产者、mq中间件、消费者:
RabbitMQ
Kafka
大体和RabbitMQ相同。
Rabbitmq
需要保证顺序的消息投递到同一个queue中,这个queue只能有一个consumer,如果需要提升性能,可以用内存队列做排队,然后分发给底层不同的worker来处理。
Kafka
写入一个partition中的数据一定是有序的。生产者在写的时候 ,可以指定一个key,比如指定订单id作为key,这个订单相关数据一定会被分发到一个partition中去。消费者从partition中取出数据的时候也一定是有序的,把每个数据放入对应的一个内存队列,一个partition中有几条相关数据就用几个内存队列,消费者开启多个线程,每个线程处理一个内存队列。
⑦ openstack用的python什么框架
openstack是最近3年学习python的人最值得学习的一个云计算框架。
OpenStack 包含两个主要模块:Nova 和 Swift,前者是 NASA 开发的虚拟服务器部署和业务计算模块;后者是 Rackspace开发的分布式云存储模块,两者可以一起用,也可以分开单独用。
在ubuntu操作系统上,可以很轻松安装openstack这个私有云框架。而openstack就是用Python编程语言编写的。
整合Tornado 网页服务器(快速响应)、Nebula运算平台
使用Twisted软件框架(高并发)
遵循Open Virtualization Format、AMQP、SQLAlchemy等标准
虚拟机器软件支持包括:KVM、Xen、VirtualBox、QEMU、 LXC 等。
KVM相对速度要快些。xen比较新。virtualbox是以qemu为基础做的谈慧。LXC还没有用过大槐。
python如果不喜欢,想做openstack也没有问题,毕竟它只是一个框架含仿答与语言本身相差很大的。
比如你不喜欢java,但不等于你不会在android上开发APP。这与JAVA语言本身关系不大。