您的位置:

jsonrpc库,jsonrpc20

本文目录一览:

如何通过zabbix 获取监控数据

zabbix基本架构:

1.Server

zabbix系统核心进程,轮询并捕获数据、发送通知等。是zabbix agent和zabbix proxy汇报数据的对象。server自身可远程检测网络服务。所有的前后端配置、统计信息、可操作数据存储于此。包含server、前段界面和后端DB几部分。

2.Agent

部署在被监控主机上用于监控本地资源和应用并向zabbix server汇报结果。使用本地系统调用故非常高效。有主动和被动两种检测模式。被动模式下agent根据server或proxy的具体请求来返回数据。主动模式下先主动由server获取监控项列表在检测并返回新的数据。采用主动或被动检测取决于相应监控项的配置。

3.Proxy

可以自由选择部署或者不部署,主要用于分担server的负载。在集中化监控远程位置、分支、网络的场景中是很好的解决方案。可从被监控设备收集数据缓存在proxy本地后传递给其所属的zabbix server。proxy需要单独的数据库。

4.Java gateway

java实现的守护进程用于监控JMX类型的应用程序。

5.Sender

命令行工具zabbix_sender,用于向zabbix server发送性能数据和可用性数据。多用于用户脚本定期向server发送数据。

如:

shell cd bin

shell ./zabbix_sender -z zabbix -s "Linux DB3" -k db.connections -o 43

6.Get

命令行工具zabbix_get,用于同agent通信从agent获取数据。可用于zabbix agents的troubleshooting。

如:

shell cd bin

shell ./zabbix_get -s 127.0.0.1 -p 10050 -k "system.cpu.load[all,avg1]"

#zabbix术语表:

host

需要被监控的设备,如交换机、路由器、WEB服务器、DB服务器等

host group

被监控设备的逻辑分组,如DB服务器一组、WEB服务器一组等。可包含主机和模板。用于权限控制

item

需要被监控的项,如CPU空闲率、某一块磁盘的使用率等

trigger

用于评估收到的监控值是否超出设定的阈值的逻辑表达式

event

如trigger状态改变等值得注意的事件

action

预先定义的响应event的一系列operations

escalation

执行action中的operations的定制场景;一连串的发送通知、执行远程命令

media

传递notification的方式

notification

通过media发送给用户的关于某个event的消息

remote command

在被监控机器上触发并自动执行的预定义命令

template

用于简化和加速主机上大规模监控任务的部署。包含一系列项目,如items, triggers, graphs, screens, applications, low-level discovery rules

application

逻辑组中的一组items

web scenario

一个或多个HTTP request用以检查web站点可用性

frontend

zabbix的web界面

zabbix api

允许通过JSON RPC 协议创建、更新和获取zabbix对象如,hosts, items, graphs and others。或者执行其他任务

zabbix server

zabbix核心,履行监控,与zabbix proxies、zabbix client交互、计算trigger、发送notification、存储数据等任务

zabbix agent

部署在被监控主机上用于监控本地资源和应用

zabbix proxy

可代zabbix server收集数据分担处理负载

#zabbix配置:

可通过WEB界面或者模板进行配置

需配置内容包括users、user groups、hosts、host groups、items、Triggers、Events、notification、templates、visualisation等。

最终配置会被存储在后端database中。

参考:

zabbix取数方式

1.zabbix api

基于WEB的API,通过JSON PRC协议获取或更改zabbix配置,并可用于获取历史监控数据。clients和API间的request和response使用JSON格式。包含一系列可从功能上分为不同组别的方法。

发起HTTP请求的格式类似如下:

POST HTTP/1.1

Content-Type: application/json-rpc

{"jsonrpc":"2.0","method":"apiinfo.version","id":1,"auth":null,"params":{}}

其中是zabbix前端的地址;Content-Type必须指明且为application/json-rpc, application/json or application/jsonrequest三者之一。{"jsonrpc":"2.0","method":"apiinfo.version","id":1,"auth":null,"params":{}}是请求的具体内容。

一些实例:

*登录认证

{

"jsonrpc": "2.0",

"method": "user.login",

"params": {

"user": "Admin",

"password": "zabbix"

},

"id": 1,

"auth": null

}

其中:

jsonrpc:指明JSON-RPC协议版本,这里是2.0版本

method:指明调用的API方法,这里是用户登录

params:需要传递给API method的参数,这里是用户名和密码

id:本次请求的标识符

auth:用户认证令牌,目前尚无所以为null

若参数无误response将会包含用户认证令牌,如:

{

"jsonrpc": "2.0",

"result": "0424bd59b807674191e7d77572075f33",

"id": 1

}

*获取hosts信息

{

"jsonrpc": "2.0",

"method": "host.get",

"params": {

"output": [

"hostid",

"host"

],

"selectInterfaces": [

"interfaceid",

"ip"

]

},

"id": 2,

"auth": "0424bd59b807674191e7d77572075f33"

}

本例使用可用的用户认证令牌通过host.get方法获取所配置的主机的ID 、name等信息,返回如下

{

"jsonrpc": "2.0",

"result": [

{

"hostid": "10084",

"host": "Zabbix server",

"interfaces": [

{

"interfaceid": "1",

"ip": "127.0.0.1"

}

]

}

],

"id": 2

}

为了考虑性能影响、尽量仅列出所需项而非返回所有数据

*创建新监控项

例如在上一步获取的host上建立新的监控项、监控/home/joe/目录的剩余空间

{

"jsonrpc": "2.0",

"method": "item.create",

"params": {

"name": "Free disk space on $1",

"key_": "vfs.fs.size[/home/joe/,free]",

"hostid": "10084",

"type": 0,

"value_type": 3,

"interfaceid": "1",

"delay": 30

},

"auth": "0424bd59b807674191e7d77572075f33",

"id": 3

}

其中params参数中的几个关键参数含义如下:

name:监控项的名称,这个可以自己灵活定义,其中的$1代表key_中的第一个参数,此处为/home/joe/

key_:预定义的监控项,zabbix提供了一系列此类监控内容,此处需从其中进行选择。

hostid:即上步获得的hostid

value_type:监控数据值的类型,不同的数字代表不同的类型,此处的3代表整型

delay:zabbix取数时间间隔,此处为30秒取一次

返回结果如下:

{

"jsonrpc": "2.0",

"result": {

"itemids": [

"24759"

]

},

"id": 3

}

itemid为生成的监控项的id

*获取历史数据:

从历史记录表获取itemids为23296的按clock降序排列的十条记录

history参数可能的取值

0 - float;

1 - string;

2 - log;

3 - integer;

4 - text.

{

"jsonrpc": "2.0",

"method": "history.get",

"params": {

"output": "extend",

"history": 0,

"itemids": "23296",

"sortfield": "clock",

"sortorder": "DESC",

"limit": 10

},

"auth": "038e1d7b1735c6a5436ee9eae095879e",

"id": 1

}

返回结果:

{

"jsonrpc": "2.0",

"result": [

{

"itemid": "23296",

"clock": "1351090996",

"value": "0.0850",

"ns": "563157632"

},

{

"itemid": "23296",

"clock": "1351090936",

"value": "0.1600",

"ns": "549216402"

},

...]

}

*错误处理

下例忘记了groups这个参数

{

"jsonrpc": "2.0",

"method": "host.create",

"params": {

"host": "Linux server",

"interfaces": [

{

"type": 1,

"main": 1,

"useip": 1,

"ip": "192.168.3.1",

"dns": "",

"port": "10050"

}

]

},

"id": 3,

"auth": "0424bd59b807674191e7d77572075f33"

}

返回结果如下,包含的不是result属性而是error属性

{

"jsonrpc": "2.0",

"error": {

"code": -32602,

"message": "Invalid params.",

"data": "No groups for host \"Linux server\"."

},

"id": 3

}

对于获取监控数据来说,比较关心的应该是history.get这个方法。这种方式实际上最终还是由后台数据库获取的。方法提供了丰富的参数,使用非常灵活。但对于一次性大规模的取出大量主机大量监控项的大批数据不太适合。

Dubbo——HTTP 协议 + JSON-RPC

Protocol 还有一个实现分支是 AbstractProxyProtocol,如下图所示:

从图中我们可以看到:gRPC、HTTP、WebService、Hessian、Thrift 等协议对应的 Protocol 实现,都是继承自 AbstractProxyProtocol 抽象类。

目前互联网的技术栈百花齐放,很多公司会使用 Node.js、Python、Rails、Go 等语言来开发 一些 Web 端应用,同时又有很多服务会使用 Java 技术栈实现,这就出现了大量的跨语言调用的需求。Dubbo 作为一个 RPC 框架,自然也希望能实现这种跨语言的调用,目前 Dubbo 中使用“HTTP 协议 + JSON-RPC”的方式来达到这一目的,其中 HTTP 协议和 JSON 都是天然跨语言的标准,在各种语言中都有成熟的类库。

下面就重点来分析 Dubbo 对 HTTP 协议的支持。首先,会介绍 JSON-RPC 的基础,并通过一个示例,快速入门,然后介绍 Dubbo 中 HttpProtocol 的具体实现,也就是如何将 HTTP 协议与 JSON-RPC 结合使用,实现跨语言调用的效果。

Dubbo 中支持的 HTTP 协议实际上使用的是 JSON-RPC 协议。

JSON-RPC 是基于 JSON 的跨语言远程调用协议。Dubbo 中的 dubbo-rpc-xml、dubbo-rpc-webservice 等模块支持的 XML-RPC、WebService 等协议与 JSON-RPC 一样,都是基于文本的协议,只不过 JSON 的格式比 XML、WebService 等格式更加简洁、紧凑。与 Dubbo 协议、Hessian 协议等二进制协议相比,JSON-RPC 更便于调试和实现,可见 JSON-RPC 协议还是一款非常优秀的远程调用协议。

在 Java 体系中,有很多成熟的 JSON-RPC 框架,例如 jsonrpc4j、jpoxy 等,其中,jsonrpc4j 本身体积小巧,使用方便,既可以独立使用,也可以与 Spring 无缝集合,非常适合基于 Spring 的项目。

下面先来看看 JSON-RPC 协议中请求的基本格式:

JSON-RPC请求中各个字段的含义如下:

在 JSON-RPC 的服务端收到调用请求之后,会查找到相应的方法并进行调用,然后将方法的返回值整理成如下格式,返回给客户端:

JSON-RPC响应中各个字段的含义如下:

Dubbo 使用 jsonrpc4j 库来实现 JSON-RPC 协议,下面使用 jsonrpc4j 编写一个简单的 JSON-RPC 服务端示例程序和客户端示例程序,并通过这两个示例程序说明 jsonrpc4j 最基本的使用方式。

首先,需要创建服务端和客户端都需要的 domain 类以及服务接口。先来创建一个 User 类,作为最基础的数据对象:

接下来创建一个 UserService 接口作为服务接口,其中定义了 5 个方法,分别用来创建 User、查询 User 以及相关信息、删除 User:

UserServiceImpl 是 UserService 接口的实现类,其中使用一个 ArrayList 集合管理 User 对象,具体实现如下:

整个用户管理业务的核心大致如此。下面我们来看服务端如何将 UserService 与 JSON-RPC 关联起来。

首先,创建 RpcServlet 类,它是 HttpServlet 的子类,并覆盖了 HttpServlet 的 service() 方法。我们知道,HttpServlet 在收到 GET 和 POST 请求的时候,最终会调用其 service() 方法进行处理;HttpServlet 还会将 HTTP 请求和响应封装成 HttpServletRequest 和 HttpServletResponse 传入 service() 方法之中。这里的 RpcServlet 实现之中会创建一个 JsonRpcServer,并在 service() 方法中将 HTTP 请求委托给 JsonRpcServer 进行处理:

最后,创建一个 JsonRpcServer 作为服务端的入口类,在其 main() 方法中会启动 Jetty 作为 Web 容器,具体实现如下:

这里使用到的 web.xml 配置文件如下:

完成服务端的编写之后,下面再继续编写 JSON-RPC 的客户端。在 JsonRpcClient 中会创建 JsonRpcHttpClient,并通过 JsonRpcHttpClient 请求服务端:

在 AbstractProxyProtocol 的 export() 方法中,首先会根据 URL 检查 exporterMap 缓存,如果查询失败,则会调用 ProxyFactory.getProxy() 方法将 Invoker 封装成业务接口的代理类,然后通过子类实现的 doExport() 方法启动底层的 ProxyProtocolServer,并初始化 serverMap 集合。具体实现如下:

在 HttpProtocol 的 doExport() 方法中,与前面介绍的 DubboProtocol 的实现类似,也要启动一个 RemotingServer。为了适配各种 HTTP 服务器,例如,Tomcat、Jetty 等,Dubbo 在 Transporter 层抽象出了一个 HttpServer 的接口。

dubbo-remoting-http 模块的入口是 HttpBinder 接口,它被 @SPI 注解修饰,是一个扩展接口,有三个扩展实现,默认使用的是 JettyHttpBinder 实现,如下图所示:

HttpBinder 接口中的 bind() 方法被 @Adaptive 注解修饰,会根据 URL 的 server 参数选择相应的 HttpBinder 扩展实现,不同 HttpBinder 实现返回相应的 HttpServer 实现。HttpServer 的继承关系如下图所示:

这里以 JettyHttpServer 为例简单介绍 HttpServer 的实现,在 JettyHttpServer 中会初始化 Jetty Server,其中会配置 Jetty Server 使用到的线程池以及处理请求 Handler:

可以看到 JettyHttpServer 收到的全部请求将委托给 DispatcherServlet 这个 HttpServlet 实现,而 DispatcherServlet 的 service() 方法会把请求委托给对应接端口的 HttpHandler 处理:

了解了 Dubbo 对 HttpServer 的抽象以及 JettyHttpServer 的核心之后,回到 HttpProtocol 中的 doExport() 方法继续分析。

在 HttpProtocol.doExport() 方法中会通过 HttpBinder 创建前面介绍的 HttpServer 对象,并记录到 serverMap 中用来接收 HTTP 请求。这里初始化 HttpServer 以及处理请求用到的 HttpHandler 是 HttpProtocol 中的内部类,在其他使用 HTTP 协议作为基础的 RPC 协议实现中也有类似的 HttpHandler 实现类,如下图所示:

在 HttpProtocol.InternalHandler 中的 handle() 实现中,会将请求委托给 skeletonMap 集合中记录的 JsonRpcServer 对象进行处理:

skeletonMap 集合中的 JsonRpcServer 是与 HttpServer 对象一同在 doExport() 方法中初始化的。最后,我们来看 HttpProtocol.doExport() 方法的实现:

介绍完 HttpProtocol 暴露服务的相关实现之后,下面再来看 HttpProtocol 中引用服务相关的方法实现,即 protocolBindinRefer() 方法实现。该方法首先通过 doRefer() 方法创建业务接口的代理,这里会使用到 jsonrpc4j 库中的 JsonProxyFactoryBean 与 Spring 进行集成,在其 afterPropertiesSet() 方法中会创建 JsonRpcHttpClient 对象:

下面来看 doRefer() 方法的具体实现:

在 AbstractProxyProtocol.protocolBindingRefer() 方法中,会通过 ProxyFactory.getInvoker() 方法将 doRefer() 方法返回的代理对象转换成 Invoker 对象,并记录到 Invokers 集合中,具体实现如下:

本文重点介绍了在 Dubbo 中如何通过“HTTP 协议 + JSON-RPC”的方案实现跨语言调用。首先介绍了 JSON-RPC 中请求和响应的基本格式,以及其实现库 jsonrpc4j 的基本使用;接下来我们还详细介绍了 Dubbo 中 AbstractProxyProtocol、HttpProtocol 等核心类,剖析了 Dubbo 中“HTTP 协议 + JSON-RPC”方案的落地实现。

从 0 到 1:全面理解 RPC 远程调用

作者 | Python编程时光

责编 | 胡巍巍

什么是RPC呢?百度百科给出的解释是这样的:“RPC(Remote Procedure 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 Procedure 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 实现是太简单了,所以这里我就不多说了,如果有人想要看这方面内容,可以收藏我的博客() ,我会更新补充 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-conductor创建rpc server的代码,这边的endpoints就是 nova/manager.py:ConductorManager

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亿败光了!

你点的每个“在看”,我都认真当成了喜欢

怎么用c#调用json-rpc

其实对于C#调用json-rpc并不点便宜,一般情况下如果是C#调用,可以考虑使用wcf等rpc技术。

对于json/xml等rpc,在C#调用时,应该遵从以下两个原则:

远程http协议流调用(使用tcpclient/webclient等类库将内容调用到本地)。

对本地流(二进制,文本——json/xml,文本——jsonp等)进行反序列化,得到相应的调用。

严格来说,这种情况其实不能称之rpc的,rpc是远程调用,指的调用远程方法并返回(不返回)相应的应答,而json/jsonp则是将执行结果以流的方式返回,而这个恰好可以序列化成本地对象,严格来说,json/jsonp/xml实际上是让浏览器调用的,浏览器本身是javascript的宿主,可以很轻易地反序列json或直接执行jsonp方法。

也就是说,浏览器通信使用json/jsonp的这种方案,目的是跨终端。而C#只能出现在页面后端,如果让后端去调用业务层逻辑的话,不如直接使用wcf等rpc。使用json/jsonp则是需要自定义序列化的,对于将来的维护等存在一定的问题。

如果把网页也看作rpc的话,json/jsonp可以算做rpc的,事实上狭义的rpc就是远程调用,是在业务层上远程集中封装。还有是一定的区别的。

python后端开发需要学什么?

可以参考下面的路径去学习,祝你学有所成,公司最近在人工智能和自然语言处理的项目后端项目,我也是网上找了很多知识,最后给自己列了一个学习的目录,按照这个在复习并在总结,希望能帮到你:

计算机基本认知,环境搭建    python环境搭建

计算机基本认识,进制转换

python注释使用

python变量使用

python数据类型_Number

python数据类型    str字符串类型

容器类型数据list,tuple,str

容器类型数据set,dict

变量缓存机制

自动类型转换

Number强制类型转换  

python运算符的使用    容器类型数据强制类型转换

字典强转等长二级容器

运算符_算数_比较

运算符_赋值_成员

运算符_身份_逻辑

运算符_位运算_优先级  

python流程控制    代码块

流程控制if

多项巢状分支

循环结构while

循环判断经典题

字符串的相关操作  

python循环结构    

关键字continue_break_pass

for循环的遍历_range  

字符串,列表内置方法    

字符串函数

format字符串格式化

format特殊符号的使用

列表的操作

列表函数  

字典,集合内置方法+文件操作    

字典的相关函数

集合操作_函数

文件操作

文件加号模式  

函数,函数参数    文件相关函数 

函数

形参实参

默认形参_关键字形参

收集参数

命名关键字参数

全局/局部变量,闭包    return返回值

函数名的使用

局部变量_全局变量

函数的嵌套LEGB

关键字nonlocal

闭包函数  

递归,匿名函数    

locals和globals

闭包特点意义

递归含义

斐波那契_尾递归

匿名函数lambda  

迭代器,高阶函数    迭代器

高阶函数_map

高阶函数_reduce

高阶函数_sorted

高阶函数_filter  

推导式    列表推导式

推导式题

集合_字典推导式

生成器表达式

生成器函数  

内置方法,linux基本命令    内置函数

可滑动序列

面试题演练

linux安装

linux基本命令  

python模块    序列化模块

数学模块

随机模块

time模块  

python模块    os模块

os_shutil

os.path模块

计算文件夹大小

zipfile

tarfile  

导入模块包,oop面向对象认知    

import_from绝对导入

import_from相对导入(单入口)

oop面向对象

类的封装性

oop之封装,继承    类的相关操作

对象和类的删除操作

单继承

多继承

菱形继承

oop之多态,魔术方法    多态

魔术方法__new__

单态模式

析构方法__del__  

oop之魔术方法,异常处理    魔术方法__call__

魔术方法__str__repr__

魔术方法__bool_add_len__

了解异常

异常处理语法

主动抛出异常

装饰器  

装饰器

静态绑定方法

property 

正则表达式    单个字符匹配

多个字符匹配

匹配分组

命名分组

正则函数

正则计算器小程序

认识网络    bs_cs流程

传输数据流程

交换机和局域网的网络通讯

arp协议  

认识tcp/udp协议  

tcp基本语法

tcp循环发消息

udp基本语法

udp循环发消息

黏包  

基于tcp协议下的应用    socketserver并发

文件校验

服务器合法性校验

tcp登录

并发编程之进程    进程

join

守护进程

lock锁

Semaphore

生产者消费者模型    Event事件

进程队列Queue

生产者和消费者模型

JoinableQueue

Manager.py

并发编程之线程

.线程

用类定义线程

守护线程

lock保证线程数据安全

信号量_Semaphore

死锁,互斥锁,递归锁

线程池,进程池,协成的使用

事件Event

线程队列

进程池和线程池

回调函数

协程

协程的爬虫案例

mysql安装(linux+windows+xshell+navicat)  

掌握数据库mysql基本操作

mysql登录,服务启动

创建账户,用户授权

数据库,数据表,数据的增删改查

认识常用数据类型  

数据库的存储引擎和约束  

字段约束

约束的删减

存储引擎区别用法

数据表之间的关系  

查询数据表  

单表查询

多表联查

子查询

带EXISTS关键字的子查询

python操作mysql  

python连接mysql的事务处理

sql注入

python连接mysql增删改查

mysql数据恢复  

HTML/CSS    html文档介绍,html标签,body标签,head标签介绍,head标签中的meta标签和link标签和title标签介绍,body中的标签分类,基础标签,img、a、列表、表格、input、label、select等标签,作业讲解,form标签介绍和示例讲解,css介绍,引入,css选择器,背景设置,高度宽度,字体效果,边框、盒子模型、display属性、float属性等  

CSS    伪类选择器,文字装饰、a标签补充、定位、权重、小米商城导航栏讲解,原型头像示例讲解  

JS基础/BOM和DOM操作    小米商城作业,js介绍和js引入,js数据类型、流程控制、函数等操作,js中的JSON,BOM对象的弹框、location对象、定时器、直接查找选择器、间接查找选择器、值操作、类值操作、样式操作、button按钮补充、事件和绑定事件的两种方式,常用事件练习  

jQuery/Bootstrap    作业讲解,jquery介绍,引入、选择器、筛选器、值操作、文档操作、删除和清空标签、逻辑运算符、克隆、事件冒泡和事件委托、绑定事件的方式,作业讲解和模态对话框示例,input事件和页面载入事件补充、bootstrap介绍和引入、全局css样式、组件和常用插件

自定义web框架    作业讲解、web框架介绍、自定义web框架实现、动态页面、返回不同的html页面、函数版、多线程版、返回静态文件版,wsgiref版等web框架通过socket来实现,还有jinja2的简单使用  

django下载安装和URL路由系统    django介绍、MTV和MVC框架介绍、常用指令、目录结构、pycharm创建django项目、request的常用属性介绍、登录示例、url路由系统介绍、有名分组和无名分组,  

视图/模板    request对象的常用方法和属性、响应方法介绍和使用,CBV和FBV、CBV和FBV加装饰器,CBV源码讲解,模板渲染系统介绍,语法、简单示例、内置过滤器、for循环标签、if标签、with标签、自定义过滤器和标签、模板继承等  

Dajngo的ORM(1)    orm介绍,数据库同步指令使用和流程分析、配置连接mysql模型类中的属性介绍和常用参数说明,创建表和数据、增加的两种方法、删除、更新的两种方法、查询的13个api接口  

Dajngo的ORM(2)    单表图书管理系统展示和添加作业讲解、choices属性、auto_now_add和auto_now参数讲解、url别名和反向解析,基于双下划线的模糊查询,多表结构介绍,图书管理系统编辑和删除作业讲解、多表关系模型类创建和字段说明和参数介绍、多表数据的添加操作,多表的删除和修改、基于对象的跨表查询、双下划线跨表查询、查看原生sql语句的方法、聚合查询、分组查询、F查询、Q查询等  

Ajax与Django/ 中间件    ajax的介绍和简单示例,ajax登录示例、列表数据展示示例,ajax操作cookie的补充、中间件介绍、自定义中间件的方法、5个中间件方法的介绍和使用、基于中间件的session登录认证 

cookie、session以及用户认证组件    cookie介绍,cookie的流程解析,django操作cookie和其他参数介绍、session的说明、django的session操作等,多表图书管理系统作业讲解  

vue初识、es6基本语法、指令系统    let、const、v-if、v-for、v-html、v-text、v-model、v-show、生命周期钩子函数、  

组件化开发、组件传值、axios简单使用    组件化开发、组件传值、axios简单使用、vue-router使用、vue-cli安装  

项目初始化/首页    项目介绍、创建、初始化、element-ui的使用,单文件组件的使用和axios在单文件中的使用和配置、vue-cli的介绍和使用、路飞项目顶部导航栏页面效果搭建,轮播图组件的使用和调整、购物车页面搭建和课程详情页面搭建,vue-video-player视频播放插件  

drf组件    序列化器、drf简单示例、restful规范、反序列化的校验机制  

drf组件    apiview、request和response对象、modelserializer、序列化器保存数据、read_only和write_only的参数  

drf组件    viewset、drf路由功能、viewset视图基类的使用、视图子类、通用视图类genericapiview/排序、django-filter过滤器、频率组件、分页组件、接口文档、异常处理、xadmin的安装和使用、认证组件和权限组件  

git、消息队列    git企业中的使用模式,rabbimq消息队列的应用  

rpc通信,grpc组件    rpc的概念以及通信模式,最火的grpc组件使用 

轻量级Flask框架    Werkzeug服务介绍、Flask框架介绍  

路由系统、自定义路由扩展  

Cookie、Session、Http请求和响应  

蓝图、消息闪现、中间件  

Flask常用扩展、WTForms、使用SQLAchemy ORM  

Admin、Restful、websocket原理、magic string, payload len,masking key   

请求和上下文、多app应用、离线脚本、自定义扩展 

服务端项目搭建,项目配置(session、数据库、日志相关),项目初始化  

jsonrpc模块基本配置和使用,客户端展示首页及登录注册叶绵,APICloud页面控制管理

python进阶    并发、同步、异步、锁,线进程概念以及协程实现原理  

mysql进阶课    基础知识梳理、索引、执行计划  

mysql进阶课    存储引擎、日志管理、备份恢复、主从赋值、优化  

redis,mongodb    事务和发布订阅、RDB和AOF持久化、缓存击穿、缓存雪崩等原理介绍、 用户管理和复制集(RS)总结、sharding cluster 分片集群的搭建、分片使用和相关策略等  

算法与设计模式    链表、二叉树、常见算法、二分查找、插入排序、希尔排序、快排、堆排序、哈希查找  

算法与设计模式    设计模式,单例模式、工厂模式、策略模式、观察者模式  

算法与设计模式    leetcode经典算法解析  

知识体系差不多就这么多了,再就是项目部分,具体项目要看需求了,学会了钓鱼的方法,不怕钓不到鱼哦,无论在哪个行业做什么样的项目都没问题呢!

我自己也搜集了一些经典的资料,要是想要加我百度网盘:艾美电商,我发给你!