En regardant Microsoft Build 2020, Dapr of Distributed Application Runtime semblait intéressant. Tutoriel était Node.js, j'ai donc créé un échantillon en utilisant Dapr de Quarkus tout en y faisant référence.
Voir ci-dessous pour le code https://github.com/koduki/example-dapr/tree/v01/api-with-java
Dapr est un framework développé par Microsoft qui simplifie la mise en œuvre des microservices en implémentant des exigences non fonctionnelles telles que l'invocation inter-service, la gestion d'état et la messagerie inter-service avec un side car (Proxy). Puisqu'il est développé par OSS, il peut être utilisé à partir de ce qui suit.
Je pensais que c'était la même chose qu'un service mesh tel qu'Istio parce que c'était une side car, mais quand j'écoutais la session, c'était un peu différent, en faisant abstraction des fichiers et de la gestion de l'état (persistance des données), ou en mettant en file d'attente comme Kafka. Il semblait y avoir un rôle à jouer. Si quoi que ce soit, cela ressemble à JNDI de Java EE, DataSource ou JCA (Java Connector Architecture). ~~ Si vous êtes un oncle ~~ C'est une chance de dire: "C'est celui que j'ai fait à Shinkenzemi!"
S'il s'agit d'un conteneur Java EE tel que Weblogic, je pense que cette zone est dans le même espace mémoire et parle avec T3 en premier lieu, mais Dapr et chaque application parlent avec HTTP ou gRPC.
Déplaçons-le pour le moment avant de faire le tutoriel proprement dit. Puisque gRPC est gênant cette fois, nous allons implémenter REST. Pour le moment, créez un modèle Quarkus avec la commande mvn et exécutez-le.
$ mvn io.quarkus:quarkus-maven-plugin:1.4.2.Final:create \
-DprojectGroupId=dev.nklab \
-DprojectArtifactId=dapr-app \
-DprojectVersion=1.0.0-SNAPSHOT \
-DclassName="dev.nklab.example.dapr.HelloResource"
$ cd dapr-app
$ ./mvnw quarkus:dev
Essayez d'accéder avec curl depuis un autre terminal.
$ curl http://localhost:8080/hello
hello
Installez Dapr lorsque vous pouvez confirmer le fonctionnement de l'application. k8s fonctionne sans aucune particularité, mais Docker semble devoir être installé à l'avance.
$ curl -fsSL https://raw.githubusercontent.com/dapr/cli/master/install/install.sh | /bin/bash
$ dapr init
L'installation est maintenant terminée. Si vous obtenez l'erreur suivante, vous avez probablement oublié dapr init
.
exec: "daprd": executable file not found in $PATH
Ensuite, enveloppez l'application Quarkus créée précédemment avec Dapr avec la commande suivante et exécutez-la.
$ dapr run --app-id javaapp --app-port 8080 --port 3500 ./mvnw quarkus:dev
...
ℹ️ Updating metadata for app command: ./mvnw quarkus:dev
✅ You're up and running! Both Dapr and your app logs will appear here.
--app-port
est le numéro de port Quarkus et --port
est le numéro de port Dapr. Accédons à Dapr avec curl.
$ curl http://localhost:3500/v1.0/invoke/javaapp/method/hello
hello
Puisque Dapr agit en tant que side car, c'est-à-dire Proxy, vous pouvez voir que vous pouvez accéder à l'application arrière avec 3500
au lieu de 8080
.
La partie javaapp
est le ʻaap-id spécifié à l'exécution. Il semble que ce sera un processus lié à l'application au verso avec ʻinvoke
.
Maintenant, effectuez les étapes 1 à 5 de Hello World. L'application à implémenter cette fois a la structure suivante.
L'utilisateur envoie une demande à Application (Java) via Dapr, accède à l'API de Dapr depuis l'application et écrit dans Redis via Dapr. Il est intéressant de ne pas passer directement par Redis pour la persistance des données, car l'application ne parle qu'à Dapr.
En tant que spécification, l'utilisateur envoie la requête POST suivante à l'application.
{
"data": {
"orderId": "42"
}
}
Ces données sont stockées dans Redis au format suivant:
[{
key: "order",
value:Commande en magasinId ici
}]
En outre, lorsqu'une demande GET est envoyée à Application, le orderId actuel est renvoyé.
Maintenant, implémentons l'application. Cette fois, nous utiliserons JSON, alors ajoutez la bibliothèque à Quarkus.
$ ./mvnw quarkus:add-extension -Dextensions="quarkus-resteasy-jsonb"
$ ./mvnw quarkus:add-extension -Dextensions="quarkus-resteasy-jackson"
Modifiez ensuite l'application comme suit:
HelloResource.java
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class HelloResource {
@ConfigProperty(name = "daprapp.daprport")
String daprPort;
String stateStoreName = "statestore";
@GET
@Path("/order")
public Map<String, Object> order() throws IOException, InterruptedException {
return Map.of("orderId", get(stateUrl() + "/order").body());
}
@POST
@Path("/neworder")
public HttpResponse neworder(Map<String, Map<String, Object>> data) throws IOException, InterruptedException {
System.out.println("orderId: " + data.get("data").get("orderId"));
var items = List.of(Map.of("key", "order", "value", data.get("data").get("orderId")));
return post(stateUrl(), items);
}
private String stateUrl() {
return "http://localhost:" + daprPort + "/v1.0/state/" + stateStoreName;
}
private HttpResponse<String> post(String url, List<Map<String, Object>> items) throws IOException, InterruptedException, JsonProcessingException {
var mapper = new ObjectMapper();
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create(url))
.POST(HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(items)))
.setHeader("Content-Type", "application/json")
.build();
return client.send(request, HttpResponse.BodyHandlers.ofString());
}
private HttpResponse<String> get(String url) throws InterruptedException, IOException {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.setHeader("Content-Type", "application/json")
.build();
return client.send(request, HttpResponse.BodyHandlers.ofString());
}
}
Je n'ai rien fait de spécial en tant que JAX-RS, donc je vais omettre les détails, mais neworder
est le point final pour l'enregistrement et ʻorder` est le point final pour référence.
Vous accédez à http: // localhost: 3500 / v1.0 / state / statestore
dans chaque méthode. C'est le point final de l'API de gestion d'état de Dapr.
Cette fois, la substance de cette API de gestion d'état est Redis. La demande et la réponse de l'API de gestion d'état seront le JSON suivant, comme décrit ci-dessus.
[{
key:valeur,
value:valeur
}]
Configurez ensuite Redis pour implémenter la gestion de l'état. Cependant, il a déjà été défini, alors vérifiez-le.
En fait, un répertoire appelé «composants» est créé au moment de «l'exécution du dapr». Il semble que le statestore.yaml
décrit ici à quel magasin se connecter.
components/statestore.yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
Peut-être que si vous réécrivez ceci dans RDB etc., ce sera une autre implémentation.
Maintenant que l'implémentation est terminée, vérifions l'opération. Tout d'abord, démarrez Dapr.
$ dapr run --app-id javaapp --app-port 8080 --port 3500 ./mvnw quarkus:dev
Alors faites une demande.
$ curl -X POST -H "Content-Type: application/json" -d '{"data": { "orderId": "41" } }' http://localhost:3500/v1.0/invoke/javaapp/method/neworder
{}
$ curl http://localhost:3500/v1.0/invoke/javaapp/method/order
{"orderId":"\"41\""}
Je pense que vous pouvez confirmer que la valeur demandée que vous avez lancée est stockée et que vous pouvez l'obtenir. Vous pouvez également écrire POST avec la commande Dapr comme suit.
$ dapr invoke --app-id javaapp --method neworder --payload '{"data": { "orderId": "41" } }'
Pour le moment, j'ai essayé d'utiliser Dapr de Java. Puisqu'il s'agit de REST, j'ai pu l'implémenter sans aucun problème. Dapr a toujours un sentiment Java EE plus qu'Istio, et en dehors de Dapr lui-même, cette idée elle-même semble aller dans la bonne direction du point de vue de la facilité de développement. L'idée de base est de cacher la substance des services et des données, y compris le modèle DAO, et il vaut mieux intégrer autant que possible les non-fonctions dans l'infrastructure.
D'un autre côté, si la couche de persistance passe également par Proxy, il semble qu'une certaine surcharge soit inévitable même si gRPC est utilisé. Je pense qu'il sera nécessaire à l'avenir de savoir comment traiter ce domaine par conception.
Dapr lui-même en est encore à ses balbutiements et il y a de nombreuses aspérités, mais j'aimerais y toucher un peu plus à l'avenir.
Bon piratage!
Recommended Posts