Micro In Action(一):入门

polaris · · 2460 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

![](https://s2.ax1x.com/2020/03/10/8FZ2kD.png) 这个系列聊一聊 [Micro](https://micro.mu/), 我们将以实际开发微服务为主线,顺带解析相关功能。从最基本的话题开始,逐步转到高级特性。 Micro 很强大,掌握后使用起来也相当便利。 但它的演进速度非常快, 导致其文档有严重缺失和滞后。 很多功能没有文档;很多基本问题不得不去 GitHub 上提 issue 或去 Slack 里面问,又得不到什么反馈。最后, 查看源码成了唯一的学习途径。 这对于使用者来说非常不友好,阻碍了 Micro 被更多人所采用。 以上成了我写此系列文章的初衷。希望能对你有所帮助。(注:本系列以 Micro v1.18.0 版本为准) --- ## Micro 到底是个啥? 先来看看[官网首页](https://micro.mu/)的说法: > The simplest way to build, share and collaborate on microservices > > Micro powers an open global services platform for developers to build microservices in the cloud and beyond without the hassle of managing infrastructure. 再看看官方文档[第 4 页](https://micro.mu/docs/goals.html)的说法: > Micro is a microservices ecosystem focused on providing products, services and solutions to enable innovation in modern software driven enterprises. 你明白了吗? 反正我仍然不明白。在通读了它现有全部文档以后, 我来给你一个更直白的说法: **Micro 是一组工具,能帮助开发者快速构建和管理微服务**。 它包含两个主要组成部分: 1. [**go-micro**](https://github.com/micro/go-micro): 一个 Golang 微服务开发框架。它是核心。 开发者可以利用它快速开发出微服务。这些微服务最常见的形态是 gRPC。 2. [**micro**](https://github.com/micro/micro): 一个命令行工具。 虽非必须, 但它可以为 Micro 开发和管理提供很多便利。 例如, 生成模板项目, 查看服务运行状态, 调用服务等。 此工具也是基于 **go-micro** 开发的。 除此以外, 实践中还会用到 [**go-plugins**](https://github.com/micro/go-plugins),这是一系列插件。涉及服务发现、异步消息、传输协议等方方面面。由于 go-micro 本身被设计成插件式架构, 配合这些插件可以达成非常灵活的组合效果,满足不同需求。 当然, 用户也可以自己开发插件,以便进一步扩展。 那么为什么官方定义如此宏大而抽象呢? 因为 Micro 的开发者 [Asim Aslam](https://medium.com/u/139d4f55a09a?source=post_page-----99c870e078f----------------------) 的野心不止于提供工具。 他最近的努力目标是[构建“分布式网络”](https://medium.com/microhq/building-a-global-services-network-using-go-quic-and-micro-2c1cf9b89c8?source=collection_home---6------0-----------------------) —— 虽然在我看来这个愿景[尚有重要问题待解决](https://medium.com/@dche423/looks-very-ambitious-im-a-little-bit-curious-about-micro-network-9c82078016bc),可行性存疑。 所以如果你只是想加速组织内的微服务开发与治理, 那么关注其核心功能即可。 这也是本系列文章的核心关注点 --- ## go-micro 的架构 为便于后续理解,先简单介绍 go-micro 的架构。 go-micro 的作用是简化微服务开发、构建分布式系统。 而有些工作是在每个分布式系统中都需要的。 所以 go-micro 把这些常见任务统一抽象成接口。 这使得开发者不必理会底层实现细节, 降低了学习和开发成本, 快速搭建灵活、健壮的系统。 ![](https://s2.ax1x.com/2020/03/10/8FZWfH.png) from <https://micro.mu/> 上述图中 Service 是系统中最核心的接口, 它负责将其它接口有机地组织在一起, 协调运行。以后会有文章对其作深入探讨。 举几个其它接口的例子加以说明: ### **服务发现** 这是每个分布式系统首先要解决的问题。 go-micro 将此类任务抽象到一个接口中 `github.com/micro/go-micro/registry/Registry` : ```go // 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) error GetService(string) ([]*Service, error) ListServices() ([]*Service, error) Watch(...WatchOption) (Watcher, error) String() string } ``` 任何实现此接口的插件都可以承担服务发现的职责。 实际上, 在 go-plugins 中已经提供了[很多插件](https://github.com/micro/go-plugins/tree/master/registry)实现。既有对 etcd / consul / zookeeper 等主流产品的支持,也有基于内存的轻量级实现。 默认实现基于 组播 DNS(mdns), 无需任何配置,开箱即用 ### 异步消息 异步消息是降低耦合、提高系统鲁棒性的关键技术。与之对应的 go-micro 接口为: `github.com/micro/go-micro/broker/Broker` ```go // 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 } ``` go-plugins 中已有的 [broker 插件](https://github.com/micro/go-plugins/tree/master/broker) 包括 RabbitMQ, Kafka,NSQ 等,默认实现基于 http,也是无需配置 ### 编解码 编解码定义了微服务之间通讯的消息传输格式,对应的接口是 ```go github.com/micro/go-micro/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 等等。 ### 除了上述 3 个,还有其它方面的接口: - **Server**, 定义微服务的服务器 - **Transport**, 定义传输协议 - **Selector**,定义服务选择逻辑, 可以灵活地实现各种负载均衡策略 - **Wrapper**,定义包装服务器和客户端请求的中间件 由此可见, go-micro 已经对分布式系统作了很好的切分与抽象, 并提供了丰富的默认实现。 即使官方插件没有提供, 开发者也可以方便地自行开发, 应用到系统中。 有了以上的架构基础, 开发者便可以更聚焦于业务功能开发,不用关注烦琐的基础任务。 极大地提高了交付效率 --- ## 用 Micro 创建第一个 gRPC 服务 上手 Micro 的最快途径是利用`micro`命令行工具创建项目骨架。 ### 安装 micro 命令行工具 使用如下命令下载安装最新的 micro 二进制文件 ```bash # Mac OS or Linux curl -fsSL https://micro.mu/install.sh | /bin/bash # Windows powershell -Command "iwr -useb https://micro.mu/install.ps1 | iex" ``` ### 创建第一个基于 go-micro 的 gRPC 服务 运行如下命令 ```bash micro new hello --namespace=com.foo --gopath=false ``` 此命令几个部分的含义分别是: - **micro new** 代表调用 micro 工具的 new 命令,创建一个 gRPC 服务 - **hello** 为服务名称 - **--namespace=com.foo** 指定了此服务的名称空间 - **--gopath=false** 表明把代码生成到当前目录,而不是 $GOPATH( 在golang 支持 [Go Module](https://blog.golang.org/using-go-modules)以后, 新项目应优先考虑放在 $GOPATH 之外) 当然, `micro new`支持更多参数, 我们在后续文章中会继续说明。运行此命令行的屏幕输出为: ```bash Creating service com.foo.srv.hello in hello. ├── main.go ├── generate.go ├── plugin.go ├── handler │ └── hello.go ├── subscriber │ └── hello.go ├── proto/hello │ └── hello.proto ├── Dockerfile ├── Makefile └── README.mddownload protobuf for micro:brew install protobuf go get -u github.com/golang/protobuf/{proto,protoc-gen-go} go get -u github.com/micro/protoc-gen-microcompile the proto file hello.proto:cd hello protoc --proto_path=.:$GOPATH/src --go_out=. --micro_out=. proto/hello/hello.proto ``` ### 安装依赖 由于 Micro 使用 protobuf 定义服务接口, 所以我们需要依上述提示安装与其相关的依赖,以 Mac 环境为例: ```bash # install protobuf brew install protobuf# install protoc-gen-go go get -u github.com/golang/protobuf/{proto,protoc-gen-go}# install protoc-gen-micro go get -u github.com/micro/protoc-gen-micro ``` 注意 `protoc-gen-micro`,它不属于 Protobuf 核心,它是 Micro 团队开发的代码生成器, 专门用于生成 Micro 相关代码 ### 运行 大家能看到骨架中包含了 Makefile, 它定义了一些常用的任务。因此可以用 make 命令编译和运行代码。 前面提到项目将使用 Go Module,而 `micro new` 并没有为我们自动生成 module 文件, 因此我们需要自己生成,运行 ```bash cd hello go mod init hello ``` 将创建默认的 module 文件 **go.mod** , 内容如下: ```bash module hellogo 1.13 ``` **\*特别提醒:\***接下来需要先安装 go-micro 的 v1.18.0 版,然后再编译运行: ```bash go get github.com/micro/go-micro@v1.18.0 ``` 运行此命令后 **go.mod** 文件内容变为**:** ```bash module hellogo 1.13require github.com/micro/go-micro v1.18.0 ``` 之所以要明确安装特定版本,是为了避免编译时自动安装 go-micro 的最新版本。 前面提到 Micro 本身在快速演进, 有时其最新版并不可靠。 举例来说,go-micro 最近的[6 个版本](https://github.com/micro/go-micro/releases)是在 35 天之内陆续发布的。个别版本存在严重问题,作为最新版本只存在了几个小时就被 hotfix 版本更新了。 好在有 Go Module 帮忙, 它帮我们锁定依赖,保证交付质量。 作了以上准备以后, 就可以编译并运行第一个服务了: ```bash make build && ./hello-srv ``` 屏幕将输出: ```bash protoc --proto_path=/Users/cuixg/go/src:. --micro_out=. --go_out=. proto/hello/hello.proto go build -o hello-srv *.go 2020-01-10 13:51:21.627440 I | Transport [http] Listening on [::]:51564 2020-01-10 13:51:21.627541 I | Broker [http] Connected to [::]:51565 2020-01-10 13:51:21.627710 I | Registry [mdns] Registering node: com.foo.srv.hello-54151215-f985-42ab-9fe8-f92a682d332d 2020-01-10 13:51:21.629620 I | Subscribing com.foo.srv.hello-54151215-f985-42ab-9fe8-f92a682d332d to topic: com.foo.srv.hello 2020-01-10 13:51:21.629839 I | Subscribing com.foo.srv.hello-54151215-f985-42ab-9fe8-f92a682d332d to topic: com.foo.srv.hello ``` **注**: 你运行得到的端口号和节点 uuid 可能与我不同,这是正常的。 以后会解释其原因。 从屏幕输出可以看到, `make build`首先执行 `protoc` ,编译 proto 文件,然后调用 `go build`, 成生可执行文件 **hello-srv**。 接着**hello-srv**被运行起来。 至于其运行细节,且听下文分解。 --- ## 总结 本文讨论了 Micro 的定义、特点。 引导大家完成了安装。 创建并运行了第一个最简单的微服务。 本系统后续文章将深入示例项目的代码, 实例剖析 micro 的原理并尝试改变其默认行为。 > 本文作者:[Che Dan](https://medium.com/@dche423) > > 原文链接:https://medium.com/@dche423/micro-in-action-getting-start-cn-99c870e078f

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2460 次点击  ∙  1 赞  
加入收藏 微博
被以下专栏收入,发现更多相似内容
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传