这是一系列介绍Micro框架的文章的第六篇,我将会把作者的博客翻译成中文,推广Micro这个微服务框架。
今天我想聊一下机器人。
机器人?真的吗…
现在我知道你在想什么,现在有许多关于机器人的夸张说法。如果你对聊天机器人熟悉的话,你会知道这些都不是什么新说法,事实上最早的历史开始于Eliza。大众对机器人重新开始着迷,是因为我们发现了机器人有更多的功能,而不仅是简单的好玩。同时他们也提醒了我们下一代的人机交互接口会演变成什么样。
从工程师的思维来看,机器人不仅是为了交谈的目的,他们在执行任务的时候,超出想象的好用。大部分的我们已经对ChatOps很熟悉了。Github创造了这个概念,推出了他们的 Hubot,这是一个聊天机器人,可以管理技术上和业务上的操作任务。
看看这篇Jesse Newland的演讲了解更多:ChatOpts at GitHub
Hubot和机器人看起来已经证明了,在技术公司他们是非常有用的,他们在运维和自动化方面成为了好用的助手。现在通过HipChat或者Slack操控机器人来执行任务,而以前我们是手动的执行一些脚本,这明显要强大的多。这对整个团队带来的价值是显而易见的,每个人都能看到你在做的事情,已经事情的结果。
Micro服务怎样与ChatOps结合起来?
Micro,这个微服务工具箱,包括了一系列的服务,提供了接入点连接你正在运行的系统。API,Web控制台,CLI等等。他们都能与你的服务进行交互,观察你的服务的运行环境。在过去的几个月,这已经变得很清楚了,机器人是另外一种接入点,用于与你的服务进行交互与观察你的服务,这也是Micro世界的第一等公民。
这样一来
首先我们要明确,Micro 机器人是处于非常早期的阶段,目前主要是通过CLI提供功能。我们现在不能说实现了ChatOps,但或许有一天可以呢…
Micro机器人包括了类似hubot的语法命令,已经一种实现的输入,比如Slack或者HipChat。这是粗糙的第一个版本,但我相信随着工作的投入,不久以后就能大大提供机器人的能力。希望社区也能加入进来。
Bot 包括了所有的CLI命令,也提供了Slack和HipChat的入口。我们的机器人目前运行在一个demo环境中,通过Micro Slack提供,在这里加入我们。
在最近的开发周期中,我们会看看增加一些入口,比如IRC,XMPP,让我们可以通过命令简单的管理运行中的微服务。如果你有新的入口或者命令需要添加,请提交PR,贡献者是非常欢迎的。目前的插件可以在这里看到:github.com/micro/go-plugins/bot
这确实是一个基础的框架,用于对Micro生态系统做可编程的机器人。整个工具箱拥有插件化的特性。让我们看看Inputs和Commands是怎样工作的。
Inputs
Inputs是micro机器人怎样连接hipchat,slack,irc,xmpp等等。我们目前已经实现了HipChat和Slack,应该覆盖了大部分的用户。
这里是Input的接口定义
1 | type Input interface { |
Input提供了方便的功能,用于添加你自己的命令行参数。Flag()
这个方法会在初始化之前调用,任何自定义的参数会增加到全局参数列表里面。
在参数被解析之后,Init()
会被调用,这样一来,这个入口的任何中间数据都会被初始化,一旦所有事情执行完成,机器人就会调用Start()
然后是Stream()
方法,用于与Input建立连接。
这是Stream方法返回的Conn接口
1 | type Conn interface { |
机器人会持续的调用Recv()
来监听事件。Recv()
应该是一个阻塞的调用,否则我们会陷入死循环,耗尽CPU。一旦机器人处理完了事件,它会通过Send()
返回一些结果。
Event是一个基础的类型,用户在机器人和入口之间通信。他可以让我们把不同的消息类型,封装成统一的格式。目前只有一个TextEvent
类型,在未来我们会有更多。
机器人是不知道命令是来自于Slack,HipChat还是其他地方。它只知道收到了一个事件,然后需要执行它。这是一种很好的方式,用于把机器人和Input拆分开。
这里是Event类型
1 | type Event struct { |
Commands
commands是可以被机器人执行的函数。这很简单,它们存储在map中,key经过正则,它们会匹配上input接收到的事件。如果正则匹配上了某个事件,关联的函数就会被执行。命令的执行结果就会被发送回input。如果事件的From字段不为空,返回会被发送到To字段。你可以看到这是怎样让机器人直接的进行交流,不管任何地方,任何时候。
当前的Command的接口非常直接,但未来可能会更改,一旦我们遇到更复杂的情况。
command的接口:
1 | type Command interface { |
这里是一个Echo Command的示例
1 | // Echo returns the same message |
其他?
只有Inputs和Commands是不够的。如果我们以后想要做些其他的操作呢?我们怎样持久化机器人的状态?双向的交流怎么样?而不是仅仅返回内容。
这必须要编译!
我们仍然处于构建这个机器人框架的早期,这是一个机会,讨论基础的接口应该是什么样的。
下一步是提供各种类型的接口。更严肃一点,我们需要一个Stream
接口或者类似的。还需要Input.Conn
,这样我们可以处理任何插件的事件流。
这潜在的让我们有能力实现同一时间接收多个input的事件流,因此我们可以从事件流中获取事件,处理后返回。
一个例子是,从Slack中接受到消息,查询micro的服务,最后发送一个总结性的邮件。
怎样运行起来?
micro机器人在你的环境中单独运行起来,就像其他某个服务一样。也会通过服务发现进行注册。
我怎样运行?
因为机器人就像运行一个其他服务一下,你首先需要启动服务发现机制,默认是consul
使用支持Slack的机器人
1 | micro bot --inputs=slack --slack_token=SLACK_TOKEN |
以及HipChat
1 | micro bot --inputs=hipchat --hipchat_username=XMPP_USERNAME --hipchat_password=XMPP_PASSWORD |
运行中的机器人
这里有一些运行起来的机器人的截图,就像你看到的,它是一个CLI命令的复制。我们有一些额外的命令比如动画和地图。在这里可以看到github.com/micro/go-plugins
增加新的Commands
Commands是一个可以被机器人执行的函数,通过字符进行匹配,类似其他的机器人比如Hubot
这里是怎样写一个简单的ping命令
编写命令
首先通过NewCommand创建一个命令,这个一个快速的方式,你也可以实现这个接口。
1 | import "github.com/micro/micro/bot/command" |
注册命令
把命令添加到Commands map中,匹配的key需要被golang/regexp.Match匹配。
这里我们只对ping命令作出响应
1 | import "github.com/micro/micro/bot/command" |
连接命令
在这里引入你的命令
1 | import _ "path/to/import" |
接下来进行编译
1 | cd github.com/micro/micro |
下一步?
我们要意识到微服务世界并不容易,它需要一系列的工具,还要进行观测。比如监控服务、分布式tracing、结构化日志,这都是重要的组成部分。
想象一个世界,机器人有能力感知分布式系统。当我们需要的时候,提供反馈给我们,而不是需要盯着控制台,处理一个个错误提示。你也许听说过NoOps?那么什么是BotOps?你不会被电话催促怎么样?常见的错误,都通过事先预定的程序处理怎么样?
总结
机器人的革命只是刚刚开始,基础设施和自动化的世界正在改变,我们相信机器人会扮演一个重要的角色,最初是传统的ChatOps ,未来会走的更远。
机器人需要被看做第一等公民,跟配置管理、命令行、和API一样。我们只是把机器人加入到Micro的生态系统中来。
这仍然是处于早期,但不就的将来将会让我们满意。