或许serverless这个概念目前在国内依旧陌生,那么,我先简单科普下,国内称serverless为无服务器架构,这点实在不敢苟同,服务器依旧需要,就像代码不可能自己产生代码而使得我们失业一样,只是服务商已经提供了标准的服务器,我们只需要关注写代码仅此而已!我来列举下serverless的特点吧!
说了这么多,不知道你是否理解它到底是什么,如果你问我,serverless到底是什么,我只能告诉你,它是云计算的一种,也可以理解为云计算的趋势,它原生就是微服务,你可以理解为云函数或者函数云计算,即在云主机上运行你的node js、python、go等函数。下面是我的一些经验之谈。
如果有机会,我还是建议你用用aws lambda,国外账号免费额度就足以了,不得不说aws国际和中国那是天囊之差,中国的服务,至少像lambda刚推出的时候就是残废,最后说端口没开放。有这么玩的嘛?此外,像数据库dynamodb在国外是免费用,我不记得是不是按需付费了,但国内NO,不是免费,但是页面写的是免费,而且创建后即使不用也要付费,我就吃过亏,几百大洋而已,此外,个人用户是注册不了的。扯淡完毕,我先谈谈 aws lambda本地开发的最佳实践,之后告诉你怎么搭建kubeless本地开发环境并一份代码同时兼容aws lambda以及kubeless
如果使用aws lambda,那么serverless-offline 是必备,而且我非常建议您使用它,天才之作啊!有了它,你可以本地调试你的代码,否则本地调试基本不可能。其次,如果你使用 dynamodb 那么一定在本地安装一份,不要直接操作云端,慢,这也是为啥我强烈建议你使用offline插件的原因,又不是我开发的,也不是我认识的人开发的,我没必要打 call 啊,然后你需要配置 aws lambda 在 vscode里的调试。这部分的详细操作我会在之后补充新的博文,欢迎关注。
接下来要说的是搭建kubeless的本地开发环境,kubeless是本地serverless开发环境,依赖k8s,但如果不熟练k8s那么建议你使用minikube,你可以参考我之前写的这篇 国内无痛使用minikube minikube一旦搭建完毕,那么就简单了。下面的命令用于搭建kubeless,可以参考官方文档 也可以参考我下面的步骤:
export OS=$(uname -s| tr '[:upper:]' '[:lower:]') curl -OL https://github.com/kubeless/kubeless/releases/download/$RELEASE/kubeless_$OS-amd64.zip && \\ unzip kubeless_$OS-amd64.zip && \\ sudo mv bundles/kubeless_$OS-amd64/kubeless /usr/local/bin/ export RELEASE=$(curl -s https://api.github.com/repos/kubeless/kubeless/releases/latest | grep tag_name | cut -d '"' -f 4) kubectl create ns kubeless kubectl create -f https://github.com/kubeless/kubeless/releases/download/$RELEASE/kubeless-$RELEASE.yaml kubectl get pods -n kubeless
另外,如果在搭建kubeless环境或者运行时出现错误等,可以用这个命令查看出错原因
kubectl logs -n kubeless $(kubectl get pods -n kubeless -l kubeless=controller -o=name)
至此,你的环境搭建完毕,我假设你已经掌握 aws lambda 或者了解serverless-offline 插件。现在我们写第一个kubeless函数,新建music.js并键入:
module.exports.save = (event, context, callback) => { return { data: { name: 'hello', }, }; };
kubeless有一个不成文的规定,handler必须在root目录,所以你的serverless,yml文件以及music.js必须在同一个目录下面,下面是serverless.yml配置文件:
functions: save-music: handler: handler.save events: - http: method: get path: music
这里我忽略了其他不重要的文件,然后你可以通过sls deploy来部署在本地,然后通过sls info查询调用API 的 url信息。你或许发现了,在上面的函数里,我传递了event、context、callback,其实这些是不必要的,仅仅传递类似pathParameter以及body、queryString、header信息即可。上面的写法和aws lambda一致,但是lambda 在node js里需要调用 callback(null, responseValue);
来返回数据给客户端。而kubeless仅仅只需要return 一个string即可,另外,我还不确定kubeless是否支持path parameter,但是 aws lambda支持。本文的关键是兼容 aws lambda 以及 kubeless,但是差不多要结尾了还没到主题,我之过错,如果你熟练 aws lambda你会发现仅仅是如何返回数据给客户端以及相应参数的问题,那么问题简单了,可以使用一个 helper 类来做兼容。至于这个类,我之后会写博文并附上链接。
最后一个问题,kubeless-serverless 插件有一个不成文的规定或者不好的设计,handler和serverless.yml必须同一个文件夹,我的项目有好几个模块,我是把代码写在同一个项目下面并没有严格微服务,aws lambda 允许你建立folder,而kubeless找不到folder,这非常严重,虽然serverless是微服务,但是不能如此最小化啊!我最后的解决方案是,一个handler.js类放在根目录,serverless.yml仅仅应用它,而它引用别的文件夹下面的js,当然,handler.js你可以明明为music.js并让他调用music目录下面的js,而music下面的js可以和serverless没有半毛钱关系,OK,现在回过头来看,这是一个耦合度超级松的架构设计!这个架构设计让这些js不仅可以用kubeless框架,自建服务器运行 serverless 也可以使用 aws 的服务器,当然还可以使用任何一个供应商的服务。因为它耦合度超级松,对具体框架 0 依赖!仅仅上层的handler.js或者music.js和框架有关。
下篇博文将讲述我是如何做到一份代码同时兼容 aws lambda 并使用 serverless-offline插件调试以及kubeless,当然依旧可以兼容 expressjs