当前位置: 首页 > 科技观察

通过Redis进行RPC远程方法调用_0

时间:2023-03-21 22:42:09 科技观察

我发现经常研究和兴奋的事情之一是扩展系统的能力。现在,这对不同的人意味着不同的事情。如何处理微服务架构是我研究RPC作为将单体应用程序移植到微服务架构的方法的一部分的原因。RPC(或远程过程调用)这个概念在计算机科学中已经存在了很长一段时间。对此很简单的理解就是能够向远程进程发送消息,无论是在同一个系统上还是在远程系统上。一般来说,这是非常模糊的,并且对许多实现都是开放的。在我看来,说到RPC,要讨论的东西还是挺多的,比如消息的格式,你怎么把消息发给远程进程。有很多方法可以实现RPC,这就是我正在使用的方法,但对于本文,我将使用“JSON-RPC”作为消息格式,使用Redis进行发布。RPC和消息队列的原理基本相同,但使用RPC时,客户端将等待包含RPC调用结果的返回消息。如果您的消息队列系统允许您为发送者处理回调消息,那么您可以将它用于RPC。在大多数消息队列中,它们用于触发不再需要回复客户端的任务。为什么使用Redis而不是其他的?楼主应该能发现Redis是一项非常先进的技术。如果你说你没有找到它,你怎么了?Redis是很多事情的好工具,你真的应该好好研究一下。学习路径可以很顺畅,不需要学习太多新内容,而Redis非常符合这些想法,让我们看看我们能做些什么。CodeClientrequire'redis'require'securerandom'require'msgpack'classRedisRpcClientdefinitialize(redis_url,list_name)@client=Redis.connect(url:redis_url)@list_name=list_name.to_senddefmethod_missing(name,*args)request={'jsonrpc'=>'2.0','method'=>name,'params'=>args,'id'=>SecureRandom.uuid}@client.lpush(@list_name,request.to_msgpack)channel,response=@client.brpop(request['id'],timeout=30)MessagePack.unpack(response)['result']endendclient=RedisRpcClient.new('redis://localhost:6379',:fib)(1..30)。每个{|i|putsclient.fib(i)}Serverrequire'redis'require'msgpack'classFibonaccideffib(n)casenwhen0then0when1then1elsefib(n-1)+fib(n-2)endendendclassRedisRpcServerdefinitialize(redis_url,list_name,klass)@client=Redis.connect(url:redis_url)@list_name=list_name.to_s@klass=klassenddefstartputs"StartingRPCserverfor#{@list_name}"whiletruechannel,request=@client.brpop(@list_name)request=MessagePack。解压(request)放"Workingonrequest:#{request['id']}"args=request['params'].unshift(request['method'])result=@klass.send*argsreply={'jsonrpc'=>'2.0','result'=>result,'id'=>request['id']}@client.rpush(request['id'],MessagePack.pack(reply))@client.expire(request['id'],30)endendendRedisRpcServer.new('redis://localhost:6379',:fib,Fibonacci.new).start这是真的,因为当你等待数据从server,Redis有允许你阻塞和等待的命令。这是一个很好的做法,它使您的客户端代码看起来像是在调用本地方法。不过,Ruby非常酷。..如果你想使用另一种语言怎么办?没问题,只要你的语言有好的Redis库,你也可以这样做。让我们看一下用Python构建服务器程序。importredisimportmsgpackclassFibonacci:deffib(self,n):ifn==0:return0elifn==1:return1else:returnself.fib(n-1)+self.fib(n-2)classRedisRpcServer:def__init__(self,redis_url,list_name,klass):self.client=redis.from_url(redis_url)self.list_name=list_nameself.klass=klassdefstart(self):print("StartingRPCserverfor"+self.list_name)whileTrue:通道,request=self.client.brpop('fib')request=msgpack.unpackb(request,encoding='utf-8')print("Workingonrequest:"+request['id'])result=getattr(self.klass,request['method'])(*request['params'])reply={'jsonrpc':'2.0','result':result,'id':request['id']}self.client.rpush(request['id'],msgpack.packb(reply,use_bin_type=True))self.client.expire(request['id'],30)RedisRpcServer('redis://localhost:6379','fib',Fibonacci()).start()结论这很好地展示了你脑子里的一些想法,当然,还需要做更多的工作来处理异常。如果您在使用此方法时遇到任何问题,我很乐意为您提供帮助。我真的很想按照相同的想法在某个地方使用RabbitMQ,但是如果您已经在您的项目中使用Redis,那么这将是一个很好的方法。英文原文:RPCusingRedis翻译链接:http://www.oschina.net/translate/rpc-using-redis