Learning/TIL / / 2025. 3. 25. 15:17

[250325] Aiven & 프로젝트

Aiven.io는 오픈소스 데이터 인프라를 관리형 클라우드 서비스로 제공하는 플랫폼입니다. 신입 자바 백엔드 개발자에게 다음과 같은 핵심 가치를 제공합니다.

 

데이터 인프라(Data Infrastructure)란?

 

데이터를 수집, 저장, 처리, 분석하기 위한 하드웨어/소프트웨어 시스템의 집합체입니다.

 

  • 핵심 구성 요소:
    • 데이터베이스 (예: PostgreSQL, MySQL) → 트랜잭션 데이터 저장
    • 스트리밍 시스템 (예: Apache Kafka) → 실시간 데이터 파이프라인 구축
    • 분석 도구 (예: InfluxDB, Grafana) → 데이터 시각화 및 모니터링
    • 캐싱 시스템 (예: Redis) → 고성능 데이터 조회

 


Aiven의 주요 서비스와 Java 개발자 연동

 

1. PostgreSQL (관계형 데이터베이스)

  • 연동 코드 예시 (Spring Boot + JPA):
    // Entity 클래스
    @Entity
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;
        // Getter & Setter
    }
    
    // Repository
    public interface UserRepository extends JpaRepository<User, Long> {}
    # application.properties
    spring.datasource.url=jdbc:postgresql://[Aiven-PostgreSQL-Endpoint]:[포트]/[DB명]
    spring.datasource.username=[사용자명]
    spring.datasource.password=[비밀번호]
    spring.jpa.hibernate.ddl-auto=update
    데이터베이스: PostgreSQL, MySQL, Redis 등 → JPA/Hibernate로 연동 가능, 자바 애플리케이션과 원활한 통합

 

2. Apache Kafka (실시간 스트리밍)

  • 연동 코드 예시 (Spring Kafka):
    // Producer
    @Service
    public class KafkaProducer {
        @Autowired
        private KafkaTemplate<String, String> kafkaTemplate;
    
        public void sendMessage(String topic, String message) {
            kafkaTemplate.send(topic, message);
        }
    }
    
    // Consumer
    @Service
    public class KafkaConsumer {
        @KafkaListener(topics = "test-topic", groupId = "my-group")
        public void listen(String message) {
            System.out.println("Received: " + message);
        }
    }
    # application.properties
    spring.kafka.bootstrap-servers=[Aiven-Kafka-Endpoint]:[포트]
    spring.kafka.security.protocol=SSL
    spring.kafka.ssl.trust-store-location=classpath:kafka.truststore.jks
    spring.kafka.ssl.trust-store-password=[패스워드]
    스트리밍 & 메시징: Apache Kafka → Kafka Client 라이브러리를 사용해 프로듀서/컨슈머 구현 가능.

 

3. Redis  ( 캐싱 )

 

  • 연동 코드 예시 (Spring Data Redis):
    @Service
    public class RedisService {
        @Autowired
        private RedisTemplate<String, String> redisTemplate;
    
        public void setValue(String key, String value) {
            redisTemplate.opsForValue().set(key, value);
        }
    
        public String getValue(String key) {
            return redisTemplate.opsForValue().get(key);
        }
    }

 

 


Aiven의 장점

 

  1. 자동화된 운영:
    • 백업, 스케일링, 패치를 Aiven이 관리 → 개발자는 비즈니스 로직에 집중.
    • 예: PostgreSQL의 Auto-Failover로 서비스 중단 시간 최소화.
  2. 보안:
    • SSL/TLS 암호화, VPC Peering 기본 제공 → 보안 설정 코드 불필요.
  3. 멀티클라우드 통합:
    • AWS, GCP, Azure에서 동일한 설정으로 서비스 배포 가능 → 벤더 종속성 탈피.

 


시각자료 예시

 

1. 아키텍처 다이어그램

[Java 애플리케이션]  
       │  
       ▼ (Kafka Producer)  
[Apache Kafka (Aiven)]  
       │  
       ▼ (Kafka Consumer)  
[PostgreSQL (Aiven)]  
       │  
       ▼ (JPA/Hibernate)  
[사용자 데이터 저장/조회]  

 

2. Kafka + Spring Boot 데이터 흐름

  1. Java 애플리케이션 → Kafka로 메시지 전송 (KafkaTemplate).
  2. Kafka → 다른 마이크로서비스가 메시지 소비 (@KafkaListener).
  3. 데이터 최종 저장을 위해 PostgreSQL에 연동.

활용 시나리오

 

  • 이커머스 플랫폼:
    • 주문 데이터 → Kafka로 실시간 처리 → PostgreSQL에 저장 → Redis로 상품 정보 캐싱.
  • 모니터링 시스템:
    • 애플리케이션 로그 → InfluxDB 저장 → Grafana로 대시보드 구축.

추천 학습 자료

 

Aiven을 사용하면 인프라 관리 시간 80% 절약하고, Java 코드에만 집중할 수 있습니다. 🚀

 


 

Aiven을 활용한 자바 백엔드 포트폴리오 프로젝트를 구체화하기 위해, 실시간 알림 시스템을 중심으로 단계별 구현 계획과 학습 포인트를 제시드립니다. 이 프로젝트는 현대 애플리케이션에서 필수적인 실시간 기능을 다루며, Aiven의 Kafka와 PostgreSQL을 효과적으로 활용할 수 있습니다.


프로젝트: 실시간 소셜 미디어 알림 시스템

📌 기술 스택

  • Backend: Java 17, Spring Boot 3.x
  • Data Streaming: Aiven Kafka
  • Database: Aiven PostgreSQL
  • Real-time Communication: WebSocket (SockJS + STOMP)
  • 추가 도구: Spring Data JPA, Lombok, MapStruct

🚀 단계별 구현 전략

1. Aiven 서비스 설정

  • Aiven Console에서 Kafka & PostgreSQL 인스턴스 생성
  • Kafka Topic 생성: user-activity, notifications
  • PostgreSQL DB에 notifications 테이블 설계:
  • CREATE TABLE notifications ( id UUID PRIMARY KEY, user_id VARCHAR(36) NOT NULL, content TEXT, type VARCHAR(20) CHECK (type IN ('LIKE', 'COMMENT', 'SHARE')), is_read BOOLEAN DEFAULT false, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );

2. 카프카 프로듀서 구현

// UserActivityProducer.java
@RequiredArgsConstructor
@Service
public class UserActivityProducer {
    private final KafkaTemplate<String, UserActivityEvent> kafkaTemplate;

    public void sendUserActivity(UserActivityEvent event) {
        kafkaTemplate.send("user-activity", event.getUserId(), event);
    }
}

// Event 예시
public record UserActivityEvent(
    String userId,
    String targetId,
    ActivityType type
) {}

3. 카프카 컨슈머 & 알림 생성

// NotificationConsumer.java
@KafkaListener(topics = "user-activity", groupId = "notification-group")
public void handleUserActivity(UserActivityEvent event) {
    Notification notification = Notification.builder()
        .userId(event.targetId()) // 알림 받을 사용자
        .content(generateContent(event))
        .type(event.type())
        .build();

    notificationRepository.save(notification);
    messagingTemplate.convertAndSendToUser(
        notification.getUserId(),
        "/queue/notifications",
        notification
    );
}

4. 웹소켓 실시간 전송

// WebSocketConfig.java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
                .setAllowedOriginPatterns("*")
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/queue");
        registry.setApplicationDestinationPrefixes("/app");
    }
}

5. REST API 엔드포인트

// NotificationController.java
@RestController
@RequestMapping("/api/notifications")
@RequiredArgsConstructor
public class NotificationController {
    private final NotificationService notificationService;

    @GetMapping
    public Page<NotificationResponse> getNotifications(
            @AuthenticationPrincipal User user,
            @PageableDefault(size = 20) Pageable pageable) {
        return notificationService.getUserNotifications(user.getId(), pageable);
    }

    @PatchMapping("/{id}/read")
    public void markAsRead(@PathVariable UUID id) {
        notificationService.markNotificationAsRead(id);
    }
}


🛠 Aiven 통합 핵심 포인트

  1. Kafka Connect 활용
    • PostgreSQL Sink Connector 설정으로 DB 자동 싱크
    curl -X POST -H "Content-Type: application/json" \\\\
    -d '{
      "name": "pg-sink-notifications",
      "config": {
        "connector.class": "io.aiven.connect.jdbc.JdbcSinkConnector",
        "connection.url": "jdbc:postgresql://your-pg-host:port/db",
        "topics": "notifications",
        "key.converter": "org.apache.kafka.connect.storage.StringConverter",
        "value.converter": "org.apache.kafka.connect.json.JsonConverter",
        "insert.mode": "upsert",
        "pk.mode": "record_value",
        "pk.fields": "id"
      }
    }' <http://kafka-connect:8083/connectors>
    
    
  2. Aiven PostgreSQL 성능 최적화
    • 연결 풀 설정 (HikariCP)
    # application.yml
    spring:
      datasource:
        hikari:
          maximumPoolSize: 10
          connectionTimeout: 30000
    
    
  3. 카프카 모니터링
    • Aiven Console 내장 대시보드로 토픽 Lag, 처리량 확인
    • Consumer 그룹 오프셋 모니터링

🌟 포트폴리오 강화 요소

  1. 테스트 전략
    • 카프카 통합 테스트: @EmbeddedKafka 활용
    @SpringBootTest
    @EmbeddedKafka(partitions = 1, brokerProperties = {"listeners=PLAINTEXT://localhost:9092", "port=9092"})
    class NotificationServiceIntegrationTest {
        @Autowired
        private KafkaTemplate<String, UserActivityEvent> kafkaTemplate;
    
        @Test
        void shouldSendNotificationOnKafkaEvent() {
            kafkaTemplate.send("user-activity", new UserActivityEvent("user1", "post123", ActivityType.LIKE));
            // Verify notification exists in DB & WebSocket message
        }
    }
    
    
  2. 성능 개선 기록
    • PostgreSQL 인덱스 추가 전후 쿼리 시간 비교
    • Kafka 배치 처리로 초당 10,000 이벤트 처리 도전
  3. 배포 아티팩트
    • Dockerfile & docker-compose.yml
    FROM eclipse-temurin:17-jdk-alpine
    VOLUME /tmp
    COPY target/*.jar app.jar
    ENTRYPOINT ["java","-jar","/app.jar"]
    
    
  4. 장애 처리 시나리오
    • Kafka 컨슈머 재시도 정책 구현
    @Retryable(retryFor = {KafkaException.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void handleUserActivity(UserActivityEvent event) {
        // ... 처리 로직
    }
    
    

📈 학습 로드맵

  1. 주간별 계획
    • 1주차: Aiven 서비스 설정 + 도메인 모델링
    • 2주차: 카프카 프로듀서/컨슈머 구현
    • 3주차: 웹소켓 실시간 통신 + API 개발
    • 4주차: 성능 테스트 + 모니터링 설정
  2. 확장 가능성
    • OpenSearch 연동으로 알림 검색 기능 추가
    • Redis로 미확인 알림 카운트 캐싱
    @Cacheable(value = "unreadCount", key = "#userId")
    public long getUnreadCount(String userId) {
        return notificationRepository.countByUserIdAndIsReadFalse(userId);
    }
    
    

이 프로젝트는 클라우드 네이티브 서비스 구축 경험을 체계적으로 보여줍니다. 실제 사용자 행동 데이터를 처리하는 파이프라인 구축, 이벤트 드리븐 아키텍처 적용, 관리형 클라우드 서비스 운영 경험을 포트폴리오에 강력하게 어필할 수 있을 것입니다. 완성 후 GitHub에 코드 공개 + 배포 URL을 포함시키고, Aiven 대시보드 스크린샷을 README에 추가하는 것이 좋습니다.

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유