Mikroservices in JavaScript: Architektur und fortgeschrittene Praxis

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Mikroservices in JavaScript: Vom Monolithen zum verteilten System



Der Übergang von einer monolithischen Anwendung zu einer Mikroservice-Architektur ist nicht nur ein technisches Refactoring, sondern eine Veränderung der Entwicklungsphilosophie. Auf fortgeschrittenem Niveau der Arbeit mit Node.js stehen wir vor der Notwendigkeit, den Code nicht nur in Module aufzuteilen, sondern ein stabiles, skalierbares und ausfallsicheres verteiltes System zu schaffen. In diesem Artikel analysieren wir die wichtigsten Architekturentscheidungen und praktischen Patterns, die Ihnen helfen, production-ready Mikroservices in JavaScript zu erstellen.



Die größten Herausforderungen für den Entwickler: Datensynchronisation zwischen Services, Wahrung der Transaktionsintegrität, Service Discovery und effiziente Kommunikation. Ein Fehler in der Entwurfsphase kann im Produktivbetrieb zu Chaos führen. Schauen wir uns an, wie man das vermeidet.



1. Kommunikation zwischen Services: RabbitMQ und gRPC



In der Welt der Mikroservices ist die Wahl des Kommunikationsprotokolls entscheidend. Für Node.js sind zwei Ansätze am beliebtesten: asynchrone Message Queue (RabbitMQ) und synchrones Hochleistungs-RPC (gRPC).



Asynchrone Queue (RabbitMQ)

Wird für ereignisgesteuerte Architekturen verwendet. Der produzierende Service wartet nicht auf eine Antwort, sondern veröffentlicht ein Ereignis. Dies reduziert die Kopplung. Betrachten wir ein Beispiel für die Übermittlung einer Bestellung an den Versandservice.



// Service "Bestellungen" — Producerconst amqp = require('amqplib');

async function publishOrderCreated(order) { const connection = await amqp.connect('amqp://rabbitmq:5672'); const channel = await connection.createChannel(); const exchange = 'order.events'; await channel.assertExchange(exchange, 'topic', { durable: true });

channel.publish(exchange, 'order.created', Buffer.from(JSON.stringify(order)), { persistent: true });

console.log(`[x] Sent order: ${order.id}`); await channel.close(); await connection.close();}

// Aufruf bei BestellungserstellungpublishOrderCreated({ id: '123', userId: '456', amount: 1500 });


Der konsumierende Service (Versand) abonniert die Queue:



// Service "Versand" — Consumerconst amqp = require('amqplib');

async function consumeOrders() { const connection = await amqp.connect('amqp://rabbitmq:5672'); const channel = await connection.createChannel(); const exchange = 'order.events'; await channel.assertExchange(exchange, 'topic', { durable: true });

const q = await channel.assertQueue('', { exclusive: true }); await channel.bindQueue(q.queue, exchange, 'order.created');

channel.consume(q.queue, (msg) => { if (msg.content) { const order = JSON.parse(msg.content.toString()); console.log(`[x] Received order: ${order.id}`); // Logik zur Erstellung des Versands channel.ack(msg); } });}

consumeOrders();


Synchrones gRPC

Für Szenarien, die eine sofortige Antwort erfordern (z. B. Überprüfung des Benutzerguthabens), bietet gRPC strenge Typisierung und hohe Geschwindigkeit über HTTP/2. Wir definieren die Proto-Datei:



// user.protoservice UserService {  rpc GetUserBalance (UserRequest) returns (UserResponse);}

message UserRequest { string user_id = 1;}

message UserResponse { double balance = 1;}


Implementierung des Servers in Node.js:



const grpc = require('@grpc/grpc-js');const protoLoader = require('@grpc/proto-loader');const PROTO_PATH = './user.proto';

const packageDefinition = protoLoader.loadSync(PROTO_PATH, { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true});const userProto = grpc.loadPackageDefinition(packageDefinition).userservice;

function getBalance(call, callback) { const userId = call.request.user_id; // Simulation einer DB-Abfrage const balance = userId === '456' ? 5000 : 0; callback(null, { balance });}

const server = new grpc.Server();server.addSe

Blogs

Buchempfehlungen