AWS lambda and dynamodb with Java

寫在前面

使用aws lambda已經一年多了,下面使用java構建一個簡單的lambda服務,大家可以自己擴展想要的功能,廢話不多說,開始吧。

AWS 上 Java Lambda 應用記要

public class LambdaFunctionHandler implements RequestHandler<Object,Object > {

    int warmNum = 0;
    public GatewayResponse handleRequest(Object input, Context context) {
        Object data = null;
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put("X-Custom-Header", "application/json");
        try {
            // 獲取傳入數據
            Object body = JSON.parseObject(JSONObject.toJSONString(input)).get("body");

            if(body.toString().equals("<body><action>WARMUP</action></body>")){
                this.timingTask();
                warmNum++;
                context.getLogger().log("啓動次數:"+warmNum);
                return new GatewayResponse("{}",headers,200);
            }

            JSONObject requestDTO = JSON.parseObject(body.toString());
            String requestMethod = requestDTO.getString("requestMethod");
            String requestData = requestDTO.getString("requestData");

            // 調用對應的方法
            String serviceName = MethodCallEnums.getServiceNameByMethod(requestMethod);
            String methodNameBymethod = MethodCallEnums.getMethodNameBymethod(requestMethod);
            Class aClass = Class.forName(serviceName);
            if (null == requestData || requestData.isEmpty()) {
                try {
                    data = aClass.getMethod(methodNameBymethod).invoke(aClass.newInstance());
                    Result result = ResultUtil.success(data);
                    return new GatewayResponse(JSON.toJSONString(result),headers,200);
                } catch (Exception e) {
                    e.printStackTrace();
                    Result result = ResultUtil.warn(ResultEnum.FAILED);
                    return new GatewayResponse(JSON.toJSONString(result),headers,500);                }
            } else {
                try {
                    data = aClass.getMethod(methodNameBymethod, String.class).invoke(aClass.newInstance(), requestData);
                    Result result = ResultUtil.success(data);
                    return new GatewayResponse(JSON.toJSONString(result),headers,200);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    Result result = ResultUtil.warn(ResultEnum.FAILED);
                    return new GatewayResponse(JSON.toJSONString(result),headers,500);                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            Result result = ResultUtil.warn(ResultEnum.FAILED);
            return new GatewayResponse(JSON.toJSONString(result),headers,500);
        }

    }

以上是我寫的一個簡單的不能再簡單的lambda例子了,其中的要點我會稍微提一下,完整代碼戳這裏github傳送門下載。

要點

  1. lambda函數的入口是handleRequest()方法,用來處理請求
  2. Context對象是lambda上下文對象,可以將其封裝進日誌類裏打印日誌信息
  3. 請求體裏本例裏直接用父類Object接收,當然你也可以自定義接收對象和響應對象,但一定要包含必要的接收變量,比如body,headers,statusCode。
  4. 本例通過枚舉類和反射來處理路由
  5. 從請求獲取請求方法的方式有兩種:(1)從lambda請求裏的proxy獲取 (2)用戶在請求體body參數裏自定義,如本例中的requestMethod ,對於自定義的好處是,當需要配APIConfig的時候,可以一個模塊只配置一個API
  6. lambda可以結合aws自身的一些產品來使用,比如本例中的aws dynamodb和aws s3
  7. lambda可以處理get和post請求,根據請求方式不同相應處理即可
  8. 首次觸發時微服務冷啓動有些慢,但一旦啓動之後就可以用這個微服務實例接受後續的請求,只有在比較長的一段時間內未被觸發 AWS 纔會把這個微服務殺掉。
    ...
    lambda還有很多其他的一些特性,這裏不一一提了。

寫在最後

AWS 的 Lambda 給了那些不想自己管理 EC2 服務器和配置負載人員很大的便利,所以 Lambda 被描述爲 Serverless。真正的只關注業務就行,怎麼調度,同時有多少個實例運行交給亞馬遜去處理就是了。運行 Lambda 的環境也是亞馬遜內部的 EC2 服務器,鏡像是 Amazon Linux, 所以如果想運行系統命令,那是 Linux 的。Lambda 支持多種語言 Node.js, Python, C#(.net core), 還有 Java 8,我們就選擇了 Java 8, 一開始還擔心它與別的語言比起來會多大劣勢,其實不然。而且所謂的 Java 8, 並非單指Java 語言,而是指 JVM 平臺,所以也可以用 Scala, Clojure, Groovy, Kotlin 來寫。

Java 與腳本語言如 Node.js, Python 相比給人一個明顯的感覺是啓動慢,還有人用統計數據來比劃AWS Lambda cold start(pseudeo-)benchmark.不過真不用擔心,人家說的是冷啓動,也就發生在部署後第一次執行啓動會比較慢。要是我們的 Lambda經常被調用,或每天觸發比較集中,Lambda 在任務到來之前處理待續狀態,就不會有冷啓動的耗時過程。或者是每次任務要執行 3分鐘左右,又何必在乎毫秒級的冷啓動時間。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章