并不优雅
大家都知道,最近我一直痴迷于开发各种并无卵用的Telegram Bot。那么这一过程,就包含了开发、部署和管理这三个过程,本文就简单的说下这段时间的经验之谈吧
开发 Telegram Bot
神说:要有这个bot,于是就有了这个bot
开发bot,最重要的一点就是进行技术选型。“技术选型”看起来很玄乎,其实就是为了实现这个bot,我们要选用什么语言,使用什么库等等。
当然一切都要从需求出发,从我的角度而言,首选语言是Go——因为静态类型,静态编译之后很适合放到Docker Image里,并且只要凭借想象力编程就基本没问题了;如果Go无法达到我的预期,那就只好选Python了;如果连Python也做不好,那这个bot就可以丢掉了。
当然,在最终选定时,需要根据需求进行一些基础的调研,拿TeleTweet为例,基础阶段它的需求有这些:
- 能够把Telegram消息发送到Twitter
- 支持图片tweet
对于Go/Python与其生态的对比
Go:
- Telebot 纯Go实现的支持Bot API的库,维护很积极,文档也比较丰富
- go-tdlib Telegram官方tdlib的json bindings,文档几乎为0,同时需要先编译tdlib
- go-twitter 功能尚可,文档缺失,并且不支持UploadMedia
Python:
- pytelegrambotapi 非常知名的Bot API wrapper,文档丰富,维护积极
- Telethon 使用纯Python实现的MTProto,注释即文档,维护积极,支持bot和client
- python-twitter 还能凑合用的一个Twitter API wrapper,该有的功能都有,支持UploadMedia
那么对于TeleTweet而言,选择Python就是更明智的选择;对于NCMBot,由于需要使用Client API,因此选用Python+Telethon也是比较优雅的选择;对于Archiver,没有太多特殊的地方,用Go就可以了。
部署Telegram Bot
开发完成之后,bot是总要部署到某台服务器上的。由于我自己有很多bot,因此根据情况不同我把他们划分成了两类:
Legacy Bot
一些历史遗留下来的bot,基本没有继续的开发计划,处于即将被Archive的状态,有些甚至连说明都没有,完全是拿来自用?所以就丢着呗!
Modern Bot
最近一段时间开发的bot,有持续的维护计划,运行稳定,表现良好。
对于第一类bot,我选择让它们留在一台新加坡的机器上,原来是怎么跑的就怎么跑,一点都不动;
对于第二类bot,我把它们全部放到了一台日本的机器上。
对于第二类bot,如何运行它们又成为了一个问题。
好吧,现在这些bot,只要还能说话的,我都给丢到一台英国的大鸡鸡上了。
systemd service
使用Python开发的bot,那么就是老生常谈的virtualenv+systemd,实际操作下来有些繁琐,尤其是配置systemd总是有一些蜜汁情况,比如说环境变量啦,比如说用户啦;使用Go开发的bot,那么也就不外乎是clone下来源代码,然后go build .
,然后继续配置systemd。这样的话当bot一旦多起来,甚至以后要换服务器,那么就会更麻烦,所有上述操作都要全部重新再来一遍,非常痛苦?
docker + docker-compose
那么如果用docker去分发部署是不是就很方便了?毕竟第二类bot都是有Dockerfile
的。
没错的,就是这样——使用Dockerfile
构建出docker image,直接docker run就可以了。
更进一步,我可以把这堆bot都丢到docker-compose
中,一个docker-compose up -d
就可以了。
当然,构建docker image时,是有很多技巧的,这个就以后再说了。
管理、维护bot
使用Makefile
开发工作总是要不断迭代的,那么如果添加了新功能,,我该如何更新服务器上bot呢?
有些bot,我创建了一个Makefile
,里面是这么写的:
default: @echo "Updating codes..." git pull @echo "Restarting service..." systemctl daemon-reload systemctl restart TeleTweet @echo "You're good to go." systemctl status TeleTweet
很简单,很黄很暴力是不是,只要ssh到服务上,跳到对应的目录,一个make
然后就可以关窗放狗咬人走人了。
对于使用Go的bot,也不过是go build .
之类的,比如DailyGakki是这样写的:
default: git pull @echo "Installing dependencies..." @go get -u github.com/go-bindata/go-bindata/... @echo "Build static files..." make asset @echo "Build current platform executable..." go build -o DailyGakki . asset: @~/go/bin/go-bindata -o assets.go images/...
反正也是本机使用,没必要用CGO_ENABLED=0
以及额外配置ldflags
如果想要查看Bot的运行状态呢?那么只能systemctl status daily-gakki
这样啦!
使用docker+docker-compose
如果使用docker的话,那么一切问题就简单了。push完代码之后,等待docker hub build成功之后,ssh到服务器上:
docker pull xxx docker restart container_name
使用docker-compose也就不过pull了之后
docker-compose up -d service_name
查看状态?
docker-compose ps
或者
docker stats
总结
由此可见,在整个bot瞎搞的过程中,使用docker来进行分发部署管理还是非常方便的。当数量多起来,要比传统的systemd、supervisor之类的方便得多。
当然docker也有缺点,比如磁盘空间比较宝贵的盆友们,有些时候docker image就可能没那么理想,毕竟有些image只能包含rootfs。提到这点,如果是Python开发的bot,做一个通用的image,包含了这些bot所有需要使用的library也不是不可以的。
另外一个难点,docker容易新手劝退,比如说volumes有时比较有趣,一个不小心就很容易写错,然后就gg啦😂
不过,如果能够用Go开发,那么docker image甚至可以使用multi-stage build的手段。像下面这样:
一眼就能看出来哪些是用Go写的了吧!非常exciting。
更进一步,我甚至准备了一个Repository,专门用来存放这些bot的docker-compose.yml
。
哪怕哪天换机器了,我也只需要把这个目录拷贝走,然后一个docker-compose up -d
就可以继续装死了。
好的,以上就是我要说的全部内容,有关于我究竟开发了哪些bot,可以看这篇文章《有趣的 Telegram Bot》