Amazon Elastic Compute Cloud(Amazon EC2)는 안전하고 크기 조정이 가능한 컴퓨팅 파워를 클라우드에서 제공하는 웹 서비스다.
안정적인 확장 가능한 인프라에 온디맨드로 액세스한다.
온디맨드란 AWS와 같은 외부 서비스 공급자가 데이터를 호스트하는 것을 말한다. 클라우드 공급자가 모든 하드웨어, 소프트웨어 및 기타 지원 인프라를 조달하고 자사의 데이터 센터에 설치 및 관리한다. 비즈니스는 인터넷을 통해 PC, 웹 브라우저 또는 모바일 앱에서 서비스에 액세스하고 계정을 관리한다.
조직 내에서 서버를 물리적으로 관리하는 온프라미스는 서버의 수평적 확장인 scale-out 확장을 하기 위해서는 물리 서버를 추가로 주문하고, 설치하는 과정에서 많은 시간이 들게 된다. 서버를 들여 놓을 공간도 필요하고 직접 관리해주어야 하는 단점도 있다.
온디맨드는 서버를 직접 관리하지 않고 네트워크를 통해 관리하기 때문에 쉽고 빠르게 sacle-out 방식의 확장을 하기 매우 쉽다.
1. 인스턴스
AWS에 회원가입을 하고, 로그인을 하면 다음과 같은 대시보드를 확인할 수 있다.
가상 머신 시작으로 EC2 인스턴스를 시작한다.
2. 인스턴스 시작
인스턴스의 이름을 입력한다.
3. OS 및 아키텍처 선택
Ubuntu 22.04 LTS, 64비트 ARM으로 선택했다.
4. 인스턴스 유형
Arm 아키텍처는 t4g.small을 프리티어로 제공하고 있으니 이를 선택한다. x86 아키텍처는 무료로 사용 가능한 다른 인스턴스 유형을 제공하고 있으니 프리티어에서 사용가능한 인스턴스 유형을 선택하면 된다.
5. 키 페어 생성
적당한 키 페어 이름을 설정하고 키 페어 유형과 파일 형식을 선택한다.
주의 : 프라이빗 키 파일을 절대로 외부에 유출하는 일이 없도록 하자.
이 파일을 통해서 인스턴스에 접속할 수 있기 때문에 누군가 접속해서 채굴기로 쓰는 등 악용한다면 수 많은 비용 청구를 겪게 될 것이다.
주변에서도 실수로 이 파일을 유출해서 몇 백만원씩 피해를 봤다는 소문을 듣기도 했다.
6. 네트워크 설정
하나의 인스턴스만 사용할 것이기 때문에 네트워크 설정은 따로 하지 않았다.
추가적인 인스턴스를 할당해서 VPC를 구성한다면 네트워크 설정을 해야 할 것이다.
ssh로 접속해서 사용하고 웹 서버를 배포할 목적이기 때문에 HTTP 트래픽과 HTTPS 트래픽을 허용했다.
인바운드 규칙은 가능하다면 액세스 가능한 IP를 제한하여 사용하는 것이 좋다.
7. 인스턴스 시작
선택한 옵션들을 확인하고 인스턴스를 시작한다.
스토리지는 현재 30GiB까지 무료로 제공하고 있어서 30GiB로 설정했다.
인스턴스 시작 버튼을 눌러서 시작한다.
8. 확인
EC2 대시보드로 돌아와서 실행 중인 인스턴스를 확인한다.
인스턴스에는 퍼블릭 주소가 있는데, 퍼블릭 주소와 아까 생성했던 pem파일을 통해 ssh 접속을 할 수 있다.
터미널에서 pem 파일이 있는 경로에서 다음 명령어를 실행해 인스턴스에 접근이 가능한지 확인해보자.
ssh -i key_pair.pem ubuntu@xxx.xxx.xxx.xxx
key_pair.pem은 아까 위에서 발급했던 키 페어 파일 이름이고 xxx는 인스턴스의 퍼블릭 주소를 입력하면 된다.
A persistence context is a set of entity instances in which for any persistent entity identity there is a unique entity instance. Within the persistence context, the entity instances and their lifecycle are managed.
1. 각각의 영속적인 엔티티 식별자에 대해 유일한 엔티티 인스턴스가 있는 엔티티 인스턴스의 집합이다. 2. 영속성 컨텍스트 내에서, 엔티티 인스턴스들과 그들의 생명주기가 관리된다.
1. 의 내용을 풀어서 말하면
컨텍스트 내에서 엔티티끼리 고유하게 식별하게 하는 id를 가지고, 동일한 id를 가진 엔티티가 존재할 수 없다.
JdbcTemplate을 사용하던 시절로 돌아가 다음 코드를 보자.
@Test
void findById() {
Member insert = memberDao.insert(new Member("maco", "pass"));
Member member1 = memberDao.findById(insert.getId()).get();
Member member2 = memberDao.findById(insert.getId()).get();
System.out.println(member1);
System.out.println(member2);
System.out.println(member1 == member2);
}
위 코드에서 member1과 member2는 같은 insert.getId()를 이용하여 DB를 조회했기 때문에 같은 데이터를 가진다.
update와 같은 것은 커맨드기 때문에 쿼리랑 분리한다. 따라서 update가 엔티티를 반환하기 보다 void나 id정도 반환하는 것이 유지보수에 좋음.
1:N 에서 고려할 점
db뻥튀기 1:다 관계에서.(컬렉션을 의존할 때) order가 1개, orderItem이 n개이면 조회의 row는 n개가 된다. order에 대한 데이터는 중복이 됨. -> jpql에 distinct를 넣어줌 -> 1. 실제 sql에 distinct가 들어가 동작함. -> 이거는 로우의 모든 값이 중복이어야 제거해줌 -> 2. jpql의 distnct는 하나 하나 객체에 담을 때 id가 같은 id면 중복인 애는 버리고 list에 담아서 반환해줌. 단점 - 페이징이 불가능하다.
1:다 인 경우에만 페치 조인을 하면 페이징이 안나간다!! llimit나 시퀀스 sql문이 안나가고 jpa가 warn을 알려줌.(애플리케이션의 메모리에서 페이징을 처리했다는)