יישומי Java רבים לוקחים 10 שניות לאתחול וצורכים 500 MB של זיכרון RAM. בסביבת Kubernetes זה קריטי: אתחול איטי הורג את ה-auto-scaling, ומשאבים עודפים מייקרים את חשבונות הענן. חשבנו מחדש על ארכיטקטורת ה-backend—אנחנו משתמשים ב-Quarkus, framework המותאם ל-cloud-native. למהנדסים שלנו יש ניסיון של 10+ שנים ב-Java ו-50+ פרויקטים שהושלמו. אנחנו מבטיחים הפחתה של פי 3–5 בעלויות התשתית באמצעות קומפילציה native. לדוגמה, לקוח קמעונאי אחד חסך $4000 בחודש בהוצאות ענן לאחר מעבר מ-Spring Boot.
איך Quarkus חוסך משאבים?
Quarkus מהדר יישומים לתמונות native באמצעות Quarkus. זמן אתחול קר—0.01–0.1 שניות לעומת 2–10 שניות ב-Spring Boot. צריכת זיכרון—20–60 MB לעומת 200–500 MB. אלה לא רק מספרים: אתחול מהיר מאפשר scaling אופקי אמיתי ב-Kubernetes, ובסביבת Serverless זה ההבדל בין פתרון שעובד לפתרון שלא.
| פרמטר | Quarkus (native) | Spring Boot (JVM) |
|---|---|---|
| זמן אתחול | 0.01–0.1 שניות | 2–10 שניות |
| שימוש בזיכרון RAM | 20–60 MB | 200–500 MB |
| גודל תמונת Docker | ~100 MB | ~500 MB |
| מוכנות ל-Kubernetes | מובנית | דורש כוונון |
Quarkus מתחיל פי 10 מהר יותר ומשתמש בפי 5 פחות זיכרון. הוא משתמש במפרטים מוכרים: JAX-RS, CDI, JPA, MicroProfile. המעבר מ-Spring אורך כמה ימים. הבדלים עיקריים: DI דרך CDI (@ApplicationScoped), REST דרך RESTEasy Reactive (JAX-RS), ORM דרך Hibernate עם Panache (Active Record או Repository).
איך עובד פיתוח עם Quarkus?
אנחנו מתחילים בהגדרת הפרויקט ו-Dev Services: PostgreSQL, Kafka, Redis מופעלים אוטומטית ב-Docker. Migrations דרך Flyway. ל-Quarkus Dev Mode יש אחד ממנגנוני ה-hot-reload הטובים ביותר במערכת האקולוגית של Java: שינויים מוחלים ללא אתחול.
דוגמת קוד: entity עם Panache
// Product entity с Panache Active Record
@Entity
@Table(name = "products")
public class Product extends PanacheEntityBase {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
@Column(nullable = false, length = 255)
public String name;
@Column(unique = true)
public String slug;
@Column(precision = 10, scale = 2)
public BigDecimal price;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id")
public Category category;
public boolean isActive = true;
@Column(columnDefinition = "jsonb")
@Type(JsonType.class)
public Map<String, Object> attributes = new HashMap<>();
// Статические методы Panache
public static List<Product> findActive() {
return list("isActive", true);
}
public static Page<Product> findActiveByCategory(Long categoryId, int page, int size) {
return find("category.id = ?1 and isActive = true", categoryId)
.page(page, size);
}
}Resources (controllers) מיושמים עם RESTEasy Reactive, התומך באופן native בפעולות non-blocking:
@Path("/api/v1/products")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ApplicationScoped
public class ProductResource {
@Inject
ProductService productService;
@GET
@Authenticated
public Response list(
@QueryParam("page") @DefaultValue("0") int page,
@QueryParam("size") @DefaultValue("20") @Max(100) int size,
@QueryParam("category_id") Long categoryId) {
PanacheQuery<Product> query = categoryId != null
? Product.find("category.id = ?1 and isActive = true", categoryId)
: Product.find("isActive", true);
List<Product> products = query
.page(page, size)
.list();
long total = query.count();
return Response.ok(new PagedResponse<>(
products.stream().map(ProductDto::from).toList(),
page,
size,
total
)).build();
}
@POST
@RolesAllowed("admin")
@Transactional
public Response create(@Valid CreateProductRequest request) {
Product product = productService.create(request);
return Response.status(Response.Status.CREATED)
.entity(ProductDto.from(product))
.build();
}
@GET
@Path("/{id}")
public ProductDto get(@PathParam("id") Long id) {
return Product.findByIdOptional(id)
.map(ProductDto::from)
.orElseThrow(NotFoundException::new);
}
@DELETE
@Path("/{id}")
@RolesAllowed("admin")
@Transactional
public Response delete(@PathParam("id") Long id) {
boolean deleted = Product.deleteById(id);
return deleted ? Response.noContent().build() : Response.status(404).build();
}
} איך להגדיר אבטחה?
אנחנו מגדירים אבטחה דרך SmallRye JWT. הגדרה ב-// Product entity с Panache Active Record @Entity @Table(name = "products") public class Product extends PanacheEntityBase { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long id; @Column(nullable = false, length = 255) public String name; @Column(unique = true) public String slug; @Column(precision = 10, scale = 2) public BigDecimal price; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "category_id") public Category category; public boolean isActive = true; @Column(columnDefinition = "jsonb") @Type(JsonType.class) public Map<String, Object> attributes = new HashMap<>(); // Статические методы Panache public static List<Product> findActive() { return list("isActive", true); } public static Page<Product> findActiveByCategory(Long categoryId, int page, int size) { return find("category.id = ?1 and isActive = true", categoryId) .page(page, size); } } :
mp.jwt.verify.publickey.location=META-INF/resources/publicKey.pem
mp.jwt.verify.issuer=https://myapp.com
quarkus.http.auth.permission.authenticated.paths=/api/v1/*
quarkus.http.auth.permission.authenticated.policy=authenticated
quarkus.http.auth.permission.public.paths=/api/v1/auth/*,/api/v1/products
quarkus.http.auth.permission.public.policy=permit מה מספקת קומפילציה native?
אנחנו מגדירים build native פעם אחת ב-CI/CD. פקודת build:
./mvnw package -Pnative -DskipTests # или через Docker ./mvnw package -Pnative -Dquarkus.native.container-build=true באתחול production, מקבלים binary שמופעל תוך מילישניות. זה חשוב במיוחד עבור פונקציות Serverless ו-pods זמניים ב-Kubernetes.
מקרה בוחן: Backend למסחר אלקטרוני על Quarkus
יישמנו קטלוג עם סינון ועגלת קניות עבור רשת קמעונאית גדולה. פרויקט Spring Boot המקורי הופעל תוך 8 שניות וצרך 400 MB זיכרון RAM. לאחר המעבר ל-Quarkus native: אתחול קר 0.05 שניות, זיכרון 45 MB. שרת זול עם 2 ליבות ו-4 GB RAM מתמודד עם עומס שיא של 1000 RPS. החיסכון בענן היה פי 4—מעל $4000 בחודש.
תהליך העבודה
- ניתוח דרישות ומפרט טכני. אנו מתעדים דרישות API, entities ואינטגרציות.
- הקמת פרויקט: Quarkus 3.x, Java 21, PostgreSQL, Redis, Docker Compose.
- פיתוח entities ו-resources באמצעות Panache ו-RESTEasy Reactive.
- יישום הרשאות (JWT, OAuth2, Keycloak).
- אינטגרציה עם שירותים חיצוניים דרך REST או תורי הודעות.
- כתיבת בדיקות (QuarkusTest + RestAssured).
- הגדרת CI/CD עם build native ופריסה ל-Kubernetes.
- מסירת תיעוד, מאגר קוד, אישורי גישה והדרכה לצוות.
מה כלול
- פיתוח REST API עם תיעוד OpenAPI
- הגדרת הרשאות (JWT, OAuth2, Keycloak)
- Migrations למסד נתונים (Flyway/Liquibase)
- אינטגרציה עם תורי הודעות (Kafka, RabbitMQ) וקאש (Redis)
- כתיבת בדיקות (QuarkusTest + RestAssured)
- צינור CI/CD עם build native ופריסה ל-Kubernetes
- מסירת מאגר קוד, תיעוד, אישורי גישה והדרכה לצוות הלקוח
לוחות זמנים משוערים
| שלב | משך |
|---|---|
| הקמת פרויקט + Dev Services + migrations | 3–5 ימים |
| Entities (Panache) + Resources | 1–1.5 שבועות |
| אבטחה + JWT | 3–5 ימים |
| Reactive endpoints | +1 שבוע |
| הגדרת build native | 2–5 ימים |
| בדיקות | שבוע אחד |
| Backend ארגוני (מחזור מלא) | 7–14 שבועות |
צרו קשר להערכת פרויקט. קבלו ייעוץ על מעבר מ-Spring Boot או התחלת פרויקט חדש. אנחנו מבטיחים לוחות זמנים שקופים ותוצאות העומדות ב-Core Web Vitals.







