abu.rpc intro

3,017 views

Published on

Published in: Technology, Education
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,017
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
65
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

abu.rpc intro

  1. 1. gevent + protobuf = abu.rpc 基于协程的RPC实现赖勇浩http://laiyonghao.com2011.5.14 TechParty.org
  2. 2. 升级版
  3. 3. RPC
  4. 4. RPC • Remote Procedure Call • Application level protocol • TCP/UDP • HTTP
  5. 5. abu.rpc
  6. 6. 特性• 更小(得益于 google protobuf)• 更快(得益于 libevent)• 同步API(利益于 greenlet)• 并行管线• 双向调用• TCP only
  7. 7. google protobuf
  8. 8. Jeff Dean, Google fellow • Protocol description language is a must. • http://outerthought.org/blog/410-ot.html
  9. 9. google protobuf • http://code.google.com/p/protobuf/ • 协议描述语言 • C++、java、Python and more • service interface
  10. 10. Quick Example message Person { required int32 id = 1; required string name = 2; optional string email = 3; }
  11. 11. Quick Example person = Person() person.id = 10 person.name = laiyonghao person.email = mail@laiyonghao.com with open(person.data, wb) as f: f.write(person.SerializeToString())
  12. 12. Quick Example service SearchService { rpc Search (SearchRequest) returns (SearchResponse); }
  13. 13. gevent
  14. 14. greenlet + libevent
  15. 15. greenlet • green thread – user space – pseudo-concurrently – scheduled by VM – http://en.wikipedia.org/wiki/Green_threads • Python 的 green thread
  16. 16. PEP 342 def echo_handler(sock): while True: try: data = yield nonblocking_read(sock) yield nonblocking_write(sock, data) except ConnectionLost: pass # exit normally if connection lost
  17. 17. libevent • 提供指定文件描述符事件发生时调用回调 函数的机制 • timeouts, signals
  18. 18. Examples
  19. 19. echo
  20. 20. echo.proto • message Packet{ • required string text = 1; • } • service EchoService{ • rpc echo(Packet)returns(Packet); • }
  21. 21. s_echo.py • @abu.rpc.check_service • class EchoService(echo.EchoService): • @abu.rpc.send_return • def echo(self, controller, request, done): • return request • service = EchoService() • services = (service,) • server = abu.rpc.Server((0.0.0.0, 10086), services) • print serving... • server.serve_forever()
  22. 22. c_echo.py • channel = abu.rpc.Channel((127.0.0.1, 10086), ()) • server = abu.rpc.Proxy(echo.EchoService_Stub(channel)) • for i in xrange(10): • req = echo.Packet() • req.text = hello • print send:%s % req.text • resp = server.EchoService.echo(req) • print recv:%s % resp.text
  23. 23. chat room
  24. 24. chat.proto • message HelloReq{ • message SayReq{ • required string name = 1; • required string name = 1; • } • required string text = 2; • } • message HelloResp{ • required string name = 1; • message SayResp{ • required bool succ = 2; • required string name = 1; • optional string info = 3; • required bool succ = 2; • } • optional string info = 3; • } • message ByeReq{ • required string name = 1; • } • message ByeResp{ • required string name = 1; • required bool succ = 2; • optional string info = 3; • }
  25. 25. chat.proto • message Message{ • service ChatServerService{ • required string name = 1; • rpc • required string text = 2; hello(HelloReq)returns(HelloR • } esp); • rpc bye(ByeReq)returns(ByeResp); • service ChatClientService{ • rpc • rpc say(SayReq)returns(SayResp); say(Message)returns(abu.rpc. Void); • } • }
  26. 26. s_chat.py:ChatServerService.hello • @abu.rpc.send_return • def hello(self, controller, request, done): • name = request.name • resp = chat.HelloResp() • resp.name = name • if name in self._clients: • resp.succ = False • resp.info = u用户名(%s)已经有人使用了。 % name • return resp • self._clients[name] = Client(controller.socket) • resp.succ = True • return resp
  27. 27. s_chat.py:ChatServerService.say • @abu.rpc.send_return • def say(self, controller, request, done): • name = request.name • resp = chat.SayResp() • resp.name = name • if name not in self._clients: • resp.succ = False • resp.info = u无效的用户名(%s) % name • return resp • msg = chat.Message() • msg.name = name • msg.text = request.text • for n, client in self._clients.iteritems(): • client.proxy.ChatClientService.say(msg) • resp.succ = True • return resp
  28. 28. c_chat.py:ChatClientService.say • @abu.rpc.check_service • class ChatClientService(chat.ChatClientService): • @abu.rpc.send_return • def say(self, controller, request, done): • print u%s 说:%s % (request.name, request.text) • return
  29. 29. Thx~ twitter.com/laiyonghaoweibo.com/gzlaiyonghao

×