用 Golang 写一个支持各种编程语言的 serverless 框架

前言

fx 是我在 Go Hack的一个小作品,Go Hack 是一个以Go语言为主要编程语言的黑客马拉松比赛。虽然我和我队友两人都是写JavaScript的前端工程师, 以Golang 零基础参加这次比赛,不过很开心我们完成了fx,也喜欢上 Golang 这门语言.

读了那么多年书,写了那么久的代码,如果说有什么概念是深入骨髓的,只能说是”函数“了。虽然在数学上和编程上,“函数”这个词有很大的不一样的,但是有一点上它们是类似:

接受输入(可能为空值),然后进行处理,最后输出处理结果。

我们几乎可以用这个概念来描述所有的行为. 比如我们可以用下面的函数的来描述我们 fx 的诞生过程:

函数 f = Go Hack (以 Golang 为项目编程语言的黑客马拉松活动)
输入 input = [两个Go语言零基础的JavaScript工程师,两台Macbook,很多很多的功能饮料]
fx = f(input)

fx 是什么

那么 fx 是什么呢,一句话来说就是 : fx 是一个可以把一个函数变成一个服务的工具. 一个简单的例子来说一下 fx 的功能吧. 比如你写好了很棒的函数 , 它是这样的:

func.js

module.exports = (input) => { return parseInt(input.a, 10) + parseInt(input.b, 10) }

它的作用就是计算两个数的和. 你把这个函数写在 func.js 这个文件里面。 这时候你希望可以将这个函数编程一个服务,对外提供一个 url 可以供外界访问. 但是想到 nginx, web server, api gateway…, 你头有点大了。 现在你可以简单的这样做。

fx up func.js

如果一切没有什么问题,你可以得到一个url.

$ fx list +------------+---------+---------------+ | ID | STATE | URL | +------------+---------+---------------+ | ce925443d5 | running | 0.0.0.0:40549 | +------------+---------+---------------+

访问你的服务试试看

$ curl -X POST 0.0.0.0:40549 -H "Content-Type: application/json" -d '{"a": 1, "b": 1}'

你会得到 2. 这说明你的函数已经变成了一个服务了。

fx 如何工作

fx 有两个部分组成,fx server 和 fx client, 最开始的 client 和 server 基于 websocket 进行通信,所有的交互基于 websocket message 来进行, 当时选择 websocket 的原因是因为其简单,能够快速验证我们的想法。当项目做完了演示了之后放到了 Github 之后, 收到了很多的反馈,有同学提出了可以采用 RPC 架构来做,gRPC 如雷贯耳很长时间,就是没有机会去实践,但是后来工作一直很忙,所以没有能够及时完成迁移,然后社区的力量是强大的,一个就职于意大利FBK的哥们发Email和我说,他想参与维护 fx, 我简单看了他的Github主页了之后,就直接把他放到了 collaborator list 去了,后来他直接发了一个很大的 Pull Request过来,就是用 gRPC 替换了 websocket 的,我当然就很开心的做了merge.

所以现在的 fx 是一个基于 gRPC 框架的工具. 提供三个核心功能:

Usage: $ fx up func1 func2 ... deploy a function or a group of functions $ fx down func1 func2 ... destroy a function or a group of functions $ fx list list deployed services

所以整个架构也很简单,fx up 会将 function 的定义内容传递给 fx server,fx server 接受到 function 的内容了之后,匹配到正确的 Dockerfile 和对应的构建镜像所需的资源, 然后会调用 Docker Engine 的 api 去构建相应的服务,最后把生成的服务的 URL 返回给客户端.

up/ deploy a function to service --------------------------------------> <-------------------------------------- down/ stop functions' services --------------------------------------> fx client <-------------------------------------- fx server list/ list deployed services --------------------------------------> <--------------------------------------

fx 支持哪些编程语言

由于 fx 的一个服务的背后都是一个 Docker Container, 所以 fx 几乎可以支持所有的编程语言,由于精力有限,目前 fx 支持这些编程语言:

  • Golang
  • JavaScript/Node
  • Ruby
  • Python
  • Java
  • PHP
  • Julia

fx 的未来

啥未来,就是一个小工具而已。

Discussing on Hacker News
C
caust1c·Nov 13
points
Isn't this just `up`?<p><a href="https://github.com/apex/up" rel="nofollow">https://github.com/apex/up</a>
S
subway·Nov 13
points
But this one's written in... Oh.
J
joshstrange·Nov 13
points
It looks like up for running something like express/koa/etc while fx is for functions (like AWS Lambda). They are both "serverless" but that's about all they share in common AFAICT. Thanks for mentioning "up" though, I'd never heard of it before, very cool.
2 more replies...
G
Gys·Nov 13
points
Sorry if I mistunderstand. The readme is very limited. But this need a (vps or something) server that I own / manage ? It does not seem to upload the functions(s) to some cloud ?<p>In general I think 'serverless' means deploying code without managing some kind of server yourself.
J
jensvdh·Nov 13
points
It's a poor man's readme
Q
quickthrower2·Nov 14
points
Get your roomie to deploy it. Then it's serverless to you.
K
kennu·Nov 13
points
Even the README says you need to start a server. So it’s not quite serverless.<p>(“Serverless”, at least to me, means a platform where I don’t have to worry about running servers.)
P
proc0·Nov 13
points
I think serverless refers to the use of 'lamdas' as the unit of deployment, as oppose to containers or VM's, but someone else may want to add/edit that.
M
metrue·Nov 14
points
README is not quiet clear, but for my understanding, lambda is kinda thing that helps you to do serverless, but lambda is also running on some kind of server maintained by AWS, right? fx is kind of lambda, but owned by yourself.
K
kennu·Nov 14
points
Well, yes, you can run your own server to provide yourself a serverless platform, but it kind of defeats the purpose... Since then you end up having to maintain your server anyway.<p>I suppose there may be a point to it if the serverless platform is extremely stable and never has any security issues or other things to update.
1 more replies...
M
metrue·Nov 14
points
Your guys are so right about fx’s ‘Poor man’s README, I will update it soon. Long story short, you can deploy fx on a host (cloud or localhost), then you can deploy a function to be a service in few seconds, just like AWS lambda ( but Poor man’s lambda).
Discussing on V2EX
gejigeji
gejigeji·Nov 14
学习能力太强
xwhxbg
xwhxbg·Nov 14
make install... 原因是要装 dep 么? 先星一波,国内 gopher 真心少
koebehshian
koebehshian·Nov 15
不明觉厉,这和 CGI 有什么区别
metrue
metrue·Nov 15
@xwhxbg 是的,而且我对 Go 的包管理有点懵逼,看 Makefile 你就知道,我似乎没有用正确的姿势来对待 glide。
metrue
metrue·Nov 15
@koebehshian 嗯好吧,其实我想实现的是一个穷人版的 aws lambda,然后结果就成了 fx 现在这个样子。
noli
noli·Nov 15
虽然很不喜欢 golang,但是题主这作品(主要是作品的说明)太潇洒了,太有黑客风了! 用这么点代码量实现这么强大的功能,确实是非常值得加个关注。
ericshine
ericshine·Nov 15
@noli 思路比较简单,但是结果还挺好的。
xwhxbg
xwhxbg·Nov 16
推荐 dep,比较无脑
Discussing on Reddit
No comments found.