blog
blog copied to clipboard
go-micro 框架使用指南(一)
说明
本文以 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-micro(micro/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 注册的心跳时间)
文中的第二种方式,是不是把服务发现改成了k8s呢?因为感觉使用k8s的话,k8s本身就有服务发现,可不可以不用consul呢?
是的,go-micro 自身已经集成了将 k8s 设置为 registry。这句代码就是创建 k8s 的 registry实例。
registry := kubernetes.NewRegistry()
你好,我现在碰到了另外一个问题,我的服务发现使用的是consul,我的clinet、service和consul都在本地的时候是没有问题的。然后我把consul放在了集群里面,然后service也放到了集群里面,但是我写好client之后,不知道怎么使用服务发现,因为服务发现的默认地址一直是localhost,然后不知道怎么修改这个地址,使用register_address不起作用?可以指导一下吗?
你可以尝试用下 server_address 试一试
@wjzhangcsu consul register 的 struct 定义是:
type consulRegistry struct {
Address string
Client *consul.Client
opts Options
sync.Mutex
register map[string]uint64
}
你可以通过修改 Address 属性来设置 consul 的地址。
micro 重试 接口幂等性怎么做
@wjzhangcsu go run main.go --registry_address 127.0.0.1:8500
同问幂等的问题,有没有best practice