27

Go Micro 总体设计

 4 years ago
source link: https://www.tuicool.com/articles/2uAnMji
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Go-micro 是什么

Go-micro框架是一套微服务分布式的框架,可以大幅度的提高开发效率。

bVbuULu?w=753&h=164

源码地址: https://github.com/micro/go-micro

Go-micro拥有很多特性:

  • 服务注册、发现
  • 负载均衡
  • 消息解码,并默认支持json以及protobuf
  • 基于rpc的请求响应
  • 异步的消息通讯
  • 接口可插拔

其中最值得一提的是最后一个特性,接口可插拔。只要实现上图的8个关键interface,就可以随意的根据需求重新时间这8个接口的功能。 这8个接口一实现了go-micro的整体架构。

这些接口都有默认的实现方式,意味着你不需要写任何的插件就可以使用这个微服务架构。

主要interface

整个Go Micro 都是有这8个interface构成的,换而言之只要理解了这8个接口,并仔细研究其中一个实现基本就能了解整个框架的实现和架构。下面先来看看这8个接口

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
}

Codec

有了传输方式,下面要解决的就是传输编码和解码问题,go-micro有很多种编码解码方式,默认的实现方式是protobuf,当然也有其他的实现方式,json、protobuf、jsonrpc、mercury等等。

源码

type Codec interface {
    ReadHeader(*Message, MessageType) error
    ReadBody(interface{}) error
    Write(*Message, interface{}) error
    Close() error
    String() string
}

type Message struct {
    Id     uint64
    Type   MessageType
    Target string
    Method string
    Error  string
    Header map[string]string
}

Codec接口的Write方法就是编码过程,两个Read是解码过程。

Registry

服务的注册和发现,目前实现的consul,mdns, etcd,etcdv3,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
}

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
}

默认的是实现是本地缓存,当前实现的有blacklist,label,named等方式。

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
}

Broker默认的实现方式是http方式,但是这种方式不要在生产环境用。go-plugins里有很多成熟的消息队列实现方式,有kafka、nsq、rabbitmq、redis,等等。

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
}

当然他也支持双工通信 Stream 这些具体的实现方式和使用方式,以后会详细解说。

默认的是rpc实现方式,他还有grpc和http方式,在go-plugins里可以找到

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
}

Service

Service是Client和Server的封装,他包含了一系列的方法使用初始值去初始化Service和Client,使我们可以很简单的创建一个rpc服务。

type Service interface {
    Init(...Option)
    Options() Options
    Client() client.Client
    Server() server.Server
    Run() error
    String() string
}

Recommend

  • 91

    源码分析概述分布式架构、大数据架构在软件开发中使用频率越来越高,然而在解决分布式数据一致性上,Zookeeper是最为成熟稳定且被大规模应用的解决方案,无论从性能、易用性还是稳定性上来说,Zookeeper都已经达到了一个工业级产品的标准。 Zookeeper是由Hadoop的...

  • 55
    • www.jisilu.cn 5 years ago
    • Cache

    有谁炒股总体盈利了?

    有谁炒股总体盈利了? - 我没亏,也没赚到多少钱。我发现大盘下跌个股跟着下跌,大盘涨回去了,个股就是涨不回去。整体盈利了40%但是钱没赚到多少

  • 39

    问与答 - @houlin - 1、坐在湖边,很黑,四周无人,水深 7 米只需要三分钟就可以溺水,心里有种冲动想走进去,不知道为啥自己没有做,走进去真的很简单。2、站在楼顶,20 楼,总想欲欲一试,只需往前走一步,就可以什么都不用

  • 44

    Apache自1990年发布以来,一直是web服务器市场的王者。Nginx出现较晚,因其在高并发下卓越的表现,最初是作为Apache在高并发情况下的补充,当时Nginx+Apache是流行的架构.现在Nginx的功能已经十分完善,多数场合下不需要Nginx+Apache这样复杂的架构,那么问题来了,选择Ng...

  • 10
    • segmentfault.com 4 years ago
    • Cache

    事件驱动的微服务-总体设计

    事件驱动的微服务-总体设计 我在 "微服务之间的最佳调用方式" 中讲到了微服务之间的两种调用方式。微服务刚兴起时,大部分都是RPC的调用模式。...

  • 15

    【编者的话】本文摘自于云计算/OpenShift领域资深专家和布道者山金孝、潘晓华、刘世民撰写的《OpenShift云原生架构:原理与实践》一书,将介绍OpenShift在架构设计上的哲学理念,分析其与Kubernetes在主要功能上的区别,探讨OpenShift在构...

  • 5

    [ASP.NET Core 3框架揭秘]服务承载系统[4]:总体设计[下篇] 在...

  • 7

    前面的实例演示了服务承载的基本编程模式,接下来我们从设计的角度来重新认识服务承载模型。总的来说,服务承载模型主要由如下图所示的三个核心对象组成:多个通过IHostedService接口表示的服务被承载于通过IHost接口表示的宿主上,IHostBuilder接口表示IHost对...

  • 2
    • www.woshipm.com 2 years ago
    • Cache

    数字化转型数据架构总体设计

    编辑导语:对于企业的经营与发展,数据起着至关重要的作用。在疫情的冲击下,越来越多的企业朝着数据化转型方向发展。作者总结了相关数字化转型数据架构设计,与你分享,希望对你有所帮助。

  • 3

    苹果今年或推出第二代Apple Watch Ultra,预计总体设计变化不大

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK