docker-compose를 이용하여 spring boot Load balancer 컨테이너 배포

도커 컴포즈를 활용하여 apache(load balancer)와 spring boot application를 배포를 해보자 

 

프로젝트 구조

프로젝트 구조는 다음과 같다.

loadbalancer -> 로드밸러서(apache2 ubuntu)
app -> spring boot

/app (spring boot)
/app/Dockerfile
/loadbalance
/loadbalance/000-default.conf
/loadbalance/Dockerfile
/loadbalance/entrypoint.sh
/docker-compose.yml

/app/Dockerfile

##### Build Stage #####
# 빌드 작업을 위한 JDK 베이스이미지
FROM openjdk:17

# openjdk에 xargs 포함 x
RUN microdnf install findutils

## 워킹 디렉토리 설정
WORKDIR /workspace/app

# gradlew 복사
COPY gradlew .
# gradle 복사
COPY gradle gradle
# build.gradle 복사
COPY build.gradle .
# settings.gradle 복사
COPY settings.gradle .
# 웹어플리케이션 소스 복사
COPY src src

# gradlew 실행 권한 부여
RUN chmod +x ./gradlew

# gradlew boot jar build
RUN ./gradlew bootJar

# deploy
#ENTRYPOINT ["java", "-Dspring.profiles.active=${PROFILE}", "-jar", "/app/app.jar"]
ENTRYPOINT ["java", "-Dspring.profiles.active=local", "-jar", "/workspace/app/build/libs/docker-load-balancer-boot-0.0.1-SNAPSHOT.jar"]
EXPOSE 8080

/loadbalance/Dockerfile

FROM ubuntu:18.04

RUN apt -y update
RUN apt install -y apache2
RUN apt install -y apache2-dev
RUN apt install -y wget
RUN apt install -y perl
RUN apt install -y make &&  mkdir /worker

# apache2 module enable
RUN a2enmod ssl
RUN a2enmod proxy
RUN a2enmod proxy_balancer
RUN a2enmod proxy_http
RUN a2enmod lbmethod_byrequests

WORKDIR /

RUN mkdir /log

# apache proxy 설정 파일
RUN rm -rf /etc/apache2/sites-available/000-default.conf
COPY ./loadbalance/000-default.conf /etc/apache2/sites-available/
RUN chmod 755 /etc/apache2/sites-available/000-default.conf

# apache service start
COPY ./loadbalance/entrypoint.sh /
RUN chmod 755 /entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]

/loadbalance/000-default.conf

<VirtualHost *:80>
        <Proxy "balancer://mycluster">
                BalancerMember http://host.docker.internal:8081
                BalancerMember http://host.docker.internal:8082
        </Proxy>
        ProxyPass        "/" "balancer://mycluster/"
        ProxyPassReverse "/" "balancer://mycluster/"

        ErrorLog /log/error.log
        CustomLog /log/access.log combined
</VirtualHost>

/loadbalance/entrypoint.sh

#!/bin/bash

sleep 1
service apache2 start
sleep 1

/bin/bash

/docker-compose.yml

version: "3"
services:
  apache:
    hostname: apache-web
    container_name: apache-web
    build:
      context: .
      dockerfile: ./loadbalance/Dockerfile
    stdin_open: true
    tty: true
    ports:
      - 8080:80

  was1: # was1
    build:
      context: ./app # Dockerfile 위치
      dockerfile: Dockerfile # Docker 파일 이름
    container_name: spring-was1 # 컨테이너 이름
    ports: # docker 포트포워딩
      - 8081:8080

  was2: # was1
    build:
      context: ./app # Dockerfile 위치
      dockerfile: Dockerfile # Docker 파일 이름
    container_name: spring-was2 # 컨테이너 이름
    ports: # docker 포트포워딩
      - 8082:8080

 

 

테스트

project 경로에서

$ docker compose up  

명령어로 이미지 생성 및 컨테이너 실행

was1 접속 (http://localhost:8081)

was2 접속 (http://localhost:8082)

apache(load balancer) 접속 (http://localhost:8080)

 

 

localhost:8080 새로고침 반복 후 로그 확인

(로그 확인을 위해 interceptor 사용)

apache container access 로그 (/log/access.log)

was 1번과 2번에 잘 분산되어 요청되는게 보인다.

느낀점

요즘은 apache 보단 nginx를 사용하여 apache사용법을 많이 까먹었는데 복습하는 느낌이 들어 재미있었다.
그리고 apache는 centOS에서만 사용해보았는데 redHat 계열과 데비안 계열 사용법(proxy, http module enable 하는법)이
다른 점이 있어 조금 당황하였다.

 

다음엔 docker compose에 데이터 베이스를 추가하여 연동를 포스팅 해보자

1. Static Area (스태틱 메모리 영역 = Method Area)

흔히 스태틱(Static) 이라고 부르는 이 메모리 영역은 글자 뜻 그대로 ‘정적 메모리’라는 뜻을 가지고 있다. 

이는 컴파일 시간 동안 할당 된 메모리이며 고정된 공간을 차지하고 런타임 중에 변경할 수 없는 특징을 가지고 있다. 

정적 메모리를 잘 사용할 경우 (Singleton 등) 메모리 사용에 있어 이점을 볼 수 있다. 

단, 잘못 사용할 경우 정적 메모리는 공유되는 자원으로써 멀티 쓰레드 환경에서 치명적인 버그를 불러올 수 있기에 주의가 필요하다.

2. Stack Area (스택 메모리 영역)

스택(Stack) 이라고 부르는 메모리 영역은 글자 뜻 처럼 위에서 아래로 쌓아가는 방식으로 작동하는 메모리이다. LIFO(Last In First Out) 방식을 취하고 있다. LIFO는 가장 처음에 들어간 것이 먼저 나간다는 뜻이다. 

Stack 메모리에 데이터를 넣는 행위를 Push라 하며 데이터를 내보내는 행위를 Pop이라 한다. 

기본 자료형 int, long, boolean 등 의 지역변수와 매개변수의 데이터값이 저장되며 추가적으로 객체 생성 시 참조 주소값도 저장된다.

3. Heap Area (힙 메모리 영역)

참조형 데이터 타입을 갖는 객체, 배열 등의 데이터가 저장되는 메모리 영역이다. (new 연산자를 통해 생성된 객체)

Stack 영역의 공간의 변수(객체, 객체 변수, 참조 변수)는 실제 데이터가 저장된 Heap 영역의 주소 값을 new 연산자를 통해서 반환받는다.

객체의 실제 데이터는 Heap 영역에 올라간다.

즉, Heap 은 참조형 데이터 객체의 실제 데이터들이 담기는 공간이고, Static 영역의 객체는 Heap 영역의 참조 값이 갖게 된다.

 

'Java' 카테고리의 다른 글

[JAVA] 자바의 특징  (0) 2022.11.20
SDLC(Software  Development Life Cycle)의 정의
  • 소프트웨어를 개발하는 전 과정을 단계별로 나눈 것으로 소프트웨어 개발 및 관리에 기본적인 틀을 제공하는 모델
  • SDLC의 의미
    • 관리적 측면 : 이정표, 기준선 제공 통한 SW개발과정 가시화
    • 기술적 측면 : 방법론, 도구, 절차 적용의 기본적인 틀 제공
  • SDLC의 구성
구성 설명 산출물
요구정의 요구사항 명세화, 기능/제약 조건 정의 요구사항 정의서
분석 문제영역, 사용자, Task를 이해하는 단계 개념/비즈니스 모델
설계 분석모델 세분화를 통한 구현 모델로 전환 설계모델
구현 실행코드 생성  Source Code
시험 숨어 있는 결함 발견 및 수정 알파/베타 테스트
유지보수 인수 후 일어나는 SW 생명연장 활동 Update,  Fixes 등
  • SDLC의 유형 
유형 내용
Waterfall Model - 검토 / 승인 통해 순차적, 하향식 개발 진행
- 장점 : 이행 용이, 다음단계 진행 전 결과 검증하여 관리 용이
- 단점 : 초기 요구사항 도출이 어려움으로 설계 / 코딩의 지연, 회구 곤란
Prototyping Model - 핵심기능 시제품화를 통한 평가 후 구현하는 검진적 모델
- 장점 : 요구사항 도출 / 시스템 이해 용이, 의사소통 항상
- 단점 : 사용자 오해(완제품), 폐기 프로토타입 존재
Spiral Model - 폭포수와 프로토타입 모델 장점에 위험분석 추가
- 장점 : 점증적 개발로 실제 위험 감소, 피드백 / 테스트 용이
- 단점 : 관리 복잡, 신한 / 비용 / 노력 많이 소요
Iterative Model - 시스템을 여러 번 나누어 릴리즈하는 모델
- Increamental : 기능 분해 후 릴리즈마다 기능 추가 개발
- Evolutionary : 반복을 통해 시스템 버전을 업그레이드하는 방법
Clean Room Model - 클린룸의 결함 예방 개념을 적용하여 핵심 기능을 프로토타입화 함으로써 반복 / 증분시키는 모델
RAD Model - Rapid Application Development Model
- 고객의 참여, Case Tool의 활용을 통한 신속한 SW개발 모델
4세대 기법 - CASE 및 자동화 도구 이용 소스코드 자동 생성 모델

 

자바란?

 

자바는 C언어에 객체 지향적 기능을 추가하여 만든 C++과 달리, 처음부터 객체 지향 언어로 개발된 프로그래밍 언어이다.
자바는 자바 가상 머신(JVM: Java Virtual Machine)을 사용하여 운영체제와 독립적으로 동작할 수 있다.
따라서 자바는 어느 운영체제에서나 같은 형태로 실행 될 수 있다.

 

자바의 특징
  • 자바는 객체지향 언어이다.
    • 객체를 만들기 위해서 설계도인 클래스를 작성하고, 객체와 객체를 연결하여 목적에 맞는 프로그램을 만든다.
    • 객체지향 언어의 특징인 캡슐화, 상속성, 다형성을 완벽하게 지원한다.
  • 이식성이 높다
    • 자바 실행환경이 설치되어 있는 모든 운영체제에서 실행 가능하다.
  • 하이브리드 언어이다.
    • 컴파일 언어인 동시에 인터프리터 언어이다.
    • 텍스트 소스를 컴파일하여 이진 파일(class)파일로 만든 다음 자바 런타임이 클래스 파일을 인터프리트 하면서 실행한다.
    • 시스템에 무관한 이진 파일을 만듦으로써 자바는 컴파일 언어에 가까운 속도와 시스템 독립성을 얻을 수 있다.
  • 메모리를 자동으로 관리한다.
    • 개발자가 직접 메모리에 접근할 수 없으면 자바가 직접 메모리를 관리한다.
    • 객체 생성시 자동으로 메모리 영역을 찾아 할당하고, 가비지 콜렉터(Garbage Collector)를 실행시켜 자동으로 사용하지 않는 객체를 제거한다.
    • 개발자는 메모리 관리의 수고를 덜고, 핵심기능 코딩에 집중할 수 있다.
  • 오픈소스 라이브러리가 풍부하다.
    • 자바는 오픈소스 언어이고 자바 프로그램에서 사용하는 라이브러리 또한 오픈소스의 양이 방대하다.
    • 고급 기능을 구현하는 코드를 작성하는 대신 검증된 오픈소스 라이브러리를 사용하면 애플리케이션을 다시 컴파일 할 필요가 없다.
  • 자바는 실행을 위해 자바 가상 머신을 거쳐야하므로, 다른 언어에 비해 실행 속도가 느리다.
  • 자바는 예외 처리가 잘 되어있지만, 개발자가 일일이 처리를 지정해 줘야한다는 불편함이 있다.
  • 자바는 다른 언어에 비해 작성해야 하는 코드의 길이가 긴 편이다.

'Java' 카테고리의 다른 글

[JAVA] 메모리 영역 Static, Heap, Stack  (0) 2022.11.28