Service Mesh وSwift: كيفية إدارة الخدمات المصغرة بدون ألم

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

Swift في عالم الخدمات المصغرة: عندما لا يكفي خادم واحد

\n\n

هل سبق لك أن شغّلت تطبيق Swift وفكرت: "ليته يعمل مثل الساعة السويسرية — كل وحدة على حدة، ولكن معًا بشكل متناغم تمامًا"؟ لهذا بالضبط تُستخدم الخدمات المصغرة. ولكن بمجرد تقسيم التطبيق المتجانس إلى عشرات الخدمات الصغيرة، تبدأ الفوضى الحقيقية: تفقد الخدمات بعضها البعض، وتسقط الطلبات، وتتحول السجلات إلى فوضى.

\n\n

هنا يظهر Service Mesh — طبقة ذكية تتولى كل السحر الاتصالي. ونعم، Swift يتعامل معها بشكل ممتاز. في هذه المقالة، سنفهم كيفية ترويض Service Mesh في نظام Swift البيئي باستخدام Vapor وKitura والممارسات الحديثة. لا ماء — فقط كود وحالات حقيقية.

\n\n

ما هو Service Mesh ولماذا يحتاجه مطور Swift؟

\n\n

تخيل أن كل خدمة مصغرة لديك هي جزيرة منفصلة. عادةً، تتصل الجزر بالعبارات (طلبات HTTP). لكن العبارات تغرق، وتتأخر، وأحيانًا ينهب القراصنة (أخطاء الشبكة) البضائع. Service Mesh هي شبكة ذكية من الجسور ومرسلي الحركة، والتي:

\n\n
    \n
  • تدير حركة المرور — تقرر إلى أين تُوجه الطلب إذا كانت الخدمة محملة بشكل زائد
  • \n
  • تُشفّر كل شيء — mTLS بين الخدمات دون سطر واحد في الكود
  • \n
  • تجمع المقاييس — ترى كم من الوقت استغرق كل استدعاء
  • \n
  • تعالج الأخطاء — إعادة المحاولة، المهلة، قاطع الدائرة بشكل مدمج
  • \n
\n\n

هذا مهم بشكل خاص لـ Swift: نظام Swift الخادم البيئي لا يزال حديثًا، والآليات المدمجة للتوجيه المعقد لا تزال قليلة نسبيًا. Service Mesh يسد هذه الفجوات دون إجبارك على كتابة أطنان من كود boilerplate.

\n\n

كيف تتواصل خدمات Swift المصغرة بدون Service Mesh؟

\n\n

لنلقِ نظرة على مثال نموذجي. لنفترض أن لديك خدمة طلبات على Vapor وخدمة دفع. بدون Service Mesh، تكتب شيئًا مثل:

\n\n
import Vapor\n\nfunc processOrder(req: Request) async throws -> Order {\n    // نجمع URL يدويًا — هذا سيء بالفعل\n    let paymentServiceURL = "http://payment-service:8080/charge"\n    \n    // نعالج المهلات بأنفسنا — هذا ممل\n    let client = req.client\n    let response = try await client.post(URI(paymentServiceURL)) { req in\n        try req.content.encode(PaymentRequest(amount: 100))\n    }\n    \n    // نتحقق من الحالة بأنفسنا — هذا مرهق\n    guard response.status == .ok else {\n        throw Abort(.badGateway, reason: "Payment failed")\n    }\n    \n    return try response.content.decode(Order.self)\n}
\n\n

يبدو مألوفًا؟ تخيل الآن أن لديك 20 خدمة، وفي كل مرة تحتاج إلى تكرار منطق إعادة المحاولة، التوازن، والتشفير. Service Mesh يخلصك من هذا الجحيم.

\n\n

Istio + Swift: الثنائي المثالي للإنتاج

\n\n

Istio هو أشهر Service Mesh لـ Kubernetes. يعمل على مستوى proxy جانبي (Envoy) يعترض كل حركة المرور. خدمة Swift لا تحتاج حتى إلى معرفة وجود Istio — فهي فقط تستمع إلى المنفذ، والـ proxy يفعل كل شيء آخر.

\n\n

لكن هناك فارق بسيط: تطبيقات Swift غالبًا ما تستخدم أطر عمل بمحرك HTTP خاص بها (Vapor, Hummingbird). يجب أن يفهم Istio الرؤوس والبروتوكولات بشكل صحيح. الخبر السار: Vapor 4+ يدعم HTTP/1.1 وHTTP/2 القياسيين، لذا لا توجد مشاكل.

\n\n

نشر خدمة Swift مع Istio

\n\n

لنفترض أن لديك خدمة بسيطة على Vapor:

\n\n
// Sources/App/routes.swift\nimport Vapor\n\nfunc routes(_ app: Application) throws {\n    app.get("health") { req -> HTTPStatus in\n        return .ok\n    }\n    \n    app.get("api", "v1", "users") { req -> [User] in\n        // منطق جلب المستخدمين\n        return [User(id: 1, name: "Alice")]\n    }\n}
\n\n

سيكون Dockerfile الخاص به عاديًا:

\n\n
FROM swift:5.9 AS build\nWORKDIR /app\nCOPY . .\nRUN swift build -c release\n\nFROM ubuntu:22.04\nWORKDIR /app\nCOPY                

المدونات

توصيات الكتب