logologo
Начало
Руководство
Разработка
Плагины
API
English
简体中文
日本語
한국어
Deutsch
Français
Español
Português
Русский
Italiano
Türkçe
Українська
Tiếng Việt
Bahasa Indonesia
ไทย
Polski
Nederlands
Čeština
العربية
עברית
हिन्दी
Svenska
Начало
Руководство
Разработка
Плагины
API
logologo

Быстрый старт

Обзор разработки плагинов
Создание первого плагина
Структура каталогов проекта

Серверная разработка

Обзор
Плагин
Коллекции (таблицы данных)
Операции с базой данных
Управление источниками данных (DataSourceManager)
Управление ресурсами (ResourceManager)
Контроль доступа (ACL)
Промежуточное ПО (Middleware)
Кэш
Событие
Контекст запроса
Миграции
Логгер
Интернационализация (I18n)
Командная строка
Управление задачами Cron (CronJobManager)
Тестирование

Клиентская разработка

Обзор
Плагин
Контекст
Маршрутизатор
Контроль доступа (ACL)
Управление источниками данных (DataSourceManager)
Ресурс
Запрос
Стили и темы
Логгер
Интернационализация (I18n)
Тестирование

Прочее

Руководство по обновлению плагинов
Список языков
Управление зависимостями
Сборка
Previous PageПромежуточное ПО (Middleware)
Next PageСобытие
Уведомление о переводе ИИ

Эта документация была автоматически переведена ИИ.

#Кэш

Модуль кэширования NocoBase основан на библиотеке node-cache-manager и предоставляет функциональность кэширования для разработки плагинов. Система имеет два встроенных типа кэша:

  • memory - Кэш в оперативной памяти на основе lru-cache, предоставляемый node-cache-manager по умолчанию.
  • redis - Кэш Redis на основе node-cache-manager-redis-yet.

Дополнительные типы кэша можно расширять и регистрировать через API.

#Базовое использование

#app.cache

app.cache — это экземпляр кэша по умолчанию на уровне приложения, который можно использовать напрямую.

// Установить кэш
await app.cache.set('key', 'value', { ttl: 3600 }); // Единица измерения TTL: секунды

// Получить кэш
const value = await app.cache.get('key');

// Удалить кэш
await this.app.cache.del('key');

#ctx.cache

В промежуточном ПО или операциях с ресурсами вы можете получить доступ к кэшу через ctx.cache.

async (ctx, next) => {
  let data = await ctx.cache.get('custom:data');
  if (!data) {
    // Промах кэша, получить из базы данных
    data = await this.getDataFromDatabase();
    // Сохранить в кэше, срок действия 1 час
    await ctx.cache.set('custom:data', data, { ttl: 3600 });
  }
  await next();
}

#Создание пользовательского кэша

Если вам нужно создать независимый экземпляр кэша (например, с разными пространствами имен или конфигурациями), вы можете использовать метод app.cacheManager.createCache().

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

export default class PluginCacheDemo extends Plugin {
  async load() {
    // Создать экземпляр кэша с префиксом
    const myCache = await this.app.cacheManager.createCache({
      name: 'myPlugin',
      prefix: 'plugin:cache:', // Все ключи будут автоматически иметь этот префикс
      store: 'memory', // Использовать кэш в памяти, необязательно, по умолчанию используется defaultStore
      max: 1000, // Максимальное количество элементов кэша
    });

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

#Описание параметров createCache

ПараметрТипОписание
namestringУникальный идентификатор кэша, обязателен
prefixstringНеобязательно, префикс для ключей кэша, используется для предотвращения конфликтов ключей
storestringНеобязательно, идентификатор типа хранилища (например, 'memory', 'redis'), по умолчанию используется defaultStore
[key: string]anyДругие пользовательские параметры конфигурации, связанные с хранилищем

#Получение созданного кэша

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

#Основные методы кэша

Экземпляры кэша предоставляют обширные методы для работы с кэшем, большинство из которых унаследованы от node-cache-manager.

#get / set

// Установить кэш со сроком действия (единица измерения: секунды)
await cache.set('key', 'value', { ttl: 3600 });

// Получить кэш
const value = await cache.get('key');

#del / reset

// Удалить отдельный ключ
await cache.del('key');

// Очистить весь кэш
await cache.reset();

#wrap

Метод wrap() — это очень полезный инструмент, который сначала пытается получить данные из кэша. Если кэш не содержит данных (промах кэша), он выполняет функцию и сохраняет результат в кэше.

const data = await cache.wrap('user:1', async () => {
  // Эта функция выполняется только при промахе кэша
  return await this.fetchUserFromDatabase(1);
}, { ttl: 3600 });

#Массовые операции

// Массовая установка
await cache.mset([
  ['key1', 'value1'],
  ['key2', 'value2'],
  ['key3', 'value3'],
], { ttl: 3600 });

// Массовое получение
const values = await cache.mget(['key1', 'key2', 'key3']);

// Массовое удаление
await cache.mdel(['key1', 'key2', 'key3']);

#keys / ttl

// Получить все ключи (примечание: некоторые хранилища могут не поддерживать это)
const allKeys = await cache.keys();

// Получить оставшееся время жизни ключа (единица измерения: секунды)
const remainingTTL = await cache.ttl('key');

#Расширенное использование

#wrapWithCondition

wrapWithCondition() похож на wrap(), но позволяет решить, использовать ли кэш, на основе условий.

const data = await cache.wrapWithCondition(
  'user:1',
  async () => {
    return await this.fetchUserFromDatabase(1);
  },
  {
    // Внешние параметры контролируют, использовать ли результат из кэша
    useCache: true, // Если установлено в false, функция будет выполнена повторно, даже если кэш существует

    // Решить, кэшировать ли на основе результата данных
    isCacheable: (value) => {
      // Например: кэшировать только успешные результаты
      return value && !value.error;
    },

    ttl: 3600,
  },
);

#Операции с кэшем объектов

Когда кэшируемое содержимое является объектом, вы можете использовать следующие методы для непосредственной работы со свойствами объекта, не извлекая весь объект.

// Установить свойство объекта
await cache.setValueInObject('user:1', 'name', 'John');
await cache.setValueInObject('user:1', 'age', 30);

// Получить свойство объекта
const name = await cache.getValueInObject('user:1', 'name');

// Удалить свойство объекта
await cache.delValueInObject('user:1', 'age');

#Регистрация пользовательского хранилища

Если вам нужно использовать другие типы кэша (например, Memcached, MongoDB и т. д.), вы можете зарегистрировать их с помощью app.cacheManager.registerStore().

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

export default class PluginCacheDemo extends Plugin {
  async load() {
    // Зарегистрировать хранилище Redis (если оно еще не зарегистрировано в системе)
    this.app.cacheManager.registerStore({
      name: 'redis',
      store: redisStore,
      close: async (redis: RedisStore) => {
        await redis.client.quit();
      },
      // Конфигурация подключения Redis
      url: 'redis://localhost:6379',
    });

    // Создать кэш, используя только что зарегистрированное хранилище
    const redisCache = await this.app.createCache({
      name: 'redisCache',
      store: 'redis',
      prefix: 'app:',
    });
  }
}

#Важные замечания

  1. Ограничения кэша в памяти: При использовании хранилища memory убедитесь, что вы установили разумный параметр max, чтобы избежать переполнения памяти.
  2. Стратегия инвалидации кэша: При обновлении данных не забывайте очищать соответствующий кэш, чтобы избежать устаревших данных.
  3. Соглашения об именовании ключей: Рекомендуется использовать осмысленные пространства имен и префиксы, например, module:resource:id.
  4. Настройки TTL: Устанавливайте TTL разумно, исходя из частоты обновления данных, чтобы сбалансировать производительность и согласованность.
  5. Подключение Redis: При использовании Redis убедитесь, что параметры подключения и пароль правильно настроены в производственной среде.