Moleculer 有一个内置的缓存服务动作的解决方案。 要启用它, 在 broker option中设置一种 <1>cacher</1> 类型 并在 action 定义中设置 cacher:true
用以缓存想要的内容。
动作缓存示例
const { ServiceBroker } = require("moleculer"); |
Console messages:
[2017-08-18T13:04:33.845Z] INFO dev-pc/BROKER: Broker started. |
如你所见,调用 Handler called
信息只出现一次,因为第二次请求的响应是从缓存中返回的。
缓存键
缓存器从服务名称、动作名称和上下文参数生成键。 键的语法是:
<serviceName>.<actionName>:<parameters or hash of parameters> |
因此, 当使用参数{ limit: 5, offset: 20 }
调用 posts.list
动作时, cacher 从参数中计算 hash. 下一次,当你用相同的参数来调用此操作时,它将会通过键在缓存中找到此项。
“posts.find” 动作 hash 键示例
posts.find:limit|5|offset|20 |
参数对象可以包含与缓存键无关的属性。 而且,如果键太长,这也会造成性能问题。 因此建议为 cache
属性设置一个对象,对象包含一个在 keys
属性中。 若要在缓存 keys
使用 meta,相关属性用 #
前缀装饰。
留意以下键生成器使用了 params
& meta
属性
{ |
Performance tip这个解决方案很快,所以我们建议在生产环境中使用它。
限制缓存键长度
有时,键可能很长,可能造成性能问题。 为了避免它,在缓存配置中限制键长度为 maxParamsLength
。 当键长于配置的限制值时, 缓存从全键计算哈希(SHA256),并将其添加到键的末尾。
maxParamsLength
不要小于44
(SHA 256 hash length in Base64).要禁用此功能,请将其设置为
0
或null
。
不受限制地从整个参数生成完整键
cacher.getCacheKey("posts.find", { id: 2, title: "New post", content: "It can be very very looooooooooooooooooong content. So this key will also be too long" }); |
生成限长键
const broker = new ServiceBroker({ |
条件缓存
条件缓存允许绕过缓存的响应并执行操作以获取“新”数据。 若要绕过缓存,请将 ctx.meta.$cache
设置为 false
然后调用一个动作。
示例关闭 greeter.hello
动作缓存
broker.call("greeter.hello", { name: "Moleculer" }, { meta: { $cache: false }})) |
作为替代,可以实现一个自定义函数来绕过 cache。 自定义函数接受上下文(ctx
) 作为参数,因此它可以访问任何参数或 meta 数据。 这允许在请求中传递旁路 flag。
自定义缓存函数示例
// greeter.service.js |
TTL
在动作定义中可以覆盖默认的 TTL 设置。
const broker = new ServiceBroker({ |
自定义键生成器
要覆盖内置的缓存键生成器,请在缓存选项中设置您自己的函数为 keygen
。
const broker = new ServiceBroker({ |
手动操作缓存
缓存模块可以手动使用。 只需调用 broker.cacher
的get
, set
, del
方法。
// Save to cache |
此外,使用内置Redis 缓存时,可用在 broker.cacher.client 使用完整的 ioredis
API :
// create an ioredis pipeline |
清除缓存
当您在您的服务中创建一个新模型时,您必须清除旧的缓存模型条目。
清除操作内缓存的示例
{ |
清除多个服务实例中的缓存
清除多个服务实例中的缓存条目的最佳做法是使用广播事件。 Note this is only required for non-centralized cachers like Memory
or MemoryLRU
.
示例
module.exports = { |
清除不同服务之间的缓存
有依赖的服务是常见的。 例如: posts
服务存储来自 users
服务缓存条目中的信息(in case of populating)。
posts
服务中的缓存条目示例
{ |
author
字段来自 users
服务 。 如果 users
服务清除缓存条目, posts
服务也必须清除自己的缓存条目。 因此,您也应该在 posts
服务中订阅 cache.clear.user
事件。
更简捷一点,请在依赖的服务方案中创建一个 CacheCleaner
mixin 并定义。
cache.cleaner.mixin.js
module.exports = function(serviceNames) { |
posts.service.js
const CacheCleaner = require("./cache.cleaner.mixin"); |
如果 users
服务发布了 cache.clean.users
事件, posts
服务也将清除自己的缓存条目。
缓存锁定
Moleculer 也支持缓存锁定功能。 详情信息 请检查此 PR。
启用锁定
const broker = new ServiceBroker({ |
Enable with TTL
const broker = new ServiceBroker({ |
禁用锁定
const broker = new ServiceBroker({ |
使用 redlock
库的 Redis 缓存示例
const broker = new ServiceBroker({ |
内建缓存
Memory cacher
MemoryCacher
是一个内置内存缓存模块。 它在堆内存中储存条目。
启用内存缓存
const broker = new ServiceBroker({ |
或
const broker = new ServiceBroker({ |
Enable with options
const broker = new ServiceBroker({ |
Options
名称 | 类型 | 默认设置 | 说明 |
---|---|---|---|
ttl |
Number |
null |
Time-to-live in seconds. |
clone |
Boolean or Function |
false |
返回时克隆缓存的数据。 |
keygen |
Function |
null |
自定义缓存键生成器函数。 |
maxParamsLength |
Number |
null |
Maximum length of params in generated keys. |
lock |
Boolean or Object |
null |
启用锁定功能。 |
克隆
Cacher 使用 lodash _.cloneDeep
方法进行克隆。 To change it, set a Function
to the clone
option instead of a Boolean
.
使用 JSON parse & stringify 自定义克隆函数
const broker = new ServiceBroker({ |
LRU memory cacher
LRU memory cacher
is a built-in LRU cache module. 删除最近使用最少的项目。
Enable LRU cacher
const broker = new ServiceBroker({ |
With options
let broker = new ServiceBroker({ |
Options
名称 | 类型 | 默认设置 | 说明 |
---|---|---|---|
ttl |
Number |
null |
Time-to-live in seconds. |
max |
Number |
null |
Maximum items in the cache. |
clone |
Boolean or Function |
false |
Clone the cached data when return it. |
keygen |
Function |
null |
Custom cache key generator function. |
maxParamsLength |
Number |
null |
Maximum length of params in generated keys. |
lock |
Boolean or Object |
null |
Enable lock feature. |
Dependencies要使用此缓存,请安装
lru-cache
模块, 使用npm install lru-cache --save
命令。
Redis 缓存
RedisCacher
is a built-in Redis based distributed cache module. 它使用 ioredis
库. Use it, if you have multiple instances of services because if one instance stores some data in the cache, other instances will find it.
启用 Redis 缓存
const broker = new ServiceBroker({ |
With connection string
const broker = new ServiceBroker({ |
With options
const broker = new ServiceBroker({ |
With MessagePack serializer 您可以为 Redis Cacher 定义一个序列化器。 默认情况下,它使用 JSON 序列化器。
const broker = new ServiceBroker({ |
使用 Redis 集群客户端
const broker = new ServiceBroker({ |
Options
名称 | 类型 | 默认设置 | 说明 |
---|---|---|---|
prefix |
String |
null |
键前缀 |
ttl |
Number |
null |
Time-to-live in seconds. Disabled: 0 or null |
monitor |
Boolean |
false |
启用 Redis 客户端 监测功能。 If enabled, every client operation will be logged (on debug level) |
redis |
Object |
null |
Custom Redis options. Will be passed to the new Redis() constructor. Read more. |
keygen |
Function |
null |
Custom cache key generator function. |
maxParamsLength |
Number |
null |
Maximum length of params in generated keys. |
serializer |
String |
"JSON" |
Name of a built-in serializer. |
cluster |
Object |
null |
Redis Cluster client configuration. More information |
lock |
Boolean or Object |
null |
Enable lock feature. |
pingInterval |
Number |
null |
Emit a Redis PING command every pingInterval milliseconds. Can be used to keep connections alive which may have idle timeouts. |
Dependencies要使用此缓存,请使用
npm install ioredis --save
命令安装ioredis
模块。
自定义缓存
可以创建自定义缓存模块。 我们建议复制 MemoryCacher 或 RedisCacher 并实现 get
set
, del
和 clean
方法。
创建自定义缓存
const BaseCacher = require("moleculer").Cachers.Base; |
使用自定义缓存
const { ServiceBroker } = require("moleculer"); |