FaaS 是 Function as a Service 的简称,是构建 Serverless 的一种框架。 那么 FaaS 做了什么事情呢?简单来讲 FaaS 将 HTTP 请求转发到可执行命令,然后将命令的执行结果转发给 HTTP Response 。
有了这么一条业务逻辑我们就可以构建自己的 FaaS 服务器。
首先定义可执行命令的数据结构:
data Proc = Proc { procFuncName :: String
, procName :: String
, procArgv :: [String]
}
procFuncName
为 HTTP 请求的函数名字procName
为可执行的命令procArgv
为可执行命令的参数执行命令使用 System.Process
里面的 readProcessWithExitCode
runProc :: Proc -> String -> IO (Either String String)
runProc (Proc { procName = name, procArgv = argv}) wb = do
(code, out, err) <- readProcessWithExitCode name argv wb
case code of
ExitSuccess -> return (Right out)
ExitFailure _ -> return (Left err)
使用 Web.Scotty
来构建 web
服务器
processHandler :: (String -> Maybe Proc) -> ActionM ()
processHandler getProc = do
func <- param "func"
case (getProc func) of
Nothing -> do
status status404
raw LB.empty
Just proc -> do
wb <- body
result <- liftIO $ runProc proc (LB.unpack wb)
case result of
Left err -> do
status status500
raw (LB.pack err)
Right out -> raw ( LB.pack out)
catProc :: Proc
catProc = Proc { procFuncName = "cat"
, procName = "cat"
, procArgv = []
}
getProcByFuncName :: String -> Maybe Proc
getProcByFuncName "cat" = Just catProc
getProcByFuncName _ = Nothing
main = scotty 3000 $ do
post "/function/:func" $ processHandler getProcByFuncName
到这里 FaaS 服务器已经完成。
FaaS 服务器就这么简单,在生产环境上我们还需要做一些事情,比如 函数可以配置。
完整的代码参见 func