Bisher habe ich AWS Lambda hauptsächlich in Python und manchmal in Node.js erstellt, aber zur Abwechslung habe ich untersucht, wie man in Java entwickelt, also werde ich es zusammenfassen.
Dieses Mal habe ich den Quellcode der in Java mit Gradle geschriebenen Lambda-Funktion erstellt und mit AWS SAM bereitgestellt. Das AWS Toolkit für Eclipse (https://docs.aws.amazon.com/ja_jp/toolkit-for-eclipse/v1/user-guide/welcome.html) wird auch für die Entwicklung in Eclipse bereitgestellt. Normalerweise entwickle ich mit Vim und stelle mit CLI bereit, also werde ich mich darauf einstellen.
~~ Wie Sie in der offiziellen Dokumentation unten sehen können, ist die einzige bereitgestellte Java-Laufzeit "Java 8" ("JDK 8"). Wenn Sie eine andere Version verwenden, müssen Sie warten, bis diese unterstützt wird, oder eine benutzerdefinierte Laufzeit verwenden. ~~
Java 11 wurde am 19. November 2019 hinzugefügt und die Laufzeit kann aus Java 8 (JDK 8) und Java 11 (JDK 11) ausgewählt werden.
Erstellen von Lambda-Funktionen mit Java-AWS Lambda
Packen und implementieren Sie eine in Java geschriebene Anwendung in einer Zip-Datei oder einem eigenständigen JAR.
Die offizielle Dokumentation zeigt, wie Sie mit Maven ein eigenständiges Glas und mit Gradle eine Zip-Datei bereitstellen. Dieses Mal habe ich die Methode zum Packen und Bereitstellen in einer Zip-Datei mit Gradle ausprobiert.
Java AWS Lambda-Bereitstellungspaket --AWS Lambda
Es gibt mehrere Methoden, um die Anforderung der Handlerfunktion zu empfangen und die Antwort wie folgt zurückzugeben.
Die Art und Weise, wie die Handlerfunktion geschrieben wird, ist für jeden unterschiedlich. Mit anderen Worten, es gibt drei Möglichkeiten, Handlerfunktionen zu schreiben.
Es scheint, dass es unter dem Gesichtspunkt, welche Art von Daten gesendet werden, richtig verwendet wird, anstatt zu entscheiden, ob "Wenn Sie diesen Ereignisauslöser verwenden, dieser Typ". In dieser Situation scheint es so etwas nicht zu geben, daher muss überlegt werden, welche Methode bei der tatsächlichen Entwicklung von Lambda-Funktionen in Java verwendet werden soll.
Dieses Mal haben wir den "POJO-Typ" übernommen.
Handler-E / A-Typ (Java) --AWS Lambda
Ich habe eine einfache Webanwendung erstellt, die "API Gateway" als Auslöser für Lambda-Funktionen verwendet. Es ist eine einfache API, die nur eine POST-Anfrage sendet und "Hallo" zurückgibt.
Der Code, den ich erstellt habe, ist hier. https://github.com/mmclsntr/awslambda-javagradle
.
├── build/
│ ├── distributions/
│ │ └── awslambda-javagradle.zip #Stellen Sie das vom Build generierte Paket bereit
│ └── ...
├── build.gradle #Gradle Build-Konfigurationsdatei
├── src/main/java/awslambda/javagradle
│ ├── Greeting.java #Der Kern der App
│ ├── Handler.java #Speichert Lambda-Handlerfunktionen
│ └── Response.java #Formatieren Sie die Lambda-Antwort
└── template.yml #CloudFormation-Vorlagendatei
└── Andere Gradle-Dateien
Handler.java
package awslambda.javagradle;
import java.util.Collections;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class Handler implements RequestHandler<Map<String, Object>, Response> {
private static final Logger LOG = Logger.getLogger(Handler.class.getName());
@Override
public Response handleRequest(Map<String, Object> input, Context context) {
LOG.info("received: " + input);
LOG.setLevel(Level.INFO);
Greeting greetingBody = new Greeting("Hello");
return Response.builder()
.setStatusCode(200)
.setObjectBody(greetingBody)
.build();
}
}
Response.java
package awslambda.javagradle;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Collections;
import java.util.Map;
import org.apache.log4j.Logger;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Response {
private final int statusCode;
private final String body;
private final Map<String, String> headers;
private final boolean isBase64Encoded;
public Response(int statusCode, String body, Map<String, String> headers, boolean isBase64Encoded) {
this.statusCode = statusCode;
this.body = body;
this.headers = headers;
this.isBase64Encoded = isBase64Encoded;
}
...
}
Erstellen Sie eine supereinfache Anwendung, die Hello als Beispiel zurückgibt.
Greeting.java
package awslambda.javagradle;
public class Greeting {
private String greetings;
public Greeting(String greetings) {
this.greetings = greetings;
}
public String getGreetings() {
return greetings;
}
public void setGreetings(String greetings) {
this.greetings = greetings;
}
}
template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
AWS Lambda Java with Gradle
Globals:
Function:
Timeout: 20
Resources:
PostGreetingFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: build/distributions/awslambda-javagradle.zip
Handler: awslambda.javagradle.Handler::handleRequest
Runtime: java8
Events:
GetOrder:
Type: Api
Properties:
Path: /
Method: post
Outputs:
ApiEndpoint:
Description: "API Gateway endpoint URL for Prod stage"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
PostGreetingFunction:
Description: "PostGreeting Lambda Function ARN"
Value: !GetAtt PostGreetingFunction.Arn
build.gradle
apply plugin: 'java'
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile (
'com.amazonaws:aws-lambda-java-core:1.1.0',
'com.amazonaws:aws-lambda-java-log4j:1.0.0',
'com.amazonaws:aws-lambda-java-events:1.1.0',
'com.fasterxml.jackson.core:jackson-core:2.8.5',
'com.fasterxml.jackson.core:jackson-databind:2.8.5',
'com.fasterxml.jackson.core:jackson-annotations:2.8.5'
)
}
// Task for building the zip file for upload
task buildZip(type: Zip) {
from compileJava
from processResources
into('lib') {
from configurations.runtime
}
}
build.dependsOn buildZip
Erstellen Sie mit dem Befehl Gradle.
gradle build
aws s3 mb s3://<Stellen Sie den Ziel-S3-Bucket bereit> --aws-profile=<AWS-Profil>
Laden Sie mit sam package
die ausführbare Datei in den oben erstellten S3-Bucket hoch und generieren Sie eine Vorlagendatei für die Bereitstellung.
sam package \
--s3-bucket <Stellen Sie den Namen des Ziel-S3-Buckets bereit> \
--s3-prefix <Name des Bereitstellungsziel-S3-Ordners(Präfix)※Irgendein> \
--output-template-file output.yml \
--profile <AWS-Profil>
Als Ausgabe wird eine Datei "output.yml" erstellt.
Verwenden Sie "sam deploy", um Lambda und API Gateway bereitzustellen.
sam deploy \
--template-file output.yml \
--stack-name awslambda-javagradle-greeting \
--capabilities CAPABILITY_IAM \
--profile <AWS-Profil>
Nachdem die Lambda-Funktion und das API-Gateway in AWS erstellt wurden, senden wir eine POST-Anforderung an den Endpunkt.
Anfrage
curl -X POST https://xxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/
Antwort
{"greetings":"Hello"}
Ich selbst benutze normalerweise kein Java, also habe ich eine Weile gebraucht, aber ich habe den Eindruck, dass es einfach zu machen war. Natürlich ist die Menge an Code größer als das Schreiben mit einer Skriptsprache wie Python, aber es ist attraktiv, eine rigorose Entwicklung ohne Server durchführen zu können.
Dieses Mal allein konnte ich die spezifischen Spezifikationen für das Schreiben in Java, wie z. B. mehrere Arten des Schreibens von Handlerfunktionen, nicht vollständig erfassen. Wenn ich es tatsächlich benutze, möchte ich es unter Berücksichtigung dieses Bereichs detailliert gestalten.
Gerüchten zufolge ist der erste Start langsam (ca. 5 Sekunden, bis er reagiert). Referenz: https://cero-t.hatenadiary.jp/entry/20160106/1452090214
Ich konnte die Eigenschaften und den Codierungssinn der Lambda-Funktionsentwicklung mit Java erfassen. Wenn Sie von einem Servlet migrieren, ist meiner Meinung nach eine umfassende Renovierung erforderlich, aber es scheint, dass es als Ersatz verwendet werden kann.
Ich bin ein wenig besorgt über die Unterstützung dort, ob die Laufzeit Java 8 ist, wie es ist. .. Ich habe API Gateway als Auslöser verwendet, möchte aber auch andere Dienste ausprobieren.
https://qiita.com/kamata1729/items/8d88ea10dd3bb61fa6cc https://qiita.com/riversun/items/7fcc06617b469aed8f27
Recommended Posts