logologo
Start
Handbuch
Entwicklung
Plugins
API
Startseite
English
简体中文
日本語
한국어
Español
Português
Deutsch
Français
Русский
Start
Handbuch
Entwicklung
Plugins
API
Startseite
logologo

Schnellstart

Plugin-Entwicklung: Überblick
Erstes Plugin schreiben
Projektverzeichnisstruktur

Serverseitige Entwicklung

Überblick
Plugin
Collections (Datentabellen)
Datenbankoperationen
DataSourceManager
ResourceManager
ACL-Zugriffskontrolle
Middleware
Cache
Events
Request-Kontext
Migration (Update-Skripte)
Logger (Protokollierung)
I18n (Internationalisierung)
Command (Befehlszeile)
CronJobManager
Tests

Clientseitige Entwicklung

Überblick
Plugin
Kontext
Router
ACL-Zugriffskontrolle
DataSourceManager
Ressourcen
Requests
Stile & Themes
Logger (Protokollierung)
I18n (Internationalisierung)
Tests

Sonstiges

Plugin-Update-Leitfaden
Sprachenliste
Abhängigkeitsverwaltung
Build
Previous PageMiddleware
Next PageEvents
KI-Übersetzungshinweis

Diese Dokumentation wurde automatisch von KI übersetzt.

#Cache

Das Cache-Modul von NocoBase basiert auf node-cache-manager und stellt Cache-Funktionen für die Plugin-Entwicklung bereit. Das System bietet zwei integrierte Cache-Typen:

  • memory – Ein In-Memory-Cache, der auf lru-cache basiert und standardmäßig von node-cache-manager bereitgestellt wird.
  • redis – Ein Redis-Cache, der auf node-cache-manager-redis-yet basiert.

Weitere Cache-Typen können Sie über die API erweitern und registrieren.

#Grundlegende Verwendung

#app.cache

app.cache ist die standardmäßige Cache-Instanz auf Anwendungsebene und kann direkt verwendet werden.

// Cache setzen
await app.cache.set('key', 'value', { ttl: 3600 }); // TTL-Einheit: Sekunden

// Cache abrufen
const value = await app.cache.get('key');

// Cache löschen
await this.app.cache.del('key');

#ctx.cache

In Middleware oder bei Ressourcenoperationen können Sie über ctx.cache auf den Cache zugreifen.

async (ctx, next) => {
  let data = await ctx.cache.get('custom:data');
  if (!data) {
    // Cache-Miss: Daten aus der Datenbank abrufen
    data = await this.getDataFromDatabase();
    // Im Cache speichern, Gültigkeit 1 Stunde
    await ctx.cache.set('custom:data', data, { ttl: 3600 });
  }
  await next();
}

#Benutzerdefinierten Cache erstellen

Wenn Sie eine unabhängige Cache-Instanz (z. B. mit unterschiedlichen Namensräumen oder Konfigurationen) erstellen möchten, können Sie die Methode app.cacheManager.createCache() verwenden.

import { Plugin } from '@nocobase/server';

export default class PluginCacheDemo extends Plugin {
  async load() {
    // Eine Cache-Instanz mit Präfix erstellen
    const myCache = await this.app.cacheManager.createCache({
      name: 'myPlugin',
      prefix: 'plugin:cache:', // Alle Keys erhalten automatisch dieses Präfix
      store: 'memory', // In-Memory-Cache verwenden (optional, standardmäßig wird defaultStore genutzt)
      max: 1000, // Maximale Anzahl von Cache-Einträgen
    });

    await myCache.set('user:1', { name: 'John' });
    const user = await myCache.get('user:1');
  }
}

#Parameterbeschreibung für createCache

ParameterTypBeschreibung
namestringEindeutiger Bezeichner für den Cache (erforderlich)
prefixstringOptional: Präfix für Cache-Keys, um Konflikte zu vermeiden
storestringOptional: Bezeichner des Store-Typs (z. B. 'memory', 'redis'), standardmäßig wird defaultStore verwendet
[key: string]anyWeitere Store-spezifische Konfigurationsoptionen

#Erstellten Cache abrufen

const myCache = this.app.cacheManager.getCache('myPlugin');

#Grundlegende Cache-Methoden

Cache-Instanzen bieten umfangreiche Methoden für Cache-Operationen, von denen die meisten von node-cache-manager geerbt werden.

#get / set

// Cache setzen, mit Ablaufzeit (Einheit: Sekunden)
await cache.set('key', 'value', { ttl: 3600 });

// Cache abrufen
const value = await cache.get('key');

#del / reset

// Einzelnen Key löschen
await cache.del('key');

// Gesamten Cache leeren
await cache.reset();

#wrap

Die Methode wrap() ist ein sehr nützliches Werkzeug: Sie versucht zunächst, Daten aus dem Cache abzurufen. Wenn der Cache-Eintrag nicht gefunden wird (Cache-Miss), wird die Funktion ausgeführt und das Ergebnis im Cache gespeichert.

const data = await cache.wrap('user:1', async () => {
  // Diese Funktion wird nur bei einem Cache-Miss ausgeführt
  return await this.fetchUserFromDatabase(1);
}, { ttl: 3600 });

#Batch-Operationen

// Batch-Setzen
await cache.mset([
  ['key1', 'value1'],
  ['key2', 'value2'],
  ['key3', 'value3'],
], { ttl: 3600 });

// Batch-Abrufen
const values = await cache.mget(['key1', 'key2', 'key3']);

// Batch-Löschen
await cache.mdel(['key1', 'key2', 'key3']);

#keys / ttl

// Alle Keys abrufen (Hinweis: Einige Stores unterstützen dies möglicherweise nicht)
const allKeys = await cache.keys();

// Verbleibende Ablaufzeit für einen Key abrufen (Einheit: Sekunden)
const remainingTTL = await cache.ttl('key');

#Erweiterte Verwendung

#wrapWithCondition

wrapWithCondition() ähnelt wrap(), kann aber anhand von Bedingungen entscheiden, ob der Cache verwendet werden soll.

const data = await cache.wrapWithCondition(
  'user:1',
  async () => {
    return await this.fetchUserFromDatabase(1);
  },
  {
    // Externe Parameter steuern, ob das Cache-Ergebnis verwendet wird
    useCache: true, // Wenn auf false gesetzt, wird die Funktion auch bei vorhandenem Cache erneut ausgeführt

    // Anhand des Datenergebnisses entscheiden, ob gecacht werden soll
    isCacheable: (value) => {
      // Beispiel: Nur erfolgreiche Ergebnisse werden gecacht
      return value && !value.error;
    },

    ttl: 3600,
  },
);

#Objekt-Cache-Operationen

Wenn der gecachte Inhalt ein Objekt ist, können Sie die folgenden Methoden verwenden, um Objekteigenschaften direkt zu bearbeiten, ohne das gesamte Objekt abrufen zu müssen.

// Eine Eigenschaft des Objekts setzen
await cache.setValueInObject('user:1', 'name', 'John');
await cache.setValueInObject('user:1', 'age', 30);

// Eine Eigenschaft des Objekts abrufen
const name = await cache.getValueInObject('user:1', 'name');

// Eine Eigenschaft des Objekts löschen
await cache.delValueInObject('user:1', 'age');

#Benutzerdefinierten Store registrieren

Wenn Sie andere Cache-Typen (wie Memcached, MongoDB usw.) verwenden möchten, können Sie diese über app.cacheManager.registerStore() registrieren.

import { Plugin } from '@nocobase/server';
import { redisStore, RedisStore } from 'cache-manager-redis-yet';

export default class PluginCacheDemo extends Plugin {
  async load() {
    // Redis-Store registrieren (falls noch nicht vom System registriert)
    this.app.cacheManager.registerStore({
      name: 'redis',
      store: redisStore,
      close: async (redis: RedisStore) => {
        await redis.client.quit();
      },
      // Redis-Verbindungskonfiguration
      url: 'redis://localhost:6379',
    });

    // Cache mit dem neu registrierten Store erstellen
    const redisCache = await this.app.createCache({
      name: 'redisCache',
      store: 'redis',
      prefix: 'app:',
    });
  }
}

#Hinweise

  1. Grenzen des In-Memory-Caches: Achten Sie bei der Verwendung des Memory-Stores darauf, einen angemessenen max-Parameter festzulegen, um Speicherüberläufe zu vermeiden.
  2. Cache-Invalidierungsstrategie: Denken Sie daran, bei Datenaktualisierungen den zugehörigen Cache zu leeren, um veraltete Daten zu vermeiden.
  3. Key-Benennungskonventionen: Es wird empfohlen, aussagekräftige Namensräume und Präfixe zu verwenden, z. B. module:resource:id.
  4. TTL-Einstellungen: Legen Sie die TTL basierend auf der Datenaktualisierungsfrequenz sinnvoll fest, um Leistung und Konsistenz auszugleichen.
  5. Redis-Verbindung: Stellen Sie bei der Verwendung von Redis sicher, dass die Verbindungsparameter und Passwörter in der Produktionsumgebung korrekt konfiguriert sind.