精华内容
下载资源
问答
  • 原文链接:深入理解大数据之——Lambda架构 文章目录查询函数的Monoid特性Lambda三层架构Batch LayerSpeed LayerSevering Layer数据合并组件选择总结 查询函数的Monoid特性 Lambda三层架构 Batch Layer Speed ...

    原文链接:深入理解大数据之——Lambda架构


    在这里插入图片描述

    查询函数的Monoid特性

    在这里插入图片描述

    Lambda三层架构

    在这里插入图片描述

    Batch Layer

    在这里插入图片描述

    Speed Layer

    在这里插入图片描述

    Severing Layer

    在这里插入图片描述

    数据合并

    在这里插入图片描述

    组件选择

    在这里插入图片描述

    总结

    在这里插入图片描述

    展开全文
  • 用于将用于,IoT应用程序和其他AWS事件的功能构建的框架。 产品特点 简化编写lambda处理程序 自动验证事件类型 强大的输入验证 与 JSON Web令牌(JWT)验证和确认 JWK支持在启动时检索密钥 从SSM参数存储自动加载...
  • 没有框架lambda-源码

    2021-02-12 13:26:38
    没有框架lambda
  • 本文主要介绍了Lambda表达式和Java集合框架的相关知识,具有很好的参考价值。下面跟着小编一起来看下吧
  • holy-lambda:通过HCR Runtime将Clojure与AWS Lambda集成的微框架
  • Java8为容器新增一些有用的方法,这些方法有些是为完善原有功能,有些是为引入函数式编程(Lambda表达式),学习和使用这些方法有助于我们写出更加简洁有效的代码.本文分别以ArrayList和HashMap为例,讲解Java8集合...

    Java8为容器新增一些有用的方法,这些方法有些是为完善原有功能,有些是为引入函数式编程(Lambda表达式),学习和使用这些方法有助于我们写出更加简洁有效的代码.本文分别以ArrayList和HashMap为例,讲解Java8集合框架(Java Collections Framework)中新加入方法的使用.

    前言

    我们先从最熟悉的Java集合框架(Java Collections Framework, JCF)开始说起。

    为引入Lambda表达式,Java8新增了java.util.funcion包,里面包含常用的函数接口,这是Lambda表达式的基础,Java集合框架也新增部分接口,以便与Lambda表达式对接。

    首先回顾一下Java集合框架的接口继承结构:

    JCF_Collection_Interfaces

    上图中绿色标注的接口类,表示在Java8中加入了新的接口方法,当然由于继承关系,他们相应的子类也都会继承这些新方法。下表详细列举了这些方法。

    接口名 Java8新加入的方法
    Collection removeIf() spliterator() stream() parallelStream() forEach()
    List replaceAll() sort()
    Map getOrDefault() forEach() replaceAll() putIfAbsent() remove() replace() computeIfAbsent() computeIfPresent() compute() merge()

    这些新加入的方法大部分要用到java.util.function包下的接口,这意味着这些方法大部分都跟Lambda表达式相关。我们将逐一学习这些方法。

    Collection中的新方法

    如上所示,接口CollectionList新加入了一些方法,我们以是List的子类ArrayList为例来说明。了解Java7ArrayList实现原理,将有助于理解下文。

    forEach()

    该方法的签名为void forEach(Consumer<? super E> action),作用是对容器中的每个元素执行action指定的动作,其中Consumer是个函数接口,里面只有一个待实现方法void accept(T t)(后面我们会看到,这个方法叫什么根本不重要,你甚至不需要记忆它的名字)。

    需求:假设有一个字符串列表,需要打印出其中所有长度大于3的字符串.

    Java7及以前我们可以用增强的for循环实现:

    // 使用曾强for循环迭代
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    for(String str : list){
        if(str.length()>3)
            System.out.println(str);
    }

    现在使用forEach()方法结合匿名内部类,可以这样实现:

    // 使用forEach()结合匿名内部类迭代
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    list.forEach(new Consumer<String>(){
        @Override
        public void accept(String str){
            if(str.length()>3)
                System.out.println(str);
        }
    });

    上述代码调用forEach()方法,并使用匿名内部类实现Comsumer接口。到目前为止我们没看到这种设计有什么好处,但是不要忘记Lambda表达式,使用Lambda表达式实现如下:

    // 使用forEach()结合Lambda表达式迭代
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    list.forEach( str -> {
            if(str.length()>3)
                System.out.println(str);
        });

    上述代码给forEach()方法传入一个Lambda表达式,我们不需要知道accept()方法,也不需要知道Consumer接口,类型推导帮我们做了一切。

    removeIf()

    该方法签名为boolean removeIf(Predicate<? super E> filter),作用是删除容器中所有满足filter指定条件的元素,其中Predicate是一个函数接口,里面只有一个待实现方法boolean test(T t),同样的这个方法的名字根本不重要,因为用的时候不需要书写这个名字。

    需求:假设有一个字符串列表,需要删除其中所有长度大于3的字符串。

    我们知道如果需要在迭代过程冲对容器进行删除操作必须使用迭代器,否则会抛出ConcurrentModificationException,所以上述任务传统的写法是:

    // 使用迭代器删除列表元素
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    Iterator<String> it = list.iterator();
    while(it.hasNext()){
        if(it.next().length()>3) // 删除长度大于3的元素
            it.remove();
    }

    现在使用removeIf()方法结合匿名内部类,我们可是这样实现:

    // 使用removeIf()结合匿名名内部类实现
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    list.removeIf(new Predicate<String>(){ // 删除长度大于3的元素
        @Override
        public boolean test(String str){
            return str.length()>3;
        }
    });

    上述代码使用removeIf()方法,并使用匿名内部类实现Precicate接口。相信你已经想到用Lambda表达式该怎么写了:

    // 使用removeIf()结合Lambda表达式实现
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    list.removeIf(str -> str.length()>3); // 删除长度大于3的元素

    使用Lambda表达式不需要记忆Predicate接口名,也不需要记忆test()方法名,只需要知道此处需要一个返回布尔类型的Lambda表达式就行了。

    replaceAll()

    该方法签名为void replaceAll(UnaryOperator<E> operator),作用是对每个元素执行operator指定的操作,并用操作结果来替换原来的元素。其中UnaryOperator是一个函数接口,里面只有一个待实现函数T apply(T t)

    需求:假设有一个字符串列表,将其中所有长度大于3的元素转换成大写,其余元素不变。

    Java7及之前似乎没有优雅的办法:

    // 使用下标实现元素替换
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    for(int i=0; i<list.size(); i++){
        String str = list.get(i);
        if(str.length()>3)
            list.set(i, str.toUpperCase());
    }

    使用replaceAll()方法结合匿名内部类可以实现如下:

    // 使用匿名内部类实现
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    list.replaceAll(new UnaryOperator<String>(){
        @Override
        public String apply(String str){
            if(str.length()>3)
                return str.toUpperCase();
            return str;
        }
    });

    上述代码调用replaceAll()方法,并使用匿名内部类实现UnaryOperator接口。我们知道可以用更为简洁的Lambda表达式实现:

    // 使用Lambda表达式实现
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    list.replaceAll(str -> {
        if(str.length()>3)
            return str.toUpperCase();
        return str;
    });

    sort()

    该方法定义在List接口中,方法签名为void sort(Comparator<? super E> c),该方法根据c指定的比较规则对容器元素进行排序Comparator接口我们并不陌生,其中有一个方法int compare(T o1, T o2)需要实现,显然该接口是个函数接口。

    需求:假设有一个字符串列表,按照字符串长度增序对元素排序。

    由于Java7以及之前sort()方法在Collections工具类中,所以代码要这样写:

    // Collections.sort()方法
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    Collections.sort(list, new Comparator<String>(){
        @Override
        public int compare(String str1, String str2){
            return str1.length()-str2.length();
        }
    });

    现在可以直接使用List.sort()方法,结合Lambda表达式,可以这样写:

    // List.sort()方法结合Lambda表达式
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    list.sort((str1, str2) -> str1.length()-str2.length());

    spliterator()

    方法签名为Spliterator<E> spliterator(),该方法返回容器的可拆分迭代器。从名字来看该方法跟iterator()方法有点像,我们知道Iterator是用来迭代容器的,Spliterator也有类似作用,但二者有如下不同:

    1. Spliterator既可以像Iterator那样逐个迭代,也可以批量迭代。批量迭代可以降低迭代的开销。
    2. Spliterator是可拆分的,一个Spliterator可以通过调用Spliterator<T> trySplit()方法来尝试分成两个。一个是this,另一个是新返回的那个,这两个迭代器代表的元素没有重叠。

    可通过(多次)调用Spliterator.trySplit()方法来分解负载,以便多线程处理。

    stream()和parallelStream()

    stream()parallelStream()分别返回该容器的Stream视图表示,不同之处在于parallelStream()返回并行的StreamStream是Java函数式编程的核心类,我们会在后面章节中学习。

    Map中的新方法

    相比CollectionMap中加入了更多的方法,我们以HashMap为例来逐一探秘。了解Java7HashMap实现原理,将有助于理解下文。

    forEach()

    该方法签名为void forEach(BiConsumer<? super K,? super V> action),作用是Map中的每个映射执行action指定的操作,其中BiConsumer是一个函数接口,里面有一个待实现方法void accept(T t, U u)BinConsumer接口名字和accept()方法名字都不重要,请不要记忆他们。

    需求:假设有一个数字到对应英文单词的Map,请输出Map中的所有映射关系.

    Java7以及之前经典的代码如下:

    // Java7以及之前迭代Map
    HashMap<Integer, String> map = new HashMap<>();
    map.put(1, "one");
    map.put(2, "two");
    map.put(3, "three");
    for(Map.Entry<Integer, String> entry : map.entrySet()){
        System.out.println(entry.getKey() + "=" + entry.getValue());
    }

    使用Map.forEach()方法,结合匿名内部类,代码如下:

    // 使用forEach()结合匿名内部类迭代Map
    HashMap<Integer, String> map = new HashMap<>();
    map.put(1, "one");
    map.put(2, "two");
    map.put(3, "three");
    map.forEach(new BiConsumer<Integer, String>(){
        @Override
        public void accept(Integer k, String v){
            System.out.println(k + "=" + v);
        }
    });

    上述代码调用forEach()方法,并使用匿名内部类实现BiConsumer接口。当然,实际场景中没人使用匿名内部类写法,因为有Lambda表达式:

    // 使用forEach()结合Lambda表达式迭代Map
    HashMap<Integer, String> map = new HashMap<>();
    map.put(1, "one");
    map.put(2, "two");
    map.put(3, "three");
    map.forEach((k, v) -> System.out.println(k + "=" + v));
    }

    getOrDefault()

    该方法跟Lambda表达式没关系,但是很有用。方法签名为V getOrDefault(Object key, V defaultValue),作用是按照给定的key查询Map中对应的value,如果没有找到则返回defaultValue。使用该方法程序员可以省去查询指定键值是否存在的麻烦.

    需求;假设有一个数字到对应英文单词的Map,输出4对应的英文单词,如果不存在则输出NoValue

    // 查询Map中指定的值,不存在时使用默认值
    HashMap<Integer, String> map = new HashMap<>();
    map.put(1, "one");
    map.put(2, "two");
    map.put(3, "three");
    // Java7以及之前做法
    if(map.containsKey(4)){ // 1
        System.out.println(map.get(4));
    }else{
        System.out.println("NoValue");
    }
    // Java8使用Map.getOrDefault()
    System.out.println(map.getOrDefault(4, "NoValue")); // 2

    putIfAbsent()

    该方法跟Lambda表达式没关系,但是很有用。方法签名为V putIfAbsent(K key, V value),作用是只有在不存在key值的映射或映射值为null,才将value指定的值放入到Map中,否则不对Map做更改.该方法将条件判断和赋值合二为一,使用起来更加方便.

    remove()

    我们都知道Map中有一个remove(Object key)方法,来根据指定key值删除Map中的映射关系;Java8新增了remove(Object key, Object value)方法,只有在当前Mapkey正好映射到value才删除该映射,否则什么也不做.

    replace()

    在Java7及以前,要想替换Map中的映射关系可通过put(K key, V value)方法实现,该方法总是会用新值替换原来的值.为了更精确的控制替换行为,Java8在Map中加入了两个replace()方法,分别如下:

    • replace(K key, V value),只有在当前Mapkey的映射存在时才用value去替换原来的值,否则什么也不做.
    • replace(K key, V oldValue, V newValue),只有在当前Mapkey的映射存在且等于oldValue才用newValue去替换原来的值,否则什么也不做.

    replaceAll()

    该方法签名为replaceAll(BiFunction<? super K,? super V,? extends V> function),作用是对Map中的每个映射执行function指定的操作,并用function的执行结果替换原来的value,其中BiFunction是一个函数接口,里面有一个待实现方法R apply(T t, U u).不要被如此多的函数接口吓到,因为使用的时候根本不需要知道他们的名字.

    需求:假设有一个数字到对应英文单词的Map,请将原来映射关系中的单词都转换成大写.

    Java7以及之前经典的代码如下:

    // Java7以及之前替换所有Map中所有映射关系
    HashMap<Integer, String> map = new HashMap<>();
    map.put(1, "one");
    map.put(2, "two");
    map.put(3, "three");
    for(Map.Entry<Integer, String> entry : map.entrySet()){
        entry.setValue(entry.getValue().toUpperCase());
    }

    使用replaceAll()方法结合匿名内部类,实现如下:

    // 使用replaceAll()结合匿名内部类实现
    HashMap<Integer, String> map = new HashMap<>();
    map.put(1, "one");
    map.put(2, "two");
    map.put(3, "three");
    map.replaceAll(new BiFunction<Integer, String, String>(){
        @Override
        public String apply(Integer k, String v){
            return v.toUpperCase();
        }
    });

    上述代码调用replaceAll()方法,并使用匿名内部类实现BiFunction接口。更进一步的,使用Lambda表达式实现如下:

    // 使用replaceAll()结合Lambda表达式实现
    HashMap<Integer, String> map = new HashMap<>();
    map.put(1, "one");
    map.put(2, "two");
    map.put(3, "three");
    map.replaceAll((k, v) -> v.toUpperCase());

    简洁到让人难以置信.

    merge()

    该方法签名为merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction),作用是:

    1. 如果Mapkey对应的映射不存在或者为null,则将value(不能是null)关联到key上;
    2. 否则执行remappingFunction,如果执行结果非null则用该结果跟key关联,否则在Map中删除key的映射.

    参数中BiFunction函数接口前面已经介绍过,里面有一个待实现方法R apply(T t, U u)

    merge()方法虽然语义有些复杂,但该方法的用方式很明确,一个比较常见的场景是将新的错误信息拼接到原来的信息上,比如:

    map.merge(key, newMsg, (v1, v2) -> v1+v2);

    compute()

    该方法签名为compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction),作用是把remappingFunction的计算结果关联到key上,如果计算结果为null,则在Map中删除key的映射.

    要实现上述merge()方法中错误信息拼接的例子,使用compute()代码如下:

    map.compute(key, (k,v) -> v==null ? newMsg : v.concat(newMsg));

    computeIfAbsent()

    该方法签名为V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction),作用是:只有在当前Map不存在key值的映射或映射值为null,才调用mappingFunction,并在mappingFunction执行结果非null时,将结果跟key关联.

    Function是一个函数接口,里面有一个待实现方法R apply(T t)

    computeIfAbsent()常用来对Map的某个key值建立初始化映射.比如我们要实现一个多值映射,Map的定义可能是Map<K,Set<V>>,要向Map中放入新值,可通过如下代码实现:

    Map<Integer, Set<String>> map = new HashMap<>();
    // Java7及以前的实现方式
    if(map.containsKey(1)){
        map.get(1).add("one");
    }else{
        Set<String> valueSet = new HashSet<String>();
        valueSet.add("one");
        map.put(1, valueSet);
    }
    // Java8的实现方式
    map.computeIfAbsent(1, v -> new HashSet<String>()).add("yi");

    使用computeIfAbsent()将条件判断和添加操作合二为一,使代码更加简洁.

    computeIfPresent()

    该方法签名为V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction),作用跟computeIfAbsent()相反,即,只有在当前Map存在key值的映射且非null,才调用remappingFunction,如果remappingFunction执行结果为null,则删除key的映射,否则使用该结果替换key原来的映射.

    这个函数的功能跟如下代码是等效的:

    // Java7及以前跟computeIfPresent()等效的代码
    if (map.get(key) != null) {
        V oldValue = map.get(key);
        V newValue = remappingFunction.apply(key, oldValue);
        if (newValue != null)
            map.put(key, newValue);
        else
            map.remove(key);
        return newValue;
    }
    return null;

    总结

    1. Java8为容器新增一些有用的方法,这些方法有些是为完善原有功能,有些是为引入函数式编程,学习和使用这些方法有助于我们写出更加简洁有效的代码.
    2. 函数接口虽然很多,但绝大多数时候我们根本不需要知道它们的名字,书写Lambda表达式时类型推断帮我们做了一切.
    展开全文
  • 使用AWS Lambda,无服务器框架和Go的按需WebSockets (WebSockets on Demand With AWS Lambda, Serverless Framework, and Go) Lambda函数和WebSockets —对立面如何在云中相遇 (Lambda functions and WebSockets —...

    aws lambda使用

    Lambda functions and WebSockets can be seen as concepts difficult to reconcile. Lambdas are ephemeral by nature. They appear when invoked and then disappear sometime after they have finished working. WebSockets, on the contrary, maintain stable, long-living connections between one server and many clients.

    Lambda函数WebSockets可以视为难以协调的概念。 Lambdas是短暂的。 它们在被调用时出现,然后在完成工作后的某个时间消失。 相反,WebSocket可以在一台服务器和许多客户端之间维持稳定的长期连接。

    The AWS APIGateway offers the possibility to bring these two things together, combining the advantages of the Lambda on-demand model with the power of WebSockets’ real-time bidirectional communication.

    AWS APIGateway提供了将这两件事结合在一起的可能性,将Lambda按需模型的优势与WebSockets实时双向通信的强大功能相结合。

    In this article, we describe how to implement a WebSocket server using AWS API Gateway and Lambda functions. We will use the Serveless framework to set up the infrastructure and deploy the solution and Go as the programming language.

    在本文中,我们描述了如何使用AWS API Gateway和Lambda函数实现WebSocket服务器。 我们将使用Serveless框架来设置基础结构并部署解决方案,并将Go用作编程语言。

    Serverless has been chosen because it is an easy and well-documented way to define infrastructure as code. Go has been chosen because it guarantees it has the potential to optimise Lambda costs and provide low cold-start latency, an important feature for the implementation of such a model.

    选择无服务器是因为它是将基础结构定义为代码的简便且有据可查的方法。 选择Go是因为它保证了它有潜力优化Lambda成本并提供低的冷启动等待时间,这是实现这种模型的重要功能。

    一个简单的WebSocket服务器以及客户端可以做什么 (A Simple WebSocket Server and What Clients Can Do)

    To make things concrete, we are going to implement a simple WebSocket server. The goal of this server is to broadcast, as an echo, each message received from one client to all connected clients.

    为了使事情具体,我们将实现一个简单的WebSocket服务器。 该服务器的目标是将从一个客户端接收到的每个消息作为回音广播到所有连接的客户端。

    Image for post
    An echo-broadcasting server
    回声广播服务器

    As we can see from the diagram, each client connects to the server, sends messages to be broadcast by the server to all connected clients, and, in the end, disconnects from the server.

    从图中可以看出,每个客户端都连接到服务器,将要由服务器广播的消息发送到所有连接的客户端,最后断开与服务器的连接。

    In other words, a client can trigger three types of events:

    换句话说,客户端可以触发三种类型的事件:

    • connect to the server

      连接到服务器

    • disconnect from the server

      服务器断开连接

    • send a message to the server

      服务器发送消息

    The server, on the other side, has to react appropriately to these events. The way it reacts is codified using Lambda function(s).

    另一方面,服务器必须对这些事件做出适当的React。 它的React方式使用Lambda函数进行编码。

    在云中设置组件 (Setup of the Components in the Cloud)

    Now that we understand what the clients can do and what the server is called to do, we can start building the infrastructure in the cloud. As we said, we are going to use the Serverless framework to do this.

    现在我们了解了客户端可以做什么以及服务器被要求做什么,我们可以开始在云中构建基础架构。 如前所述,我们将使用无服务器框架来完成此任务。

    The configuration of the API Gateway and the Lambda function(s) is pretty simple. We start linking the Lambda function(s) to the types of event they are asked to manage. This is the Serveless yaml configuration that defines such links.

    API网关和Lambda函数的配置非常简单。 我们开始将Lambda函数链接到要求它们管理的事件类型。 这是Serveless yaml配置,它定义了此类链接。

    Serverless configuration yaml
    无服务器配置Yaml

    In the above snippet, we define a service, a provider, and a Lambda function to be executed when the WebSocket events reach the server. The route property links an event to its function, meaning that when the event occurs, the function is triggered. The handler property points to the code that the Lambda function will execute, which in this case is bin/handleRequest, a Go compiled executable.

    在上面的代码片段中,我们定义了当WebSocket事件到达服务器时要执行的服务,提供程序和Lambda函数。 route属性将事件链接到其功能,这意味着事件发生时,将触发该功能。 handler属性指向Lambda函数将执行的代码,在这种情况下为bin/handleRequest ,它是Go编译的可执行文件。

    In this example, the same function (implemented by bin/handleRequest) manages the connect, disconnect, and default events. We could have defined different functions to manage different events, but we opted for a single function for the sake of simplicity and to allow some forms of optimisation which we will discuss later.

    在此示例中,相同的功能(由bin/handleRequest )管理connectdisconnectdefault事件。 我们可以定义不同的功能来管理不同的事件,但是为了简单起见,我们选择了一个功能,并允许某些形式的优化,我们将在后面讨论。

    Let’s go back to the events. We know what connect and disconnect are. But what is default?

    让我们回到事件。 我们知道什么是connectdisconnect 。 但是default是什么?

    When a client sends a message to the server, the meaning (i.e., the semantic) of the message is embedded in the content of its payload. For instance, if the message carries a JSON payload, then the JSON could have a property action to identify the logic the message is supposed to trigger. We could then configure AWS API Gateway to react with different Lambda functions to messages with different semantics. In other words, we could attach different Lambda functions to the different values of the action field (if we follow the example above). If no match is found, then the system reverts back to the default event and the Lambda function linked to it.

    当客户端向服务器发送消息时,消息的含义(即语义)将嵌入其有效负载的内容中。 例如,如果消息携带JSON有效负载,则JSON可以具有属性action来标识消息应该触发的逻辑。 然后,我们可以配置AWS API Gateway以与不同的Lambda函数对具有不同语义的消息作出React。 换句话说,我们可以将不同的Lambda函数附加到action字段的不同值(如果我们遵循上面的示例)。 如果未找到匹配项,则系统将还原为default事件,并将Lambda函数链接到该default事件。

    In our case we use the same Lambda function for all types of events, so no custom event is defined and only the $default event is configured.

    在我们的案例中,我们对所有类型的事件使用相同的Lambda函数,因此未定义custom事件,仅配置了$default事件。

    执行结构 (Go Implementation Structure)

    The structure of the Go implementation of a Lambda function used by an API Gateway WebSocket service is also pretty simple.

    API网关WebSocket服务使用的Lambda函数Go实现的结构也非常简单。

    We need to define a main function in the main package. The main function simply calls lambda.Start(handleRequest).

    我们需要在main包中定义一个main函数。 main功能只是调用lambda.Start(handleRequest)

    Since in our case one single Lambda function manages all types of events, we need to find the way to recognise the type of event and implement some switch logic based on it. handleRequest knows which type of event it is dealing with by querying the RouteKey field of the RequestContext of the event struct passed in as a parameter, which is of type APIGatewayWebsocketProxyRequest. Based on the type of event, the appropriate logic is executed.

    由于在我们的案例中,一个Lambda函数可以管理所有类型的事件,因此我们需要找到一种方法来识别事件的类型并基于此实现一些开关逻辑。 handleRequest知道它是通过查询处理事件的类型RouteKey所述的字段RequestContext在作为参数传递,它的类型的事件结构的APIGatewayWebsocketProxyRequest 。 根据事件的类型,执行适当的逻辑。

    $ connect,$ disconnect和connectionID ($connect, $disconnect and connectionIDs)

    A WebSocket server is able to send targeted messages to specific clients. This means that each connected client needs to have a unique connectionID and that the server needs to keep track of such connectionIDs.

    WebSocket服务器能够将目标消息发送到特定客户端。 这意味着每个连接的客户端都需要具有唯一的connectionID ,并且服务器需要跟踪此类connectionID

    Image for post

    The API Gateway is responsible to assign a unique connectionID to each client when they connect to the server. That connectionID is passed as a parameter in each invocation of the handleRequest function.

    当每个客户端连接到服务器时,API网关负责为其分配唯一的connectionID 。 在每个handleRequest函数调用中,该connectionID作为参数传递。

    The WebSocket server needs to have some form of store for the active connectionIDs. When a $connect event is received, the connectionID is added to the store. When a $disconnect event occurs, the connectionID is removed from the store.

    WebSocket服务器需要具有某种形式的活动connectionID存储。 收到$connect事件时, $connect connectionID添加到存储中。 发生$disconnect事件时, connectionID从存储中删除。

    Given the ephemeral nature of Lambda functions, we can not use its internal memory to store the connectionIDs, but we need to rely on some durable external system, for instance a database.

    鉴于Lambda函数的短暂特性,我们不能使用其内部存储器来存储connectionID ,但是我们需要依赖一些持久的外部系统,例如数据库。

    Image for post
    ConnectionIDs store
    ConnectionIDs存储

    Typically we would consider to use AWS Dynamo DB, but any permanent storing mechanism would work (we actually use MongoDB on Atlas in the code provided, just to add an unusual bit to the example). So, to keep the implementation open, we define an interface, connectionStorer, to describe the behaviour we expect and delegate to some dependency injection mechanism the decision on the specific implementation to use for it.

    通常,我们会考虑使用AWS Dynamo DB,但是任何永久存储机制都可以使用(我们在提供的代码中实际上在Atlas上使用了MongoDB ,只是在示例中添加了一个不寻常的地方)。 因此,为了保持实现的开放性,我们定义了一个接口connectionStorer ,以描述我们期望的行为,并将对特定实现的决策委派给某种依赖注入机制。

    connectionStorer interface
    connectionStorer接口
    manage $connect and $disconnect events
    管理$ connect和$ disconnect事件

    $ default,动作发生的地方 ($default, Where the Action Happens)

    Well, actually in our example not much happens. The logic is pretty simple. Every message received is echoed back to all connected clients. This simple logic is triggered by the $default case and is delegated to an echo function.

    好吧,实际上在我们的例子中并没有发生太多。 逻辑很简单。 收到的每个消息都会回显给所有连接的客户端。 这个简单的逻辑由$default情况触发,并委托给echo函数。

    manage $default event
    管理$ default事件

    The Lambda function acts like a client of the API Gateway, creating an instance of the gateway and posting to it the echoed message, one post per active connection.

    Lambda函数的行为就像API网关的客户端一样,创建网关的实例并将其回显的消息发布到该实例,每个活动连接一个消息。

    There is also a small trick in the implementation. If the message received from the client represents an integer, then this value is used to simulate a long running process using time.Sleep. We will use this trick later to test how Lambda reacts to concurrent requests coming from different clients.

    在实现中还有一个小技巧。 如果从客户端收到的消息表示一个整数,则此值用于使用time.Sleep模拟长时间运行的过程。 我们稍后将使用此技巧来测试Lambda如何响应来自不同客户端的并发请求。

    优化策略 (Optimisation Strategies)

    It is worth noticing that we use the global variable apigateway to store one single instance of the gateway for the entire lifespan of the Lambda function. The reason behind this choice is that an instance of a Lambda function can serve more than one subsequent request. So, while it is true that a Lambda function can be instantiated on demand, when a request arrives, it is also true that this instance remains active and ready to serve other requests for a certain period of time (simple empiric measurements suggest that this period is about ten minutes). We can define global variables to hold resources which we want to reuse for subsequent request processing, like, for instance, the API Gateway instance.

    值得注意的是,我们使用全局变量apigateway在Lambda函数的整个生命周期中存储一个网关实例。 该选择背后的原因是Lambda函数的实例可以处理多个后续请求。 因此,虽然可以按需实例化Lambda函数,但当请求到达时,也确实是该实例保持活动状态并准备在一定时间内为其他请求提供服务(简单的经验测量表明,这一时期大约十分钟)。 我们可以定义全局变量来保存我们要重用于后续请求处理的资源,例如API Gateway实例。

    Similarly, we hold in a global variable the MongoDB connection since creating it is an expensive operation which we want to perform only one time per Lambda function instantiation. This is the reason why having a single handleRequest function to manage all events — $connect, $disconnect, and $default — brings an advantage in terms of efficiency. All these events need to connect to the MongoDB, a single handler for all these events means a single Lambda function and therefore the need to open a single database connection for all events.

    同样,我们将MongoDB连接保存在全局变量中,因为创建它是一项昂贵的操作,我们希望每个Lambda函数实例化仅执行一次。 这就是为什么只有一个handleRequest函数来管理所有事件( $connect$disconnect$default在效率方面具有优势的原因。 所有这些事件都需要连接到MongoDB,所有这些事件的单个处理程序意味着单个Lambda函数,因此需要为所有事件打开单个数据库连接。

    相同的Lambda函数可以满足多少个请求 (How Many Requests Can Be Served by the Same Lambda Function)

    A Lambda function is ephemeral but not too ephemeral. The same instantiation of a Lambda function can serve more than one request. Let’s examine few different cases.

    Lambda函数是短暂的,但不是短暂的。 Lambda函数的相同实例可以服务多个请求。 让我们研究几种不同的情况。

    相同Lambda函数处理的顺序请求 (Sequential requests served by the same Lambda function)

    Image for post
    One Lambda function instance serves more requests
    一个Lambda函数实例可处理更多请求

    Some requests are sent sequentially to the same Lambda endpoint. The Lambda function is fast and completes the execution of a request before the next one comes in. In this case, we can expect only one instance of Lambda function serving all the requests. (This can be checked simply logging when the global variables are set and verifying that this happens only once.)

    某些请求将顺序发送到同一Lambda端点。 Lambda函数速度很快,可以在下一个请求进入之前完成请求的执行。在这种情况下,我们可以预期只有Lambda函数的一个实例可以满足所有请求。 (这可以通过简单地记录设置全局变量的时间并验证是否仅发生一次来检查。)

    两个后续请求之间的空闲时间长 (Long idle time between two subsequent requests)

    Image for post
    Lambda function remains idle too long and is terminated
    Lambda函数保持空闲时间过长并终止

    On the other hand, if we leave the Lambda function idle for a too long period, then the Lambda function is eventually terminated. When the next request arrives, a new Lambda function is created to execute the new request. Again, this can be checked by logging the creation of the global variables.

    另一方面,如果我们将Lambda函数保持空闲时间太长,则Lambda函数最终会终止。 下一个请求到达时,将创建一个新的Lambda函数以执行新请求。 同样,可以通过记录全局变量的创建来检查。

    并发请求 (Concurrent requests)

    Image for post
    Two concurrent requests are processed by two different Lambda functions
    两个并发请求由两个不同的Lambda函数处理

    The last case is that of concurrent requests. A request is still being processed by a Lambda function instance when the next one comes in. In this case, another instance of Lambda function is spun off since, as per AWS Lambda documentation, “a single instance of your Lambda function will never handle multiple events simultaneously”. This can be tested using the Sleep capability of the echo function.

    最后一种情况是并发请求。 当下一个请求传入时,Lambda函数实例仍在处理请求。在这种情况下,Lambda函数的另一个实例会被剥离,因为根据AWS Lambda文档 ,“ Lambda函数的单个实例永远不会处理多个活动同时进行”。 可以使用echo功能的“睡眠”功能进行测试。

    It is important to be aware of such behaviours since this gives us the possibility to implement some optimisations, like the caching of database connections. On the other hand, we need to be cautious when using such techniques since many details are not documented, e.g., the time a Lambda function can remain idle before being terminated, and we cannot blindly count on them in our logic.

    重要的是要意识到这种行为,因为这使我们能够实现一些优化,例如缓存数据库连接。 另一方面,由于没有记录许多细节,例如,Lambda函数在被终止之前可以保持空闲的时间,并且我们不能在逻辑上盲目指望它们,因此在使用此类技术时我们需要谨慎。

    为什么去? (Why Go?)

    We have seen that one Lambda function can serve only one request at a time. So we cannot use the power of goroutines to process more requests concurrently. Managing the concurrency among different requests is the job of API Gateway and Lambda.

    我们已经看到,一个Lambda函数一次只能服务一个请求。 因此,我们无法使用goroutine的功能来同时处理更多请求。 管理不同请求之间的并发是API Gateway和Lambda的工作。

    Nonetheless, we can still leverage Go concurrency within the process of a single request, if this makes sense. And in many cases it can make sense.

    尽管如此,如果有必要,我们仍然可以在单个请求的过程中利用Go并发。 在许多情况下,这是有道理的。

    Image for post
    A Lambda function leveraging Go concurrency
    利用Go并发的Lambda函数

    Let’s consider the above example, where the process of a single request requires different I/O operations, e.g., call a REST API, access a DB, do something with storage. In this case, we can make good use of Go by executing concurrently all I/O operations, reducing thus the total time of Lambda processing, minimising the response time, and potentially optimising costs, considering that Lambda are priced also by processing time.

    让我们考虑上面的示例,其中单个请求的过程需要不同的I / O操作,例如,调用REST API,访问数据库,对存储进行某些操作。 在这种情况下,考虑到Lambda也按处理时间定价,我们可以通过同时执行所有I / O操作来充分利用Go,从而减少Lambda处理的总时间,最小化响应时间并潜在地优化成本。

    Go, being a compiled language, is also a good choice if we want to have efficient use of memory. And memory is the other factor that influences the cost of executing Lambda functions.

    如果我们想有效利用内存,Go是一种编译语言,也是一个不错的选择。 内存是影响执行Lambda函数成本的另一个因素。

    Finally, Go seems also a good choice if we want to have a low cold-start latency, i.e., the time required to start a Lambda function which does not yet have an execution context, even if benchmarks for this aspect vary.

    最后,如果我们希望具有低的冷启动延迟 (即,启动尚不具有执行上下文的Lambda函数所需的时间),即使该方面的基准有所不同 ,Go也是一个不错的选择。

    构建,部署和测试 (Build, Deploy, and Test)

    Finally, we need to build, deploy, and test our WebSocket server. The Serverless framework template guides us in these steps, which anyways are pretty straightforward.

    最后,我们需要构建,部署和测试WebSocket服务器。 无服务器框架模板指导我们执行这些步骤,无论如何这些步骤都非常简单。

    For build we need to run the following command:

    对于构建,我们需要运行以下命令:

    env GOOS=linux go build -ldflags="-s-w" -o ./bin/handleRequest ./handleRequest

    env GOOS=linux go build -ldflags="-sw" -o ./bin/handleRequest ./handleRequest

    Once the build is complete, we can deploy with the following command:

    构建完成后,我们可以使用以下命令进行部署

    sls deploy

    sls deploy

    In the deploy command, we can specify environment variable values in case we use them in the implementation, e.g., to pass db connection strings.

    在deploy命令中,我们可以指定环境变量值,以防我们在实现中使用它们,例如,传递数据库连接字符串。

    To manually test the server functionalities, we use wscat to launch an interactive command line base session via the following command:

    为了手动测试服务器功能,我们使用wscat通过以下命令启动交互式命令行基础会话:

    wscat -c wss://urlOfTheServer

    wscat -c wss://urlOfTheServer

    From the prompt, we can type any message and press enter to send a message to the server.

    在提示符下,我们可以键入任何消息,然后按enter将消息发送到服务器。

    结论 (Conclusions)

    We have gone through the steps required to build a WebSocket server based on AWS API Gateway and AWS Lambda functions. We have used Serverless for the setup of the cloud configuration and the deployment, and Go to program the logic.

    我们已经完成了基于AWS API Gateway和AWS Lambda函数构建WebSocket服务器所需的步骤。 我们已使用Serverless进行云配置和部署的设置,并使用Go语言对逻辑进行编程。

    The good news is that this is a relatively easy way to build a WebSocket server available on demand, as per Serverless philosophy.

    好消息是,按照无服务器理念,这是一种构建按需可用的WebSocket服务器的相对简单的方法。

    We have now a powerful additional tool to address use cases where we want to provide rich, interactive, many-to-many platforms without incurring the complexity and costs involved in setting up and manage dedicated servers or containerised solutions.

    现在,我们有了功能强大的附加工具,可以解决需要提供丰富,交互式,多对多平台的用例,而又不会引起设置和管理专用服务器或容器化解决方案所涉及的复杂性和成本。

    You can find all the code of the example on GitHub.

    您可以在GitHub上找到该示例的所有代码

    翻译自: https://medium.com/better-programming/websockets-on-demand-with-aws-lambda-serverless-framework-and-go-616bd7ff11c9

    aws lambda使用

    展开全文
  • step是用于构建,测试和部署AWS Step Functions和Lambda Step(Beta)的框架。step是Go中用于构建和测试AWS Step Functions和Lambdas的Go语言中的AWS State Machine语言的自觉实现。 Step将状态机的结构与lambda的...
  • aws lambda 什么是路由管理框架? (What is a Route Management Framework?) Most software engineers who’ve built and delivered production software have encountered the need for route management ...

    aws lambda

    什么是路由管理框架? (What is a Route Management Framework?)

    Most software engineers who’ve built and delivered production software have encountered the need for route management frameworks. These frameworks are designed and built to ease the development & management of REST APIs inside NodeJS-based applications.

    大多数已经构建和交付了生产软件的软件工程师都遇到了对路由管理框架的需求。 这些框架的设计和构建是为了简化基于NodeJS的应用程序内部REST API的开发和管理。

    Image for post
    Traditional route management framework inside an API application
    API应用程序内的传统路由管理框架

    The most popular use of route management frameworks is that they enable us to express ROUTES that our REST APIs expose to consuming parties (web apps, backend workers, customer applications) and assign them a specific execution logic on how to handle requests that were received by our servers.

    路由管理框架最流行的用途是使我们能够表达 REST API公开给使用方(Web应用程序,后端工作程序,客户应用程序)的ROUTES ,并为它们分配有关如何处理由接收方接收的请求的特定执行逻辑 。我们的服务器。

    Some of the most popular route management frameworks in NodeJS are Express JS, Restify, Fastify, Loopback, Hapi JS, Koa, Loopback, etc.

    NodeJS中一些最流行的路由管理框架是Express JS,Resify,Fastify,Loopback,Hapi JS,Koa,Loopback等。

    无服务器路由管理框架 (Serverless Route Management Frameworks)

    To ease the learning curve and migration efforts that organizations have to face in adopting serverless-based development, different RMF frameworks provided a way to port existing applications to lambda-based architectures which we can call Serverless Route Management Frameworks.

    为了缓解组织在采用基于无服务器的开发中必须面对的学习曲线和迁移工作,不同的RMF框架提供了一种将现有应用程序移植到基于lambda的体系结构的方法,我们可以将其称为无服务器路由管理框架。

    Image for post
    Think of serverless route management frameworks as code-level routers running inside your lambda functions
    将无服务器路由管理框架视为运行在lambda函数内部的代码级路由器

    Now that we have a better understanding of route management frameworks (RMF), we can start exploring which frameworks are available in serverless-based architectures and which of their traits make them stand out in the selection process.

    现在我们对路由管理框架(RMF)有了更好的了解,我们可以开始探索哪些框架在基于无服务器的体系结构中可用,以及它们的哪些特征使其在选择过程中脱颖而出。

    Image for post
    https://www.npmjs.com/package/aws-serverless-expresshttps://www.npmjs.com/package/aws-serverless-express

    AWS无服务器Express (AWS Serverless Express)

    Express JS has served the NodeJS community well for years and stayed as the most popular RMF for a long while. No wonder AWS Labs built a routing framework for this wonderful framework. If you are interested in learning more about this framework, I’ve recently written an article that explained the pros & cons of using it.

    Express JS多年来一直为NodeJS社区提供良好的服务,并且长期以来一直是最受欢迎的RMF。 难怪AWS Labs为此出色的框架构建了路由框架。 如果您有兴趣了解有关此框架的更多信息,我最近写了一篇文章 ,解释了使用该框架的利弊。

    Strengths

    长处

    • Elite framework in the NodeJS community

      NodeJS社区中的Elite框架
    • Its popularity makes the hiring of developers easier

      它的受欢迎程度使开发人员的雇用更加容易
    • Tons of articles & sample projects on top of this framework

      在此框架之上的大量文章和示例项目
    • Built by AWS Labs so you can be assured of its continuity

      由AWS Labs构建,因此可以确保其连续性
    • Offers a low learning-curve for developers with Express background

      为具有Express背景的开发人员提供较低的学习曲线
    • Good for migration of existing workloads

      适合迁移现有工作负载
    • Strong usage metrics on NPM (200K+)

      强大的NPM使用量指标(200K +)

    Weaknesses

    弱点

    • Not popular for async/await syntax

      异步/等待语法不流行
    • Catching errors is not so easy

      捕捉错误并非易事
    • Built on top of external dependencies which bloats the framework

      建立在使框架膨胀的外部依赖项之上
    • Coldstart can be a challenge

      冷启动可能是一个挑战
    Image for post
    https://www.npmjs.com/package/lambda-apihttps://www.npmjs.com/package/lambda-api

    Lambda API (Lambda API)

    This is my personal favorite in our serverless RMF list as it strikes a perfect balance in terms of size-in-bytes & feature set. It also has no underlying dependencies which make it safe from dependency hell issues and lighter than its competitors.

    在无服务器RMF列表中,这是我个人的最爱,因为它在字节大小和功能集方面达到了完美的平衡。 它也没有底层依赖,因此可以避免依赖地狱问题,并且比竞争对手轻。

    Fun Fact: It was written by the Lebron James of the Serverless field (Jeremy Daly). I would highly recommend checking out his Github repositories and podcast if you are looking into building awesome serverless applications for AWS.

    趣闻:这是由无服务器领域的勒布朗·詹姆斯( Jeremy Daly )撰写的。 如果您正在考虑为AWS构建出色的无服务器应用程序,我强烈建议您查看他的Github存储库和播客

    Strengths

    长处

    • Standalone & does not have any dependency

      独立且没有任何依赖性
    • Good for greenfield projects

      适合新建项目
    • Sleek and sweet API Syntax

      流畅甜美的API语法
    • Native async/await out of the box

      本机异步/等待开箱即用
    • Built by Jeremy Daly of Serverless Chats

      无服务器聊天的 Jeremy Daly构建

    • Boasting an upward usage trend in NPM

      NPM使用量呈上升趋势

    Weaknesses

    弱点

    • 14 contributors in Github. This is a good investment of your time if you are willing to do some volunteer work!

      Github的14位贡献者。 如果您愿意做一些志愿工作,这是您宝贵的时间!
    • Requires learning curve to be utilized in migration projects

      要求学习曲线可用于迁移项目
    • Slower migration compared to serverless-variants of established RMFs

      与已建立RMF的无服务器版本相比,迁移速度更慢
    Image for post
    https://www.npmjs.com/package/serverless-httphttps://www.npmjs.com/package/serverless-http

    无服务器HTTP (Serverless HTTP)

    Serverless HTTP is an open-source framework that allows wrapping of existing APIs for serverless use without requiring any significant amount of changes.

    无服务器HTTP是一个开放源代码框架,该框架允许包装现有API以供无服务器使用,而无需进行大量更改。

    If you are in the stage of exploring the feasibility and impact of migration for your APIs and your organization has existing APIs on different RMFs, this framework would contribute positively to migrating your diversified API portfolio by reducing research and implementation time due to the standardized integration mechanism with different RMFs.

    如果您正在探索迁移API的可行性和影响的阶段,并且您的组织在不同的RMF上已有现有的API,那么由于采用了标准化的集成机制,该框架将通过减少研究和实施时间来为迁移您多样化的API产品组合做出积极贡献。具有不同的RMF。

    On the other hand, I would suggest doing a responsible & thorough benchmarking and behavioral check on your APIs before deciding if its a GO or NO. The framework is known for its support of several RMF frameworks which means that it might contain some dependencies related to other RMFs that you are not interested in.

    另一方面,建议您在确定API是否合格之前,对API进行负责任且彻底的基准测试和行为检查。 该框架以其对多个RMF框架的支持而闻名,这意味着它可能包含一些与您不感兴趣的其他RMF相关的依赖项。

    Strengths

    长处

    • Jack of all RMFs (Good old Swiss Knife Tech)

      所有RMF的杰克(好旧的瑞士刀技术)
    • Supports 3 major old-school RMFs at the time of writing (KOA, Connect, Express)

      在撰写本文时支持3种主要的老式RMF(KOA,Connect,Express)
    • Supports 7 other RMFs at the experimental stage (Restana, Sails, Hapi, Fastify, Restify, Polka, Loopback)

      在实验阶段还支持其他7种RMF(Restana,Sails,Hapi,Fastify,Restify,Polka,Loopback)
    • NPM usage trend is rising nicely

      NPM使用趋势呈上升趋势
    • Good for migration of existing APIs compatible with it

      适合迁移与其兼容的现有API
    • Offers a lower learning-curve for developers familiar with selected RMF

      为熟悉特定RMF的开发人员提供较低的学习曲线

    Weaknesses

    弱点

    • Support to multiple RMFs make it innately heavier

      对多个RMF的支持使其本来就更重
    • The extra bit of work when searching for code samples

      搜索代码样本时的额外工作
    • Coldstart can be a challenge due to codebase & dependency size

      由于代码库和依赖项的大小,冷启动可能是一个挑战
    • Not ideal for most greenfield projects

      对于大多数未开发项目而言并不理想
    Image for post
    https://www.npmjs.com/package/lambda-serverless-apihttps://www.npmjs.com/package/lambda-serverless-api

    Lambda无服务器API (Lambda Serverless API)

    This RMF is an interesting one as it was documented in Github as a “Middleware for AWS Lambda and API gateway”, I always like to call it as RMF with awesome HTTP verb support, sweet APIs, and cool integrations.

    这个RMF非常有趣,因为它在Github中被记录为“ AWS Lambda和API网关的中间件”,我一直喜欢将其称为RMF,它具有出色的HTTP谓词支持,可爱的API和出色的集成。

    Strengths

    长处

    • Good for greenfield projects

      适合新建项目
    • Decent NPM usage trend

      良好的NPM使用趋势
    • Sweet and sleek APIs

      甜美时尚的API
    • In-memory & S3-based rate limiting

      内存和基于S3的速率限制
    • Swagger integration

      Swagger整合

    Weaknesses

    弱点

    • 9 contributors in Github

      Github的9位贡献者
    • Heavier than a usual RMFs due to its dependencies with AWS SDK, Swagger

      由于其与AWS开发工具包Swagger的依赖关系,因此比常规RMF重
    • Expect a steeper learning curve when utilized in migration projects

      在迁移项目中使用时,期望学习曲线更陡峭
    • Slower migration compared to serverless-variants of established RMFs

      与已建立RMF的无服务器版本相比,迁移速度更慢
    • Coldstart can be a challenge due to codebase & dependency size

      由于代码库和依赖项的大小,冷启动可能是一个挑战
    Image for post
    https://www.npmjs.com/package/hapi-lambdahttps://www.npmjs.com/package/hapi-lambda

    哈皮·兰达(Hapi Lambda) (Hapi Lambda)

    Just like Express JS & KOA, this is another serverless implementation for easing migration of existing HAPI-based API workloads to the serverless paradigm. HAPI was boasting more built-in APIs (eg. Form Handling) compared to what Express JS can offer.

    就像Express JS和KOA一样,这是另一种无服务器的实现,可简化现有基于HAPI的API工作负载向无服务器范式的迁移。 与Express JS相比,HAPI拥有更多内置API(例如,表单处理)。

    Fun Fact: HAPI was originally built on top of Express JS and was made to be standalone due to some challenges with Express JS. It was also built by Walmart for special shopping events like Black Friday Sale.

    有趣的事实: HAPI最初是在Express JS之上构建的,由于Express JS的一些挑战,使其成为独立的。 它也是由沃尔玛建造的,用于特殊购物活动,例如黑色星期五销售。

    Strengths

    长处

    • Easier migration of HAPI-based APIs

      基于HAPI的API更容易迁移
    • Simple integration with the Lambda function’s entry point

      与Lambda函数的入口点轻松集成
    • Lower adaption/learning curve for organizations with developers familiar with HAPI

      具有熟悉HAPI的开发人员的组织的适应/学习曲线较低

    Weaknesses

    弱点

    • Immature at the time of writing

      写作时还不成熟
    • 87 downloads per week at NPM

      NPM每周87次下载
    • 18 stars in Github

      Github 18星级
    • Coldstart can be a challenge due to porting of HAPI

      由于HAPI的移植,冷启动可能是一个挑战
    • Slightly harder to utilize in a greenfield project

      在未开发项目中难以利用
    Image for post
    https://www.npmjs.com/package/aws-serverless-koahttps://www.npmjs.com/package/aws-serverless-koa

    AWS无服务器KOA (AWS Serverless KOA)

    Like Express JS, this is a wrapper of a well known RMF framework named KOA which is built by Express JS framework authors and designed to be more expressive, smaller, and faster by utilizing async/await syntax with better error-handling.

    像Express JS一样,它是由知名JS框架作者构建的,名为KOA的著名RMF框架的包装,该框架通过利用具有更好错误处理能力的 async / await语法, 表现得更强,更小,更快。

    Strengths

    长处

    • Dead simple integration with KOA

      与KOA的简单集成
    • More of a middleware instead of an RMF

      更多的是中间件而不是RMF
    • Tiny framework

      小框架

    Weaknesses

    弱点

    • Immature at the time of writing

      写作时还不成熟
    • Low Github star count (20 atm! Show some love guys)

      Github明星人数少(20个大气压!显示一些爱心人士)

    • Low NPM download count per week (330 atm! Show some love guys)

      每周NPM下载量低(330 atm!显示一些爱心人士)
    • 2 Contributors in Github

      Github的2位贡献者
    Image for post
    https://www.npmjs.com/package/@midwayjs/faashttps://www.npmjs.com/package/@midwayjs/faas

    MidwayJS-制作中的黑马 (MidwayJS — A Dark Horse in the Making)

    Here comes a newborn TypeScript-based RMF. This framework was made by Harry Chen who is a battle-tested serverless veteran within Alibaba & Taobao!

    这是新生的基于TypeScript的RMF。 这个框架是由哈里·陈 ( Harry Chen)创建的 ,他是阿里巴巴和淘宝网中经过测试的无服务器资深人士!

    What makes this framework shine in the competition is its functional style syntax which just became a hit in Vue 3.0 syntax and was piloted by React hooks!

    使该框架在竞争中脱颖而出的是其功能样式语法,该语法在Vue 3.0语法中大受欢迎,并由React挂钩进行了试验!

    On top of its mojo, TypeScript syntax, and functional programming style are cool features like IOC & Decorators which makes it cohesive with the projects built on top of newly released VueJS & React Hooks!

    除了其Mojo之外,TypeScript语法和函数式编程样式还具有IOC和Decorators等超酷功能,使其与基于新发布的VueJS和React Hooks构建的项目紧密结合!

    Strengths

    长处

    • Functional Programming Syntax

      功能编程语法
    • Typescript Support

      打字稿支持
    • Inversion of Control (IOC)

      控制反转(IOC)
    • Decoration Syntax

      装饰语法
    • Good for greenfield projects

      适合新建项目
    • Reduced cognitive switching required when working with VueJS 3 & React Hooks

      减少使用VueJS 3和React Hooks时所需的认知转换
    • Extremely lightweight (65KB)

      极其轻巧(65KB)
    • Ease of local invocations

      简化本地调用

    Weaknesses

    弱点

    • Support for AWS just got released this month

      本月刚刚发布了对AWS的支持

    • Needs to catch up with released RMFs at the time of writing

      在撰写本文时需要赶上已发布的RMF
    • Slower migration compared to serverless-variants of established RMFs

      与已建立RMF的无服务器版本相比,迁移速度更慢

    摘要 (Summary)

    • Route management frameworks are code-level routers inside an API application

      路由管理框架是API应用程序中的代码级路由器
    • RMFs existed way before serverless architecture did

      RMF在无服务器架构之前就已经存在
    • RMFs help in easing the learning-curve during an organization’s serverless adoption phase

      RMF帮助缓解组织的无服务器采用阶段的学习曲线
    • Some RMFs ease migration efforts by providing routing syntax familiar to your developers

      一些RMF通过提供开发人员熟悉的路由语法来简化迁移工作
    • Some RMFs are way better utilized on greenfield projects

      一些RMF在新建项目中得到了更好的利用
    • We got acquainted with 7 RMFs

      我们熟悉了7个RMF
    • We’ve seen their strengths and weaknesses

      我们已经看到了他们的优势和劣势
    • Selecting RMFs should be decided on a case-to-case basis

      选择RMF应该视情况而定
    • A dark horse arrived in the form of Midway JS!

      一匹黑马以Midway JS的形式到达!

    下一步是什么? (What’s Next?)

    The list of strengths and weaknesses listed in this article is purely based on my observations and research around the frameworks. To be more objective in comparing these RMFs, we’re going to perform a data-driven analysis of relevant KPIs and I will post the results I get to collect on my upcoming article.

    本文列出的优点和缺点列表纯粹是基于我对框架的观察和研究。 为了更客观地比较这些RMF,我们将对相关的KPI进行数据驱动的分析,我将在接下来的文章中发表收集到的结果。

    翻译自: https://medium.com/javascript-in-plain-english/route-management-frameworks-for-aws-lambda-and-node-js-ab685aeec839

    aws lambda

    展开全文
  • Lambda表达式
  • 无服务器框架+ Lambda入门套件 无服务器框架1.x AWS Lambda(Node JS 8.10) Webpack 4.x Babel 6.x
  • 使用无服务器框架和Go的Lambda SQS示例 自2018年6月起,可以使用Amazon SQS触发AWS Lambda函数。 此示例项目演示了如何在无服务器框架和Go中使用此功能。 用法 make deploy echo '{"Records":[{"messageID":"1",...
  • 此仓库已弃用! 这是1.0 lambda引擎。 从那以后很多事情改变了。 有关完形和激光的最新版本,请访问: ... 当前的适配器工作支持在Mesos下作为Mesos框架运行。 这允许将硬件资源有效地用于一次性或很少发生的计算任务。
  • 按照安装无服务器框架 设置您的 按照步骤创建php二进制层并上传到AWS 编写您的无服务器应用程序(!)-默认值在hello-world/handler.php 运行sls deploy部署到Lambda 运行sls invoke -f hello -l调用您的函数 当我们...
  • 弹射 使用C#/。NET和Microsoft的扩展程序(用于依赖项注入,...高度可测试的:便于使用依赖项注入来简化Lambda的测试。 灵活性:您可以使用AWS提供的运行时,也可以滚动自己的包含.NET的运行时。 Lambdajection可以双
  • 一个简单的用Node.js编写的AWS Lambda中间件框架。 它没有作为库发布,但是如果您要创建自己的中间件,则可以作为示例。 更多细节可以在找到 目的 能够将lambda定义为返回promise而不是调用回调的函数。 提供一种...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,912
精华内容 764
关键字:

lambda框架