از یکپارچه تا میکروسرویس – جامعه dev

من به عنوان یک توسعه دهنده جاوا ، من همیشه علاقه مند به ساختن سیستمهایی هستم که نه تنها کار می کنند ، بلکه به صورت مقیاس پذیر ، انعطاف پذیر و آسان نیز نگهداری می شوند. من روی همه پروژه ها کار کرده ام ، از یکپارچه تجارت گرفته تا استراحت APIS ، اما هیچکدام به اندازه حمله من به میکروسرویس با سیستم رزرواسیون هتلبشر این پروژه به من اجازه تسلط می دهد 3 الگوی انعطاف پذیری (قطع کننده مدار + مجدد) برای ذخایر هتل ، با تداوم پلی گلوت (postgresql + mongoDB)بشر در این مقاله ، من چالش ها ، یادگیری و توصیه های عملی را برای توسعه دهندگان با تجربه جاوا که می خواهند با رویکردی به میکروسرویس ها بپردازند ، با یک رویکرد به اشتراک می گذارم الگوهای طراحی و مقاومت
مقدمه: جستجوی تاب آوری برای یک توسعه دهنده جاوا
با چند سال تجربه در جاوا ، من سیستم های قوی ایجاد کرده ام ، اما ظهور معماری های ابر بومی من را به کشف میکروسرویس ها انگیزه داد. من می خواستم فراتر از متعارف بروم و یاد بگیرم چگونه الگوهای طراحی به عنوان قطع کننده مداربا مجدداً حرف مشخصات آنها می توانند کیفیت برنامه های من را بالا ببرند. هدف من جاه طلب بود: توسعه سیستم ذخیره هتل برای رسیدگی به خرابی های دنیای واقعی با ظرافت ، استفاده از ابزارهای مدرن مانند بوت بهار 3.2.4با مگسبا پس ازبا منگولهبا مقاومت حرف swagger/openapiبشر
او سیستم رزرواسیون هتل این آزمایشگاه شخصی من شد که از سه سرویس دهنده تشکیل شده است: hotel-rooms-service
(مدیریت اتاق) ، hotel-reservations-service
(رزرو) و hotel-payments-service
(پرداخت). این پروژه نه تنها سعی در برنامه ریزی بلکه اتخاذ یک ذهنیت توزیع شده ، ادغام پایداری چند ضلعی و نمایش با اسکلهبشر در طول راه ، من با چالش های قابل توجهی روبرو شدم ، درسهای ارزشمندی را آموختم و لحظات زندگی کردم که باعث شد من به عنوان یک توسعه دهنده از رویکرد خود تجدید نظر کنم.
چالش ها: قایقرانی از طریق پیچ و خم میکروسرویس
انتقال به میکروسرویس ساده نبود. در اینجا من موانع اصلی را که پیدا کردم و درسهایی که مرا به جا گذاشت ، جزئیات می کنم:
چالش 1: محدودیت های میکروسرویس را تعریف کنید
با آمدن از یک محیط یکپارچه ، محدود کردن مسئولیت های هر میکروسرویس برای من دشوار بود. آیا خدمات پرداخت باید رزرو را تأیید کند؟ آیا سرویس اتاق باید در دسترس بودن را مدیریت کند؟ پیچیدگی سیستم های توزیع شده در ابتدا مرا تحت الشعاع قرار داد.
یادگیری: اصلی اتخاذ شده از طراحی به کارگردانی دامنه (DDD) برای ایجاد زمینه های محدود به عنوان مثال ، hotel-rooms-service
او فقط با استفاده از موجودی اتاق متمرکز شد الگوی مشخصات برای فیلتر در دسترس بودن به صورت پویا:
public List<Room> findAvailableRooms(Integer guestCount, Double maxPrice) {
Specification<Room> spec = Specification.where(RoomSpecifications.isAvailable())
.and(RoomSpecifications.hasGuestCapacity(guestCount))
.and(RoomSpecifications.hasMaxPrice(maxPrice));
return roomRepository.findAll(spec);
}
این الگوی منطق فیلتر را محاصره کرده و آن را قابل استفاده مجدد و آسان برای آزمایش ، ستونی از کد تمیز در میکروسرویس ها.
چالش 2: مقاومت در دنیای توزیع شده
خرابی های میکروسرویس اجتناب ناپذیر است: مشکلات شبکه ، زمان انتظار در پایگاه داده ها یا خدمات خارجی کاهش می یابد. اولین تلاش های من برای پردازش پرداخت شکننده بود و قبل از خطاهای گذرا فرو می رفت.
یادگیری: اجرا شده الگوهای انعطاف پذیری (قطع کننده مدار + مجدد) برای ذخایر هتل با هم زدن مقاومتبشر سرویس پرداخت قسمت آزمایش من بود:
@CircuitBreaker(name = "paymentService", fallbackMethod = "processPaymentFallback")
@Retry(name = "paymentService", fallbackMethod = "processPaymentFallback")
public Payment processPayment(String reservationId, double amount) {
logger.info("Procesando pago para reservationId: {}", reservationId);
if (Math.random() > 0.7) {
throw new RuntimeException("Fallo en el servicio de pagos");
}
Payment payment = new Payment(UUID.randomUUID().toString(), reservationId, amount, "COMPLETED");
return paymentRepository.save(payment);
}
public Payment processPaymentFallback(String reservationId, double amount, Throwable t) {
logger.warn("Fallback activado para reservationId: {} debido a: {}", reservationId, t.getMessage());
return new Payment(UUID.randomUUID().toString(), reservationId, amount, "PENDING");
}
- دوره شکن: هنگام باز کردن مدار پس از 5 خطا (50 ٪ از 10 تماس) ، از خرابی آبشار خودداری کنید و تغییر مسیر را تغییر دهید.
- مجدداً: قبل از تسلیم ، 3 بار با بازگشت به نمایی (500ms ، 1000ms ، 2000ms) مجدداً مجدداً مجدداً انجام شود.
-
پیکربندی (در
application.properties
):
resilience4j.circuitbreaker.instances.paymentService.slidingWindowSize=10
resilience4j.circuitbreaker.instances.paymentService.failureRateThreshold=50
resilience4j.retry.instances.paymentService.maxAttempts=3
resilience4j.retry.instances.paymentService.waitDuration=500
resilience4j.retry.instances.paymentService.enableExponentialBackoff=true
این ترکیب باعث شد که سرویس پرداخت قوی باشد و بدون ایجاد تجربه کاربر ، خرابی های گذرا را به وجود آورد.
چالش 3: پایداری polyglot
برای استفاده پس از برای اتاق و رزرو و منگوله برای پرداخت او پیچیدگی اضافه کرد. من تفاوت در مدل سازی داده ها و مدیریت اتصال را دست کم گرفتم.
یادگیری: پایداری چند ضلعی نیاز به برنامه ریزی دارد. به عنوان مثال ، hotel-rooms-service
JPA برای داده های ساخت یافته استفاده شده است:
@Entity
public class Room {
@Id
private String id;
private String type;
private int guestCapacity;
private double price;
private boolean available;
// Getters y setters
}
در عوض ، hotel-payments-service
از انعطاف پذیری MongoDB استفاده کرد:
@Document(collection = "payments")
public class Payment {
@Id
private String id;
private String reservationId;
private double amount;
private String status;
// Getters y setters
}
من یاد گرفتم که انتخاب پایگاه داده ها را با نیازهای دامنه تراز کنم: پس از برای یکپارچگی رابطه ای ، منگوله برای سناریوهای نوشتن بالا به عنوان پرداخت.
چالش 4: dockerizing یک پروژه چند ماژول
نمایش دادن با اسکله وی عدم تجربه من با پروژه های Maven Multule را ارائه داد. اولین تلاش های من با صدای بلند با خطاهایی مانند:
ERROR: failed to solve: maven:3.9.6-openjdk-17: not found
و بعداً:
[FATAL] Non-resolvable parent POM for org.xsoto.springcloud.msvc:hotel-payments-service:0.0.1-SNAPSHOT
یادگیری: ساخت و سازهای چند مرحله ای و مدیریت زمینه بسیار مهم هستند. این است Dockerfile
نهایی برای hotel-payments-service
:
# Stage 1: Build the application
FROM maven:3.9.6-eclipse-temurin-17 AS builder
WORKDIR /app
COPY ../pom.xml ./pom.xml
COPY ./pom.xml ./hotel-payments-service/pom.xml
RUN mvn dependency:go-offline -B
COPY src ./hotel-payments-service/src
RUN mvn clean package -pl hotel-payments-service -am -DskipTests
# Stage 2: Create the runtime image
FROM eclipse-temurin:17.0.10_7-jre-alpine
WORKDIR /app
COPY --from=builder /app/hotel-payments-service/target/hotel-payments-service-1.0-SNAPSHOT.jar app.jar
EXPOSE 8083
ENV SPRING_DATA_MONGODB_URI=mongodb://mongo:27017/payments_db
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
نکته اصلی این بود که pom.xml
پدر و ساخت از فهرست اصلی برای برطرف کردن وابستگی ها.
یک حکایات شخصی: فاجعه با داکر
بگذارید لحظه ای به شما بگویم که من را فروتن تر کرد. در ابتدای فرآیند dockerization ، من متقاعد شدم که ایجاد یک Dockerfile
این نان خورده می شود. من با maven:3.8.6-openjdk-17-slim
با فرض اینکه وجود داشته باشد. اینگونه نبود – ساخت با شکست image not found
بشر من تغییر کردم maven:3.9.6-openjdk-17
، اما خطا همچنان ادامه داشت. سپس ضربه نهایی: وحشتناک Non-resolvable parent POM
بشر ساختار چند ماژول را نادیده گرفته بود ، فقط کپی کردن pom.xml
از ماژول
بعد از ساعت ها تصفیه ، اشتباه خود را کشف کردم: زمینه داکر به آن نیاز داشت pom.xml
پدر ، و باید برچسب ها را در Docker Hub تأیید کند. این یک یادآوری دردناک برای عدم ارائه هیچ چیز به صورت مناسب بود. اما این ناامیدی باعث شد من بر ساخت چند مرحله ای تسلط داشته باشم ، .dockerignore
حرف docker-compose
بشر این احمقانه به من آموخت که جزئیات حاوی را ارزیابی کنم.
تجربه عملی: پیوستن به قطعات
ساخت سیستم رزرواسیون هتل لازم برای ادغام بوت بهار 3.2.4با مگسبا پس ازبا منگولهبا مقاومت حرف swagger/openapiبشر من موفق شدم:
version: '3.8'
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
mongo:
image: mongo:6
ports:
- "27017:27017"
hotel-rooms-service:
build:
context: .
dockerfile: hotel-rooms-service/Dockerfile
ports:
- "8081:8081"
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/rooms_db
hotel-reservations-service:
build:
context: .
dockerfile: hotel-reservations-service/Dockerfile
ports:
- "8082:8082"
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/reservations_db
hotel-payments-service:
build:
context: .
dockerfile: hotel-payments-service/Dockerfile
ports:
- "8083:8083"
environment:
SPRING_DATA_MONGODB_URI: mongodb://mongo:27017/payments_db
-
swagger/openapi:
هر سرویس یک رابط swagger ارائه می دهد (به عنوان مثال ،http://localhost:8083/swagger-ui.html
) ، تست تست های API. -
شواهد:
تست های جامع الگوهای تاب آوری معتبر:
@Test
void testProcessPayment_FallbackTriggered() {
String reservationId = "res1";
double amount = 150.0;
circuitBreaker.transitionToOpenState();
Payment result = paymentService.processPayment(reservationId, amount);
assertEquals("PENDING", result.getStatus());
}
نکاتی برای توسعه دهندگان جاوا در انتقال
برای توسعه دهندگان جاوا که می خواهند جهش به میکروسرویس ها را انجام دهند ، در اینجا نکات عملی وجود دارد:
-
تسلط بر الگوهای طراحی:
- یاد می گیرد قطع کننده مداربا مجدداً حرف مشخصاتبشر آنها فقط تئوری نیستند – آنها مشکلات واقعی را برطرف می کنند. برای نمونه های عملی ، مستندات Resilience4J را کاوش کنید.
- نکته: پارامترهای آزمایش مجدد را با دقت تنظیم کنید تا خدمات خارجی اشباع نشود.
-
پایداری چندگلوت را اتخاذ کنید:
- پایگاه داده ها را مطابق با دامنه انتخاب کنید. در سیستم ما ، پس از یکپارچگی مطمئن برای اتاق ها ، در حالی که منگوله او داده های پرداخت نوشتن بالا را اداره کرد.
- برای ساده کردن کد مخزن از انتزاع داده های بهار استفاده کنید.
-
Docker Con Docker:
- از ساختهای چند مرحله ای برای تصاویر سبک استفاده کنید. تصاویر آلپ مانند
eclipse-temurin:17.0.10_7-jre-alpine
آنها 200 مگابایت پوند برای خدمات ذخیره کردند. - همیشه قبل از ساخت ، برچسب ها را در Docker تأیید کنید.
- مثال: الف
.dockerignore
خوب پیکربندی شده:
target/ *.jar *.log .idea/
- از ساختهای چند مرحله ای برای تصاویر سبک استفاده کنید. تصاویر آلپ مانند
-
بدون استراحت امتحان کنید:
- برای الگوهای انعطاف پذیری تست ها را بنویسید. شکست را در اعتبارسنجی های خطای شبیه سازی شبیه سازی می کند.
- برای اندازه گیری پوشش و برجسته کردن کار خود از ابزارهایی مانند Jacoco استفاده کنید.
-
از ابتدا خودکار کنید:
- یک خط لوله لوله/CD (به عنوان مثال ، اقدامات GitHub) را برای ساخت و امتحان کردن تصاویر Docker به طور خودکار پیکربندی کنید.
- مثال: یک جریان اساسی برای ساخت تصاویر:
name: Build Docker Images on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: docker-compose build
-
از خطاها بیاموزید:
- از خطاهای مانند نترسید
image not found
ایnon-resolvable POM
بشر آنها فرصت هایی برای رشد هستند. - برای مستند کردن آنچه که کار کرده و چه چیزی نیست ، یک سابقه تصفیه بگیرید.
- از خطاهای مانند نترسید
نتیجه گیری: سفر به ارزش
انتقال به میکروسرویس با سیستم رزرواسیون هتل دیدگاه من به عنوان یک توسعه دهنده تغییر کرد. او به من آموخت که با استفاده از سیستم های انعطاف پذیر و مقیاس پذیر بسازم 3 الگوی انعطاف پذیری (قطع کننده مدار + مجدد) برای ذخایر هتل ، با تداوم پلی گلوت (postgresql + mongoDB)بشر چالش ها – محدودیت ها را تعریف کنید ، بر انعطاف پذیری حاکم باشید و بر داکر غلبه کنید – آنها سخت اما پاداش دهنده بودند. هر خطا ، از برچسب های تصاویر غیر موجود گرفته تا مشکلات مربوط به POM ، مهارت ها و ذهنیت من را تصفیه کرد.
به همکاران توسعه دهنده و توسعه دهنده جاوا: غوطه ور در میکروسرویس و الگوهای طراحیبشر تجربه چکمه بهاریبا مقاومت حرف اسکلهبشر این جاده می تواند مجروح شود ، اما توانایی ایجاد سیستمهایی که تحت فشار رونق داشته باشند ، ارزش هر تلاش را دارند. کوچک ، با دقت را امتحان کنید و بدون ترس خودکار کنید. پروژه بعدی او می تواند حرفه او را تعریف کند.
🔍 آیا دوست دارید کد را در عمل ببینید؟
کاوش کردن بهار در GitHub:
👉 github.com/xsoto-developer/springresilienthotel
ماجراجویی بعدی شما در خدمات میکروسرویس چه خواهد بود؟ ایده های خود را در نظرات به اشتراک بگذارید یا در GitHub با من تماس بگیرید!
✨ جایزه: احساس راحتی کنید که یک ⭐ را ترک کنید یا با پیشنهادات یک مسئله را باز کنید. من از بازخورد قدردانی می کنم!
این مقاله به زبان انگلیسی نیز موجود است