404 Not Found

404 Not Found


nginx

إدارة التهيئة

إدارة التهيئة هي الجسر بين التطوير والإنتاج—قاعدة كود واحدة، تهيئات متعددة، والتبديل بين البيئات يتطلب معاملاً واحداً فقط.

1. ما ستتعلمه


2. قصة حقيقية لمهندس عمليات

(1) نقطة الألم: التهيئات متناثرة في كل مكان

Bob هو مهندس عمليات في OrderFlow، وكل نشر يبدو وكأنه "حفريات أثرية": كلمات مرور قاعدة البيانات مشفرة بشكل ثابت في الكود، وتهيئات بيئتي الاختبار والإنتاج مختلطة في ملف واحد. غيّر أحدهم كلمة مرور قاعدة بيانات الإنتاج لكنه نسي تحديث الكود، مما أدى إلى توقف النظام لساعتين. عندما ضغط عليه Charlie بشأن SLA، لم يتمكن Bob إلا من التوضيح، بتنهيدة، أن "إدارة التهيئة فوضوية."

(2) حلول Spring Boot Profiles

Spring Boot يستخدم آلية Profile لفصل تهيئات البيئات المتعددة:

YAML
# application-dev.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/orderflow_dev
    username: dev_user
    password: dev_pass
YAML
# application-prod.yml
spring:
  datasource:
    url: jdbc:mysql://prod-db.internal:3306/orderflow
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}

(3) العوائد

بعد أن أعاد Bob بناء الكود باستخدام Profile ومتغيرات البيئة، أصبحت بيئة التطوير تستخدم dev وبيئة الإنتاج تستخدم prod. المعلومات الحساسة لم تعد تظهر في مستودع الكود، والتبديل بين النشرات يتطلب فقط --spring.profiles.active=prod، مما قلل وقت التوقف الناجم عن أخطاء التهيئة إلى الصفر.


3. Profile: تهيئة البيئات المتعددة

(1) اصطلاحات تسمية ملفات Profile

Spring Boot يحمل تهيئات Profile وفقاً لاصطلاح التسمية application-{profile}.yml:

TEXT
src/main/resources/
├── application.yml            # تهيئة مشتركة
├── application-dev.yml        # ملف تعريف التطوير
├── application-prod.yml       # ملف تعريف الإنتاج
└── application-test.yml       # ملف تعريف الاختبار
100%
graph TD
    A["application.yml<br/>تهيئة مشتركة"] --> B["application-dev.yml<br/>تجاوزات التطوير"]
    A --> C["application-prod.yml<br/>تجاوزات الإنتاج"]
    A --> D["application-test.yml<br/>تجاوزات الاختبار"]
    B --> E["تهيئة مدمجة<br/>Profile=dev"]
    C --> F["تهيئة مدمجة<br/>Profile=prod"]
طريقة التفعيل الأمر الأولوية
ملف التهيئة spring.profiles.active=dev في application.yml الحد الأدنى
متغير البيئة SPRING_PROFILES_ACTIVE=dev متوسطة
معامل سطر الأوامر --spring.profiles.active=dev الحد الأقصى

(1) ▶ مثال: Profile

YAML
# application.yml (مشترك)
spring:
  application:
    name: orderflow-service
  profiles:
    active: dev

server:
  port: 8080

الناتج:

TEXT
تم تطبيق التهيئة بنجاح
YAML
# application-dev.yml
spring:
  datasource:
    url: jdbc:h2:mem:orderflow_dev
    username: sa
    password:
  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true

logging:
  level:
    com.orderflow: DEBUG
YAML
# application-prod.yml
spring:
  datasource:
    url: jdbc:mysql://${DB_HOST:localhost}:3306/orderflow
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false

logging:
  level:
    com.orderflow: WARN

4. مقارنة بين @Value و@ConfigurationProperties

(1) طريقتا الحقن

(1) ▶ مثال: حقن @Value

JAVA
@RestController
public class OrderController {

    @Value("${orderflow.max-items-per-order:100}")
    private int maxItemsPerOrder;

    @Value("${orderflow.default-currency:USD}")
    private String defaultCurrency;

    @GetMapping("/api/config/check")
    public Map<String, Object> checkConfig() {
        return Map.of(
            "maxItemsPerOrder", maxItemsPerOrder,
            "defaultCurrency", defaultCurrency
        );
    }
}

الناتج:

TEXT
// التنفيذ ناجح

(2) ▶ مثال: الربط الآمن بالأنواع باستخدام @ConfigurationProperties

JAVA
@ConfigurationProperties(prefix = "orderflow")
public record OrderFlowProperties(
    int maxItemsPerOrder,
    String defaultCurrency,
    Duration orderTimeout,
    ShippingConfig shipping
) {
    public record ShippingConfig(
        boolean freeShippingEnabled,
        BigDecimal freeShippingThreshold
    ) {}
}

// التفعيل في الصنف الرئيسي أو صنف التهيئة
@EnableConfigurationProperties(OrderFlowProperties.class)

الناتج:

TEXT
// التنفيذ ناجح
البُعد @Value @ConfigurationProperties
أمان الأنواع ضعيف (أساساً String) قوي (تحويل أنواع تلقائي)
الكائنات المتداخلة غير مدعوم مدعوم
ربط المجموعات غير مدعوم يدعم List/Map
التحقق بدون بالاقتران مع @Validated
دعم IDE بدون تلميحات إكمال تلقائي (بيانات وصفية)
حالات الاستخدام عدد قليل من القيم البسيطة تهيئة أعمال مهيكلة

(3) ▶ مثال: تعيين YAML وConfigurationProperties

YAML
orderflow:
  max-items-per-order: 50
  default-currency: USD
  order-timeout: 30m
  shipping:
    free-shipping-enabled: true
    free-shipping-threshold: 49.99

الناتج:

TEXT
تم تفعيل التهيئة.
JAVA
// مثال على الوصول
@Component
public class OrderService {
    private final OrderFlowProperties props;

    public OrderService(OrderFlowProperties props) {
        this.props = props;
    }

    public boolean isFreeShipping(BigDecimal orderTotal) {
        return props.shipping().freeShippingEnabled()
            && orderTotal.compareTo(props.shipping().freeShippingThreshold()) >= 0;
    }
}

5. التسلسل الهرمي لأولوية التهيئة

(1) الأولوية من الأعلى إلى الأدنى

100%
graph TD
    A["1. معاملات سطر الأوامر<br/>--server.port=9090"] --> B["2. خصائص JNDI"]
    B --> C["3. خصائص نظام Java<br/>-Dserver.port=9090"]
    C --> D["4. متغيرات بيئة نظام التشغيل<br/>SERVER_PORT=9090"]
    D --> E["5. application-{profile}.yml<br/>خاصة بـ Profile"]
    E --> F["6. application.yml<br/>تهيئة افتراضية"]
    F --> G["7. @القيم الافتراضية<br/>في تعليقات الكود"]
الأولوية المصدر مثال
1 (الأعلى) معاملات سطر الأوامر --server.port=9090
2 خصائص JNDI java:comp/env/...
3 خصائص نظام JVM -Dserver.port=9090
4 متغيرات بيئة نظام التشغيل SERVER_PORT=9090
5 Profile application-prod.yml
6 ملف التهيئة الافتراضي application.yml
7 (الأدنى) القيمة الافتراضية @Value("${x:default}")
💡 نصيحة: في بيئة الإنتاج، يُوصى بتجاوز التهيئات الحساسة باستخدام متغيرات البيئة أو معاملات سطر الأوامر؛ لا تضع كلمات المرور في ملفات التهيئة.


6. التهيئة المتداخلة وربط المجموعات

(1) ربط القوائم والخرائط

(1) ▶ مثال: تهيئة List وMap

YAML
orderflow:
  supported-currencies:
    - USD
    - EUR
    - GBP
  payment-gateways:
    stripe:
      api-key: ${STRIPE_API_KEY}
      webhook-secret: ${STRIPE_WEBHOOK_SECRET}
    paypal:
      client-id: ${PAYPAL_CLIENT_ID}
      secret: ${PAYPAL_SECRET}

الناتج:

TEXT
تم تحميل تهيئة خط أنابيب CI/CD
حالة الخط: ناجح
الاختبارات: 12 ناجح، 0 فاشل
JAVA
@ConfigurationProperties(prefix = "orderflow")
public record OrderFlowProperties(
    List<String> supportedCurrencies,
    Map<String, GatewayConfig> paymentGateways
) {
    public record GatewayConfig(
        String apiKey,
        String webhookSecret,
        String clientId,
        String secret
    ) {}
}

7. مثال شامل: نظام التهيئة الكامل لـ OrderFlow

JAVA
// OrderFlowProperties.java
package com.orderflow.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.List;
import java.util.Map;

@ConfigurationProperties(prefix = "orderflow")
public record OrderFlowProperties(
    int maxItemsPerOrder,
    String defaultCurrency,
    Duration orderTimeout,
    ShippingConfig shipping,
    List<String> supportedCurrencies,
    Map<String, GatewayConfig> paymentGateways
) {
    public record ShippingConfig(
        boolean freeShippingEnabled,
        BigDecimal freeShippingThreshold
    ) {}

    public record GatewayConfig(
        String apiKey,
        String webhookSecret,
        String clientId,
        String secret
    ) {}
}

// AppConfig.java
package com.orderflow.config;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(OrderFlowProperties.class)
public class AppConfig {}
YAML
# application.yml
spring:
  application:
    name: orderflow-service
  profiles:
    active: dev

orderflow:
  max-items-per-order: 50
  default-currency: USD
  order-timeout: 30m
  supported-currencies:
    - USD
    - EUR
    - GBP
  shipping:
    free-shipping-enabled: true
    free-shipping-threshold: 49.99
  payment-gateways:
    stripe:
      api-key: ${STRIPE_API_KEY:dev-key}
      webhook-secret: ${STRIPE_WEBHOOK_SECRET:dev-secret}

❓ أسئلة شائعة

س أيهما أختار، @ConfigurationProperties أم @Value؟
ج استخدم @ConfigurationProperties للتهيئة المهيكلة (أمان الأنواع، التداخل، دعم IDE)، و@Value لعدد قليل من القيم البسيطة. تجنب الخلط بينهما بكثرة في مشروع واحد.
س كيف أمنع تسرب المعلومات الحساسة إلى مستودع الكود؟
ج 1) استخدم العنصر النائب ${ENV_VAR} في ملفات التهيئة للإشارة إلى متغيرات البيئة؛ 2) استبعد ملفات التهيئة الحساسة في .gitignore؛ 3) استخدم K8s Secrets أو Vault لإدارة الأسرار في بيئة الإنتاج.
س كيف يتم دمج تهيئات Profile والتهيئات الافتراضية؟
ج Spring Boot يحمل التهيئة الافتراضية أولاً، ثم يستخدم تهيئة Profile لتجاوز الخصائص المتطابقة. الخصائص المختلفة تُكمل بعضها؛ الخصائص المتطابقة يكون لـ Profile الأسبقية.
س كيف أكتب قائمة في YAML ضمن قسم "Properties"؟
ج orderflow.supported-currencies[0]=USD، orderflow.supported-currencies[1]=EUR. مؤشرات القائمة تبدأ من 0.
س كيف أبدل ملفات Profile ديناميكياً في الكود؟
ج لا يُوصى بتبديل ملفات Profile ديناميكياً في الكود. يجب تحديد ملفات Profile عند التشغيل. إذا كنت بحاجة إلى تبديل التهيئة ديناميكياً أثناء التشغيل، استخدم Spring Cloud Config أو آلية تحديث تهيئة مخصصة.
س ما هي قيود استخدام record كـ ConfigurationProperties؟
ج record غير قابل للتغيير ومناسب للتهيئات للقراءة فقط. Spring Boot 3.x يدعم ربط record. ومع ذلك، لا يمكن استخدامه مع @Validated للتحقق JSR-380 (لأن record يفتقر إلى مُنشئ بدون معاملات)، لذا يجب استخدام صنف بدلاً من ذلك.

📖 ملخص


📝 تمارين

  1. تمرين أساسي (الصعوبة ⭐): قم بتهيئة ملفي Profile لـ OrderFlow—أحدهما لـ dev والآخر لـ prod. يستخدم ملف dev قاعدة بيانات H2 في الذاكرة، بينما يستخدم ملف prod قاعدة بيانات MySQL. بدّل بينهما باستخدام معاملات سطر الأوامر.

  2. مسألة متقدمة (الصعوبة ⭐⭐): استخدم @ConfigurationProperties لإنشاء PaymentGatewayProperties، الذي يتضمن تهيئات مفتاح API لـ Stripe وPayPal؛ حقن قيم المفاتيح عبر متغيرات البيئة.

  3. تحدٍ (الصعوبة: ⭐⭐⭐): نفّذ PropertySource مخصص لتحميل التهيئة من مركز تهيئة بعيد (يمكنك استخدام نقطة نهاية HTTP محاكاة)، وفكّر في الدافع التصميمي وراء تجريد Environment في Spring Boot.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%