这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

欢迎使用 Server饭

感谢你能来到这里,查看 Server饭 的文档。这个小服务适合个人、独立开发者或者小团队简单管理自己的服务器或云端服务。 在国内用微信真的很方便,也不用装什么别的 App,目前只能把我们的服务号LetServerRun当作控制台。

直观印象

右侧有一张使用截图

所以它的原理大概是这样:

  1. 与公众号对话发送指令
  2. 云端分拣和暂存
  3. Agent 拉取指令并执行返回结果
  4. 公众号回复你执行结果

一些特性

  • 发送消息给 Agent 并追踪结果
  • 通过 API 在公众号给自己发提醒
  • 内网穿透
  • 核心部分开源
  • 绝对的安全,Agent 的能力只由您控制

开始吧

您需要关注我们的公众号,把它当作一个Terminal使用,输入help或者帮助查看命令。

二维码

然后跟着 快速开始去部署一个 Agent, 或者直接查看文档编写自己的 Agent.

1 - 快速开始

先最快的用起来,然后再慢慢配置。

关注微信服务号

在文档首页有二维码了,这里再贴一次吧,如果关注了请继续后边的步骤。

二维码

关注后,输入help或者帮助看看一切是否正常。

主动发送通知

给自己发消息是最常用的功能, 在服务号发送 token 命令查看自己的用户 token 。

使用用户 token,您就可以用 API 向公众号发警告消息了:

curl "https://api.letserver.run/message/info?token=YOUR-TOKEN&msg=hello"

PS. 这个 GET 接口是为了调试和轻量使用场景的,在程序中使用的话有更完善的 POST 接口,SDK 也支持主动发消息。

反向控制原理

发送通知的服务很多,Server饭 的特色功能是反向用微信控制服务器做简单的事情。 放心,不需要你提供ssh密钥,为了安全,命令能做什么完全由你定义。

下面是反向控制的大概原理:

graph LR
  IM(服务号对话) --> c{{Server饭}}
  c -- 拉取命令 --> a(Agent)
  a -- 返回结果 --> c
  c --> IM

第一个 Agent

通过命令agent add 它的名字增加一个 Agent。
通过status命令,可以看到你加的这个 Agent 在离线状态。一个 Agent 如果三分钟以上没有心跳就会离线。

我们先使用一个 开源的通用 Agent来上手。
它可以帮你在服务器执行特定的命令。后面我们可以根据需求,自己通过 API 或 SDK,集成 Agent 或自己编写。

假设你的服务器是 Debian/Ubuntu ,如果是别的请参考 安装通用Agent
如果您本身就是 root 用户,麻烦去掉所有命令中的 sudo

# 注册仓库
curl -1sLf \
  'https://dl.cloudsmith.io/public/hackfan/skadi/setup.deb.sh' \
  | sudo -E bash
# 更新
apt update
# 安装
apt install skadi

在安装后,因为还没有 Token,所以并没有自动启动。 我们用 skadi 把之前公众号添加 Agent 得到的 Token 写入配置文件。 你也可以编辑 /etc/skadi/skadi.yml 这个文件自己写入。

# 写入 Token
sudo skadi AGENT-TOKEN
# 启动服务
sudo systemctl start

只有第一次需要配置Token后手动启动服务,服务器重启它是会依靠systemd自己启动的。

试用 Agent

在公众号输入 它的名字 help ,在一分钟之内,命令会被Agent拉走并返回结果。
这个官方的通用 Agent 功能由你部署它的服务器上的 /etc/skadi/skadi.yml 这个配置文件定义。

然后你可以顺次输入名字 date,名字 lsroot,名字 free -m,名字 Hi Fool, 去试用,接下来,更改配置文件就可以完成重启服务,查看状态等简单的动作了。

# 调试模式,打开可以看到更多日志,使用 journalctl -u skadi 查看日志
debug: false
# 可以直接填写token到这里,或者用 skadi TOKEN 命令去写入
token:
# shortcuts 将一个单词精确的翻译为一条命令
# short: 你在公众号输入的消息
# dir: 命令的工作目录,可选。有的命令不需要工作目录就不填。
# cmd: 精确的命令。
shortcuts:
  - short: date
    cmd: "date --rfc-3339=second"
  - short: lsroot
    dir: /
    cmd: ls
# commands 是一个命令白名单,这里列出命令,在公众号使用时可以随意加参数。
# dir: 命令的工作目录,可选。有的命令不需要工作目录就不填。
# prefix: 允许的命令,比如这里允许free,实际使用时可以输入 free -k
commands:
  - prefix: free
# templates 是一个模板引擎,可以预留参数,调用时只用输入参数
# name: 调用时接在 Agent 名称后的第一个词
# dir: 命令的工作目录,可选。有的命令不需要工作目录就不填。
# temp: 模板,用的 golang 的模板引擎
# 示例 name:"Hi" temp:"echo I am not %s!"
# 在公众号输入 [Hi 傻瓜] 会收到结果 [I am not 傻瓜!]
templates:
  - name: Hi
    temp: "echo I am not %s!"

修改完配置文件后,用命令重启服务,它们就生效了。

sudo systemctl restart skadi

编写自己的 Agent

如果是控制集群重启之类的,使用我们的 Agent 就够用了。

如果想实现更多的功能,可能需要你自己根据开放接口写一个 Agent 。

甚至直接在服务中集成一个 Agent 实例,就可以把微信当作简单的业务控制台了。

2 - 基本功能

介绍服务拥有的基本能力

请看各章节详情。

2.1 - 给自己发送通知

轻松给自己的微信发送通知。

获取你的 Token

调用用户级别的功能,需要用户 Token
向公众号发送 token 就可以得到自己的用户 Token

发送消息

现在调用发送消息的 API 就可以往公众号发送消息了

GET https://api.letserver.run/message/info?token=YOUR-TOKEN&msg=hello

用 curl 命令就是这样

curl "https://api.letserver.run/message/info?token=YOUR-TOKEN&msg=hello"

消息类型

目前有四个消息接口,它们的区别如下:

  • info 公众号模板消息,提醒,默认为蓝色
  • warning 公众号模板消息,警告,默认为红色
  • text 利用公众号客服消息直接发文本,每次和公众号互动后有20条额度
  • auto 先尝试发送 text ,如果失败则改用 info 接口

GET 和 POST

GET 版本的接口是为了调试和简单的使用的,比如在 CI 脚本中,写起来简单。

POST 版本接口需要把 token 携带在 Authorization Header 中。
并且还支持自定义颜色等,详情参见 接口文档

User 和 Agent

在接口文档中,除了 User 接口,还有若干 Agent 发消息接口,比如 /agent/message/info
Agent 版本和 User 版本的区别是使用的 Token 不一样。

Agent 版本是为了 Agent 能方便的直接调用,不用再传入 User Token
另外在发送模板消息时,Agent 版本会标注消息来源。

限制

公众号模板消息有每天100条的限制,而纯文本的客服消息,是在你向公众号说话后,会在48小时内有20条发送额度。 每次说话都会重置这个额度。

2.2 - Agent简介

关于 Agent 的基本信息。

除了在服务器上调用我们的 API 给公众号发通知,Server饭 更有用的功能是把这个过程反过来, 在公众号输入文字控制服务器的行为,您只要一次配置,以后便有个随身的控制台了。

什么是 Agent

Agent 是一个概念,它是帮你处理你在公众号中输入的指令的一个程序。

它可以在服务器,在PC,在路由器,在智能设备中。它可以用任何语言写成。 它甚至可以没有实体,只需要在你的服务中调用 API ,就相当于完成了 Agent 的功能。

采取这种 Agent 拉取并执行命令的模式,是为了绝对的安全。你的 Agent 只会执行你允许的动作。
Server饭 的云服务不会主动访问你的服务器,这也带来了内网穿透的功能,你可以任意使用代理。

怎么写一个 Agent

这里是 Agent API

写一个 Agent 只需要按如下逻辑调用这三个 API 就好了:

  1. 每分钟调用一次 接收Job
  2. 如果返回结果是 204,证明没有 Job 需要执行。如果是 200,则解析出 Job 去执行它。
  3. 执行完成之后,调用 成功失败 修改 Job 状态,这时你在公众号中会收到相应的通知。

能更方便一点吗?

我们正在添加各个语言的 SDK,这样写起来会更方便,目前只有 Go

欢迎为你喜欢的语言写 SDK

有例子吗?

同样的,目前还只有 Go 的例子,后续会在 SDK 完成后添加 python nodejs java php 等语言。

执行shell命令的例子

管理 Docker Swarm 的例子

能再方便一点吗?

我们会写很多现成的 Agent 供大家使用。目前写好了一个,它可以通过简单配置就启动在 Linux 当中帮你执行指定的命令。

比如重启服务之类的常用需求,使用这个就完全够了。详情见下一节。

2.3 - 一个通用Agent

可以轻松的部署在服务器上,帮你根据配置文件执行命令,使用 Golang 编写。

如果只是想在服务器上执行简单的命令,使用我们开源的这个通用 Agent 就够了。

它的源代码在: https://github.com/hack-fan/skadi-agent-shell

命令和服务的名字叫 skadi , 和我们的开源项目保持一致。

安装

Debian/Ubuntu

第一步,增加软件源

curl -1sLf \
  'https://dl.cloudsmith.io/public/hackfan/skadi/setup.deb.sh' \
  | sudo -E bash

如果你本身用的 root 用户,请去掉命令中的 sudo

第二步,更新源,安装 skadi

apt update
apt install skadi

这里安装就完成了,skadi 在安装完成后并不会立即启动,因为还需要配置 Agent Token, 请参考后续的配置环节。

ps. 如果你对第一步的自动脚本不放心,那么可以用如下步骤手动增加软件源:

apt-get install -y debian-keyring  # debian only
apt-get install -y debian-archive-keyring  # debian only
apt-get install -y apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/hackfan/skadi/gpg.75A5AACF21FC017E.key' | apt-key add -
curl -1sLf 'https://dl.cloudsmith.io/public/hackfan/skadi/config.deb.txt?distro=ubuntu&codename=xenial' > /etc/apt/sources.list.d/hackfan-skadi.list
apt-get update

注意:你需要更改上述命令中的 ubuntuxenial 为你的发行版和版本。

ps2. 卸载软件源

在使用 apt 卸载 skadi 之后,你也许还想卸载软件源,执行如下命令即可卸载干净:

rm /etc/apt/sources.list.d/hackfan-skadi.list
apt-get clean
rm -rf /var/lib/apt/lists/*
apt-get update

Redhat/CentOS/Amazon/Fedora/SUSE

第一步,增加软件源

curl -1sLf \
  'https://dl.cloudsmith.io/public/hackfan/skadi/setup.rpm.sh' \
  | sudo -E bash

如果你本身用的 root 用户,请去掉命令中的 sudo

第二步,更新源,安装 skadi,如果是 Fedora或SUSE用户,自行替换命令为 dnf/zypper

yum install skadi

这里安装就完成了,skadi 在安装完成后并不会立即启动,因为还需要配置 Agent Token, 请参考后续的配置环节。

ps. 如果你对第一步的自动脚本不放心,那么可以用如下步骤手动增加软件源,这里仅列出 Redhat/CentOS 脚本:

yum install yum-utils pygpgme
rpm --import 'https://dl.cloudsmith.io/public/hackfan/skadi/gpg.75A5AACF21FC017E.key'
curl -1sLf 'https://dl.cloudsmith.io/public/hackfan/skadi/config.rpm.txt?distro=el&codename=7' > /tmp/hackfan-skadi.repo
yum-config-manager --add-repo '/tmp/hackfan-skadi.repo'
yum -q makecache -y --disablerepo='*' --enablerepo='hackfan-skadi'

注意:你需要更改上述命令中的 el7 为你的发行版和版本。

ps2. 卸载软件源

在使用 apt 卸载 skadi 之后,你也许还想卸载软件源,执行如下命令即可卸载干净:

rm /etc/yum.repos.d/hackfan-skadi.repo
rm /etc/yum.repos.d/hackfan-skadi-source.repo

配置

配置文件在 /etc/skadi/skadi.yml 按照注释自行修改即可。

# 调试模式,打开可以看到更多日志,使用 journalctl -u skadi 查看日志
debug: false
# 可以直接填写token到这里,或者用 skadi TOKEN 命令去写入
token:
# shortcuts 将一个单词精确的翻译为一条命令
# short: 你在公众号输入的消息
# dir: 命令的工作目录,可选。有的命令不需要工作目录就不填。
# cmd: 精确的命令。
shortcuts:
  - short: date
    cmd: "date --rfc-3339=second"
  - short: lsroot
    dir: /
    cmd: ls
# commands 是一个命令白名单,这里列出命令,在公众号使用时可以随意加参数。
# dir: 命令的工作目录,可选。有的命令不需要工作目录就不填。
# prefix: 允许的命令,比如这里允许free,实际使用时可以输入 free -k
commands:
  - prefix: free
# templates 是一个模板引擎,可以预留参数,调用时只用输入参数
# name: 调用时接在 Agent 名称后的第一个词
# dir: 命令的工作目录,可选。有的命令不需要工作目录就不填。
# temp: 模板,用的 golang 的模板引擎
# 示例 name:"Hi" temp:"echo I am not %s!"
# 在公众号输入 [Hi 傻瓜] 会收到结果 [I am not 傻瓜!]
templates:
  - name: Hi
    temp: "echo I am not %s!"

修改完配置文件后,用命令重启服务,它们就生效了。

sudo systemctl restart skadi

一些示例

重新部署一个 docker stack, 发送xxx 重启就会重启这个 stack

shortcuts:
    - short: 重启
      # 你的 compose file 的位置
      dir: "/root/swarm/"
      # docker-compose.yml 是你的 compose file 名称, api 是你的 stack 名称
      cmd: "docker stack deploy --prune --with-registry-auth -c docker-compose.yml api"

如果服务器上有多个 stack ,我们可以把配置文件和 stack 做成同名,然后为了使用方便,可以写一个shell,up.sh

docker stack deploy --prune --with-registry-auth -c $1.yml $1

然后用模板功能,最终效果是发送 xxx up api 就会重启 api 这个stack

templates:
    - name: up
      temp: "sh up.sh %s"
      dir: "/root/swarm"

2.4 - 延迟队列

把 Server饭 当作一个可靠的延迟队列。

为什么需要延迟队列

很多业务场景都要用到延迟队列:

  • 新订单如果未付款在一个小时后自动关闭。
  • 订单发货后15天自动确认收货。
  • 餐厅消费后一个小时请求评价。

类似的还有很多,不一一列举了。

延迟队列的误解

因为叫队列,所以如果项目用了某种队列,第一反应就是去看这种队列是不是支持延迟队列

很不幸,各家队列和云服务商提供的队列,都对延迟队列支持的不怎么好。只有 RabbitMQ 稍微好一点。

为什么会这样呢?因为延迟队列和传统的队列压根是两种东西。想兼容当然不容易了。 传统的队列一般都是先进先出,可以是生产消费模式或者广播订阅模式。更侧重于性能、可靠性、顺序性等方面的改善。

但是延迟队列实际上是一种持久存储的计划任务,它更应该和传统的队列结合使用。Job存储在一个安全可靠的地方,到时间了拿出来放某个队列供消费。

为什么 Server饭 是一个不错的选择

  1. 网上有很多在代码中实现延迟队列的教程,各个语言也有轮子,这个方式是最不推荐的。把信息存在内存当中,难道服务永远不升级重启了?
  2. 用 Redis 当延迟队列,可以使用 zset 或者 过期事件实现。问题是同样的,一般的 redis 没那么可靠,除非你用的有可靠性保障的 Redis 集群。
  3. 自己写一个有独立存储的延迟队列。如果你有这个力气当然是可以的……一般来说延迟队列在总的需求中占比很小,你可能没有那么多的时间预算去写一个服务,然后维护它。
  4. 想找一个类似的云服务,结果这个功能太小了,找不到。

这个时候我们开箱即用的接口就很方便了。

一个例子

我已经在 坚橙艺术 中实际使用了一段时间,分享给大家。

  1. 订单123卖家发货后,调用 延迟任务接口发送15天订单完成 123
  2. 如果买家在收货之后手动点击了确认收货,则系统自动调用订单完成的函数。
  3. 如果卖家在发货一周后着急确认,客服在询问买家确实收货后,在 LetServerRun 公众号发送 订单完成 123
  4. 15天后,Agent 收到当时设定的延迟任务,会再执行一次。这就要求这个订单完成需要判断订单状态,保证自己是幂等的,重复执行也不会出错。

3 - 更多有创意的用法

一些功能创意,也许你可以玩出更特别的。

3.1 - 在 Github Action 中使用

通知 Github Action 的结果

通过引用官方的 Github Action ,可以方便的在你的 Action 最后通过 Server饭 反馈执行结果。

Github 市场: https://github.com/marketplace/actions/serverfan-notifier

源码: https://github.com/hack-fan/skadi-action

3.2 - 一些零碎的小技巧

也许能给你些提示

LetServerRun 置顶。在手机端和 Windows 桌面版,都可以很方便的进入从而下达指令。 在 Mac 版里,会被折叠进订阅号,想用的话只能搜索 lets 然后就能搜出来。


输入 poster 指令,获得分享海报。别人通过你的海报关注后,会为你们双方各增加一个 Agent 配额哦。


你可以利用 Agent 上线离线自动产生的通知,做很多有趣的事情。比如只要服务中集成了 Agent,什么都不做相当于在监控它了。

4 - API 和 SDK

通过 HTTP API 和各语言的 SDK ,你可以自由的完成各种功能。

HTTP API 文档在顶端目录里边。 点击这里也可以直接访问。

API 分为 User 系列和 Agent 系列。

  • User 系列使用用户的 User Token,一般用在 CI 等主动发起场合。
  • Agent 系列使用 Agent Token,可以用来写 Agent。

然后为了方便大家使用,会陆续推出各个语言的 SDK,会尽量都写成0依赖的。

这个章节就是各 SDK 的简单说明。

5 - 更新说明

我要写一份大家能看得懂的更新说明。

2022年5月30日

新增功能

  • 现在向公众号发送随意一个字符,会被认为是维持对话,不会得到任何回应。

改动

  • 默认 Agent skadi-agent-shell 增加了 arm64 版本。

2021年8月19日

新增功能

  • 增加了一个官方的 Github Action

改动

  • 默认 Agent skadi-agent-shell 检查任务间隔从1分钟降低到10秒。
  • Go SDK skadigo 默认检查任务间隔从1分钟降低到30秒。

2021年6月11日

改动

  • 模版消息配额从每小时5次,修改为每天100次,以应对有时候的爆发需求。

2021年5月30日

修复

  • Agent 版本的 Auto 有时有问题,在发现报错日志之后已经修复了。但是 Agent 调用发消息报的所有错都无法反馈给调用者,还需要想办法解决。

2021年5月11日

改动

  • Go SDK skadigo 支持传入 Debug 参数,此模式下不发送任何网络请求,没有 token 也不会报错。

2021年4月29日

新增功能

  • 新增 POST /agent/job/delayed 接口,让 Agent 可以给自己发延迟任务了。
  • Go SDK skadigo 同步增加了目前所有支持的接口。

2021年4月27日

新增功能

  • 新增 /agent/message/auto 接口,让 Agent 也能使用自动适配发送方式的消息。
  • 新增 /agent/job/add POST 接口,让 Agent 可以给别的 Agent 发送任务了。

改动

  • Break API: 所有的 Agent 发送消息的接口统一了前缀为 /agent/message/

2021年4月25日

新增功能

  • 新增 /message/auto 系列接口,在可以用微信文本消息的时候用文本消息,如果不行就用模版消息。
  • 新增 /job/add 接口,可以调用 API 向 Agent 发 Job 了, CI 利器。

2021年4月23日

新增功能

  • 新增实验室,里边包含实验性的功能

改动

  • 现在所有的命令关键字不区分大小写了,输入法让首字母大写了也没关系。
  • 各种超长错误提示更加友好了。
  • 统一资源配额,永久资源类的公用一个配额。并行度类的会共享同一个系数。

2021年4月12日

新增功能

  • Agent上线和离线事件现在会在公众号通知了

改动

  • 现在会校验各种输入的信息了,不符合要求会有更友好的错误提示。
  • Golang SDK被重构,现在handler可以得到任务id,用以阶段汇报
  • 开源Agent现在在token错误时会退出并不再重启
  • 开源Agent现在在任务执行失败时会返回错误输出

2021年4月10日 初始版本

把这个版本当作初始版本吧,目前的功能有:

  • 通过公众号进行 Agent 管理
  • 通过公众号给 Agent 发布任务
  • Agent 任务相关所有接口
  • Agent Golang SDK
  • 一个通用版的 Agent
  • 用户发送公众号通知相关接口
  • Agent 发送通知相关接口