美文网首页
微服务大逃离, 函数即服务呼风唤雨-01: haskell勇赴云

微服务大逃离, 函数即服务呼风唤雨-01: haskell勇赴云

作者: larluo_罗浩 | 来源:发表于2018-09-29 21:47 被阅读452次

国庆节开始了,为大家献上一篇!

  1. 前言
  2. 开战函数式-faas on docker!
  3. 开战云计算-faas on k8s!

一. 前言: faas时代已至,云计算领域必将欣起一场血雨腥风。。。

微服务已逐渐被人们所接受,没吃过猪肉的,想必也见过猪跑。。。
大量的人在迷信微服务,把整个系统搞得一团乱,我是非常气愤的!

但是我不排斥微服务,因为我相信

微服务嘛,必将成为函数即服务faas的踮脚石。

1. 计算机原本很简单,最初一个PHP就可以搞定前后端。。。

但是呢,后端怎么可以乱动?前端是可以乱动的!
毕竟用户体验是不断变化的,用户特效是不断变化的,但后台核心功能岂可胡来。。。
所以,在有限的后台服务上,我们可以自由组合出各种前端,并且分工更加明显。
这显然是好事。。。

2. 前后端分离是第一步,随着科技日益发展,后端功能也越堆越多。

部门之间业务更加集密,这时候跨部门的业务集成是非常有必要的了。
SOA的时候已经过去,REST的简单使服务变得如此便宜, oauth2协议也成了标配。。。
所以,不同部门已不再限技术 ,不再限平台,只需要接口的体系。
这也算是好事。。。

3. 各系统之间交互,必然有大量基础设施,这自然也形成了微服务体系标准。

比如验证功能,存储功能,调度功能大家都可以一起用,开开心心。。。
所以,微服务开始呼风唤雨。。。
但是呢,人们慢慢熟悉,慢慢发现,微服务深处,让人可怕。。。

4. 微服务哪里让人可怕了?简单的地方隐藏了无数复杂。。。

比如我要做一个文件格式转码器,很自然可以做成一个微服务,大家一起开心使用。
一切看起来似乎很美好,但是如果你有10个服务,有个服务挂掉了呢?B服务依赖A服务呢?
我靠,什么服务降级?什么熔断机制?什么服务注册?什么配置中心?什么什么,请问,我是在写代码吗?
我的功能本身可以是一个插件JAR包,得到前台请求,运行JAR包里面的功能就可以了,
什么事情都没有,一台服务挂了,另一个来嘛。
所有请求处理都从代码插件包里加载响应,没有额外进程额外开销,没服务你怎么出问题怎么监控!。。。就应该这么简单啊!

5. 微服务有错吗?

微服务有错吗?
微服务从思维上来说,是正确无疑的,服务确实应该被 拆解成可维护可组合的过程。
微服务从技术上来说,就错到离谱了!
服务从本质上来说是分离的,越分离越复杂越难管理,
连接他们需要大量的调试与接线,运维他们需要大量的监控!
等等,可组合?插件是可以组合的,所以插件机制应得得非常广泛。
那么能不能微服务也能像插件一样自由组合呢?
不行,服务本质是来说是分离的,除非,我们无服务!

6.无服务是个什么鬼? 函数即服务!

既然需要组合,那么我们选择像插件一样去响应式加载功能,而不是作为一个独立的服务!
需要了就加载,服务状态各种异常需要监控,函数加载总不会有问题吧,毕竟函数是无状态的?
这次不行,下次重新来,一点问题都没有!

所以,有了函数即服务faas,我们可以像插件一样动态去扩展组合功能,而没有微服务的复杂度!因为我们是无状态的!



听你说得挺简单,那你做给我们瞧瞧 !
本来就很简单嘛。。。
为了体现它的伟大性,我们得用正式的函数式编程语言haskell进行讲解,其它的一样简单!
faas平台挺多,这里选择oracle的fnproject讲解! 因为其它的还没玩过。。。
其它的选择, openwhisk, openfaas。。。
商业的amazon lambda对于我这种开源爱好者,就忽略了。。。

二. 开战函数式-faas on docker!

  1. 构建docker函数
  2. 启动fn服务器
  3. 创建docker函数trigger
  4. 测试检查

是不是很简单呀!直接接着干!

1. 构建docker 函数

目前docker具有较好的封装性,所以大部分平台采用docker来封装函数单元。
docker函数要做什么呢? 接受标准输入,输出标准输出!
是不是很熟悉,shell不就是这玩意,用shell来做docker函数也完全没问题呀!
就是这么简单!

那我们简单用haskell写一个对数据进行base64编码解码的小服务吧。输出输出都用JSON,与rest标准保持一致。
其它语言也一样简单,最终达到的效果就是:

[larluo@larluo-nixos:~/my-repo]$ echo -n '{"action":"encode","content":"larluo"}' | docker run -i my-base64:latest
{"result": "bGFybHVvCg=="}

a. 创建haskell项目my-base64

[larluo@larluo-nixos:~/my-repo]$ stack new my-base64
......
All done.
[larluo@larluo-nixos:~/my-repo]$ cd my-base64/ && rm package.yaml
[larluo@larluo-nixos:~/my-repo/my-base64]$ cat stack.yaml | grep -v ^# | grep -v ^$
resolver: lts-12.10
packages:
- .
allow-newer: true
nix:
  enable: true

[larluo@larluo-nixos:~/my-repo/my-base64]$ cat my-base64.cabal  | grep -v '^--'

name:           my-base64
version:        0.1.0.0
description:    Please see the README on GitHub at <https://github.com/githubuser/my-base64#readme>
homepage:       https://github.com/githubuser/my-base64#readme
bug-reports:    https://github.com/githubuser/my-base64/issues
author:         Author name here
maintainer:     example@example.com
copyright:      2018 Author name here
license:        BSD3
license-file:   LICENSE
build-type:     Simple
cabal-version:  >= 1.10
extra-source-files:
    ChangeLog.md
    README.md

source-repository head
  type: git
  location: https://github.com/githubuser/my-base64

executable my-base64-exe
  main-is: Main.hs
  other-modules:
      Paths_my_base64
  hs-source-dirs:
      app
  ghc-options: -threaded -rtsopts -with-rtsopts=-N
  build-depends:
      base >=4.7 && <5
    , aeson
    , bytestring
    , base64-bytestring
  default-language: Haskell2010
  default-extensions:
    OverloadedStrings
[larluo@larluo-nixos:~/my-repo/my-base64]$ cat app/Main.hs                                                                                                                                                   
{-# LANGUAGE DeriveGeneric #-}                                                                                                                                                                            
{-# LANGUAGE OverloadedStrings #-}                                                                                                                                                                        
{-# LANGUAGE FlexibleContexts #-}                                                                                                                                                                         

module Main where

import Data.Text (Text (..))
import Data.Text.Encoding (encodeUtf8, decodeUtf8)
import Data.Aeson (decodeStrict, FromJSON, encode)
import Data.Maybe (fromMaybe)
import GHC.Generics
import qualified Data.ByteString as B


import qualified Data.HashMap.Strict as HM
import qualified Data.ByteString.Base64 as B64

data Request = Request { action :: Text, content :: Text} deriving (Generic, Show)
instance FromJSON Request

invoke :: Maybe Text -> Maybe Text -> Either Text Text
invoke (Just "encode") (Just content) = Right . decodeUtf8 . B64.encode . encodeUtf8 $ content
invoke (Just "decode") (Just content) = Right . decodeUtf8 . B64.decodeLenient . encodeUtf8 $ content
invoke _ _ = Left "action is null!"

main :: IO ()
main = do
  req <- B.getContents
  let reqJson = decodeStrict req:: Maybe Request
      resp = invoke (action <$> reqJson) (content <$> reqJson)
      mkSuccess message = show . encode $
        (HM.fromList[("status", "success"), ("result", message)]::HM.HashMap Text Text)
      mkError message = show . encode $
        (HM.fromList[("status", "error"), ("message", message)]::HM.HashMap Text Text)
    in putStrLn $ (either mkError mkSuccess resp)

{--
:{
  invoke (Just "decode") $
    either (const Nothing) (Just . id) $
      (invoke (Just "encode") (Just "larluo"))
:}
--}


image.png
image.png

b. 构建docker镜像my-base64:latest

[larluo@larluo-nixos:~/my-repo/my-base64]$ cabal2nix . > docker.nix
[larluo@larluo-nixos:~/my-repo/my-base64]$ cat docker.nix 
{ mkDerivation, aeson, base, base64-bytestring, bytestring, stdenv
, text, unordered-containers
}:
let 
  my-base64=mkDerivation {
    pname = "my-base64";
    version = "0.1.0.0";
    src = ./.;
    isLibrary = false;
    isExecutable = true;
    executableHaskellDepends = [
      aeson base base64-bytestring bytestring text unordered-containers
    ];
    homepage = "https://github.com/githubuser/my-base64#readme";
    license = stdenv.lib.licenses.bsd3;

    enableSharedExecutables = false;
    enableLibraryProfiling = false;
    doHaddock = false;
    postFixup = "rm -rf $out/lib $out/nix-support $out/share/doc";
  } ;
in
dockerTools.buildImage {
  name = "my-base64" ;
  tag = "latest" ;
  config = {
    Cmd = [ "${my-base64}/bin/my-base64-exe" ] ;
  } ;
}

image.png
image.png
image.png

c. 测试docker函数

image.png

2. 启动fn服务器

fnproject github网址: https://github.com/fnproject/fn
下载地址: https://github.com/fnproject/cli/releases

[larluo@larluo-nixos:~/my-repo/my-base64]$ fn --version
fn version 0.5.8
image.png

3. 创建docker函数trigger

[larluo@larluo-nixos:~/my-repo/my-base64]$ fn create app my-fn
Successfully created app:  my-fn

[larluo@larluo-nixos:~/my-repo/my-base64]$ fn create function my-fn base64 my-base64:latest
Successfully created function: base64 with my-base64:latest

[larluo@larluo-nixos:~/my-repo/my-base64]$ fn create trigger --source /base64 --type http my-fn base64 base64
Successfully created trigger: base64

[larluo@larluo-nixos:~/my-repo/my-base64]$ fn list triggers my-fn
FUNCTION        NAME    TYPE    SOURCE  ENDPOINT
base64          base64  http    /base64 http://localhost:8080/t/my-fn/base64

4. 测试检查

image.png

是不是太简单了太好用了!

三. 开战云计算-faas on k8s! (待续)

相关文章

  • 微服务大逃离, 函数即服务呼风唤雨-01: haskell勇赴云

    国庆节开始了,为大家献上一篇! 前言 开战函数式-faas on docker! 开战云计算-faas on k8...

  • faas 云函数使用技巧

    Faas(Functions-as-a-Service ) 函数即服务,四大升级,助力移动开发。 云函数支持小程序...

  • Serverless

    BaaS:后端服务化,例如CDN服务、对象存储服务、日志服务、云监控、云数据库、消息队列等FaaS:函数服务化,即...

  • k8s学习笔记之核心概念

    一、背景介绍 云计算三大类型: IaaS:即基础设施即服务 PaaS:即平台即服务 SaaS:即软件即服务 doc...

  • 2021-04-13 ServerLess

    FasS(Function as a Service,函数即服务) 就是一些运行函数的平台,比如阿里云的函数计算、...

  • SaaS Pass IaaS 区别

    均为云服务模型:SaaS(软件即服务),PaaS(平台即服务)和IaaS(基础架构即服务)。 SaaS:软件即服务...

  • Azure+

    云计算的概念 云服务及其优势 公有云,私有云,混合云 基础架构即服务IaaS 平台理解即服务PaaS 软件理解即服...

  • 云计算的未来趋势是什么?

    云计算可以为用户提供众多的服务,大致包括三个层次的服务,分别是基础设施即服务、平台即服务和软件即服务。 通过云计算...

  • 云计算的未来趋势是什么?新手怎么入门云计算

    云计算可以为用户提供众多的服务,大致包括三个层次的服务,分别是基础设施即服务、平台即服务和软件即服务。通过云计算技...

  • 云原生

    只有变化是唯一不变的准则 什么是云 Paas 平台即服务 Iaas 基础设施即服务 Saas 软件即服务 什么是云...

网友评论

      本文标题:微服务大逃离, 函数即服务呼风唤雨-01: haskell勇赴云

      本文链接:https://www.haomeiwen.com/subject/xpoboftx.html