golang rpc 远程调用

rpc

golang rpc 远程调用

1. 面临的问题
  a. Call 的 id 映射
  b. 序列化和反序列化  json 序列化/反序列化
  c. 网络传输
  
  http2.0 ==> rpc
  
### 自己实现的 demo 级别的 rpc 封装
提供 add 方法方

# -*- coding: utf-8 -*-
# __author__: Frank Li
# 10/7/2021 11:41 AM
import json
from urllib.parse import urlparse, parse_qsl
from http.server import HTTPServer, BaseHTTPRequestHandler

host = ('', 8003)

class AddHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        parsed_url = urlparse(self.path)
        qs = dict(parse_qsl(parsed_url.query))

        a = int(qs.get("a", 0))
        b = int(qs.get("b", 0))
        self.send_response(200)
        self.send_header("content-type", "application")
        self.end_headers()
        self.wfile.write(json.dumps({
            "result": a+b
        }).encode("utf-8")
        )

if __name__ == '__main__':
    server = HTTPServer(host, AddHandler)
    print("启动 rpc 服务...")
    server.serve_forever()

远程调用客户端
# -*- coding: utf-8 -*-
# __author__: Frank Li
# 10/7/2021 11:47 AM
import requests
import json


class Client:

    def __init__(self, url):
        self.url = url

    def add(self, a, b):
        res = requests.get(f"{self.url}/?a=1&b=2")
        return json.loads(res.text).get("result")

if __name__ == '__main__':
    client = Client("http://127.0.0.1:8003")
    print(client.add(1,2))

  
# 基于 xml 的 rpc py 库
# -*- coding: utf-8 -*-
# __author__: Frank Li
# 10/7/2021 12:33 PM
from xmlrpc.server import SimpleXMLRPCServer


class Calculate:
    def add(self, x, y):
        return x+y

    def multiply(self, x, y):
        return x*y

    def substract(self, x, y):
        return x-y

    def divide(self, x, y):
        return x/y

if __name__ == '__main__':
    cal = Calculate()
    server = SimpleXMLRPCServer(("localhost", 8014))

    # 将实例注册给 rpc server
    server.register_instance(cal)
    print("Listening on port 8014")
    server.serve_forever()

-------=========-----------
# -*- coding: utf-8 -*-
# __author__: Frank Li
# 10/7/2021 12:37 PM
from xmlrpc import client

class RPCClient:

    def __init__(self, url):
        self.client = client.ServerProxy(url)

    def add(self, x, y):
        return self.client.add(x, y)

if __name__ == '__main__':
    rpc_client = RPCClient("http://localhost:8014")
    ret = rpc_client.add(1, 2)
    print(ret)


json-rpc   ==》 jsonrpclib  支持并发, 支持 HTTPS

zeromq  这个 rpc 框架 是否支持 多语言?
zerorpc == zeroMQ + msgpack(消息序列化二进制)来实现 类似 grpc 的 功能
通信模式 ROUTER-DEALER  模拟 grpc 的请求-响应式 和 应答流式
此外他还支持 PUB-SUB 通信模式的远程调用
zerorpc 实际上依赖 msgpack-python, pyzmq, future, greenlet, gevent
支持 python + nodejs

// go 的 rpc 入门级 demo
package main

import (
	"fmt"
	"net"
	"net/rpc"
)

type HelloService struct {
	
}

// 固定格式如下
func(service *HelloService) Hello(request string, reply *string) error{
	// 返回值是通过修改 reply 的值
	*reply = "hello, "+request
	return nil
}

func main(){
	//1. 实例化 server
	listen, err := net.Listen("tcp", ":1234")
	if err != nil{
		fmt.Println("")
	}

	//2. 注册处理逻辑 handler
	_ = rpc.RegisterName("HelloService", &HelloService{})


	//3. 启动服务
	accept, err := listen.Accept()
	rpc.ServeConn(accept)

}



package main

import (
	"fmt"
	"net/rpc"
)

func main(){
	client, err := rpc.Dial("tcp", "localhost:1234")
	if err != nil{
		fmt.Println("连接失败...", err)
	}
	var reply string
	client.Call("HelloService.Hello", "frank", &reply)
	fmt.Println("reply: ", reply)

}
    

golang rpc 远程调用

上一篇:分布式框架RPC框架Dubbo


下一篇:分布式Dubbo+Zookeeper