nfarring / redisrpc
Redis 的轻量级 RPC
Requires
- php: >=5.3.2
- predis/predis: >=0.7.0
This package is not auto-updated.
Last update: 2024-09-22 03:19:01 UTC
README
由 Nathan Farrington http://nathanfarrington.com
RedisRPC 是世界上最容易使用的 RPC 库。 (这不是一个小声明!) 它在 Ruby、PHP 和 Python 中都有实现。
简介
Redis 是一个强大的内存数据结构服务器,对于构建快速分布式系统非常有用。Redis 通过使用列表数据结构和 LPOP
、BLPOP
和 RPUSH
命令来实现消息队列功能。RedisRPC 通过使用 Redis 消息队列来临时存储 RPC 请求和响应消息,实现了一个轻量级 RPC 机制。这些消息被编码为 JSON 字符串,以实现可移植性。
许多其他 RPC 机制要么是特定于编程语言的(例如,Java RMI),要么需要显式类型定义的样板代码(例如,Thrift)。RedisRPC 设计得非常易于使用,通过消除样板代码同时保持编程语言中立。高性能并不是 RedisRPC 的初始目标,其他 RPC 库可能具有更好的性能。相反,RedisRPC 具有更好的程序员性能;它让您可以立即让某件事运行起来。
计算器示例
每个库实现都使用基于可变计算器对象的相同客户端和服务器示例。来自不同语言的客户端和服务器可以互操作。
- 客户端通过使用 Redis 的
RPUSH
命令将 RPC 请求消息推入名为calc
的 Redis 列表中来发出 RPC 请求。 - 服务器通过使用 Redis 的
BLPOP
命令检索 RPC 请求消息。 - 服务器将 RPC 请求调度到本地对象,在这个例子中是一个计算器对象。
- 服务器接受来自计算器对象的返回值(或异常)。
- 服务器通过使用 Redis 的
RPUSH
命令将 RPC 响应消息推入客户端选择的名为calc:rpc:<RAND_STRING>
的 Redis 列表中,来发出 RPC 响应。 - 客户端通过使用 Redis 的
BLPOP
命令检索 RPC 响应消息。
请注意,可以通过使用 Redis 的 LPOP 命令而不是 BLPOP 来使服务器或客户端非阻塞。我目前不需要这个功能,并且还没有添加对这个功能的支持,但是欢迎补丁。
这就是全部了!
Ruby 使用方法
client.rb
redis_server = Redis.new message_queue = 'calc' calculator = RedisRPC::Client.new redis_server, 'calc' calculator.clr calculator.add 5 calculator.sub 3 calculator.mul 4 calculator.div 2 assert calculator.val == 4
server.rb
redis_server = Redis.new message_queue = 'calc' local_object = Calculator.new server = RedisRPC::Server.new redis_server, message_queue, local_object server.run
PHP 使用方法
请注意,PHP 库目前不支持命名函数参数。
client.php
$redis_server = new Predis\Client(); $message_queue = 'calc'; $calculator = new RedisRPC\Client($redis_server, $message_queue); $calculator->clr(); $calculator->add(5); $calculator->sub(3); $calculator->mul(4); $calculator->div(2); assert($calculator->val() == 4);
server.php
$redis_server = new Predis\Client(); $message_queue = 'calc'; $local_object = new Calculator(); $server = new RedisRPC\Server($redis_server, $message_queue, $local_object); $server->run();
Python 使用方法
client.py
redis_server = redis.Redis() message_queue = 'calc' calculator = redisrpc.Client(redis_server, message_queue) calculator.clr() calculator.add(5) calculator.sub(3) calculator.mul(4) calcaultor.div(2) assert calculator.val() == 4
Python 客户端还接受额外的关键字参数 timeout
和 transport
。如果 transport='pickle'
,则可以发送 Python 对象作为函数参数,但前提是服务器也是用 Python 实现的,并且服务器有权访问相同的库来反序列化对象。
server.py
redis_server = redis.Redis() message_queue = 'calc' local_object = calc.Calculator() server = redisrpc.Server(redis_server, message_queue, local_object) server.run()
安装
Ruby 安装
需要 redis-rb 库。使用 RubyGems 安装
gem install redisrpc
PHP 安装
需要 Predis 库。
RedisRPC PHP库可以从Packagist获取:[https://packagist.org.cn/packages/nfarring/redisrpc](https://packagist.org.cn/packages/nfarring/redisrpc)。您可以使用Composer将其安装到您的PHP项目中。
Python安装
需要redis-py库。
RedisRPC Python库可以从PyPI获取:[http://pypi.python.org/pypi/redisrpc](http://pypi.python.org/pypi/redisrpc)。您可以使用
pip install redisrpc
内部消息格式
所有RPC消息都是JSON对象。用户代码永远不会看到这些对象,因为它们由RedisRPC库处理。
RPC请求
RPC请求包含两个成员:一个function_call
对象和一个response_queue
字符串。
function_call
对象有一个必需的成员:一个表示函数名称的name
字符串。它还有两个可选成员:(a)一个用于位置参数的args
列表,以及(b)一个用于命名参数的kwargs
对象。
response_queue
字符串是服务器应将相应的RPC响应消息推入的Redis列表的名称。客户端程序会通过编程方式选择该队列,以确保在Redis命名空间中没有冲突。此外,该队列仅用于单个RPC响应消息,不会用于未来的RPC响应消息。
{ "function_call" : { "args" : [ 1, 2, 3 ], "kwargs" : { "a" : 4, "b" : 5, "c" : 6 }, "name" : "foo" }, "response_queue" : "calc:rpc:X7Y2US" }
RPC响应(成功)
如果RPC成功,则RPC响应对象将包含一个成员,即某种JSON类型的return_value
。
{ "return_value" : 4.0 }
RPC响应(异常)
如果RPC遇到异常情况,则RPC响应对象将包含一个成员,即一个exception
字符串。请注意,exception
字符串的值可能对客户端没有意义,因为客户端和服务器可能用不同的语言编写,或者客户端可能不知道服务器封装的对象。因此,最佳做法可能是向用户显示exception
值。
{ "exception" : "AttributeError(\\"\'Calculator\' object has no attribute \'foo\'\\",)" }
源代码
源代码可在http://github.com/nfarring/redisrpc获取。
许可证
此软件可在GPLv3或更高版本下使用。
变更日志
版本0.3.5
- Ruby:功能:使用multi_json gem [Ryan Biesemeyer]
- Ruby:功能:server.run!刷新队列,但server.run不刷新 [Ryan Biesemeyer]
- Ruby:性能:只调用一次rand,而不是八次 [Ryan Biesemeyer]
- Ruby:错误修正:RedisRPC::VERSION [Ryan Biesemeyer]
- Ruby:安全:删除eval [Ryan Biesemeyer]
版本0.3.4
- 客户端现在支持可选的超时。
- 服务器现在在启动时删除消息队列。
- PHP:修复异常处理。
版本0.3.3
- Ruby:添加了Ruby库实现。
版本0.3.2
- 修复了README.markdown中的某些格式问题,这些问题在转换为reStructredText时会引起问题。
- 向README.markdown添加了版本信息。
- 向README.markdown添加了安装说明。
- Python:添加了使用logging模块的RPC消息日志记录。
- Python:将redis作为安装依赖项。
- Python:现在使用Distribute而不是distutils。
版本0.3.1
- PHP:更改了composer.json中predis依赖项的版本。
版本0.3.0
- 不再传输空函数调用参数和kwargs。
- PHP:添加了对PHP语言的支持。
- PHP:现在可以通过PHP Composer安装。
- Python:缩短了Client和Server类的名称。
- Python:调试已修改为打印JSON表示。
- Python:将README文件切换回ReStructred Text。
版本0.2.1
- Python:修复了MANIFEST.in,以反映文件名更改。
版本0.2.0
- 简化了JSON RPC消息格式。
- 记录了JSON RPC消息格式。
- Python:使用HTML文件作为README,它会工作吗?
- Python:将calc_client重命名为client.py。
- Python:将calc_server重命名为server.py。
- Python:添加了RemoteException类,客户端可以抛出此异常。
版本0.1.2
- Python:修复了setup.py中的download_url。
- Python:将README文件重命名为README.rst以支持在GitHub上的浏览。
版本0.1.1
- Python:添加了README。
- Python:在setup.py中添加了long_description。
- Python:添加了MANIFEST.in文件。
- Python:将examples/子目录添加到MANIFEST。
- Python:修改了examples/目录,使其与README文件保持一致。
- Python:修复了setup.py中的download_url。
版本0.1.0
- 改为GPL许可证。
- Python:从python/redisrpc.py中移除了未使用的功能。
- Python:添加了setup.py安装脚本。