blog icon indicating copy to clipboard operation
blog copied to clipboard

go-micro 框架使用指南(一)

Open imjoey opened this issue 7 years ago • 8 comments

说明

本文以 FAQ 的形式,介绍如何基于 micro 微服务框架,以及其为 go 提供的 go-micro 库构建微服务系统。

FAQ

Q:micro 提供了什么

micro 框架基于 go 语言实现,其是一个微服务的 ecosystem,提供了多个组件:

  • API:位于 micro/api 下,可以作为微服务系统中的 API 网关,其提供了自动将 HTTP PATH 的访问转换为对应 microservice以及自动数据转换的功能,支持三种模式:HTTP-API(以 http handler 收发数据,数据格式任意)、RPC(以 rpc handler 收发数据,支持 json/protobuf 格式)、Proxy(简单的 http 代理,微服务也要基于 http)。
  • Web:将提供网页服务的 Web 也抽象为微服务,其中:micro/go-web 提供了编写 Web 微服务的库和说明,micro/web 提供了 UI(系统状态、微服务查询等)和 Proxy 功能,其中 Proxy 会自动将 /foo 的访问请求转换访问 go.micro.web.foo 微服务;
  • SRV:micro 框架中有两个粒度的微服务,一个是最简单最底层最纯粹的,默认 namespace 是 go.micro.srv,micro/go-micro 提供了编写 srv 微服务的库和说明,另一种是聚合底层微服务的微服务,默认 namespace 是 go.micro.api,[micro/go-api](提供了编写 api 微服务的库和说明);
  • ja-micro:Java 语言的 micro 微服务框架,与 go micro 兼容,所以很容易将 Java 和 Go 都纳入到 micro 微服务框架中作为主力开发语言,位于 Sixt/ja-micromicro/ja-micro只是一个未更新的 fork);
  • SideCar:micro 也提供了与其他语言集成的 SideCar 功能;

Q: micro 中的 plugin 机制都支持哪些组件?

其实 micro 中基于 go interface 大量使用了 plugin。比如:传输层 Transport,默认是 HTTP,但通过插件体制还提供了 TCP;Registry 除了默认的 Consul 之外,还提供了 etcd、NATS 等。 以下是 go-plugins 中目前支持的所有插件:

Directory Description
Broker Asynchronous Pub/Sub; NATS, NSQ, RabbitMQ, Kafka
Client Alternative clients; gRPC, HTTP
Codec RPC Encoding; BSON, Mercury
KV Key-Value; Memcached, Redis
Metrics Instrumentation; Statsd, Telegraf, Prometheus
Micro Micro Toolkit Plugins
Registry Service Discovery; Etcd, Gossip, NATS
Selector Node Selection; Label, Mercury
Server Alternative servers; gRPC, HTTP
Sync Locking/Leadership election; Consul, Etcd
Trace Distributed tracing; Zipkin
Transport Synchronous Request/Response; NATS, RabbitMQ
Wrappers Client/Server middleware; Circuit Breakers, Rate Limit

使用 plugin 的方式有两种: 第一种是 通过 CLI 方式,代码如下:

import (
	"github.com/micro/go-micro"
	_ "github.com/micro/go-plugins/broker/rabbitmq"
	_ "github.com/micro/go-plugins/registry/kubernetes"
	_ "github.com/micro/go-plugins/transport/nats"
)

func main() {
	service := micro.NewService(
		// Set service name
		micro.Name("my.service"),
	)

	// Parse CLI flags
	service.Init()
}
```go

然后:

```bash
go run service.go --registry= kubernetes --transport=nats --broker=rabbitmq

MICRO_REGISTRY=kubernetes MICRO_TRANSPORT=nats MICRO_BROKER=rabbitmq go run service.go

第二种方式是在代码中直接设置:

import (
	"github.com/micro/go-micro"
	"github.com/micro/go-plugins/registry/kubernetes"
)

func main() {
	registry := kubernetes.NewRegistry() //a default to using env vars for master API

	service := micro.NewService(
		// Set service name
		micro.Name("my.service"),
		// Set service registry
		micro.Registry(registry),
	)
}

Q:micro 中 service 的服务发现都支持什么?是怎么实现的?

micro 中的服务发现默认使用 consul,使用 plugin 机制(micro/go-plugins)支持 etcd、Gossip、NATS 等。 实现原理是:在每个微服务启动时,都将自己注册到 registry 上,退出时自动解注册,并且定时 RegisterInterval 向 registry 上注册自己(实现参见:micro/go-micro/service.go

Q: micro 在 创建并运行之后 时,各个 options/plugin 的默认值是什么?

各个 option/plugin 的默认值是:

  • Service Option: 参见 micro/go-micro/options.go
  • broker: "http"
  • client: "rpcclient"
  • server: "rpcserver"
  • registry: "consul"
  • transport: "http"
  • service id: servicename-uuid.NewUUID()
  • Service Server Option: 参见
    • address: ":0"
    • name: "go-server"
    • version: "1.0.0"
    • Id: uuid.NewUUID()
    • RegisterInterval: 1分钟(微服务自动向 registry 注册的心跳时间)

imjoey avatar Nov 30 '17 01:11 imjoey

文中的第二种方式,是不是把服务发现改成了k8s呢?因为感觉使用k8s的话,k8s本身就有服务发现,可不可以不用consul呢?

gexinworks avatar Apr 17 '18 02:04 gexinworks

是的,go-micro 自身已经集成了将 k8s 设置为 registry。这句代码就是创建 k8s 的 registry实例。

registry := kubernetes.NewRegistry()

imjoey avatar Apr 17 '18 07:04 imjoey

你好,我现在碰到了另外一个问题,我的服务发现使用的是consul,我的clinet、service和consul都在本地的时候是没有问题的。然后我把consul放在了集群里面,然后service也放到了集群里面,但是我写好client之后,不知道怎么使用服务发现,因为服务发现的默认地址一直是localhost,然后不知道怎么修改这个地址,使用register_address不起作用?可以指导一下吗?

gexinworks avatar May 06 '18 06:05 gexinworks

你可以尝试用下 server_address 试一试

crazyIceChen avatar May 09 '18 01:05 crazyIceChen

@wjzhangcsu consul register 的 struct 定义是:

type consulRegistry struct {
	Address string
	Client  *consul.Client
	opts    Options

	sync.Mutex
	register map[string]uint64
}

你可以通过修改 Address 属性来设置 consul 的地址。

imjoey avatar May 10 '18 01:05 imjoey

micro 重试 接口幂等性怎么做

jinbanglin avatar Aug 20 '18 04:08 jinbanglin

@wjzhangcsu go run main.go --registry_address 127.0.0.1:8500

xbox1994 avatar Sep 26 '18 02:09 xbox1994

同问幂等的问题,有没有best practice

anakin avatar Aug 09 '19 01:08 anakin