@Bean
//redis를 사용하기위해서는 key와 value로 이루어져있는데 그걸 지정해주고
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
{
RedisTemplate<String, Object> template = new RedisTemplate<>();
//redisTemplate에다 connection연결하여 redis와의 연결을 설정한다.
template.setConnectionFactory(redisConnectionFactory);
// Key를 문자열로 직렬화하기 위해 StringRedisSerializer 설정
template.setKeySerializer(new StringRedisSerializer());
// Value를 JSON 형식으로 직렬화/역직렬화하기 위해 GenericJackson2JsonRedisSerializer 설정
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
설명은 주석참고!
2. docker를 실행
user@localhost:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
testdocker latest dbb90c63cb6d 4 days ago 762MB
redis/redisinsight latest 227e84a952e3 4 days ago 250MB
node-test 1.0 ab7e6a400426 6 days ago 139MB
debian latest c7f9867d6721 9 days ago 117MB
ubuntu 22.04 97271d29cb79 3 weeks ago 77.9MB
alpine latest 91ef0af61f39 4 weeks ago 7.8MB
ubuntu latest b1e9cef3f297 5 weeks ago 78.1MB
kjuno/nginx-test 1.0 9527c0f683c3 7 weeks ago 188MB
nginx latest 9527c0f683c3 7 weeks ago 188MB
redis latest 7e49ed81b42b 2 months ago 117MB
mysql latest c757d623b190 2 months ago 586MB
debian 10 69530eaa9e7e 3 months ago 115MB
redis 6.2 9aac89b4d50f 4 months ago 106MB
nginx 1.25.3-alpine 2b70e4aaac6b 11 months ago 42.6MB
ubuntu 14.04 13b66b487594 3 years ago 197MB
user@localhost:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
user@localhost:~$ docker run --name redis-container -p 6379:6379 -d redis
c503b66ea8e66e3a1ef0215d2a7a7355f8720599151c24cf3549ac228148e3d4
user@localhost:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c503b66ea8e6 redis "docker-entrypoint.s…" 3 seconds ago Up 3 seconds 0.0.0.0:6379->6379/tcp redis-container
user@localhost:~$
레디스는 이미 이미지로 만들어진 상태라서 바로 실행해준다.
3. 서버 실행 4. 테스트해보기
@GetMapping("/get")
public String temp1()
{
String title = "이론수업 개꿀";
redisTemplate.opsForValue().set("test", title);
return title;
}
redis template를 통해서 값을 넣어줫다 현재 test라는 key에는 이론수업 개꿀 이라는 value가 저장되어있다.
127.0.0.1:6379> get test
"\"\xec\x9d\xb4\xeb\xa1\xa0\xec\x88\x98\xec\x97\x85 \xea\xb0\x9c\xea\xbf\x80\""
역직렬화되지않은 상태의 값을 보여준다.
저장된 값을 다시 받아와보자
@GetMapping("/get")
public String temp2()
{
String result = (String) redisTemplate.opsForValue().get("test");
return result;
}
이론수업 개꿀이라는 내용이 반환될까?
자 그럼 redis는 어느 분야에서 사용될까? redis는 빠르다고했다 1. 단순조회할때 많이 사용된다 2. 잘 변경되지 않은 데이터를 레디스에 넣어서 많이 사용한다 ex) 주민등록번호를 조회하는 api가 있다고 가정하자 가. redis에 값이 있는지 없는지 확인한다. 나. 값이 있으면(cache가 hit를 했다면..) 그 값을 바로 리턴해준다. 다 .값이 없다면(cache가 miss했다면) db를 조회해서 주민등록번호를 가져와서 redis에 값을 넣어준다.
redis의 단점은? 휘발성
해결하는방법은?
방법1 일정한 주기마다 모든 값을 db에 저장한다 >> rdb스냅샷
장점 주기적으로 저장, 장애시 복구가능 설정이 간단함
단점 스냅샷 사이의 데이터는 손실 될수있음
방법2 redis의 동작 기록을 로그에 기록하여 파일 자체를 갖고있는것, 복구가 필요하면 모든 명령어를 하나씩 실행하는법
장점 데이터 손실은 서버가 터졌을때 밖에없음
단점 파일크기가 오래걸리고 복구시간이 오래걸릴수있다.
방법3 redis를 데이터를 복제하자 master에 요청한 데이터를 처리하고 처리한 데이터를 바로 slave 레디스에 저장을하자.
방법3의 예시는 sentienl전략 cluster전략이 있다.
redis sentinel redis와 sentinel이 있는데 reis는 master과 slave 구조로 되어있고 sentinel은 각 redis의 상태를 모니터링 하고있다.
과정 1. 일정 시간마다 sentinel은 redis에 ping 을 보낸다, redis는 pong을 답신한다 2. 어느순간 redis에서 pong이 오지않는다면? 3. 문제 발생시 failover과정을 진행한다. 장애가 있는 master를 kill하고 살아있는 slave를 master로 승격시킨다.
만약 failover과정에서 장애감지를 하는 sentinel이 오류로 master가 장애가 발생되었다고 한다면? 다른 slave에 있는 sentinel도 master의 헬스 체크를하는데 몇개의 sentinel이 장애가 있다고 판단했을때 교체를하는지의 과정도 포함되어있다(퀀텀)
로컬에서 테스트를 하면 localhost라는 주소로 테스트를 하게되었을건데, 외부에서는 접속 할 수 없다. 배포를 하게되면 IP나 도메인과같이 고유의 주소를 부여받게되고, 그 주소로 접속할 수 있게 된다.
EC2
하나의 컴퓨터를 대여하는 서비스이다
왜 EC2를 대여할까? 1. 내 컴퓨터로 24시간 서버를 배포해야한다 2. 보안적으로도 위험할 수 있다. >> 이러한 위험과 불편으로 인해 EC2를 사용한다 또한 EC2는 여러 부가기능들(로깅, 오토스케일링, 로드밸런싱 등)을 많이 가지고있다
현업에서는? EC2를 많이사용한다. 백엔드 서버를 배포할때면 EC2서버를 배포한다.
리전
인프라를 지리적으로 나누어 배포한 각각의 데이터 센터이다 EC2는 컴퓨터를 빌려서 원격으로 접속하는 서비스라고했는데, 그 컴퓨터가 실제 있을 위치를 지정해야한다 아마존은 전세계에 각각의 데이터센터가 있다 지리적으로 가까울수록 속도가 빠르다 애플리케이션을 사용할 사용자들의 위치와가까운곳으로 선택하는게 좋다.
리전마다 EC2가 다르게 관리되고있기때문에 시드니 들어가놓고 인스턴스가 사라졌다고 생각하면 안된다!(내가 그랬어!) 낄낄...
EC2 세팅하기
1. EC2 검색 > 인스턴스 시작 인스턴스란? EC2에서 빌리는 컴퓨터의 한대 단위이다
2. 내용작성 인스턴스이름과 os를 선택한다 왜 윈도우나 맥이 아닌 ubuntu인가? 서버 배포용으로 윈도우나 맥은 너무 무거울수 있다.
인스턴스 유형(컴퓨터의 사양)을 지정한다 키 페어(EC2 인스턴스에 접근하기 위한 키)를 설정해준다
네트워크 설정
보안그룹 AWS 클라우드에서의 네트워크 보안을 의미한다 인바운드 트래픽 : 외부에서 EC2 인스턴스로 보내는 트래픽 아웃바운드 트래픽 : EC2 인스턴스에서 외부로 나가는 트래픽 즉 들어오는 트래픽과 나가는 트래픽을 제어하는 규칙이다.
보안그룹 생성이나, 기존 보안그룹 선택이 있다.
ssh란 ec2에 원격으로 접속하기 위한 포트이다 어디서든 원격으로 접속할수 있다는뜻.
스토리지 구성 EC2도 하나의 컴퓨터라서 저장공간이 필요하다. AWS는 이것을 EBS라고 한다. 프리티어는 30기가까지 사용할수 있긴하다.
그리고 인스턴스 시작을 누르며된다
EC2 인스턴스 확인
대시보드 > 인스턴스 > 인스턴스id 클릭
몰 지워야하는지 모르겠으니까 다 지우기
위에서 퍼블릭 ipv4주소랑 ipv4 : 외부에서 접속하기 위한 주소 인스턴스 상태 : 현재 인스턴스가 어떤 상태(실행중, 중지, 종료 등등)
보안 메뉴로 간다.
인바운드 (들어오는) 규칙은 한정 아웃바운드 (나가는) 규칙은 전체로 열려있다
현재 인스턴스의 상태 정보를 모니터링하는 기능도 제공한다.
EC2 접속해보기 연결
기본 우분투 cil로 연결된것을 볼 수 있다.
탄력적 IP연결하기 EC2 인스턴스를 생성하면 IP를 할당받는데 이 IP는 임시적인 IP이다(중지 후 재실행하면 IP가 바뀐다) 재실행해도 다시 바뀌지않는 고정 IP를 할당받고싶다 그것을 탄력적 IP라고 하는데 어떻게 설정하는지 한번 확인해보자
네트워크 및 보안 > 탄력적 IP 기본값으로 할당을 받는다
작업 > 탄력적 IP 주소 연결 인스턴스 선택 퍼블릭 IP 주소가 바뀐것을 확인할수있고 재기동을 해도 고정된 상태임을 확인 할 수 있다.
IP와 PORT의 개념
IP 네트워크 상에서의 특정 컴퓨터를 가리키는 주소
PORT 한 컴퓨터 내에서 실행되고 있는 특정 프로그램 주소 0~1023까지의 포트는 주요 통신을위한 규약에 따라 이미 정해져있다 22(SSH) : 원격 접속을 위한 포트 번호 80(HTTP) : HTTP로 통신 할 때 사용 443(HTTPS) : HTTPS로 통신 할 때 사용
서버와 연결할때는 컴퓨터의 주소와 서버를 실행하는 프로그램 주소가 필요하다 IP:PORT 127.0.0.1:8080 여기서 IP는 127.0.0.1 포트는 8080이다.
spring 서버를 ec2에 배포해보기 인스턴스 > 연결 > 원격접속을 수행한다
#apt를 업데이트한다
$ sudo apt update && /
#jdk 17버전을 설치한다
sudo apt install openjdk-17-jdk -y
#설치 확인
java -version
#깃허브에 올려진 스프링 프로젝트를 가져온다
git clone 스프링 프로젝트 가져오기
#application.yml파일을 만들기위해 접근한다
cd src/main/resources
#application.yml파일을 만든다 빠져 나올때는 esc > :wq (저장후 종료)
vi application.yml
#yml 파일을 만든후 스프링 최상단 디렉토리라 간다
cd..
cd..
cd..
#서버 실행시키기
#빌드를 한다
$ ./gradlew clean build
#jar 파일을 찾기위해 이동한다
cd build/libs
#jar 파일을 실행한다
$ sudo java -jar 파일명.jar
빌드 후 생긴 jar파일이 spring 실행파일이다. 그 jar파일을 실행하면 아래와같이 스프링이 실행된 화면을 볼 수 있다. ipv4 주소 : 포트를 링크에 적자
그럼 위와같이 연결된것을 볼 수 있다.
인스턴스를 종료하기 인스턴스를 종료하지않으면 과금이 될수도있다 종료해보자 인스턴스 > 종료할 인스턴스
인스턴스 상태 > 인스턴스 종료
탄력적 ip도 돈을받는다! 따라서 탄력적 ip도 삭제해야한다.
네트워크및 보안 카테고리 > 탄력적 ip
작업 > 탄력적 ip주소 릴리스를 하면된다 기존 작업이 완전히 종료되지 않은 상태에서는 종료되지않으니 주의하기!
도메인 연결(Route53)
기존에는 ip주소:포트로 접속을 했다, 우리도 naver.com 같이 주소로 들어갈수없을까? 도메인을 발급하고 관리해주는 서비스인 route53을 사용하여 도메인으로 접속해보자
왜쓰는걸까? 어느 페이지든 ip기반으로 통신을하지않고 도메인 기반으로 통신을한다 ip기반 통신에서는 https가 적용이 되지않기때문인데, 이때문에 도메인 주소를 쓰기도한다.
Route53 사용법
route 53 검색
우리는 도메인 등록이에용
쉬주노 엠주노 주노디자인 주노.ninja... 일단 진짜 살건아니니까 선택
1년에 30달러? 괜찮지않나요?
이메일로 도메인 등록 메일이 날라오니 꼭 이메일은 제대로 등록해야한다 도메인 등록은 구매한 시점으로 10~20분뒤에 등록이된다
route53을 ec2에 연결하기 호스팅 영역에서 레코드생성 버튼을 누른다.
레코드 이름과 (이름을 붙이면 앞에 그 문자가 붙음 예를들면 hi라고 적었으면 hi.juno.ninja로) 레코드 유형(주로 A - 특정 ipv4 주소에 연결하고 싶거나나 CNAME - 특정 도메인 주소에 연결하고 싶을때을 사용) 값에는 탄력적 IP주소를 등록한 값을 넣는다.
ELB ELB는 로드밸런서 기능도 제공해주지만 SSL / TLS기능도 제공해준다 >> 쉽게말하면 SSL/TLS 인증서를 활용해 HTTP가 아닌 HTTPS로 통신할수있게해준다
HTTPS를 써야하는이유 데이터를 서버와 주고 받을때 암호화를 시켜서 통신을 해아한다. 암호화를 시키지 않으면 중간에 가로챌수 있기때문 HTTPS 인증을 받은 웹사이트가 백엔드와 통신하려면 백엔드도 HTTPS인증을 받아야한다.
ELB 아키텍처 기존 방식 : 사용자 > EC2 ELB 도입 후 방식 : 사용자 > ELB > EC2 위와 같은 방식으로 요청한다. 추후 트래픽이 증가하여도 EC2를 증가하여도 구조가 바뀌지 않으므로 확장성이 있다.
적용하는법
EC2 > 로드밸런싱 > 로드밸런서 > 로드밸런서 생성
세가지 유형중 Application Load Balancer를 사용해본다
로드 밸런스가 어떤 가용영역으로만 트래픽을 보낼 건지 제한하는 기능이다 가용 영역에 제한을 두지않고 모든 영역에 트래픽을 보내는것으로 하자.
보안그룹 적용하기 ec2 > 보안그룹으로 간다
elb는 유저의 모든 요청을 '받아서' 그것을 ec2서버로 보내주는 역할을 한다. 따라서 elb는 인바운드규칙을 http나 https에서 오는 모든요청을 받아주는 역할을 해야한다. 따라서 위와같이 설정을한다.
그리고 보안그룹에 방금 등록한 보안그룹을 설정해준다.
elb 리스너 및 라우팅
elb로 들어온 요청을 어떤 ec2 인스턴스로 전달할것인지 설정하는 부분이다. 대상그룹 생성 클릭
대상유형은 인스턴스로, elb가 사용자로부터 트래픽을 받아서 보낼 인스턴스에게 어떤 방식으로 트래픽을 전송할지 지정하는 부분이다. elb는 인스턴스에게 http프로토콜을 이용하여 80번 포트로 보내고 대상은 ipv4 프로토콜버전은 http1이다. 상태검사 기능이있는데, elb는 ec2의 상태(에러가 났는지, 정상작동하는지)를 체크하기 위해 주기적으로 각각의 ec2인스턴스에 요청을 보내본다, 그 요청에 대한 200번대 응답이 잘 날라온다면, 서버가 정상적으로 잘 작동되었다고 판단하며, 200번대 응답이 날라오지 않는다면 elb는 해당 인스턴스에는 요청을 보내지않는다.
각각 ec2 인스턴스에 get 요청으로 /healt 에 get 요청을 보내면서 정상 동작인지 체크를 한다.
대상 등록에 현재 등록할 인스턴스를 체크한후 아래에 보류중인것으로 포함
있으면 대상그룹 생성을 하면된다.
그리고 다시 리스너 및 라우팅에서 대상그룹을 지정하면되는데 elb에 http 프로토콜을 활용하여 80번 포트로 들어온 요청은 위 인스턴스로 분배해서 (그룹이니 여러개일수 있음)
elb에 도메인 연결해보기 기존에는 우리가 ec2 서버를 직접 건들였지만 현재는 elb를 건들여야한다.
route 53 > 호스팅영역 > 구매했던 도메인 클릭
레코드 유형은 A 그대로 다만 별칭을 체크하고 Application/Classic Load Balancer에 대한 별칭 클릭 로드 밸런서에서 봤던 dns주소 복붙
HTTPS 적용을 해보자 HTTPS 적용을하기위해 인증서를 발급받아야한다. 서비스 > certificate Manager 클릭 인증서 요청 퍼블릭 인증서 요청
도메인추가 활성화된 인증서 id 클릭
검증대기중인 상태인것을 볼 수 있다. 도메인이 내 소유인지, 확인하는작업이다, route53에 레코드를 생성하는데 Cname이름으로 보내면 Cname값을 반환해주면 맞는지... 확인한다는뜻이다. route53에서 레코드 생성을 누르면 자동으로 등록이되고, 인증이 된다.
ELB에 HTTPS 설정하기 로드 밸런서에 HTTPS 프로토콜을 받기위해 수정하자
EC2 > 로드밸런싱 카테고리 > 로드밸런서 > 이름선택 리스너 및 규칙 > 리스너 추가 HTTPS에 요청이 들어오면 대상그룹으로 보내준다.
보안 리스너 설정에서 보안정책은 디폴트값으로 certificate는 아까 등록해놓은 인증서를 넣는다
추후 https://본인의 도메인 으로 접속한다.
http요청을 https로 전환해보기 기존에 도메인을 입력하면 자동으로 http프로토콜로 들어오게 된다 그걸 https로 바꿀순 없을까?
기존 http 프로토콜의 리스너를 삭제해주고
다시 http리스너를 추가해주되, 대상그룹으로 전달하는것이아닌 url로 리디렉션을 선택해서 옮겨준다. 다음 도메인을 입력해도 https로 리디렉션이되는것을 볼 수있다.
IPv4 와 IPv6의 차이는? IPv4 : 192.0.0.1와같이 기존의 IP주소를 말한다 IPv6 : IPv4가 고갈됨에따라 더 많은 주소값을 만들어낼수있게 구성되었다 형태는 2001:0db8:85a3:0000:0000:8a2e:0370:7334 이런 형식이다
과금이 되지 않게 지워줘야하는것들 로드밸런서 삭제 >ec2 삭제 > 탄력적 ip 삭제(ec2가 종료되어야함!)
RDS
주의 : rds에서 rds에 publicIp를 할당하면 과금이 될수도 있습니다! 2시간 썼는데 0.01usd니까..
RDS를 사용하지 않고 EC2에 mysql 설치해서 활용하기
VPC 개념을 활용해서 RDS는 Public IP를 할당하지 않고 Private IP로만 연결해서 사용하기
라고 하네요..!
EC2로 스프링을 올려서 배포했지만 정작 데이터베이스는 배포하지 않았다. 그걸 배포하기 위해 생긴 기능이 RDS이다
EC2에 RDS를 설치한다면 별도의 RDS비용이 나오지 않기때문에 비용을 절감할 수 있지만, 실제 현업에서는 어지간하면 같이 사용하지는 않는다. 또한 RDS가 제공하는 편의사항이 있어서 RDS를 사용한다.
사용자는 EC2에 요청을 하게되면, RDS에 요청을보내 데이터를 가져온다(ELB가 없을때)
RDS 생성하기 RDS 검색 > 데이터베이스 생성 MYSQL 생성 템플릿은 프리티어 ec2도 하나의 인스턴스 rds도 하나의 인스턴스이다. 인스턴스의 이름을 지정해주고 db에 접근하기전에 아이디랑 비밀번호 입력하잖아요?.. root 1234같이.. 그걸 입력해줘야한다.
인스턴스는 디폴트값 그대로 연결에서는 퍼블릭 엑세스를 학습용으로 예 눌러주자. 외부에서 rds를 접속할수있게끔 하는장치이다.
다른건 돈땃쥐
보안 그룹 생성하기
EC2 > 네트워크 및 보안 > 보안그룹
아웃바운드는 고치지 않고 인바운드만 고친다. mysql 3306으로포트가 할당된다 (왜 3306일까?..)
아무튼 보안그룹을 설정한 다음
rds로 다시 들어가서
DB.인스턴스 DB 체크 수정
보안그룹을 default를 지우고, 등록한 보안그룹을 넣은다음 계속
즉시 적용
파라미터 그룹 세팅하기
RDS > 파라미터 그룹
파라미터 그룹 생성
위 설정대로..생성한다
생성된 파라미터 그룹 클릭
우측 상단 편집 문자형식 지정 character_set을 검색해서 나오는 6가지를 utf8mb4로 변환을 character_set_client character_set_connection character_set_database characater_set_filesystem characater_set_results character_set_server
정렬방식 지정 collation_connection collation_server 위속성은 전부 utf8mb4_unicode_ci로 바꿔준다.
time_zone은 Asia/Seoul로 설정한다.
RDS의 파라미터 그룹 변경하기
다시 수정을 추가구성에 우리가 방금 등록한 파라미터 그룹을 설정한다. 타임존을 변경했기때문에 DB를 재부팅해야만한다 작업 > 재부팅을.
RDS에 접속해보기 WORKBENCH, DATAGRIP, DBEAVER등등을 사용해도된다 일단 DBEAVER로 접속을 해보겠다.
db정보에 엔드포인트가 있을것이다
mysql을
서버 호스트에 엔드포인트를 기입해주면된다.
username과 password를 아까 등록했던 username과 password를
테이블을 하나 더 만들어보자
위 내용을 간단히 요약하자면 aws-study-static-files에 있는 모든 객체에 대하여 객체를 읽는작업(파일을 읽는작업)허용한다 라는 정책이다
변경사항 저장
파일을 업로드 할 수 있도록 IAM에서 액세스 키 발급받기 지금까지는 파일을 다운로드 할수있도록 정책을 변경했지만, 업로드 할 권한은 부여받지 않았다. 백엔드 서버만 파일을 업로드 할수있게 권한을 부여해보도록 하자 사용자 > 사용자 생성 S3FULL검색 및 체크 S3에 대한 모든 접근권한을 얻는 정책이다 그후 사용자 생성까지