configure Redis cache and distributed locks
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
# کش ورکفلو در چند نود؛ راهنمای سریع
|
||||
|
||||
این راهنما برای مرور سریع است. [آموزش مبتدی با مثال و تمرین](workflow-cache-beginner.fa.md) و [جزئیات فنی و سورس](workflow-cache-explained.fa.md) موضوع را کاملتر توضیح میدهند.
|
||||
|
||||
## خلاصهٔ کاربردی
|
||||
|
||||
| بخش | مسئولیت |
|
||||
|---|---|
|
||||
| `UseCaching` | انتخاب مشترک provider، مدت و تنظیمات کش |
|
||||
| `management.UseCache()` | کش تعریفها و نتایج جستوجوی آنها |
|
||||
| `runtime.UseCache()` | کش Triggerها و هماهنگی تغییرهای مرتبط با Runtime |
|
||||
| `http.UseCache()` | کش lookup ورکفلو برای HTTP ورودی |
|
||||
| `DistributedLocking` | هماهنگی عملیات همزمان نودها، مستقل از کش |
|
||||
|
||||
نام Redis در سه `UseCache` لازم نیست تکرار شود؛ مصرفکنندهها مدیر کش مشترک همان ماژول را دریافت میکنند. `RegisterRedis` قابلیت انتخاب را ثبت میکند؛ `Provider=Redis` در فایل یا `UseRedis` در کد آن را انتخاب میکند. پیشفرض عمومی Core برابر Memory است.
|
||||
|
||||
نسخهٔ فعلی Framework در سورس و مصرف NextBank برابر `1.1.0-preview.28` و ماژولهای تغییرکردهٔ Core برابر `1.1.0-preview.10` هستند.
|
||||
|
||||
## تنظیم فایل پایهٔ NextBank
|
||||
|
||||
در هر سه میزبان Web، Admin و Workers، بخشهای زیر داخل `appsettings.json` پایه قرار دارند. سایر تنظیمات برنامه مانند اتصال SQL باید حفظ شوند. فایل Production جداگانهای وجود ندارد:
|
||||
|
||||
```json
|
||||
{
|
||||
"Redis": {
|
||||
"AllowAdmin": true,
|
||||
"Ssl": false,
|
||||
"ConnectTimeout": 5000,
|
||||
"ConnectRetry": 2,
|
||||
"Database": 1,
|
||||
"ServiceName": "Redis1",
|
||||
"Hosts": [
|
||||
{
|
||||
"Host": "192.168.234.146",
|
||||
"Port": 26379
|
||||
},
|
||||
{
|
||||
"Host": "192.168.234.145",
|
||||
"Port": 26379
|
||||
},
|
||||
{
|
||||
"Host": "192.168.234.144",
|
||||
"Port": 26379
|
||||
}
|
||||
]
|
||||
},
|
||||
"Workflow": {
|
||||
"Cache": {
|
||||
"Enabled": true,
|
||||
"Provider": "Redis",
|
||||
"Duration": "1.00:00:00",
|
||||
"Redis": {
|
||||
"Database": 1,
|
||||
"KeyPrefix": "nextbank:workflow:cache:"
|
||||
}
|
||||
},
|
||||
"Runtime": {
|
||||
"DistributedLocking": {
|
||||
"Provider": "Redis",
|
||||
"Database": 1,
|
||||
"KeyPrefix": "nextbank:workflow:locks:",
|
||||
"LockAcquisitionTimeout": "00:00:10"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
فایلها: [Web](../../../NextBankParsian/Repo/src/Web/appsettings.json)، [Admin](../../../NextBankParsian/Repo/src/Admin/appsettings.json) و [Workers](../../../NextBankParsian/Repo/src/Workers/appsettings.json).
|
||||
|
||||
اتصال از بخش اصلی `Redis` توسط میزبان ثبت میشود. کش و قفل، `IConnectionMultiplexer` میزبان را مصرف میکنند. هر process نمونهٔ سرویس خودش را دارد، ولی به Redis مشترک وصل میشود.
|
||||
|
||||
مدت کش یک روز و حداکثر انتظار گرفتن قفل Runtime ده ثانیه است. این دو مقدار مدت نگهداشتن قفل را تعیین نمیکنند. قفل پس از آزادشدن میتواند از Redis حذف شود و همیشه قابل مشاهده نیست.
|
||||
|
||||
## تنظیم لوکال و اولویت فایلها
|
||||
|
||||
### ترکیب فایلها و آرایهٔ Hosts را درست بفهمیم
|
||||
|
||||
فایل `appsettings.json` پایه ابتدا خوانده میشود. اگر فایل مربوط به محیط وجود داشته باشد، مقادیر آن روی فایل پایه اعمال میشوند. در ساختار فعلی NextBank، فایل جداگانهٔ Production وجود ندارد؛ محیط Production تنظیمات Sentinel را از فایل پایه دریافت میکند. در Development، فایل `appsettings.development.json` روی پایه اعمال میشود.
|
||||
|
||||
تنظیمات بر اساس کلید ترکیب میشوند. آرایهٔ `Hosts` نیز کلیدهای شمارهدار مانند `Redis:Hosts:0:Host` دارد. اگر فایل پایه سه endpoint و فایل Development یک endpoint داشته باشد، فقط شمارهٔ صفر جایگزین میشود؛ شمارههای یک و دو از پایه باقی میمانند. نوشتن یک آرایهٔ کوتاهتر به معنی پاکشدن آرایهٔ قبلی نیست.
|
||||
|
||||
وقتی قصد دارید در لوکال فقط یک Redis فعال باشد، باید اثر endpointهای اضافی پایه را هم بردارید. در helper اتصال فعلی NextBank، Host خالی کنار گذاشته میشود، بنابراین این نمونهٔ override قابل استفاده است:
|
||||
|
||||
```json
|
||||
{
|
||||
"Redis": {
|
||||
"ServiceName": "",
|
||||
"Hosts": [
|
||||
{ "Host": "localhost", "Port": 6379 },
|
||||
{ "Host": "", "Port": 26379 },
|
||||
{ "Host": "", "Port": 26379 }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
این نمونه روش تنظیم لوکال روی یک فایل پایهٔ دارای سه Sentinel را آموزش میدهد. عدد پورتِ ردیف دارای Host خالی مصرف نمیشود. در فایلهای Development فعلی فقط ردیف صفر تعیین شده است؛ پس ترکیب فعلی فایلها هنوز دو endpoint دیگر پایه را نگه میدارد. برای تشخیص تنظیم واقعی، مقادیر نهاییِ ترکیبشده را بررسی کنید، نه فقط یک فایل را.
|
||||
|
||||
متغیرهای محیطی، User Secrets و خط فرمان نیز میتوانند مقادیر فایلها را تغییر دهند. نام محیط و بزرگی و کوچکی حروف نام فایل، بهخصوص روی Linux، باید با روش بارگذاری میزبان سازگار باشد. روی سرور باید فایل پایهٔ دارای تنظیمات Sentinel همراه خروجی باشد و override لوکال در محیط Production اعمال نشود.
|
||||
|
||||
|
||||
## تنظیم از کد
|
||||
|
||||
در Framework ترتیب اولویت عبارت است از پیشفرض، فایل، سپس مقدار صریح callback:
|
||||
|
||||
```csharp
|
||||
builder.AddWorkflowFramework(connectionString, cache =>
|
||||
{
|
||||
cache.Duration = TimeSpan.FromMinutes(30);
|
||||
cache.UseRedis(redis =>
|
||||
{
|
||||
redis.ConnectionFactory =
|
||||
sp => sp.GetRequiredService<IConnectionMultiplexer>();
|
||||
redis.Database = 1;
|
||||
redis.KeyPrefix = "nextbank:workflow:cache:";
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
ثبت اتصال میزبان و دریافت اتصال معتبر SQL باید طبق کد برنامه انجام شده باشند. بدون callback، `builder.AddWorkflowFramework(connectionString)` تنظیمات فایل را مصرف میکند.
|
||||
|
||||
در داخل Framework تنظیم مشترک چنین است:
|
||||
|
||||
```csharp
|
||||
.UseCaching(cache =>
|
||||
{
|
||||
cache.Duration = TimeSpan.FromDays(1);
|
||||
cache.RegisterRedis();
|
||||
cache.UseConfiguration(
|
||||
builder.Configuration.GetSection("Workflow:Cache"));
|
||||
configureCache?.Invoke(cache);
|
||||
})
|
||||
```
|
||||
|
||||
ثبت ثابتِ جداگانهٔ `Configure<CachingOptions>` حذف شده تا مقدار فایل یا callback دوباره به یک روز برنگردد. خود CacheFeature مقدار نهایی را در Options ثبت میکند. `runtime.UseCache` قبلاً هم فعال بود؛ شرط ثابت `useCaching=true` حذف شد و کنترل payload از `Enabled` انجام میشود.
|
||||
|
||||
برای Memory، `Workflow:Cache:Provider` را `Memory` قرار دهید. با `Enabled=false`، خواندن و نوشتن payload کش کنار گذاشته میشود؛ هماهنگی تغییرات در حالت Redis ادامه دارد. این تغییرها provider قفل را خودکار عوض نمیکنند. پس از تغییر provider، برنامه را دوباره اجرا کنید.
|
||||
|
||||
## داده و اعتبار
|
||||
|
||||
تعریفها، نتایج جستوجوی تعریفها، Triggerها و اطلاعات قابل ذخیرهٔ lookup HTTP میتوانند در Redis باشند. گراف اجرایی، کد کامپایلشده، اسکریپت و قالب آمادهٔ اجرا در process ساخته یا نگهداری میشوند. Bookmarkها، وضعیت اجرا و لاگها در SQL باقی میمانند.
|
||||
|
||||
جدول `Elsa.CacheMutations` اعتبار کش را در SQL ثبت میکند. خواندن نسخهٔ جدید باعث استفاده از کلیدهای آن نسخه میشود. هنگام تغییر ناتمام یا تراکنش جاری، مسیر مربوط از payload کش عبور میکند. migration آمادهٔ SQL Server، `20261007000000_AddCacheMutationFences` است؛ schema باید پیش از مصرف کش مشترک فراهم باشد.
|
||||
|
||||
تعداد کلیدهای Redis با تعداد تعریفها برابر نیست. هر کلید میتواند نتیجهٔ یک query، یک صفحه شامل چند تعریف یا نتیجهٔ خالی باشد. کلیدها هنگام خواندن ایجاد میشوند و کلیدهای Revision قدیمی تا پایان TTL ممکن است باقی بمانند.
|
||||
|
||||
برای چندنودی، SQL ورکفلو، Redis، دیتابیس Redis و پیشوندهای میزبانهای مرتبط باید هماهنگ باشند. کش عمومی NextBank و Redis Streamها مصرفکنندههای جدا هستند، هرچند ممکن است همان اتصال Redis را استفاده کنند.
|
||||
|
||||
## بررسی و محدودیت نتایج
|
||||
|
||||
نمونههای JSON و لینکهای سورس در بازسازی این مستند بررسی شدهاند. فایلهای پایه و Development با Configuration واقعی .NET ترکیب شدهاند؛ این بررسی اتصال شبکه یا اجرای migration نیست.
|
||||
|
||||
گزارش آزمون قبلی با `preview.27` اشتراک payload و رفتار قفل را بین سه ServiceProvider مستقل تأیید کرده است. آزمونهای زیرساخت Core نیز شامل تست کش، Runtime و process مستقل بودهاند. این نتایج مربوط به همان مراحلاند؛ آزمون اجرایی جدید `preview.28`، اتصال واقعی Sentinel و failover سرورها در این بازسازی انجام نشدهاند.
|
||||
Reference in New Issue
Block a user