Remote RPC method calling through Redis

Source: Internet
Author: User

Remote RPC method calling through Redis

One of the things I find I often study and excited about is the expansion of the system. Now, this has different meanings for different people. As part of the migration of Monolithic applications to the Microservices architecture method, how to handle the Microservices architecture is the reason why I study RPC.
 

RPC or remote process call) is a concept that has existed in the computer science field for a long time. A very simple understanding of this is the ability to send a message to a remote process, whether on the same system or remote system. In general, this is very vague and open to many implementations. In my opinion, when talking about RPC, there will be a considerable amount of content for discussion, such as the message format and how you can send messages to remote processes. There are many methods to implement RPC, and this is one of the methods I have used. But for this article, I am going to use 'json-RPC 'to process the Message format, use Redis to publish messages.

RPC and Message Queue

The principle is basically the same, but when RPC is used, the client will wait for a response message containing the RPC call result. If your message queue system allows you to process callback messages for the sender, you may be able to use it for RPC. In most message queues, they are used to trigger tasks that no longer need to be returned to the client.

Why use Redis instead of others?

You should be able to find Redis is a very advanced technology in a landlord. If you say no, what's wrong with you? Redis is a great tool for many things. You should study it carefully. The learning path is smooth, and there is no need to learn too much new content. Redis perfectly fits these ideas, so let's see what we can do.

Code

Client

 
 
  1. require 'redis' 
  2. require 'securerandom' 
  3. require 'msgpack' 
  4.    
  5. class RedisRpcClient  
  6.    
  7.   def initialize(redis_url, list_name)  
  8.     @client = Redis.connect(url: redis_url)  
  9.     @list_name = list_name.to_s  
  10.   end 
  11.    
  12.   def method_missing(name, *args)  
  13.     request = {  
  14.       'jsonrpc' => '2.0',  
  15.       'method' => name,  
  16.       'params' => args,  
  17.       'id' => SecureRandom.uuid  
  18.     }  
  19.    
  20.     @client.lpush(@list_name, request.to_msgpack)  
  21.     channel, response = @client.brpop(request['id'], timeout=30)  
  22.    
  23.     MessagePack.unpack(response)['result']  
  24.   end 
  25.    
  26. end 
  27.    
  28. client = RedisRpcClient.new('redis://localhost:6379', :fib)  
  29. (1..30).each { |i| puts client.fib(i) } 

Server

 
 
  1. require 'redis' 
  2. require 'msgpack' 
  3.    
  4.    
  5. class Fibonacci  
  6.    
  7.   def fib(n)  
  8.     case n  
  9.     when 0 then 0  
  10.     when 1 then 1  
  11.     else 
  12.       fib(n - 1) + fib(n - 2)  
  13.     end 
  14.   end 
  15.    
  16. end 
  17.    
  18.    
  19. class RedisRpcServer  
  20.    
  21.   def initialize(redis_url, list_name, klass)  
  22.     @client = Redis.connect(url: redis_url)  
  23.     @list_name = list_name.to_s  
  24.     @klass = klass  
  25.   end 
  26.    
  27.   def start  
  28.     puts "Starting RPC server for #{@list_name}" 
  29.     while true 
  30.       channel, request = @client.brpop(@list_name)  
  31.       request = MessagePack.unpack(request)  
  32.    
  33.       puts "Working on request: #{request['id']}" 
  34.    
  35.       args = request['params'].unshift(request['method'])  
  36.       result = @klass.send *args  
  37.    
  38.       reply = {  
  39.         'jsonrpc' => '2.0',  
  40.         'result' => result,  
  41.         'id' => request['id']  
  42.       }  
  43.    
  44.       @client.rpush(request['id'], MessagePack.pack(reply))  
  45.       @client.expire(request['id'], 30)  
  46.     end 
  47.    
  48.   end 
  49.    
  50. end 
  51.    
  52. RedisRpcServer.new('redis://localhost:6379', :fib,  Fibonacci.new).start 

Indeed, it works because Redis has commands to block the wait when you wait for the data to be sent back from the server. This is an excellent practice. It makes your client code look like calling a local method.

Ruby is cool,...

What if you want to use other languages? No problem. As long as your language has a good Redis database, you can do the same thing. Let's take a look at using Python to build a server program.

 
 
  1. import redis  
  2. import msgpack  
  3.    
  4. class Fibonacci:  
  5.    
  6.   def fib(self,n):  
  7.     if n == 0:  
  8.       return 0  
  9.     elif n == 1:  
  10.       return 1  
  11.     else:  
  12.       return self.fib(n-1) + self.fib(n-2)  
  13.    
  14.    
  15. class RedisRpcServer:  
  16.    
  17.   def __init__(self, redis_url, list_name, klass):  
  18.     self.client = redis.from_url(redis_url)  
  19.     self.list_name = list_name  
  20.     self.klass = klass  
  21.    
  22.   def start(self):  
  23.     print("Starting RPC server for " + self.list_name)  
  24.     while True:  
  25.       channel, request = self.client.brpop('fib')  
  26.       request = msgpack.unpackb(request, encoding='utf-8')  
  27.    
  28.       print("Working on request: " + request['id'])  
  29.    
  30.       result = getattr(self.klass, request['method'])(*request['params'])  
  31.    
  32.       reply = {  
  33.         'jsonrpc': '2.0',  
  34.         'result': result,  
  35.         'id': request['id']  
  36.       }  
  37.    
  38.       self.client.rpush(request['id'], msgpack.packb(reply, use_bin_type=True))  
  39.       self.client.expire(request['id'], 30)  
  40.    
  41.    
  42. RedisRpcServer('redis://localhost:6379', 'fib', Fibonacci()).start() 

Conclusion

This proves some ideas in your mind. Of course, more work is needed to handle exceptions. If you encounter any problems using this method, I will be happy to help you. I do want to use RabbitMQ in the same way, but if you have already used Redis in your project, this will be a very good method.

RPC using Redis

Http://www.oschina.net/translate/rpc-using-redis.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.