用 20 行 Haskell 写 FaaS 服务器

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.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 服务器已经完成。

FaaS 服务器就这么简单,在生产环境上我们还需要做一些事情,比如 函数可以配置。

完整的代码参见 func

你可能感兴趣的:(用 20 行 Haskell 写 FaaS 服务器)