انتقل إلى المحتوى الرئيسي

اختبار: Spring Cloud والخدمات المصغرة

اختبر معرفتك بهندسة الخدمات المصغرة وSpring Cloud.

30 سؤالاً - انقر على كل سؤال لكشف الإجابة.


الأسئلة 1-10: هندسة الخدمات المصغرة​

السؤال 1: ما الفرق بين النظام الأحادي والخدمات المصغرة؟

الإجابة:

النظام الأحاديالخدمات المصغرة
تطبيق واحدخدمات مستقلة
قاعدة بيانات واحدةقاعدة بيانات لكل خدمة
نشر شاملنشر مستقل
توسيع شاملتوسيع لكل خدمة
بسيط في البدايةمعقد في البداية
ترابط قويترابط ضعيف

السؤال 2: متى تختار هندسة الخدمات المصغرة؟

الإجابة:

  • فريق كبير (فرق متعددة)
  • الحاجة إلى توسيع متباين
  • تقنيات مختلفة لكل خدمة
  • عمليات نشر متكررة ومستقلة
  • تحمل الأعطال لكل خدمة

تجنبها لـ: الفرق الصغيرة، النماذج الأولية، التطبيقات البسيطة.


السؤال 3: ما هو اكتشاف الخدمة؟

الإجابة: آلية تتيح للخدمات العثور على بعضها البعض ديناميكياً دون تكوين ثابت لعناوين IP.

الخدمة A: "أين الخدمة B؟"
↓
خادم Eureka: "الخدمة B موجودة في 192.168.1.10:8081 و192.168.1.11:8081"
↓
الخدمة A تستدعي الخدمة B

السؤال 4: ما هو API Gateway؟

الإجابة: نقطة دخول واحدة لجميع الخدمات المصغرة:

  • التوجيه إلى الخدمات
  • توثيق مركزي
  • تحديد المعدل
  • موازنة الحمل
  • تسجيل/مراقبة
العميل → API Gateway → الخدمة A
→ الخدمة B
→ الخدمة C

السؤال 5: ما هو Circuit Breaker؟

الإجابة: نمط مرونة "يقطع" الاستدعاءات إلى خدمة معطلة:

الحالات:
CLOSED → استدعاءات عادية
OPEN → استدعاءات محظورة (تراجع)
HALF_OPEN → اختبار الاسترداد

يمنع تسلسل الأعطال.

السؤال 6: ما هو نمط Saga؟

الإجابة: إدارة المعاملات الموزعة عبر سلسلة من المعاملات المحلية مع تعويضات:

الطلب → الدفع → المخزون → الشحن
↓ (فشل)
تعويض: استرداد

كل خدمة تدير معاملتها ويمكنها الإلغاء (التعويض) إذا لزم الأمر.


السؤال 7: ما هو CQRS؟

الإجابة: فصل عمليات القراءة والكتابة:

الأوامر (الكتابة) → خدمة الأوامر → قاعدة بيانات الكتابة
الاستعلامات (القراءة) → خدمة الاستعلام → قاعدة بيانات القراءة (محسنة)

يسمح بتحسين كل جانب بشكل مستقل.


السؤال 8: ما هو Event Sourcing؟

الإجابة: تخزين جميع الأحداث بدلاً من الحالة الحالية:

الأحداث:
1. UserCreated {id: 1, name: "John"}
2. UserEmailChanged {id: 1, email: "john@new.com"}
3. UserDeleted {id: 1}

الحالة = إعادة تشغيل جميع الأحداث

الفوائد: تدقيق كامل، إعادة بناء الحالة، إعادة تشغيل الأحداث.


السؤال 9: ما هي العوامل الـ 12 لتطبيق سحابي أصلي؟

الإجابة:

  1. Codebase: مستودع واحد، عمليات نشر متعددة
  2. Dependencies: معلنة ومعزولة
  3. Config: في البيئة
  4. Backing services: تعامل كموارد مرفقة
  5. Build, release, run: مراحل منفصلة بصرامة
  6. Processes: بدون حالة
  7. Port binding: ذاتي الاحتواء
  8. Concurrency: توسيع أفقي
  9. Disposability: بدء/إيقاف سريع
  10. Dev/prod parity: بيئات متشابهة
  11. Logs: تدفق الأحداث
  12. Admin processes: مهام لمرة واحدة

السؤال 10: كيف تدير الاتصال بين الخدمات؟

الإجابة:

النوعالبروتوكولالاستخدام
متزامنREST/gRPCاستجابة فورية مطلوبة
غير متزامنRabbitMQ/Kafkaفك الارتباط، الأحداث

يفضل غير المتزامن عندما يكون ذلك ممكنًا للمرونة.


الأسئلة 11-20: Spring Cloud​

السؤال 11: كيف تقوم بتكوين Eureka Server؟

الإجابة:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication { }
server:
port: 8761

eureka:
client:
register-with-eureka: false
fetch-registry: false

السؤال 12: كيف تسجل خدمة في Eureka؟

الإجابة:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
spring:
application:
name: user-service

eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/

السؤال 13: كيف تستدعي خدمة أخرى باستخدام RestTemplate وموازنة الحمل؟

الإجابة:

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}

@Service
public class OrderService {

private final RestTemplate restTemplate;

public User getUser(Long id) {
// استخدم اسم الخدمة، وليس عنوان URL
return restTemplate.getForObject(
"http://user-service/api/users/" + id, User.class);
}
}

السؤال 14: كيف تستخدم OpenFeign لاستدعاءات بين الخدمات؟

الإجابة:

@EnableFeignClients
@SpringBootApplication
public class OrderApplication { }

@FeignClient(name = "user-service")
public interface UserClient {

@GetMapping("/api/users/{id}")
User getUser(@PathVariable Long id);
}

@Service
public class OrderService {

private final UserClient userClient;

public Order createOrder(OrderRequest req) {
User user = userClient.getUser(req.getUserId());
// ...
}
}

السؤال 15: كيف تقوم بتكوين Spring Cloud Config Server؟

الإجابة:

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication { }
server:
port: 8888

spring:
cloud:
config:
server:
git:
uri: https://github.com/org/config-repo
default-label: main

السؤال 16: كيف يستخدم خدمة العميل Config Server؟

الإجابة:

# bootstrap.yml
spring:
application:
name: user-service
cloud:
config:
uri: http://localhost:8888

تقوم الخدمة باسترجاع user-service.yml من Config Server.


السؤال 17: كيف تقوم بتكوين Spring Cloud Gateway؟

الإجابة:

spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1

- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
- Method=GET,POST

السؤال 18: كيف تضيف فلتر عالمي في Gateway؟

الإجابة:

@Component
public class LoggingFilter implements GlobalFilter, Ordered {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("Request: {} {}",
exchange.getRequest().getMethod(),
exchange.getRequest().getPath());

return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("Response: {}",
exchange.getResponse().getStatusCode());
}));
}

@Override
public int getOrder() {
return -1;
}
}

السؤال 19: كيف تقوم بتكوين Resilience4j Circuit Breaker؟

الإجابة:

resilience4j:
circuitbreaker:
instances:
userService:
slidingWindowSize: 10
failureRateThreshold: 50
waitDurationInOpenState: 10000
permittedNumberOfCallsInHalfOpenState: 3
@CircuitBreaker(name = "userService", fallbackMethod = "fallback")
public User getUser(Long id) {
return userClient.getUser(id);
}

public User fallback(Long id, Exception ex) {
return new User(id, "Fallback User", "N/A");
}

السؤال 20: كيف تقوم بتكوين إعادة المحاولة مع Resilience4j؟

الإجابة:

resilience4j:
retry:
instances:
userService:
maxAttempts: 3
waitDuration: 1000
enableExponentialBackoff: true
exponentialBackoffMultiplier: 2
@Retry(name = "userService")
@CircuitBreaker(name = "userService", fallbackMethod = "fallback")
public User getUser(Long id) {
return userClient.getUser(id);
}

الأسئلة 21-30: الأنماط المتقدمة​

السؤال 21: كيف تنفذ تراجع مع Feign؟

الإجابة:

@FeignClient(name = "user-service", fallbackFactory = UserClientFallback.class)
public interface UserClient {
@GetMapping("/api/users/{id}")
User getUser(@PathVariable Long id);
}

@Component
public class UserClientFallback implements FallbackFactory<UserClient> {

@Override
public UserClient create(Throwable cause) {
return id -> new User(id, "Fallback", "N/A");
}
}

السؤال 22: كيف تنفذ تحديد المعدل في Gateway؟

الإجابة:

spring:
cloud:
gateway:
routes:
- id: api-route
uri: lb://api-service
predicates:
- Path=/api/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
key-resolver: "#{@userKeyResolver}"
@Bean
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getRemoteAddress().getHostName()
);
}

السؤال 23: كيف تقوم بتحديث التكوين بشكل مباشر؟

الإجابة:

@RefreshScope
@RestController
public class ConfigController {

@Value("${app.message}")
private String message;

@GetMapping("/message")
public String getMessage() {
return message;
}
}
# تفعيل التحديث
curl -X POST http://localhost:8080/actuator/refresh

أو باستخدام Spring Cloud Bus لنشر التحديث إلى جميع الخدمات.


السؤال 24: كيف تتبع الطلبات الموزعة؟

الإجابة: باستخدام Micrometer Tracing (سابقاً Sleuth) + Zipkin:

<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
</dependency>
management:
tracing:
sampling:
probability: 1.0
zipkin:
tracing:
endpoint: http://zipkin:9411/api/v2/spans

كل طلب يحتوي على traceId فريد يتم تمريره بين الخدمات.


السؤال 25: كيف تؤمن الاتصالات بين الخدمات؟

الإجابة:

  1. mTLS: شهادات متبادلة
  2. JWT propagation: تمرير التوكن بين الخدمات
  3. Service mesh: Istio، Linkerd
  4. Network policies: Kubernetes
// تمرير JWT مع Feign
@Configuration
public class FeignConfig {

@Bean
public RequestInterceptor authInterceptor() {
return template -> {
String token = SecurityContextHolder.getContext()
.getAuthentication().getCredentials().toString();
template.header("Authorization", "Bearer " + token);
};
}
}

السؤال 26: كيف تدير الأسرار في الخدمات المصغرة؟

الإجابة:

  1. Spring Cloud Config مع التشفير
  2. Vault (HashiCorp)
  3. Kubernetes Secrets
  4. AWS Secrets Manager / Azure Key Vault
# Config Server مع التشفير
spring:
cloud:
config:
server:
encrypt:
enabled: true

encrypt:
key: ${ENCRYPT_KEY}

السؤال 27: كيف تدير إصدارات API؟

الإجابة:

  1. URL versioning: /api/v1/users
  2. Header versioning: Accept: application/vnd.api.v1+json
  3. Query param: /api/users?version=1
@RestController
@RequestMapping("/api/v1/users")
public class UserControllerV1 { }

@RestController
@RequestMapping("/api/v2/users")
public class UserControllerV2 { }

السؤال 28: كيف تنشر الخدمات المصغرة باستخدام Kubernetes؟

الإجابة:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: user-service:1.0
ports:
- containerPort: 8080
env:
- name: EUREKA_SERVER
value: "http://eureka:8761/eureka"
---
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- port: 80
targetPort: 8080

السؤال 29: كيف تراقب الخدمات المصغرة؟

الإجابة:

  1. مقاييس: Prometheus + Grafana
  2. سجلات: ELK Stack (Elasticsearch، Logstash، Kibana)
  3. تتبع: Zipkin / Jaeger
  4. تنبيه: Prometheus Alertmanager

لوحة تحكم مركزية مع:

  • زمن الاستجابة لكل خدمة
  • معدل الخطأ
  • الإنتاجية
  • التبعيات

السؤال 30: ما هي أفضل الممارسات للخدمات المصغرة؟

الإجابة:

  1. Bounded context: خدمة واحدة = مجال عمل واحد
  2. Database per service: لا توجد قاعدة بيانات مشتركة
  3. API contracts: OpenAPI/Swagger
  4. Idempotence: عمليات قابلة للتكرار بدون تأثير
  5. Healthchecks: Actuator لكل خدمة
  6. Circuit breakers: حماية من الأعطال
  7. Async communication: يفضل عند الإمكان
  8. Centralized logging: ارتباط بواسطة traceId
  9. Infrastructure as Code: Terraform، Helm
  10. Feature flags: نشر تدريجي

النتيجة​

النتيجةالمستوى
27-30ممتاز - إتقان الخدمات المصغرة
21-26جيد - بعض المراجعات
15-20متوسط - أعد قراءة الفصول
أقل من 15بحاجة إلى مراجعة

العودة إلى الوحدة 13