Багато Java-застосунків стартують 10 секунд і споживають 500 МБ пам'яті. У Kubernetes це критично: повільний старт вбиває автоскейлінг, а зайві ресурси збільшують рахунок за хмару. Ми переосмислили підхід до бекенду — використовуємо Quarkus, фреймворк, оптимізований для cloud-native. Наші інженери мають 10+ років досвіду в Java та 50+ реалізованих проєктів. Гарантуємо скорочення витрат на інфраструктуру в 3–5 разів завдяки нативній компіляції. Наприклад, один клієнт-рітейлер після міграції з Spring Boot заощадив $4000 на місяць на хмарних витратах.
Як Quarkus економить ресурси?
Quarkus компілює застосунок у native image через Quarkus. Час холодного старту — 0.01–0.1 секунди проти 2–10 секунд у Spring Boot. Споживання пам'яті — 20–60 МБ проти 200–500 МБ. Це не просто цифри: швидкий старт означає реальне горизонтальне масштабування в Kubernetes, а для Serverless це різниця між робочим і неробочим рішенням.
| Параметр | Quarkus (native) | Spring Boot (JVM) |
|---|---|---|
| Час старту | 0.01–0.1 с | 2–10 с |
| Споживання RAM | 20–60 МБ | 200–500 МБ |
| Розмір Docker-образу | ~100 МБ | ~500 МБ |
| Готовність до 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. Міграції через Flyway. Dev Mode Quarkus — один із найкращих hot-reload механізмів у Java-екосистемі: зміни застосовуються без перезапуску.
Приклад коду: сутність з 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);
}
}
Ресурси (контролери) реалізуємо з RESTEasy Reactive, що підтримує неблокуючі операції нативно:
@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();
}
}
Як налаштувати безпеку?
Security налаштовуємо через SmallRye JWT. Конфігурація в application.properties:
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 налаштовуємо один раз у CI/CD. Команда збірки:
./mvnw package -Pnative -DskipTests
# або через Docker
./mvnw package -Pnative -Dquarkus.native.container-build=true
На старті продакшену ви отримуєте бінарник, який запускається за мілісекунди. Це особливо важливо для функцій Serverless та ефемерних подів у Kubernetes.
Приклад: інтернет-магазин на Quarkus
Реалізували каталог з фільтрацією та кошик для великого рітейлера. Вихідний Spring Boot-проект стартував 8 секунд, споживав 400 МБ RAM. Після міграції на Quarkus native: холодний старт — 0.05 с, пам'ять — 45 МБ. Дешевий сервер на 2 ядра та 4 ГБ RAM справляється з піковим навантаженням 1000 RPS. Економія на хмарі склала 4 рази — понад $4000 на місяць.
Процес роботи
- Аналітика та складання ТЗ. Фіксуємо вимоги до API, сутностей, інтеграцій.
- Налаштування проекту: Quarkus 3.x, Java 21, PostgreSQL, Redis, Docker Compose.
- Розробка сутностей та ресурсів з використанням Panache та RESTEasy Reactive.
- Реалізація авторизації (JWT, OAuth2, Keycloak).
- Інтеграція з зовнішніми сервісами через REST або черги.
- Написання тестів (QuarkusTest + RestAssured).
- Налаштування CI/CD з native build та деплоєм у Kubernetes.
- Передача документації, репозиторію, доступів та навчання команди.
Що входить в роботу
- Розробка REST API з документацією OpenAPI
- Налаштування авторизації (JWT, OAuth2, Keycloak)
- Міграції бази даних (Flyway/Liquibase)
- Інтеграція з чергами (Kafka, RabbitMQ) та кешем (Redis)
- Написання тестів (QuarkusTest + RestAssured)
- CI/CD pipeline з native build та деплоєм у Kubernetes
- Передача репозиторію, документації, доступів та навчання команди замовника
Терміни (орієнтовно)
| Етап | Термін |
|---|---|
| Налаштування проекту + Dev Services + міграції | 3–5 днів |
| Entities (Panache) + Resources | 1–1,5 тижні |
| Security + JWT | 3–5 днів |
| Reactive endpoints | +1 тиждень |
| Native build налаштування | 2–5 днів |
| Тести | 1 тиждень |
| Корпоративний бекенд (повний цикл) | 7–14 тижнів |
Зв'яжіться з нами для оцінки вашого проекту. Отримайте консультацію щодо міграції з Spring Boot або старту нового проекту. Ми гарантуємо прозорі терміни та результат, що відповідає Core Web Vitals.







