golang微服务框架go-micro使用 (一) Getting Started

文档

不断更新的文档,需要翻墙
官方文档

主要接口

服务发现

服务发现是每个分布式系统都需要解决的问题,go-micro将这个任务抽象到一个接口中,github.com/micro/go-micro/v2/registry/Registry

// The registry provides an interface for service discovery
// and an abstraction over varying implementations
// {consul, etcd, zookeeper, ...}
type Registry interface {
	Init(...Option) error
	Options() Options
	Register(*Service, ...RegisterOption) error
	Deregister(*Service, ...DeregisterOption) error
	GetService(string, ...GetOption) ([]*Service, error)
	ListServices(...ListOption) ([]*Service, error)
	Watch(...WatchOption) (Watcher, error)
	String() string
}

所有实现这个结构的插件都可以作服务发现的角色。事实上,在go-plugins上已经有很过实现,包括主流的etcd/consul/zookeeper。以及在内存中的轻量实现。默认实现基于mdns,无需配置,开箱即用。

异步消息

异步消息是构建松耦合与健壮系统的关键技术,相应的接口:
github.com/micro/go-micro/v2/broker/Broker

// Broker is an interface used for asynchronous messaging.
type Broker interface {
	Init(...Option) error
	Options() Options
	Address() string
	Connect() error
	Disconnect() error
	Publish(topic string, m *Message, opts ...PublishOption) error
	Subscribe(topic string, h Handler, opts ...SubscribeOption) (Subscriber, error)
	String() string
}

已经有一些插件,包括RabbitMQ, Kafka, NSQ, etc,默认使用HTTP,无需设置。

编解码器

编解码器接口定义了消息编码与解码格式,github.com/micro/go-micro/v2/codec/Codec:

// Codec encodes/decodes various types of messages used within go-micro.
// ReadHeader and ReadBody are called in pairs to read requests/responses
// from the connection. Close is called when finished with the
// connection. ReadBody may be called with a nil argument to force the
// body to be read and discarded.
type Codec interface {
	Reader
	Writer
	Close() error
	String() string
}

现在支持json 、bson、msgpack等

服务

定义微服务接口

// Server is a simple micro server abstraction
type Server interface {
	// Initialise options
	Init(...Option) error
	// Retrieve the options
	Options() Options
	// Register a handler
	Handle(Handler) error
	// Create a new handler
	NewHandler(interface{}, ...HandlerOption) Handler
	// Create a new subscriber
	NewSubscriber(string, interface{}, ...SubscriberOption) Subscriber
	// Register a subscriber
	Subscribe(Subscriber) error
	// Start the server
	Start() error
	// Stop the server
	Stop() error
	// Server implementation
	String() string
}

Transport

// Transport is an interface which is used for communication between
// services. It uses connection based socket send/recv semantics and
// has various implementations; http, grpc, quic.
type Transport interface {
	Init(...Option) error
	Options() Options
	Dial(addr string, opts ...DialOption) (Client, error)
	Listen(addr string, opts ...ListenOption) (Listener, error)
	String() string
}

Selector

abstracts logic of service selection. you can implement various load balancing strategies with this interface

Wrapper

// Wrapper wraps a client and returns a client
type Wrapper func(Client) Client

简单示例

最快速的构建micro服务模板的方法是使用micro命令行工具

GO111MODULE=on  go get github.com/micro/micro/v2@v2.4.0

then

micro new hello --namespace=com.foo --gopath=false

目录结构

luslin@local:~/go/workspace/tools/micro-hello$ tree
.
├── Dockerfile
├── generate.go
├── go.mod
├── go.sum
├── handler
│   └── micro.go
├── main.go
├── Makefile
├── plugin.go
├── proto
│   └── micro
│       └── micro.proto
├── README.md
└── subscriber
    └── micro.go

在micro-hello/proto/micro 目录下只有定义的proto文件,没有生成文件,需要执行

protoc --proto_path=. --micro_out=. --go_out=. micro.proto

生成文件micro.pb.go、micro.pb.micro.go
需要安装protoc、protoc-gen-go、protoc-gen-micro
protoc-gen-micro安装:

GO111MODULE=on go get -u github.com/micro/protoc-gen-micro/v2

参考
protoc安装,protoc-gen-go安装
然后修改micro-hello/main.go文件

package main

import (
	"github.com/micro/go-micro/v2"
	log "github.com/micro/go-micro/v2/logger"
	"micro-hello/handler"
	"micro-hello/subscriber"

	proto "micro-hello/proto/micro"  // 这里将原来的micro 修改为proto 可能与命名冲突有关
)

func main() {
	// New Service
	service := micro.NewService(
		micro.Name("comm.foo.service.micro"),  // bug,不使用我们提供的,需要修改
		micro.Version("latest"),
	)

	// Initialise service
	service.Init()

	// Register Handler
	proto.RegisterMicroHandler(service.Server(), new(handler.Micro)) // 这里与上面相同

	// Register Struct as Subscriber
	micro.RegisterSubscriber("go.micro.service.micro", service.Server(), new(subscriber.Micro))

	// Run service
	if err := service.Run(); err != nil {
		log.Fatal(err)
	}
}

运行main.go,可以看到同时启动了rrpc与http服务

2020-05-22 10:34:42  file=auth.go:31 level=info Auth [noop] Authenticated as go.micro.service.micro-41b5434c-22cc-4846-ae0b-a76af49eedae in the go.micro namespace
2020-05-22 10:34:42  file=service.go:205 level=info Starting [service] go.micro.service.micro
2020-05-22 10:34:42  file=grpc.go:845 level=info Server [grpc] Listening on [::]:46805
2020-05-22 10:34:42  file=grpc.go:862 level=info Broker [http] Connected to 127.0.0.1:40695
2020-05-22 10:34:42  file=grpc.go:676 level=info Registry [mdns] Registering node: go.micro.service.micro-41b5434c-22cc-4846-ae0b-a76af49eedae
2020-05-22 10:34:42  file=grpc.go:711 level=info Subscribing to topic: go.micro.service.micro

有个问题是micro没有使用我们提供的命名空间,而是go.micro.service.micro, 需要我们自己修改main.go与proto文件, 将proto包名修改为package com.foo.service.micro

总结

本文介绍了如何构建一个demo mirco project, 接下来将会介绍micro的更多特性,并且改变它的默认行为

猜你喜欢

转载自blog.csdn.net/luslin1711/article/details/106261478