rpc

rpc相对高效,http接口相对灵活
rpc更适合微服务间的应用间通讯
restful更适合终端与服务端之间的交互

rpc就是一种通信协议
grpc是由Google开发,是一款语言中立、平台独立、开源的远程过程调用系统
grpc客户端和服务端可以在多种环境中运行和交互,例如Java写一个服务端,可以用go客户端调用

 

python  -  xmlrp库

rpc_server.py

from xmlrpc.server import SimpleXMLRPCServer

# 调用函数
def respon_string(str):
    return "get string:%s"%str


if __name__ == '__main__':
    server = SimpleXMLRPCServer(('localhost', 8888)) # 初始化
    server.register_function(respon_string, "get_string") # 注册get_string函数
    print ("Listening for Client")
    server.serve_forever() # 保持等待调用状态

rpc_client.py

from xmlrpc.client import ServerProxy

if __name__ == '__main__':
    server = ServerProxy("http://localhost:8888") # 初始化服务器
    print (server.get_string("RPC RPC")) # 调用get_string函数并传参,调用get_string让服务端通过respon_string函数处理请求,并返回。
 golang
1、golang官方的net/rpc库使用encoding/gob进行编解码,支持tcp和http数据传输方式,由于其他语言不支持gob编解码方式,
  所以golang的RPC只支持golang开发的服务器与客户端之间的交互 2、官方还提供了net
/rpc/jsonrpc库实现RPC方法,jsonrpc采用JSON进行数据编解码,因而支持跨语言调用,
  目前jsonrpc库是基于tcp协议实现的,暂不支持http传输方式

 

protobuf

 

 

 

 

一种跨语和平台的数据序列化协议 (二进制)

与XML/JSON相比,系列化效率更快、体积更小/更安全
与XML/JSON相比,可读性差、灵活性低
自带编译器,定义proto源文件,可编译成多种语言
https://tech.meituan.com/2015/02/26/serialization-vs-deserialization.html

 

微服务架构中,由于每个服务对应的代码库是独立运行的,无法直接调用,彼此间的通信就是个大问题
grpc可以实现微服务,将大的项目拆分为多个小且独立的业务模块,也就是服务,
各服务间使用高效的protobuf协议进行RPC调用,gRPC默认使用 protobuf 进行结构数据序列化机制
可以用proto files创建grpc服务,用message类型来定义方法参数和返回类型

 

  

go-micro框架
专注于微服务的一种RPC框架
通过分布式系统相关的接口集合
l、 Go Micro是一个插件化的基础框架,基于此可以构建微服务,Micro的设计哲学是可插拔的插件化架构
2、 在架构之外,它默认实现了consul作为服务发现(2019年源码修改了默认使用mdns),通过http进行通信,通过protobufjson进行编解码
1、服务发现:自动服务注册和名称解析。服务发现是微服务开发的核心。当服务A需要与服务B通话时,它需要该服务的位置。默认发现机制是
    多播DNS(mdns),一种零配置系统。您可以选择使用SWIM协议为p2p网络设置八卦,或者为弹性云原生设置设置consul 2、负载均衡:基于服务发现构建的客户端负载均衡。一旦我们获得了服务的任意数量实例的地址,我们现在需要一种方法来决定要路由到哪个节点。
    我们使用随机散列负载均衡来提供跨服务的均匀分布,并在出现问题时重试不同的节点 3、消息编码:基于内容类型的动态消息编码。客户端和服务器将使用编解码器和内容类型为您无缝编码和解码Go类型。
    可以编码任何种类的消息并从不同的客户端发送。客户端和服务器默认处理此问题。这包括默认的protobuf和json 4、请求
/响应:基于RPC的请求/响应,支持双向流。我们提供了同步通信的抽象。对服务的请求将自动解决,负载平衡,拨号和流式传输。
    启用tls时,默认传输为http / 1.1或http2 5、Async Messaging:PubSub是异步通信和事件驱动架构的一流公民。事件通知是微服务开发的核心模式。启用tls时,
    默认消息传递是点对点http
/ 1.1或http2 6、可插拔接口:Go Micro为每个分布式系统抽象使用Go接口,因此,这些接口是可插拔的,并允许Go Micro与运行时无关,可以插入任何基础技术   插件地址:https://github.com/micro/go-plugins
通信流程
1、Server监听客户端的调用,和Brocker推送过来的信息进行处理。并且Server端需要向Register注册自己的存在或消亡,
    这样Client才能知道自己的状态 2、Register服务的注册的发现,Client端从Register中得到Server的信息,然后每次调用都根据算法选择一个的Server进行通信,
    当然通信是要经过编码
/解码,选择传输协议等一系列过程的 3、如果有需要通知所有的Server端可以使用Brocker进行信息的推送,Brocker 信息队列进行信息的接收和发布
核心接口
go-micro之所以可以高度订制和他的框架结构是分不开的,go-micro由8个关键的interface组成,每一个interface都可以根据自己的需求重新实现,
这8个主要的inteface也构成了go-micro的框架结构

 

 

 

1. Transort通信接口

服务之间通信的接口,也就是服务发送和接收的最终实现方式,是由这些接口定制的
type Socket interface {
   Recv(*Message) error
   Send(*Message) error
   Close() error
}

type Client interface {
   Socket
}

type Listener interface {
   Addr() string
   Close() error
   Accept(func(Socket)) error
}

type Transport interface {
   Dial(addr string, opts ...DialOption) (Client, error)
   Listen(addr string, opts ...ListenOption) (Listener, error)
   String() string
}
2.Codec编码接口
go-micro有很多种编码解码方式,默认的实现方式是protobuf,当然也有其他的实现方式,json、jsonrpc、mercury等等
type Codec interface {
   ReadHeader(*Message, MessageType) error
   ReadBody(interface{}) error
   Write(*Message, interface{}) error
   Close() error
   String() string
}
View Code

2. Codec编码接口

go-micro有很多种编码解码方式,默认的实现方式是protobuf,当然也有其他的实现方式,json、jsonrpc、mercury等等
type Codec interface {
   ReadHeader(*Message, MessageType) error
   ReadBody(interface{}) error
   Write(*Message, interface{}) error
   Close() error
   String() string
}
View Code

3. Registry注册接口

服务的注册和发现,目前实现的有consul、mdns、etcd、zookeeper、kubernetes等
type Registry interface {
   Register(*Service, ...RegisterOption) error
   Deregister(*Service) error
   GetService(string) ([]*Service, error)
   ListServices() ([]*Service, error)
   Watch(...WatchOption) (Watcher, error)
   String() string
   Options() Options
}
View Code

4. Selector负载均衡

以Registry为基础,Selector 是客户端级别的负载均衡,当有客户端向服务发送请求时,selector根据不同的算法从Registery中的主机列表,得到可用的Service节点,进行通信,目前实现的有循环算法和随机算法,默认的是随机算法
type Selector interface {
   Init(opts ...Option) error
   Options() Options
   // Select returns a function which should return the next node
   Select(service string, opts ...SelectOption) (Next, error)
   // Mark sets the success/error against a node
   Mark(service string, node *registry.Node, err error)
   // Reset returns state back to zero for a service
   Reset(service string)
   // Close renders the selector unusable
   Close() error
   // Name of the selector
   String() string
}
View Code

5. Broker发布订阅接口

Broker是消息发布和订阅的接口。例如,因为服务的节点是不固定的,如果需要修改所有服务行为,可以使服务订阅某个主题,当有信息发布时,所有的监听服务都会收到信息,根据你的需要做相应的行为即可
type Broker interface {
   Options() Options
   Address() string
   Connect() error
   Disconnect() error
   Init(...Option) error
   Publish(string, *Message, ...PublishOption) error
   Subscribe(string, Handler, ...SubscribeOption) (Subscriber, error)
   String() string
}
View Code

6. Client客户端接口

Client是请求服务的接口,他封装Transport和Codec进行rpc调用,也封装了Brocker进行信息的发布
type Client interface {
   Init(...Option) error
   Options() Options
   NewMessage(topic string, msg interface{}, opts ...MessageOption) Message
   NewRequest(service, method string, req interface{}, reqOpts ...RequestOption) Request
   Call(ctx context.Context, req Request, rsp interface{}, opts ...CallOption) error
   Stream(ctx context.Context, req Request, opts ...CallOption) (Stream, error)
   Publish(ctx context.Context, msg Message, opts ...PublishOption) error
   String() string
}
View Code

7、Server服务端接口

Server监听等待rpc请求,监听broker的订阅信息,等待信息队列的推送等
type Server interface {
   Options() Options
   Init(...Option) error
   Handle(Handler) error
   NewHandler(interface{}, ...HandlerOption) Handler
   NewSubscriber(string, interface{}, ...SubscriberOption) Subscriber
   Subscribe(Subscriber) error
   Register() error
   Deregister() error
   Start() error
   Stop() error
   String() string
}
View Code

8、Serveice接口

Service是Client和Server的封装,他包含了一系列的方法使用初始值去初始化Service和Client,使我们可以很简单的创建一个rpc服务
type Service interface {
   Init(...Option)
   Options() Options
   Client() client.Client
   Server() server.Server
   Run() error
   String() string
}
View Code

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2020-02-23 10:35  慕沁  阅读(206)  评论(0)    收藏  举报