1. 실행 환경에 따른 yml 파일 분리
api 구현에만 집중한 채 진행했기 때문에 application.yml의 요소들이 외부에 노출되어있는 문제점이 있었다.
이 항목들을 local, prod로 분리해서 사용할 것이다.
이렇게 3가지 파일로 분리하고, 테스트를 위해서 local은 포트번호 8081, prod는 포트번호 8082로 둔 후 application.yml에서 프로퍼티를 지정해주었다.
#application.yml
server:
port: 8080
spring:
profiles:
active: local
#application-test.yml
spring:
config:
activate:
on-profile: test
server:
port: 8081
#application-prod.yml
spring:
config:
activate:
on-profile: prod
server:
port: 8082
하지만 예상과 다르게 8080번으로 실행되었다.
그래서 prod로 변경해서 실행해봤는데 이번에는 정상적으로 8082로 실행됐다.
테스트 해본 결과 local로 active를 설정할 경우에 application-local.yml파일을 읽는게 아니라 application.yml파일을 읽는 것이란 결론이 나왔다...
그래서 프로퍼티명에서 local을 제외하고, test, prod로 사용하기로 했다.
2. prod.yml 파일 작성
이제 aws에 실행해 둔 rds를 prod 프로퍼티에서 연결되도록 yml 파일을 작성했다.
기존 test.yml 파일과 달라진 부분을 따로 분리해서 가져오면,
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
open-in-view: true
show-sql: true
generate-ddl: true
hibernate:
ddl-auto: create
properties:
hibernate.format_sql: true
dialect: org.hibernate.dialect.MySQL8InnoDBDialect
database connect 설정 부분과 jpa, sql 더미 데이터 삽입 부분이다.
mysql에서 테이블을 하나씩 만드는 방법보다 jpa에서 제공해주는 ddl-auto 기능을 활용하고자 create 옵션을 선택했다
.(첫 실행 이후에는 계속 update 옵션 사용)
하지만 실행결과 수 많은 에러가 발생했다. 에러 메시지가 발생하는 부분은 DDL 부분이었다.
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
create table users (
id bigint not null auto_increment,
created_at datetime(6),
updated_at datetime(6),
authority varchar(255) not null,
email varchar(30) not null,
introduction varchar(50000),
nickname varchar(20) not null,
password varchar(100) not null,
profile_image varchar(200),
primary key (id)
) engine=InnoDB" via JDBC Statement
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.6.1.Final.jar:5.6.1.Final]
기존에 h2 데이터베이스에서 실행했을 경우에는 정상적으로 실행됐던 엔티티 구조였기 때문에
mysql에서는 불가능한 제약조건이 있을 것이라 추측했고, `introduction varchar(50000)` 의 string 용량이 의심되었다.
찾아본 결과 역시나 자료형 별로 정해진 용량이 있었고, 긴 글이 들어가는 부분에 너무나 많은 글자 수를 제공했던 것이 에러의 원인이었다.
varchar 컬럼은 최대 행 크기가 65,535 Byte로 utf-8문자 기준 21,844자가 최대였다.
그렇기 때문에 다른 자료형을 찾아보았고, longtext형을 사용하는 것이 적당 해 보였다.
자료형 | 크기 |
TINYTEXT | 256 bytes |
TEXT | 64,535 bytes ~ 64KB |
MEIUMTEXT | 16,777,215 Bytes ~ 16MB |
LONGTEXT | 4,294,967,295 Bytes ~ 4GB |
4가지 유형 모두 가변 길이 문자형이고, 최대 저장 길이에만 차이가 있다.
가변 길이 문자형이기 때문에 저장 용량에는 문제가 없을 수도 있지만, DB 구축 용량이 너무 커질 수도 있기 때문에
적당한 용량을 선택하여 기존 varchar로 선언했던 String형의 DB 자료형을 변경해주었다.
//@Column(nullable = false, length = 300)
@Column(nullable = false, columnDefinition = "TEXT")
@Column(nullable = false, columnDefinition = "LONGTEXT")
변경 후에는 컬럼들과 외래키들이 모두 생성되었음을 확인할 수 있었다.
3. 보안 관련 프로퍼티 외부 주입 - intellij
test의 항목들은 배포용 정보가 아니기 때문에 git에 노출되도 상관이 없지만,
배포용으로 사용할 prod파일의 내용은 노출되면 안되기 때문에 외부에서 정보를 주입하는 방법을 사용했다.
spring:
config:
activate:
on-profile: prod # 환경이름설정
redis:
lettuce:
pool:
max-active: 5
max-idle: 5
min-idle: 2
host: ${REDIS_HOST}
port: 6379
password: ${REDIS_PASSWORD}
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
open-in-view: true
show-sql: true #
generate-ddl: true
hibernate:
ddl-auto: update
properties:
hibernate.format_sql: true
dialect: org.hibernate.dialect.MySQL8InnoDBDialect
jwt:
secret: ${JWT_SECRET_KEY}
expire-min: 30
refresh-secret: ${JWT_REFRESH_SECRET_KEY}
refresh-expire-min: 30
refresh-reissue-day: 1
logging:
level:
root: info
intellij에서 실행할 때는 ide에서 제공 해 주는 기능을 통해서 실행 할 수 있었다.
Edit Configurations...에서 Environment variables 항목에 값을 주입한다.
항목이 없을 경우 아래 사진처럼 Modify options를 클릭하여 옵션을 추가하면 보인다.
값을 넣는 방법은 간단하다. db의 주소를 넣고싶다면 yml파일에서 작성한 depth를 순서대로 적어주면 되는데,
예를들어 db 관련 정보를 작성 해 보면
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
넣을 정보가 위 3가지이므로
SPRING\_DATASOURCE\_URL=127.0.0.1;SPRING\_DATASOURCE\_USERNAME=root;SPRING\_DATASOURCE\_PASSWORD=1234
이런 식으로 key=value;key2=value
형식으로 적어준다.
4. 보안 관련 프로퍼티 외부 주입 - aws ec2 환경
이제 실제 실행 환경에서 외부 프로퍼티 값을 넣어줘야 한다.
spring boot가 실행되는 서버에 전역변수로 각 설정값을 넣어주어 ${DB_URL}
이런 식으로 설정한 값을 인식할 수 있도록 할 예정이다.
문제가 있다면, 지금 상태에서 application.yml 파일의 profile을 prod로 변경해 jenkins에서 build한다면 테스트가 정상적으로 실행되지 않는다는 점이다.
그렇기 때문에 test폴더에 따로 test용 yml 파일을 추가해 줬다.
이렇게 되면 실행 환경이 prod로 되어있어도 테스트 진행 시에는 test폴더 안에 있는 yml파일이 적용되기 때문에 보안 정보를 적을 필요가 없어진다.
이제 환경변수를 설정해보겠다.
linux 명령어 중 export는 일시적으로 환경변수를 설정해주는 명령어이다. 하지만 시스템 재부팅 시 값이 사라지게 되는 단점이 있다.
따라서 .bashrc
파일을 사용한다. .bashrc
파일은 사용자가 로컬 터미널 세션을 열 때마다 실행되는파일이기 때문에
해당 파일에 환경변수를 설정 하도록 작성해 터미널을 열 때마다 환경변수를 재설정 하도록 한다.
vi ~/.bashrc
를 입력해 파일에 환경변수를 추가해준다.
#~/.bashrc
...shell
export DB_URL=127.0.0.1
export DB_USERNAME=username
export DB_PASSWORD=password
설정 후 시스템 재부팅 혹은 source ~/.bashrc
를 입력하면 환경변수가 적용된다.
그리고 마지막으로 jar 파일 실행 시 실행 환경을 선택해주는 명령어를 sh 파일에 추가해 주면 끝이다.
nohup java -jar -DSpring.profiles.active=prod $JAR_PATH > nohup.out 2>&1 &
5. 리팩토링이 필요한 부분
mysql 관련해서 자료형을 찾아보면서 바꾸면 좋을것 같은 엔티티 컬럼들이 있었다.
enum과 datetime관련된 부분들인데,
enum은 user부분에서 쓰인 UserType은 enum형식을 그대로 사용하지만, 다른 부분에서는 service단에서 long으로 값을 변환하여 저장하고 있었다. 이 부분은 enum을 사용하는 방식으로 통일해야 할 것 같다.
그리고 datetime 부분도 jpa 어노테이션이 제공하고있는 변환 방식이 있는 것 같아 updated_at, created_at, runningtime을 해당 자료형으로 변경하면 좋을 것 같다.
refrence
https://reference-m1.tistory.com/293
[SQL] MySQL 버전에 따라 다른 VARCHAR LENGTH
MySQL에서 VARCHAR에 유효 최대 길이는 최대 행 크기(65,535 Byte) 및 사용된 문자셋에 따라 달라진다. 예를 들어 UTF-8는 문자당 최대 3Byte를 요구할 수 있으므로 VARCHAR 컬럼은 최대 21,844 자로 선언될 수
reference-m1.tistory.com
https://krksap.tistory.com/2183
SpringBoot Intellij에서 Environment Variable을 application.yml에 넣기
application.yml에 민감 정보가 들어가는 경우 실수로 git에 올라가는 경우 해킹을 당할 수 있습니다. 아래와 같이 db접속 정보가 모두 노출이 되어 있습니다. application.yml spring: # 배포 시에 환경변수
krksap.tistory.com
https://bugoverdose.github.io/development/spring-profile-and-environment-variables-tutorial/
[Spring] Profile: yml 파일 하나로 프로퍼티 관리하기
Spring Profile, JVM System Parameter, Linux Environment Variable 등을 포괄적으로 다룹니다.
bugoverdose.github.io
https://tecoble.techcourse.co.kr/post/2022-10-04-active_profiles/
Spring Profile: yml 파일 하나로 프로퍼티 관리하기
서비스를 개발하다보면 하나의 서버 애플리케이션을 다양한 환경에서 실행할 일이 생깁니다. 그리고 H2 DB를 사용하는 테스트 환경과 MySQL DB…
tecoble.techcourse.co.kr
https://servermon.tistory.com/245
[Linux] 환경 변수 확인 및 추가
안녕하세요. 주식회사 서버몬 입니다. 이번 시간에는 리눅스에서 환경변수를 설정하는 env, set, export명령에 대해서 알아보겠습니다. env : 전역 변수 설정 및 조회 명령어 입니다. $ env 현재 세션에
servermon.tistory.com
'토이프로젝트 > 리뷰어(영화 리뷰 사이트)' 카테고리의 다른 글
백엔드 cicd 구축하기3 (0) | 2023.07.21 |
---|---|
백엔드 cicd 구축하기2 (0) | 2023.07.21 |
백엔드 cicd 구축하기 (0) | 2023.06.02 |
영화 정보 크롤링 Api 구현 (0) | 2023.06.01 |
영화 정보 크롤링 하기 (0) | 2023.05.25 |