FaaS 是 Function as a Service 的簡稱,是構建 Serverless 的一種框架。
那么 FaaS 做了什么事情呢?簡單來講 FaaS 將 HTTP 請求轉發(fā)到可執(zhí)行命令,然后將命令的執(zhí)行結果轉發(fā)給 HTTP Response。
有了這么一條業(yè)務邏輯我們就可以構建自己的 FaaS 服務器。
首先定義可執(zhí)行命令的數(shù)據(jù)結構:
data Proc = Proc { procFuncName :: String
, procName :: String
, procArgv :: [String]
}
-
procFuncName為 HTTP 請求的函數(shù)名字 -
procName為可執(zhí)行的命令 -
procArgv為可執(zhí)行命令的參數(shù)
執(zhí)行命令使用 System.Process.ByteString.Lazy 里面的 readProcessWithExitCode
runProc :: Proc -> ByteString -> IO (Either ByteString ByteString)
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 wb
case result of
Left err -> do
status status500
raw err
Right out -> raw 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 服務器已經(jīng)完成。
FaaS 服務器就這么簡單,在生產環(huán)境上我們還需要做一些事情,比如 函數(shù)可以配置。
完整的代碼參見 func