네로개발일기

개발자 네로의 개발 일기, 자바를 좋아합니다 !

'programming language/Dev'에 해당되는 글 12건


반응형

클라이언트와 WAS 사이에 리버스 프록시 서버를 둔다. 클라이언트는 리버스 프록시 서버에 요청하고, WAS는 리버스 프록시로부터 사용자의 요청을 대신 받는다. 클라이언트는 리버스 프록시 서버 뒷단의 WAS의 존재를 알지 못한다. 이로 인해 보안이 한층 강화되었다.

 

리버스 프록시 서버에 SSL 인증서를 발급하여 HTTPS를 적용한다. WAS 서버가 여러대로 늘어나도 SSL 인증서 발급은 추가로 하지 않아도 되니 확장성이 좋다. 또한 WAS 서버가 SSL 요청을 처리하는데 비용도 들지 않는다.

 

리버스 프록시 서버는 Nginx를 사용한다. CA로 무료 SSL 인증서 발급기관인 Let's Encrypt를 사용한다. 또한, 간단한 SSL 인증서 발급 및 Nginx 환경설정을 위해 Certbot을 사용한다.

리버스 프록시란? 클라이언트 요청을 대신 받아 내부 서버로 전달해주는 것
- 서버의 응답을 캐시에 저장하여 서버에 요청하지 않고, 응답해서 리소스를 절약한다.
- 내부의 WAS를 보호한다.
- 많은 요청을 처리하기 위해 여러 대의 서버에 부하를 분산시킬 수 있다.

리버스 프록시인 Nginx를 사용하면 클라이언트 요청을 프록시 서버에 분산하기 위해 로드밸런싱으로 부하가 줄여줄 수 있고, 분산처리 또한 가능하며, 웹 서버의 SSL 인증도 적용할 수 있다.

 

WAS 서버 세팅

준비된 서버에 WAS를 띄우자. 이 포스팅에선 8080포트로 어플리케이션 서버를 실행한다.

 

리버스 프록시 서버 세팅

Nginx 설치

nginx 패키지를 설치한다.

$ sudo apt update

# Nginx 설치
$ sudo apt install nginx

# Nginx 실행
$ sudo service nginx start

Nginx 리버스 프록시 설정

리버스 프록시를 위한 Nginx 설정을 해줄 것이다. /etc/nginx/conf.d 디렉토리로 이동해서 Nginx를 위한 설정파일을 생성하자.

sites-available, sites-enabled는 더이상 사용하지 않는 Nginx 설정방법이라고 한다. conf.d 디렉터리에 Nginx 설정 파일을 만들고 관리한다.
만약 sites-available과 sites-enabled에 기본 설정 파일이 있다면 제거하자. 또한 conf.d에 기본으로 default.conf 파일이 존재하면, 그 파일을 수정해서 설정하자.
$ cd /etc/nginx/conf.d
$ vi default.conf

위 명령을 실행해서 default.conf 파일을 생성하자.

server {
    listen 80;
    server_name your.domain.com;

    location / {
        proxy_pass http://192.168.XXX.XXX;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
    }
}

server_name 은 SSL을 적용할 도메인을 입력한다. 후술할 Certbot은 이 server_name을 기준으로 Nginx 설정파일을 찾고 여기에 HTTPS에 대한 설정을 자동으로 추가해준다.

proxy_pass 에는 프록시 서버가 클라이언트 요청을 전달할 리얼 서버의 주소를 적는다. 리버스 프록시의 가장 큰 목적 중 하나는 실제 서버의 IP 주소를 클라이언트에게 노출하지 않기 위함이므로 여기서는 프라이빗 IP를 입력한다. (퍼블릭 IP를 입력해도 큰 차이는 없다.)

 

Certbot 설치 및 Let's Encrypt에서 SSL 인증서 발급

Certbot은 손쉽게 SSL 인증서를 자동 발급할 수 있도록 도와주는 도구이다. Certbot은 우분투의 snap라는 패키지 매니저를 사용하여 설피하는 것이 권장된다. (참고: Certbot 사이트 주소)

# snapd 설치
$ sudo yum install snapd
$ sudo snap install core
$ sudo snap refresh core
$ sudo snap install certbot --classic

아래 명령을 실행하여 SSL 인증서를 발급받는다.

$ sudo certbot --nginx

이메일을 입력하고, 이용약관에 동의 후 사용할 도메인을 입력한다. 이때, 적용할 도메인에 대한 A 레코드가 반드시 적용되어 있어야 한다.

이 과정을 거치면 Certbot은 Let's Encrypt를 통해 자동으로 SSL 인증서를 발급해온다.

위 명령을 수행 후, 아래처럼 뜬다면 잘 발급받은 것이다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Your existing certificate has been successfully renewed, and the new certificate
has been installed.

The new certificate covers the following domains: https://your.domain.com # https가 설정된 도메인
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Subscribe to the EFF mailing list (email: jy.jeon@gmail.com).

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/your.domain.com/fullchain.pem # 공개키 경로이므로 기억해두자.
   Your key file has been saved at:
   /etc/letsencrypt/live/your.domain.com/privkey.pem # 비밀키 경로이므로 기억해두자.
   Your certificate will expire on 2021-08-15. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again with the "certonly" option. To non-interactively
   renew *all* of your certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

출력된 문구를 보면 다음을 확인할 수 있다.

1. https가 설정된 도메인

https://your.domain.com

2. 공개키 경로

/etc/letsencrypt/live/your.domain.com/fullchain.pem

3. 비밀키 경로

/etc/letsencrypt/live/your.domain.com/privkey.pem

 

또한 우리가 작성한 Nginx의 default.conf 를 확인해보면 HTTPS를 위한 여러 설정이 자동으로 추가된 것을 볼 수 있다.

# 433 포트로 접근 시, ssl 적용 후 8080 포트로 요청을 전달
server {
    server_name your.domain.com;

    location / {
        proxy_pass http://192.168.XXX.XXX:8080;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header Host $http_host;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/your.domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/your.domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

# 80 포트로 접근 시, 433 포트로 리다이렉트
server {
    if ($host = your.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name your.domain.com;
    return 404; # managed by Certbot
}

기존에 작성한 리버스 프록시 관련 세팅을 유지한 채 80 포트 즉, HTTP로 들어온 요청중 host 헤더가 your.domain.com 이라면 443 즉, HTTPS로 301 Moved Permanently Status를 사용해서 리디렉션 해주는 것을 확인할 수 있다. host가 일치 하지 않으면 404 를 반환한다.

 

Crontab으로 SSL 인증서 자동 갱신 설정

Let's Encrypt에서 발급해주는 SSL 인증서는 90일짜리 단기 인증서이다. 90일마다 SSL 인증서를 수동으로 갱신해줘야한다.

# ssl 인증서 갱신 테스트
$ certbot renew --dry-run

# ssl 인증서 갱신
$ certbot renew

# ssl 인증서 만료일 확인
$ certbot certificates

 

리눅스 Crontab을 이용하여 ssl 인증서 갱신 자동화를 할 수 있다.

Crontab이란 리눅스에서 제공하는 기능으로 특정한 시간 혹은 특정한 주기로 명령을 수행하고 싶을 때 사용한다. 즉, Crontab은 스케줄링 도구이다. 아래 명령을 이용해서 cron job 하나를 생성하자.

$ crontab -e

vim 선택 후, 주석 가장 아래에 아래 내용을 추가하고 파일을 저장하자.

0 0 * * * certbot renew --post-hook "sudo service nginx reload"

매월, 매일 0시 0분에 certbot을 실행하여 SSL 인증서를 갱신하고, 갱신 이후 nginx의 설정파일을 reload 해주는 작업이다.

 

 참고 

https://frogand.tistory.com/109

 

[Nginx] Nginx 이해하기

문제 동시 접속자 폭발 네트워크 소켓을 통해 최대로 커버 가능한 동시 접속자의 작업수는 1만개였다. 이때 당시는 사용자 수 = 프로세스 개수(혹은 쓰레드 개수)로 서버 인프라가 설계되어 CPU,

frogand.tistory.com

 

 출처 

https://hudi.blog/https-with-nginx-and-lets-encrypt/

 

Nginx와 Let's Encrypt로 HTTPS 웹 서비스 배포하기 (feat. Certbot)

목표 우리의 목표 우리의 목표는 위 그림과 같다. 클라이언트와 WAS 사이에 리버스 프록시 서버를 둔다. 클라이언트는 웹서버처럼 리버스 프록시 서버에 요청하고, WAS는 리버스 프록시로부터 사

hudi.blog

https://gist.github.com/woorim960/dda0bc85599f61a025bb8ac471dfaf7a

 

Nginx를 이용하여 https 적용하는 법

Nginx를 이용하여 https 적용하는 법. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

https://devlog.jwgo.kr/2019/04/16/how-to-lets-encrypt-ssl-renew/

 

Let's Encrypt SSL 인증서 자동 갱신 설정 방법 · Tonic

사이트 운영에 도움을 주실 수 있습니다. 고맙습니다. --> Let's Encrypt SSL 인증서 자동 갱신 설정 방법 2019년 04월 16일 Let’s Encrypt에서 발급하는 인증서는 90일짜리 단기 인증서입니다. 3개월에 적어

devlog.jwgo.kr

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

메시지 큐란

메시지 큐(Message Queue)는 프로세스 또는 프로그램 간에 데이터를 교환할 때 사용하는 통신 방법 중 하나로, 메시지 지향 미들웨어(Message Oriented Middleware:MOM)를 구현한 시스템을 의미한다. 메시지 지향 미들웨어란 비동기 메시지를 사용하는 응용 프로그램들 사이에서 데이터를 송수신하는 것을 의미한다. 여기서 메시지란, 요청/응답/오류 메시지 혹은 단순한 정보 등의 작은 데이터가 될 수 있다.

 

메시지 큐는 메시지를 임시로 저장하는 간단한 버퍼라고 생각하면 된다. 메시지를 전송 및 수신하기 위해 중간에 메시지 큐를 둔다.

메시지 전송 시 생산자(Producer)로 취급되는 컴포넌트가 메시지를 메시지 큐에 추가한다. 해당 메시지는 소비자(Consumer)로 취급되는 또 다른 컴포넌트가 메시지를 검색하고 이를 사용해 어떤 작업을 수행할 때까지 메시지 큐에 저장된다. 각 메시지는 하나의 소비자에 의해 한 번만 처리될 수 있는데, 이러한 이유로 메시지 큐를 이용한 방식을 일대일통신이라고 부른다.

 

메시지 큐를 사용하는 경우는?

일반적인 클라이언트-서버 구조에서는 사용자가 요청을 하면 서버는 그에 대한 처리를 한 후 클라이언트에게 응답을 한다. 간단한 서버 구조에서는 굳이 메시지 큐를 사용할 필요가 없다. 사용자가 응답을 기다려야하는 경우, HTTP 요청을 바로 처리하지 않고 중간에 메시지 큐를 두는 경우는 바람직하지 않다. 또한, 메시지 큐를 적용하려면 다양한 메시지 큐 중에서 시스템의 목적에 맞는 것을 선정해야 한다. 이후 선정된 메시지 큐의 사용방법을 익혀 지원하는 다양한 옵션 중에 시스템이 추구하는 옵션을 설정해야 한다. 

왜 메시지 큐를 사용하며, 어떤 경우에 사용하는 걸까?

메시지 큐는 소비자(Consumer)가 실제로 메시지를 어느 시점에 가져가서 처리하는지는 보장하지 않는다. 언젠가 큐에 넣어둔 메시지가 소비되어 처리될 것이라고 믿는 것이다. 이러한 비동기적 특성때문에 메시지 큐는 실패하면 치명적인 핵심 작업보다는 어플리케이션의 부가적인 기능에 사용하는 것이 적합하다.

 

이메일 전송

어떤 웹 사이트의 비밀번호를 잊어버려서 임시 비밀번호를 받거나, 새로운 회원가입을 위한 인증 코드를 보내는 이메일 서비스는 어느정도의 응답 지연이 허용되며, 어플리케이션의 핵심 기능이 아닌 경우이므로 메시지 큐를 사용할 수 있다.

- 비밀번호 재설정을 위해 이메일을 발급하는 서비스, 회원가입을 위해 이메일을 발급하는 서비스 등

- 이메일 전송 전용 서비스는 이메일이 어느 서비스로부터 생산되었는지와 관계없이, 메시지 큐의 메시지를 하나씩 소비하고, 그저 이메일이 전송되어야 할 곳으로 이메일을 전송한다.

- 메시지 큐에 들어오는 메시지 수가 많아지는 경우 이메일 전송 전용 서비스 인스턴스를 더 둠으로써 확장할 수 있다. (확장성이 뛰어남)

 

블로그 포스팅

모든 블로그 사용자가 웹에 최적화되어 있거나, 용량이 작은 이미지만 업로드하는 것이 아니다. 블로그 사용자가 서비스의 응답 시간을 저해하지 않으면서 사용자들에게 유연성을 제공하는 방법으로, 사용자가 업로드한 모든 이미지를 게시하는 과정에서 즉각 처리가 아닌 사후 처리로 최적화한다. 

- 사용자가 고용량의 이미지가 포함된 블로그 포스팅을 한다.

- 이미지는 저장소에 전송된다.

- 업로드된 이미지에 대한 정보가 포함된 메시지를 이미지 최적화 서비스의 메시지 큐에 담는다.

- 이미지 최적화 서비스는 저장소에서 이미지를 가져와 최적화 후 이미지를 대체한다.

 

메시지 큐의 이점

1. 비동기(Asynchronous)

메시지 큐는 생산된 메시지의 저장, 전송에 대해 동기화 처리를 진행하지 않고, 큐에 넣어두기 때문에 나중에 처리할 수 있다. 여기서 기존 동기화 방식은 많은 메시지를 전송할 경우 병목 현상이 생길 수도 있고, 뒤에 들어오는 요청에 대한 응답이 지연될 것이다.

 

2. 낮은 결합도(Decoupling)

생산자 서비스와 소비자 서비스가 독립적으로 행하면서 서비스간 결합도가 낮아진다.

 

3. 확장성(Scalable)

생산자 서비스 혹은 소비자 서비스를 원하는대로 확장할 수 있기 때문에 확장성이 좋다.

 

4. 탄력성(Resilience)

소비자 서비스가 다운되더라도 어플리케이션이 중단되는 것이 아니라 메시지는 메시지 큐에 남아있다. 소비자 서비스가 다시 시작될 때마다 추가설정이나 작업을 수행하지 않아도 메시지 처리를 시작할 수 있다.

 

5. 보장성(Guarantees)

메시지 큐는 큐에 보관하는 모든 메시지가 결국 소비자 서비스에게 전달된다는 일반적인 보장을 제공한다.

 

메시지 큐의 오픈소스 시스템

- RabbitMQ

- Kafka

- ActiveMQ

 

 

 출처 

https://tecoble.techcourse.co.kr/post/2021-09-19-message-queue/

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

bool 변수 작명은 4가지로 한다.

  • is
  • has
  • 조동사
  • 동사원형

 

is 용법

가장 흔한 케이스이다. 보통 3가지 케이스로 나뉜다.

  • is + 명사
  • is + 현재진행형 (~ing)
  • is + 형용사

is + 명사

"(무엇)인가?" 라는 뜻으로 쓰인다.

boolean isStudent; // user는 학생인가?

is + 현재진행형 (~ing)

"~하는 중인가?" 라는 뜻으로 쓰인다.

boolean isExecuting; // 실행 중인가?
boolean isPending; // 대기 중인가?

is + 형용사 => 형용사 / ~ed(수동태)

boolean isSelected;
boolean isHidden;

 

has 용법

  • has + 명사 
  • has + 과거분사 (pp)

has + 명사

"~를 가지고 있는가?" 

boolean hasICloudAccount; // iCloud 계정을 가지고 있는가
boolean hasVideo; // video를 가지고 있는가?

has + 과거분사 => 현재완료

"과거에 완료된 것이 현재까지 유지가 되고 있다." "~가 유지되고 있는가?"

boolean hasConnected; // 연결되어 있는가?
boolean hasEnded; // 끝났는가?

 

조동사 + 동사원형

can / should / will 등이 있다.

can "~ 할 수 있는가?"

should, will "~ 해야하는 가?", "~할 것인가?"

boolean canEdit() { ... } // 편집할 수 있는가?

 

동사원형 => 3인칭단수로

예를 들어

  • supports : ~을 지원하는가?
  • includes : ~을 포함하는가?
  • shows : ~을 보여줄 것인가?
  • allows : ~을 허용할 것인가?
  • accepts : ~을 받아 주는가?
  • contains : ~을 포함하고 있는가?
boolean supportsVideo; // 비디오를 지원하는가?
boolean allowsEditing; // 편집을 허용하는가?

 

 

해당 사항은 Swift 언어의 bool 변수 작명(스위프트 디자인 가이드)으로 Java와 다른 부분이 있을수도 있지만, boolean 변수의 조동사를 넣어 자주 사용하는 필자로서, 그리고 Java와 비슷한 부분이 있어보여 정리할 필요가 있어보여 정리해보았다.

 

 출처 

https://soojin.ro/blog/naming-boolean-variables

 

Bool 변수 이름 제대로 짓기 위한 최소한의 영어 문법 · Soojin Ro

Background 프로그래머의 가장 어려운 업무가 이름 짓기라는 설문 결과도 있듯이 변수에 적절한 이름을 지어주는 것은 어렵고 오래걸리는 일이다. 영어가 모국어가 아닌 사람들에게는 더 어려울

soojin.ro

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형
kill -9로 종료하는 것은 좋지않다. jvm shutdown hook 또는 spring의 @PreDestroy의 실행을 보장하기 힘들다. kill -2(SIGINT) 혹은 kill -15(SIGTERM)을 쓰는 것이 좋다.

kill 명령어와 Graceful Shutdown에 대해서 알아보고자 한다.

 

 kill 명령어 알아보기 

https://frogand.tistory.com/69

 

[Linux] ps 명령어 / kill 명령어 / 프로세스 확인 및 죽이기 / 프로세스 일괄 종료 / kill process

# 프로세스란? 실행중인 프로그램 # ps 명령어 - Process 와 관련 linux 명령어는 ps 입니다. 옵션 기능 -e 시스템 상의 모든 프로세스 정보를 출력 -f 상세한 정보를 출력 (full-format) $ ps -ef UID PID PPID C..

frogand.tistory.com

 

애플리케이션 구동도 중요하지만, 안전한 종료야 말로 신규 버전을 배포하기 위해 필수적으로 진행해야 한다. 

 

Graceful Shutdown이란?

프로그램이 종료될 때, 최대한 side effect없이 로직을 잘 처리하고 종료하는 것을 의미한다.

지속가능한 소프트웨어를 위해 폐기 가능한(Disposability) 시스템을 구성해야 한다. 그리고 소프트웨어의 안전성을 높이기 위하여 graceful shutdow이 필요하다. 프로세스가 갑작스러운 하드웨어 문제에 의해 죽는 상황이 발생하더라도 문제가 없는 견고한 프로그램을 만들어야 한다. 프로그래머는 이를 준비해야 한다. (The Twelve-Factor App 방법론)

 

SIGTERM, SIGKILL 차이점

kill -9 $PID는 강제종료이다. -9인 SIGKILL은 리소스를 정리하는 핸들러를 지정하지 않고 프로세스를 바로 죽인다는 의미이다. 만약, 실행 중인 쓰레드가 있더라도 이를 무시하고 중단하는데 혹시라도 굉장히 중요한 작업중이라면 최악의 상황이 일어날 수 있기 때문이다.

 

 

Spring boot에서는 actuator를 사용해서 graceful shutdown을 할 수 있다.

 

 참고자료 

https://blog.marcosbarbero.com/graceful-shutdown-spring-boot-apps/

 

Graceful Shutdown Spring Boot Applications

This guide walks through the process of graceful shutdown a Spring Boot application. The implementation of this blog post is originally created by Andy Wilkinson and adapted by me to Spring Boot 2. The code is based on this GitHub comment. Introduction A l

blog.marcosbarbero.com

https://heowc.dev/2018/12/27/spring-boot-graceful-shutdown/

 

Spring Boot - 안전하게 종료시키기 | 허원철의 개발 블로그

Spring Boot를 안전하게 종료시키는 방법에 대한 소개이다.

heowc.dev

https://kapentaz.github.io/spring/Spring-Boot-Actuator-Graceful-Shutdown/#

 

Spring Boot Actuator Graceful Shutdown

Spring Boot 환경에서 application을 shutdown 하는 방법 중 대표적인 것이 actuator의 shutdown endpoint 기능을 이용하는 것입니다. 이 endpoint는 예상과 달리 처리 중인 요청이 있더라도 그냥 shutdown 처리를 합니

kapentaz.github.io

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

Windows는 ntfs와 fat 파일 시스템만 읽을 수 있지만 맥의 경우 모두 다 읽을 수 있다. 하지만 mac에서는 ntfs 파일시스템은 Read Only이기 때문에 Mounty 소프트웨어를 활용해서 쓸 수 있게 변경할 수 있다.

 

 

아래 명령어로 Mounty를 설치하고 실행해주면 된다. (Mac OS에 homebrew가 설치되어있어야 한다.)

$ brew install --cask mounty

https://formulae.brew.sh/cask/mounty

 

mounty

Homebrew’s package index

formulae.brew.sh

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !