العودة إلى التحديثات
New releaseSep 1, 2026

pingap v0.13.10

وكيل عكسي مثل nginx، مبني على pingora، بسيط وفعّال.

مشاركة

بينجاب

قبل أن يصبح إصدار بينجاب مستقرًا، لن يتم قبول أي طلبات سحب. إذا كان لديك أي أسئلة، يُرجى إنشاء مشكلة جديدة أولاً.

شعار بينجاب

نظرة عامة

بينجاب هو وكيل عكسي عالي الأداء مدعوم من Cloudflare Pingora. يبسّط الإدارة التشغيلية من خلال تمكين إعادة التحميل الديناميكي للتكوين بدون توقف باستخدام ملفات TOML موجزة وواجهة إدارة ويب بديهية.

تتمثل قوته الأساسية في نظام إضافات قوي، يقدم أكثر من عشرين ميزة جاهزة للاستخدام للمصادقة (JWT، Key Auth)، والأمان (CSRF، تقييد IP/Referer/UA)، والتحكم في المرور (تحديد المعدل، التخزين المؤقت)، وتعديل المحتوى (إعادة التوجيه، استبدال المحتوى)، وقابلية الملاحظة (معرف الطلب). هذا يجعل بينجاب ليس مجرد وكيل، بل بوابة تطبيقات مرنة وقابلة للتوسعة، مصممة للتعامل بسهولة مع السيناريوهات المعقدة من حماية واجهات API إلى نشر تطبيقات الويب الحديثة.

English | الوثائق · الوثائق بالصينية | أمثلة | الإضافات | Crates

flowchart LR
  internet("الإنترنت") -- طلب --> pingap["بينجاب"]
  pingap -- وكيل:pingap.io/api/* --> apiUpstream["10.1.1.1,10.1.1.2"]
  pingap -- وكيل:cdn.pingap.io --> cdnUpstream["10.1.2.1,10.1.2.2"]
  pingap -- وكيل:/* --> upstream["10.1.3.1,10.1.3.2"]

الميزات الرئيسية

  • 🚀 أداء عالٍ وموثوقية

    • مبني بلغة Rust لأمان الذاكرة وأفضل أداء.
    • مدعوم من Cloudflare Pingora، مكتبة شبكات غير متزامنة مجربة.
    • يدعم وكيل HTTP/1.1 و HTTP/2 و gRPC-web.
  • 🔧 ديناميكي وسهل الاستخدام

    • تغييرات التكوين بدون توقف مع إعادة التحميل الساخن.
    • ملفات تكوين TOML بسيطة وسهلة القراءة.
    • واجهة ويب كاملة للتحكم البديهي في الوقت الفعلي.
    • يدعم كلاً من الملفات و etcd كخلفيات للتكوين.
    • يدعم سجل تاريخ التكوين، ويمكن استعادة الإصدار السابق بنقرة واحدة.
  • 🧩 قابلية توسع قوية

    • نظام إضافات غني للتعامل مع مهام البوابة الشائعة.
    • توجيه متقدم مع مطابقة المضيف والمسار والتعبير المنتظم.
    • اكتشاف خدمة مدمج عبر قوائم ثابتة أو DNS أو Docker labels.
    • HTTPS تلقائي مع Let's Encrypt (يدعم تحديات HTTP-01 و DNS-01).
  • 📊 قابلية ملاحظة حديثة

    • مقاييس Prometheus أصلية للمراقبة (أوضاع السحب والدفع).
    • دعم OpenTelemetry المتكامل للتتبع الموزع.
    • سجلات وصول قابلة للتخصيص بدرجة عالية مع أكثر من 30 متغيرًا.
    • مقاييس أداء مفصلة، بما في ذلك وقت اتصال المنبع ووقت المعالجة وغيرها.

🚀 البدء السريع

أسهل طريقة للبدء مع بينجاب هي باستخدام Docker Compose.

  1. أنشئ ملف docker-compose.yml:
# docker-compose.yml
version: '3.8'

services:
  pingap:
    image: vicanso/pingap:latest # للإنتاج، استخدم إصدارًا محددًا مثل vicanso/pingap:0.12.1-full
    container_name: pingap-instance
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      # قم بتثبيت دليل محلي لحفظ جميع التكوينات والبيانات
      - ./pingap_data:/opt/pingap
    environment:
      # التكوين باستخدام متغيرات البيئة
      - PINGAP_CONF=/opt/pingap/conf
      - PINGAP_ADMIN_ADDR=0.0.0.0:80/pingap
      - PINGAP_ADMIN_USER=pingap
      - PINGAP_ADMIN_PASSWORD=<YourSecurePassword> # قم بتغيير هذا!
    command:
      # بدء بينجاب وتمكين إعادة التحميل الساخن
      - pingap
      - --autoreload
  1. أنشئ دليل بيانات وشغّل:
mkdir pingap_data
docker-compose up -d
  1. الوصول إلى واجهة الإدارة:

يعمل مثيل بينجاب الخاص بك الآن! يمكنك الوصول إلى واجهة الإدارة عبر الويب على http://localhost/pingap باستخدام بيانات الاعتماد التي قمت بتعيينها.

تثبيت الملف الثنائي عبر curl

لنظامي Linux و macOS، يمكنك تثبيت أحدث ملف ثنائي تم بناؤه مسبقًا إلى /usr/local/bin/pingap بأمر واحد:

curl -sSL https://raw.githubusercontent.com/vicanso/pingap/main/install.sh | sh

متغيرات البيئة الاختيارية:

  • PINGAP_FULL=1 — تثبيت الإصدار الكامل (جميع الميزات الاختيارية مفعلة)
  • PINGAP_LIBC=gnu — على Linux، استخدم إصدار glibc بدلاً من الإصدار الثابت musl الافتراضي
# إصدار كامل الميزات
curl -sSL https://raw.githubusercontent.com/vicanso/pingap/main/install.sh | PINGAP_FULL=1 sh

الأهداف المدعومة: Linux x86_64/arm64, Darwin x86_64/arm64. راجع صفحة الإصدارات لجميع الأصول المتاحة.

لمزيد من التعليمات التفصيلية، بما في ذلك التشغيل من ملف ثنائي، راجع الوثائق.

بدء وكيل بدون ملف تكوين

يكفي أمر واحد لتقديم نطاق عبر https وإعادة توجيهه إلى خلفية:

# شهادة مطلوبة من Let's Encrypt
pingap --domain=pingap.io --upstream=192.168.1.1:3000

# أو استخدم شهادتك الخاصة
pingap --domain=pingap.io --upstream=192.168.1.1:3000 --cert=/etc/ssl/pingap.io

بدون --cert، يطلب بينجاب شهادة من Let's Encrypt عبر تحدي HTTP-01، لذلك يجب أن يحل pingap.io إلى هذا المضيف ويجب أن يكون المنفذ 80 قابلاً للوصول من الإنترنت. يتم حفظ الشهادة الصادرة في ~/.pingap/acme/<domains>.toml ويتم إعادة استخدامها عند إعادة التشغيل — الإصدار محدود المعدل، لذا لا تحذفها. كل شيء آخر لا يزال يأتي من سطر الأوامر: تغيير --upstream يصبح ساريًا عند بدء التشغيل التالي دون لمس الشهادة.

يقبل --cert الشهادة نفسها أو الدليل الذي يحتوي عليها — يتم اكتشاف التخطيطات الشائعة fullchain.pem / privkey.pem, cert.pem / key.pem و tls.crt / tls.key تلقائيًا، استخدم --key لأي شيء آخر. المستمع الافتراضي هو 0.0.0.0:443 عند وجود شهادة و 0.0.0.0:80 عند عدم وجود شهادة أو نطاق، و --addr يتجاوزه. --upstream يأخذ قائمة بخوادم خلفية مفصولة بفواصل، --domain يأخذ قائمة بمضيفين مفصولة بفواصل (احذفه لخدمة كل مضيف عبر http عادي).

يتم إنشاء التكوين في كل بدء، لذا لا يمكن تعديله من خلال واجهة الإدارة: لأي شيء يتجاوز خادمًا واحدًا استخدم --conf، والذي لا يمكن دمجه مع هذه العلامات.

التكوين الديناميكي

تم تصميم بينجاب للتكيف مع تغييرات التكوين دون توقف.

إعادة التحميل الساخن (--autoreload): بالنسبة لمعظم التغييرات—مثل تحديث المنبع والمواقع أو الإضافات—يطبق بينجاب التكوين الجديد في غضون 10 ثوانٍ دون إعادة تشغيل. هذا هو الوضع الموصى به للبيئات المحتواة.

إعادة التشغيل الآمن (-a أو --autorestart): بالنسبة للتغييرات الأساسية (مثل تعديل منافذ استماع الخادم)، يقوم هذا الوضع بإعادة تشغيل كاملة دون توقف، مما يضمن عدم فقدان أي طلب.

🔧 التطوير

make dev

إذا كنت بحاجة إلى واجهة إدارة ويب، فيجب عليك تثبيت nodejs وبناء أصول الويب.

# إنشاء أصول إدارة الويب
cd web
npm i 
cd ..
make build-web

📝 التكوين

server "test" {
  addr = "127.0.0.1:6118"

  location "github-api" {
    path = "/api"
    proxy_set_headers = ["Host:api.github.com"]
    rewrite = "^/api/(?<path>.+)$ /$1"

    upstream "api" {
      addrs     = ["api.github.com:443"]
      discovery = "dns"
      sni       = "api.github.com"
    }
  }

  location "static" {
    plugin "staticServe" {
      category = "directory"
      path     = "~/Downloads"
      step     = "request"
    }
  }
}
[upstreams.api]
addrs = ["api.github.com:443"]
discovery = "dns"
sni = "api.github.com"

[plugins.staticServe]
category = "directory"
path = "~/Downloads"
step = "request"

[locations.github-api]
upstream = "api"
path = "/api"
proxy_set_headers = ["Host:api.github.com"]
rewrite = "^/api/(?<path>.+)$ /$1"

[locations.static]
plugins = ["staticServe"]

[servers.test]
addr = "127.0.0.1:6118"
locations = ["github-api", "static"]

يمكنك العثور على التعليمات ذات الصلة هنا: https://pingap.io/crates/config.

🔄 خطوة الوكيل

graph TD;
  server["خادم HTTP"];
  locationA["الموقع أ"];
  locationB["الموقع ب"];
  locationPluginListA["قائمة إضافات الوكيل أ"];
  locationPluginListB["قائمة إضافات الوكيل ب"];
  upstreamA1["المنبع أ1"];
  upstreamA2["المنبع أ2"];
  upstreamB1["المنبع ب1"];
  upstreamB2["المنبع ب2"];
  locationResponsePluginListA["قائمة إضافات الاستجابة أ"];
  locationResponsePluginListB["قائمة إضافات الاستجابة ب"];

  start("طلب جديد") --> server

  server -- "host:HostA, Path:/api/*" --> locationA

  server -- "Path:/rest/*"--> locationB

  locationA -- "تنفيذ إضافات الوكيل" --> locationPluginListA

  locationB -- "تنفيذ إضافات الوكيل" --> locationPluginListB

  locationPluginListA -- "تمرير وكيل: 10.0.0.1:8001" --> upstreamA1

  locationPluginListA -- "تمرير وكيل: 10.0.0.2:8001" --> upstreamA2

  locationPluginListA -- "تم" --> response

  locationPluginListB -- "تمرير وكيل: 10.0.0.1:8002" --> upstreamB1

  locationPluginListB -- "تمرير وكيل: 10.0.0.2:8002" --> upstreamB2

  locationPluginListB -- "تم" --> response

  upstreamA1 -- "تنفيذ إضافات الاستجابة" --> locationResponsePluginListA
  upstreamA2 -- "تنفيذ إضافات الاستجابة" --> locationResponsePluginListA

  upstreamB1 -- "تنفيذ إضافات الاستجابة" --> locationResponsePluginListB
  upstreamB2 -- "تنفيذ إضافات الاستجابة" --> locationResponsePluginListB

  locationResponsePluginListA --> response
  locationResponsePluginListB --> response

  response["استجابة HTTP"] --> stop("تسجيل");

📊 الأداء

وحدة المعالجة المركزية: M4 Pro، الخيط: 1

Ping بدون سجل وصول

wrk 'http://127.0.0.1:6118/ping' --latency

Running 10s test @ http://127.0.0.1:6118/ping
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    66.41us   23.67us   1.11ms   76.54%
    Req/Sec    73.99k     2.88k   79.77k    68.81%
  Latency Distribution
     50%   67.00us
     75%   80.00us
     90%   91.00us
     99%  116.00us
  1487330 requests in 10.10s, 194.32MB read
Requests/sec: 147260.15
Transfer/sec:     19.24MB
رمز QR لبينجاب

📦 إصدار Rust

إصدار MSRV الحالي لدينا هو 1.88

📄 الترخيص

هذا المشروع مرخص بموجب رخصة Apache، الإصدار 2.0.

الفئات