88 lines
2.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 缓存
SDK 使用 `We\Contract\StoreCacheInterface` 缓存 access token 和 component access token。接口语义包括 TTL、删除和刷新锁
```php
<?php
declare(strict_types=1);
use We\Contract\StoreCacheInterface;
final class ApplicationCache implements StoreCacheInterface
{
public function get(string $key, mixed $default = null): mixed
{
return $default;
}
public function set(string $key, mixed $value, int $ttl): void
{
}
public function del(string $key): void
{
}
public function lock(string $key, int $ttl, callable $callback): mixed
{
return $callback();
}
}
```
生产适配器的 `lock()` 必须在多进程或多节点之间互斥执行回调,避免多个请求同时刷新同一平台凭据。上例只展示接口形状,不具备生产锁语义。
## 内置实现
| 实现 | 用途 | 锁语义 |
|------|------|--------|
| `FileCacheStore` | 单机、本地开发、小规模部署 | `flock` 进程锁 |
| `PsrSimpleCacheStore` | Redis 等 PSR-16 实现 | 由调用方注入分布式锁回调 |
| `NullCacheStore` | 测试或显式禁用缓存 | 直接执行回调,不互斥 |
文件缓存使用临时文件和原子重命名提交新值。读取过期文件只返回默认值,不会按旧路径删除,因此不会误删并发写入的新值。
## PSR-16 适配
```php
<?php
declare(strict_types=1);
use We\Client;
use We\Support\PsrSimpleCacheStore;
$store = new PsrSimpleCacheStore(
cache: $psr16Cache,
locker: static function (string $key, int $ttl, callable $callback) use ($distributedLock): mixed {
return $distributedLock->run($key, $ttl, $callback);
},
);
$client = new Client(
cache: $store,
cacheKeyPrefix: 'production-tenant-a',
);
```
如果没有注入 `locker`,需要刷新 token 时 `PsrSimpleCacheStore::lock()` 会抛出 `SdkException`,而不是静默绕过并发保护。
## 缓存键
完整键由部署前缀、平台通道和逻辑键三段组成。每段使用 `rawurlencode()`,再用点号连接:
```text
production-tenant-a.wechat.platform.wechat%3Aapp%3Awx_appid%3Aplatform%3Aaccess_token
```
该格式不会包含 PSR-16 保留字符 `{ } ( ) / \\ @ :`。部署前缀和通道仍保持稳定隔离;逻辑键的内部层次被编码在第三段内。
2.0 发布前的旧冒号格式不属于稳定接口。升级时不需要迁移旧 token 缓存,允许 SDK 按新键重新获取。
## 多租户
- 使用根 `Client::$cacheKeyPrefix` 隔离部署或大租户。
- 使用微信配置中的 `storageScope` 隔离同一 appid 下的业务账号或子租户。
- 不要在请求间随机改变这两个值,否则会失去缓存命中并放大平台 token 请求。