تخطَّ إلى المحتوى
getnextpdf.com

Enterprise الإصدار

القياس — مرجع متعمّق

يوفّر مجال الأسماء NextPDF\Enterprise\Metering قياسًا للاستخدام على مستوى التنسيق من أجل وضوح الفوترة والتدقيق. يتكوّن السطح العام من ستة رموز: MeterCollector وMeterEntry وMeteringReporter وMeteringBackendInterface وPrometheusMeteringBackend وPrometheusPushgatewayException. يخزّن المجمِّع الإدخالات غير القابلة للتغيير في الذاكرة مؤقّتًا ويفرّغها على دفعات. ويوزّع المُبلِّغ كل دفعة على خلفية واحدة أو أكثر مع إعادة المحاولة وعزل الفشل لكل خلفية. القياس بذلُ أفضل جهد وغير قاتل: فانقطاع خلفية القياس يُضعف قابلية المراقبة، لا معالجة المستندات أبدًا. وهذا التدفّق ليس المصدر الموثوق لفرض الحصص. وللاطّلاع على الدليل على مستوى سير العمل، انظر القياس.

تُشحن هذه الإمكانية في ⁨NextPDF Enterprise⁩ (nextpdf/enterprise) وتُفعَّل بمظروف ترخيص من فئة ⁨Enterprise⁩. لا يُحمِّل أي نشر يفتقر إلى هذا الاستحقاق أصناف الإمكانية. قارن بين الإصدارات واحصل على ترخيص.

القياس إمكانية أساسية في ⁨Enterprise⁩، تتوفّر بمجرّد تثبيت حزمة ⁨Enterprise⁩؛ ولا توجد راية منفصلة لكل ميزة. لا يملك ⁨NextPDF Core⁩ (Apache-⁨2.0⁩) ولا ⁨NextPDF Pro⁩ أي سطح للمجمِّع أو المُبلِّغ أو الخلفية؛ فالعقد يُشحن في nextpdf/enterprise فقط.

الرمزالمعامِلاتالسلوك الافتراضييُعيديرمي أو يفشل بـملاحظات
MeterCollector::__constructMeteringReporter $reporter، int $bufferSize = 100يُنشئ مجمِّعًا بمخزن مؤقّت فارغ في الذاكرةMeterCollector جديدلا يرمي$bufferSize موثّق بوصفه positive-int
MeterCollector::recordstring $operation، int $count، string $tenantId، string $licenseId، int $pagesProcessed = 0، float $durationMs = 0.0، array $metadata = []يُلحق MeterEntry واحدًا غير قابل للتغيير مختومًا بالوقت الحالي؛ ويُفرّغ تلقائيًا عندما يبلغ المخزن المؤقّت $bufferSizevoidلا يرمي؛ يُفوِّض التفريغ التلقائي إلى المُبلِّغ الذي لا يرمي أبدًايُؤخذ الطابع الزمني وقت التسجيل
MeterCollector::flushيُسلّم جميع الإدخالات المخزّنة مؤقّتًا إلى المُبلِّغ؛ والمخزن المؤقّت الفارغ عملية لا أثر لهاvoidلا يرمي؛ يمتصّ المُبلِّغ إخفاقات الخلفيةيُستبدل المخزن المؤقّت قبل التسليم؛ آمن لإعادة الدخول
MeterCollector::bufferCountيُعيد عدد الإدخالات المخزّنة مؤقّتًاint<0, max>لا يرميقرارات التشخيص والضغط العكسي
MeterCollector::registerShutdownFlushيُسجّل flush() عبر register_shutdown_functionvoidلا يرمياستدعِ مرة واحدة عند الإقلاع في عمليات نشر ⁨PHP-FPM⁩
MeterEntry::__constructstring $operation، int $count، DateTimeImmutable $timestamp، string $tenantId، string $licenseId، int $pagesProcessed = 0، float $durationMs = 0.0، array $metadata = []يخزّن القيم المقدَّمة حرفيًاMeterEntry جديدلا يوجد @throws مُعلَن؛ يرفع ⁨PHP⁩ خطأ TypeError عند عدم تطابق أنواع الوسائط تحت strict_typesfinal readonly؛ جميع الخصائص المرقّاة الثماني عامة
MeteringReporter::__constructlist<MeteringBackendInterface> $backends، int $maxRetries = 2، LoggerInterface $logger = new NullLogger()يتحقّق من قائمة الخلفيات ويخزّنهاMeteringReporter جديدInvalidArgumentException عندما تكون $backends فارغةيَعُدّ $maxRetries إجمالي محاولات التسليم لكل خلفية
MeteringReporter::reportlist<MeterEntry> $entriesيُسلّم الدفعة إلى كل خلفية على نحو مستقل، مع إعادة المحاولة لكل خلفيةvoidلا يرمي؛ تُسجَّل المحاولات المستنفدة على مستوى الخطأ وتُسقَط دفعة تلك الخلفيةالقائمة الفارغة عملية لا أثر لها
MeteringBackendInterface::reportlist<MeterEntry> $entriesيُسلّم دفعة إلى الخلفيةvoidRuntimeException عندما يتعذّر الوصول إلى الخلفيةيجب أن تكون التطبيقات مُتعادِلة (إزالة التكرار بحسب ⁨timestamp + operation + tenantId⁩)
MeteringBackendInterface::isHealthyفحص إمكانية الوصولboolلا يوجد @throws مُعلَنللتشخيص فقط؛ لا يستخدمه المُبلِّغ بوابةً
MeteringBackendInterface::backendNameاسم الخلفية التشخيصيnon-empty-stringلا يوجد @throws مُعلَنعلى سبيل المثال "prometheus"، "billing-api"، "null"
PrometheusMeteringBackend::__constructClientInterface $httpClient، RequestFactoryInterface $requestFactory، StreamFactoryInterface $streamFactory، string $pushgatewayUrl، string $jobName = 'nextpdf_metering'يُهيّئ هدف دفع ⁨Pushgateway⁩PrometheusMeteringBackend جديدلا يرمييُحقَن عميل ⁨PSR-18⁩ ومصانع ⁨PSR-17⁩
PrometheusMeteringBackend::reportlist<MeterEntry> $entriesيجمّع الدفعة بحسب سلسلة العملية والمستأجر ويرسل نص العرض عبر POST إلى <pushgatewayUrl>/metrics/job/<jobName>voidPrometheusPushgatewayException عند حالة غير 2xx أو إخفاق نقل ⁨PSR-18⁩القائمة الفارغة عملية لا أثر لها
PrometheusMeteringBackend::isHealthyيفحص نقطة نهاية صحة ⁨Pushgateway⁩؛ true فقط عند HTTP 200boolلا يرمي؛ أي إخفاق يُعيد falseفحص GET للقراءة فقط
PrometheusMeteringBackend::backendNameيُعيد "prometheus"non-empty-stringلا يرميثابت
PrometheusPushgatewayExceptionيشير إلى إخفاق تسليم ⁨Pushgateway⁩هو الكائن القابل للرميfinal؛ يمتدّ من RuntimeException
public function __construct(
private readonly MeteringReporter $reporter,
private readonly int $bufferSize = 100,
) {}
public function record(
string $operation,
int $count,
string $tenantId,
string $licenseId,
int $pagesProcessed = 0,
float $durationMs = 0.0,
array $metadata = [],
): void
public function flush(): void
public function bufferCount(): int
public function registerShutdownFlush(): void
public function __construct(
public string $operation,
public int $count,
public DateTimeImmutable $timestamp,
public string $tenantId,
public string $licenseId,
public int $pagesProcessed = 0,
public float $durationMs = 0.0,
public array $metadata = [],
) {}
public function report(array $entries): void;
public function isHealthy(): bool;
public function backendName(): string;
public function __construct(
array $backends,
private readonly int $maxRetries = 2,
private readonly LoggerInterface $logger = new NullLogger(),
)
public function report(array $entries): void
public function __construct(
private readonly ClientInterface $httpClient,
private readonly RequestFactoryInterface $requestFactory,
private readonly StreamFactoryInterface $streamFactory,
private readonly string $pushgatewayUrl,
private readonly string $jobName = self::DEFAULT_JOB_NAME,
) {}
final class PrometheusPushgatewayException extends RuntimeException {}

خصائص MeterEntry العامة للقراءة فقط

الخاصيةالنوعالمعنى
$operationnon-empty-stringنوع العملية، على سبيل المثال "parse"، "compress"، "embed"، "rag_query"
$countpositive-intعدد الوحدات المستهلكة
$timestampDateTimeImmutableوقت حدوث العملية؛ يختمه المجمِّع وقت التسجيل
$tenantIdnon-empty-stringمعرّف المستأجر
$licenseIdnon-empty-stringمعرّف الترخيص
$pagesProcessedint<0, max>صفحات PDF المعالَجة؛ 0 للعمليات غير المتعلّقة بـ PDF
$durationMsfloatمدة العملية بالميلي ثانية
$metadataarray<string, mixed>بيانات وصفية حرة الشكل خاصة بالعملية
  • يبني MeterCollector::record() كائن MeterEntry واحدًا غير قابل للتغيير، ويختمه بالوقت الحالي، ويُلحقه بالمخزن المؤقّت في الذاكرة. وعندما يبلغ المخزن المؤقّت $bufferSize إدخالًا، يُفرّغ المجمِّع تلقائيًا.
  • flush() عملية مُتعادِلة وآمنة لإعادة الدخول. والمخزن المؤقّت الفارغ عملية لا أثر لها. ويُستبدل المخزن المؤقّت قبل تسليم الدفعة إلى المُبلِّغ، بحيث لا يمكن لتفريغ معاد الدخول أن يرسل مرتين.
  • يرفض MeteringReporter الإنشاء بقائمة خلفيات فارغة. وذلك InvalidArgumentException هو الاستثناء الوحيد على مسار المجمِّع/المُبلِّغ.
  • يُسلّم MeteringReporter::report() كل دفعة إلى كل خلفية على نحو مستقل. ولا تمنع خلفية فاشلة أبدًا خلفية أخرى من استلام الدفعة نفسها.
  • يَعُدّ $maxRetries إجمالي محاولات التسليم لكل خلفية؛ والقيمة الافتراضية 2 تعني محاولة أولية واحدة زائد إعادة محاولة واحدة. وتُسجّل كل محاولة فاشلة تحذيرًا يتضمّن اسم الخلفية ورقم المحاولة وعدد الإدخالات.
  • عندما تفشل المحاولة الأخيرة لخلفية ما، يُسجّل المُبلِّغ إضافةً على مستوى الخطأ مع عدد الإدخالات المُسقَطة، ثم يمضي. ولا يرمي أبدًا من report()، لذا يجب ألّا يستنتج المستدعون التسليم من عودة عادية.
  • يجب أن تكون الخلفيات مُتعادِلة. ويتطلّب عقد الواجهة إزالة تكرار مفتاحها الطابع الزمني والعملية ومعرّف المستأجر. والمُبلِّغ نفسه لا يزيل التكرار.
  • يجمّع PrometheusMeteringBackend::report() الدفعة في سلاسل لكل عملية ولكل مستأجر ويرسل عرض ⁨Prometheus⁩ النصي عبر POST إلى <pushgatewayUrl>/metrics/job/<jobName> مع Content-Type بقيمة text/plain; version=0.0.4. واسم المهمة الافتراضي هو nextpdf_metering.
  • تحمل الحمولة المدفوعة ثلاثة عدّادات — nextpdf_operations_total وnextpdf_pages_processed_total وnextpdf_operation_duration_ms_total — كلٌّ منها موسوم بالعملية والمستأجر.
  • تدفّق القياس هذا غير موثوق. ويستهلك فرضُ الحصص والقياسُ الحوسبي الموثوق رقمَ الاستخدام الموثوق المنفصل الخاص بالنشر، لا هذا المخزن المؤقّت أبدًا. والفجوة في قياس التنسيق فجوةٌ في قابلية المراقبة، لا فجوةٌ في صحة الفوترة.

الحالات الحدّية وأنماط الفشل

قسم بعنوان «الحالات الحدّية وأنماط الفشل»
  • دفعة مكرّرة أو مُعادة. تمتصّها تعادلية الخلفية؛ والمُبلِّغ لا يزيل التكرار. لا تعتمد على تسليم مرة-واحدة-بالضبط.
  • إعادات المحاولة المستنفدة. تُسقَط دفعة تلك الخلفية وتُسجَّل على مستوى الخطأ. والعودة العادية من report() أو flush() لا تعني التسليم أبدًا.
  • خروج العملية قبل التفريغ. المخزن المؤقّت في الذاكرة فقط. ويؤدّي التعطّل، أو الخروج دون معالج إيقاف مُسجَّل، إلى فقدان الإدخالات المخزّنة مؤقّتًا.
  • عدم تطابق نموذج العامل. تستدعي عمليات نشر ⁨PHP-FPM⁩ الدالة registerShutdownFlush() مرة واحدة عند الإقلاع كي يُفرَّغ الباقي عند نهاية الطلب. أما العمّال طويلو التشغيل (⁨Octane⁩، عامل ⁨Symfony⁩، عامل الطابور) فيجب أن يُفرّغوا على مؤقّت دوري بدلًا من ذلك؛ وإلّا تتراكم الإدخالات حتى تخرج عملية العامل.
  • $bufferSize أقل من 1. يخالف عقد positive-int الموثّق؛ والنتيجة الملحوظة تفريغ عند كل استدعاء لـ record().
  • بيانات وصفية حسّاسة. $metadata حرة الشكل وقد تحمل سياق عملية حسّاسًا. والتخزين والاحتفاظ والتحكّم في الوصول مسؤولية مُشغّل الخلفية.
  • إخفاق تسليم ⁨Pushgateway⁩. ترفع الاستجابة غير 2xx خطأ PrometheusPushgatewayException يحمل حالة ⁨HTTP⁩ وجسم الاستجابة؛ ويُلَفّ إخفاق نقل ⁨PSR-18⁩ في نوع الاستثناء نفسه. وتمتصّ حلقة إعادة المحاولة والعزل في المُبلِّغ كليهما.
  • فحص الصحة. يُصدر PrometheusMeteringBackend::isHealthy() طلب GET إلى <pushgatewayUrl>/-/healthy ويُعيد true فقط عند ⁨HTTP⁩ 200. وأي خطأ نقل يُعيد false؛ والفحص لا يرمي أبدًا.
  • قيم وسوم عدائية. تُهرَّب أحرف الشرطة المائلة الخلفية وعلامة الاقتباس المزدوجة والتغذية السطرية في قيم العملية أو المستأجر عند الإصدار، بحيث لا تستطيع قيمة وسم حقن أسطر عرض إضافية أو إفساد كتلة الوسوم.
  • وضع ⁨FIPS⁩. لا يُجري المجمِّع والمُبلِّغ أي عمليات تشفيرية وليس لهما سلوك خاص بـ ⁨FIPS⁩. والخلفية التي توقّع أو تشفّر أثناء النقل ترث وضعية ⁨FIPS⁩ لمزوّد التشفير المضيف لها.

لا يحكم أي معيار خارجي المجمِّعَ أو المُبلِّغَ داخل العملية أو عقدَ الخلفية؛ ولا توجد مواصفة معيارية للاستشهاد بها، لذا لا تحمل هذه الصفحة أي استشهاد RAG بحكم التصميم. تُصدر خلفية ⁨Prometheus⁩ صيغة العرض النصي لـ ⁨Prometheus⁩ وتدفع بقيمة Content-Type مساوية لـ text/plain; version=0.0.4؛ وتلك الصيغة عُرف بيئي وليست معيارًا من ISO أو IETF، والادّعاء مؤسَّس على مصدر المنتج. لا يقدّم ⁨NextPDF⁩ أي ادّعاء مطابقة أو اعتماد لهذا السطح.

  • تُعلن جميع الأصناف strict_types=1 وهي final؛ وMeterEntry هو final readonly بخصائص عامة مرقّاة. وترفع أنواع الوسائط غير المتطابقة خطأ TypeError من ⁨PHP⁩ في المستدعي.
  • تحمل أصناف الوحدة توضيح @since للحزمة بقيمة 2.1.0؛ ويحمل PrometheusPushgatewayException توضيح @since بقيمة 3.2.0.
  • يتخلّف مُسجّل المُبلِّغ إلى NullLogger من ⁨PSR-3⁩. احقن مُسجّلًا حقيقيًا في الإنتاج، وإلّا لن تترك الدفعات المُسقَطة أي أثر.
  • اختبار الوحدة: نفّذ MeteringBackendInterface مزيّفًا وابنِ قيم MeterEntry مباشرة. وتأخذ خلفية ⁨Prometheus⁩ تجريدات ⁨PSR-18/PSR-17⁩، لذا يمرّن عميل ⁨HTTP⁩ وهمي مسار الدفع الكامل دون اتصال.
  • اختبارات حدّية موصى بها: مخزن مؤقّت عند $bufferSize بالضبط، وتفريغ معاد الدخول، وتفريغ مخزن مؤقّت فارغ، وفشل خلفية واحدة بينما تنجح ثانية، وتسجيل استنفاد إعادة المحاولة.
  • يرمي مُنفّذو الخلفيات RuntimeException (أو صنفًا فرعيًا) عند إخفاق التسليم؛ ويمتصّه المُبلِّغ. التزم بمتطلّب التعادلية قبل إضافة مزيد من إعادات المحاولة في الأعلى.

توثّق هذه الصفحة السلوك الملحوظ خارجيًا وسطح واجهة ⁨API⁩ العامة المدعوم فقط. أما مسارات مجالات الأسماء الداخلية والأصناف المساعدة وجداول الآليات وأسماء ملفات كتيّبات التشغيل وبادئات التذاكر فخارج النطاق.