
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