반응형

Spring Data Jpa 를 사용하게 되면서 전에 쓰지 않았던 paging 기능에 대해서 이야기 해보려 한다. 

Domain 을 조회하는 Repository interface를 만들때에 JpaRepository 를 상속해서 사용하는 경우가 많다. 
이 JpaRepository 를 살펴보면 내부에 이렇게 구현이 되어있다.  

public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor { 
..... 
} 

그리고 다시 PagingAndSortingRepository 를 살펴보면 다음과 같다.

public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> { 
    Iterable findAll(Sort var1); 

    Page findAll(Pageable var1); 
} 

위에서 볼수 있듯이 Page를 리턴해주는 메소드가 이미 포함되어있다. 

 

그럼 간단히 검색 조건 없이 모든 Data를 검색하는 코드를 작성해보자

 

AccountRestController.java

@GetMapping
public Page<AccountResDto> getPageableAccountList(Pageable pageable){
	return accountService.findAll(pageable);
}

AccountServiceImpl.java

@Override
public Page<AccountResDto> findAll(Pageable pageable) {
  Page<Account> accounts = accountRepository.findAll(pageable);
  return accounts.map(AccountResDto::new);
}

 

http://localhost:9000/api/v1/accounts 로 요청을 하면 다음과 같이 응답을 받을수 있다.

{
    "content": [
        {
            "loginId": "admin",
            "username": "admin",
            "email": "admin@spring.com"
        },
        {
            "loginId": "auser01",
            "username": "user",
            "email": "user01@spring.com"
        },
        {
            "loginId": "guest",
            "username": "guest",
            "email": "guest@spring.com"
        },
        {
            "loginId": "buser02",
            "username": "user",
            "email": "user02@spring.com"
        },
        {
            "loginId": "cuser03",
            "username": "user",
            "email": "user03@spring.com"
        },
        {
            "loginId": "duser04",
            "username": "user",
            "email": "user04@spring.com"
        },
        {
            "loginId": "euser05",
            "username": "user",
            "email": "user05@spring.com"
        },
        {
            "loginId": "fuser06",
            "username": "user",
            "email": "user06@spring.com"
        },
        {
            "loginId": "guser07",
            "username": "user",
            "email": "user07@spring.com"
        },
        {
            "loginId": "huser08",
            "username": "user",
            "email": "user08@spring.com"
        },
        {
            "loginId": "iuser09",
            "username": "user",
            "email": "user09@spring.com"
        },
        {
            "loginId": "juser10",
            "username": "user",
            "email": "user10@spring.com"
        }
    ],
    "pageable": {
        "sort": {
            "sorted": false,
            "unsorted": true,
            "empty": true
        },
        "offset": 0,
        "pageSize": 20,
        "pageNumber": 0,
        "paged": true,
        "unpaged": false
    },
    "last": true,
    "totalPages": 1,
    "totalElements": 12,
    "number": 0,
    "size": 20,
    "sort": {
        "sorted": false,
        "unsorted": true,
        "empty": true
    },
    "first": true,
    "numberOfElements": 12,
    "empty": false
}

리턴 결과를 잘 보면 totalPages 는 1, data 개수는 12, size 는 20 으로 되어있다. 

 

그리고 정렬된 결과를 얻고 싶으면 다음과 같이 파라메터를 추가해주면 된다.

 

http://localhost:9000/api/v1/accounts?sort=loginId,DESC

 

이렇게 하면 loginId 로 정렬된 형태의 결과를 받을수 있다. (그런데 주의할점은 컴마(,) 이후에 공백이 포함되어 있으면 에러가 난다 -_-)

 

그리고 size 도 지정할수 있는데 위 결과는 지정을 하지 않아서 기본 default 로 20 으로 설정된 경우이다.

 

마찬가지로 파라메터에 size 값을 지정해주면 지정한 값으로 size 가 정해지며 그에 따른 totalPages 값도 달라지게 된다.

 

위 코드가 포함된 소스는 아래 주소에서 볼수 있다. (단, 계속 수정을 하기 때문에 소스가 완전히 일치하지 않을수 있다. )

 

https://github.com/blusky10/study_spring

 

blusky10/study_spring

Contribute to blusky10/study_spring development by creating an account on GitHub.

github.com

 

728x90
반응형
반응형

아래와 같이 @RestController  에 메소드가 있다고 생각해보자.

@PostMapping
public ResponseEntity<AccountResDto> getResDto(@RequestBody AccountReqDto dto){
    return ResponseEntity.ok(AccountResDto.builder().email("test@test.com")
    .loginId("test")
    .username("tester")
    .build()
  );
}

Post 요청에 대해서 AccountReqDto 라는 Object 형태의 파라메터를 받아서 Response 를 리턴하는 메소드 이다.

AccountReqDto 는 다음과 같이 되어있다.

@Getter
public class AccountReqDto {

    private String loginId;

    @Builder
    public AccountReqDto(String loginId) {
        this.loginId = loginId;
    }
}

그리고 나서 난 아무 생각없이 테스트 케이스를 돌렸다.

@Test
public void getResDtoTest() throws Exception {
  MvcResult mvcResult = this.mockMvc.perform(
      post("/api/v1/accounts")
      	.contentType(MediaType.APPLICATION_JSON_UTF8)
      	.content(objectMapper.writeValueAsString(reqDto)))
      .andExpect(status().isOk())
      .andDo(print())
      .andReturn();

  String contentAsString = mvcResult.getResponse().getContentAsString();
  AccountResDto accountResDto = objectMapper.readValue(contentAsString, AccountResDto.class);
  Assert.assertEquals("test", accountResDto.getLoginId());
}

당연히 성공할줄 알았던 테스트 케이스는 실패를 한다. 실패의 원인은 다음과 같다. 

 

Status expected:<200> but was:<400>
Expected :200
Actual   :400

 

아니 왜??? 왜 400 error 가 났을까??

결론부터 말하자면 AccountReqDto 클래스에 기본 생성자가 없기 때문에 위와 같은 에러가 발생 했다. 그렇다면 왜 기본 생성자가 있어야 하나??? 그걸 알기 위해서 찾아보다 보니 Serialization 이 연관이 있다는 것을 찾게 되었다. 

 

Serialization

Serialization 은 Object 의 상태를 byte stream 형태로 변환하는 것을 말한다. Deserialization 은 반대의 경우를 말한다. java  에서 Serialization 을 이용하면 객체를 네트워크를 통해 전송이 가능해진다. 

 

그럼 왜 Serialization에는 No-Argument Constructor 가 필요한걸까? 

To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.
During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.

(출처 : https://docs.oracle.com/javase/10/docs/api/java/io/Serializable.html)

 

요약을 해보면 클래스의 상태를 초기화 할 때 No-Argument Constructor 를 이용한다는 의미이다. 만약 선언되어있지 않으면 에러가 발생한다고 되어있다. 

 

결과적으로 Serialization 을 위해서는 No-Argument Constructor  가 필요하고 그것을 사용하고 있는 Controller 의 RequestBody 에 들어가는 Object 에도 No-Argument Constructor 가 존재 해야 한다는 의미이다.

 

그래서 위 소스에서 테스트가 성공하기 위해서는 No-Argument Constructor 를 만들어 주거나 Lombok 을 사용한다면 @NoArgsConstructor 를 넣어주면 된다.

 

728x90
반응형
반응형

내 github 에 있는 프로젝트들중 예전에 만들었던 건데 내용좀 다시 볼겸 수정을 하고 있었다. 

사실, 간단한거 빼고는 잘 작동을 안하는것 같다.

 

그래서 이번에 라이브러리 버전 업데이트 좀 할겸 소스를 수정을 했다.

 

Spring Boot 버전도 최신 버전으로 수정을 하고 Security 버전도 수정을 했다. 그리고 나서 간단히 로그인을 해보려고 하니 다음과 같은 에러가 발생했다.

 

There is no PasswordEncoder mapped for the id "null"

 

음.. ?

찾아보니 Spring Security 버전이 올라가면서 PasswordEncoder가 변경되면서 발생한 에러였다. 

The general format for a password is:

{id}encodedPassword

Such that id is an identifier used to look up which PasswordEncoder should be used and encodedPassword is the original encoded password for the selected PasswordEncoder. The id must be at the beginning of the password, start with { and end with }. If the id cannot be found, the id will be null. For example, the following might be a list of passwords encoded using different id. All of the original passwords are "password".

(출처 : https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released)

 

그래서 방법은 다음과 같다. (내가 가지고 있는 소스 기준이다. )

 

1. DB 에 password 값을 변경한다. 

 

생성되는 password 값에 "{noop}" 을 붙여서 저장을 한다. 

 

2. UserDetail 서비스를 새로 구현 하였다면 password 부분을 수정해준다. 

    public CustomUserDetails(Account account) {
        this.username = account.getLoginId();
        this.password = "{noop}" + account.getPassword();
    }

 

1번이나 2번이나 결과적으로 password 값 앞에 "{id}" 값을 넣어주면 된다는 의미이다.

 

728x90
반응형
반응형

VPC network

기본적으로 독립적인 private network 이다.

서로 다른 network 간에 internal IP 로 통신을 하기 위해서는 VPC peering 또는 VPN 설정이 필요하다.

 

Instance 간 External IP 를 통한 연결

다른 VPC  network, 다른 region, 다른 zone 일 경우에도 External IP 를 통한 연결은 가능하다. 

Instance 에 대한 access는 오직 ICMP firewall rule 에 의해서 컨트롤 되기 때문이다. (0.0.0.0/0)

 

Instance 간 Internal IP 를 통한 연결

기본적으로 동일한 VPC Network상에 존재하지 않으면 불가능 하다.

단, 동일한 VPC Network 에 속한 instance 들은 zone, region다르더라도 internal IP 을 통한 연결이 가능하다.

 

위 그림을 보자.

Instance Network Region
mynet-us-vm mynetwork us-cental1
mynet-eu-vm mynetwork europe-west1
managementsubent-us-vm managementnet us-cental1
privatenet-us-vm privatenet us-cental1
privatenet-eu-vm privatenet us-cental1

 

Internal IP 접속 여부

  mynet-us-vm mynet-eu-vm managementsubent-us-vm privatenet-us-vm privatenet-eu-vm
mynet-us-vm - O X X X
mynet-eu-vm O - X X X
managementsubent-us-vm X X - X X
privatenet-us-vm X X X - O
privatenet-eu-vm X X X O -

위 표를 보면 동일 VPC  Network 가 아닌 instance 는 Internal IP 로 ping 이나가질 않는다. 

 

그래서 위 구성에서는 vm-appliance라는 instance 를 하나 더 만들었다. 이 instance 를 생성할때에 network interface 에 mynetwork, managementnet, privatent을 등록해주면 vm-appliance 에서 서로 다른 Network  에 있는 Instance  와 통신이 가능하게 된다. 

 

 

 


참고자료

https://google.qwiklabs.com/focuses/1230?parent=catalog

 

728x90
반응형
반응형

 

Spring boot Application 을 Dockerfile 로 build 할 때에 profile 값을 전달 해야해서 찾아본 것을 적어보았다.

profile 값을 전달하기 위해서는 다음과 같은 방법들이 있다. 

 

1.Dockerfile 에 profile 값을 넣고 build 를 한다.

FROM java:8
ADD target/app.jar app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=dev","-jar","/app.jar"]

2.Docker run 할때 환경 변수로 전달한다.

docker run -d -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=dev" --name rest-api dockerImage:lates

3.DockerCompose 로 전달한다.

version: "3"
services:
	rest-api:
	image: rest-api:0.0.1
	ports:
		- "8080:8080"
	environment:
		- "SPRING_PROFILES_ACTIVE=dev"

 

여기에서 난 1번을 선택해서 적용을 했는데 한가지 Dockerfile 에 전달되는 profile 값이 변경 될수 있도록 하고 싶었다. 그럴려면 docker build 시점에 값을 넘겨줘야 하는데 document를 찾아보니 ARG 를 사용하게 되면 docker build 시점에 값을 넘길수가 있다.

FROM ubuntu
VOLUME /tmp
ADD app.jar app.jar
RUN bash -c 'touch ./app.jar'
ARG SPRING_PROFILES_ACTIVE
RUN echo $SPRING_PROFILES_ACTIVE
ENV SPRING_PROFILES_ACTIVE=$SPRING_PROFILES_ACTIVE
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom", "-jar","./app.jar"]
docker build --build-arg SPRING_PROFILES_ACTIVE=dev .

결과적으로 docker build 시에 --build-arg 로 SPRING_PROFILES_ACTIVE 값을 넘겨주고 Dockerfile 에서는 전달 받은 SPRING_PROFILES_ACTIVE 값을 ENV 로 등록을하면 ENTRYPOINT 에 -D 옵션을 넣어서 실행하지 않아도 자동으로 profile 이 적용되서 실행이 된다.

 


참고자료

https://docs.docker.com/engine/reference/builder/#arg

https://stackoverflow.com/questions/43707770/spring-boot-in-docker

 

728x90
반응형
반응형

Projects

 

Project 는 Network 를 포함하고 있며 Network 에는 Subnetwork, Firewall rules, Route 가 포함된다.

 

Organization > Folders > Projects > Resources

 


Network

 

Network : 외부에서 각각의 Resource 들을 직접 접속한다. 외부에서 들어오거나 외부로 나가는 접속에 대해서 Firewall 을 사용한다. Global(Multiple Region) 또는 Regional(Single Region) 이 가능하다. 프로젝트가 생성되면 default Network 가 생성된다.

 

Subnetwork : Compute Engine instance 같이 관련된 resouce 들을 group 화 한다. Regional 만 가능하며 auto mode 와 custom mode 가 있다.

 

1. auto mode : Network 생성시 region 당 하나의 subnet이 자동으로 생성된다.

2. custom mode : Network 생성시에는 subnet이 생성되지 않는다. subnet 이 region 당 존재하지 않을 수 있고 여러개 존재할 수 있다.


 

Network 생성 방법

 

1. auto

gcloud compute networks create autoNetwork --subnet-mode=auto

2. custom

gcloud compute networks create customNetwork --subnet-mode=custom

custom 일 경우 subnet이 자동으로 생성되지 않기 때문에 subnet 도 만들어줘야 한다.

gcloud compute networks subnets create customNetwork --network=privatenet \
--region=us-central1 --range=10.0.0.0/24 --enable-private-ip-google-access

Cloud Route

 

Instance 를 Nat gateway 로 활용할 수 있다.

 

gcloud compute routes create NAME --destination-range=DESTINATION_RANGE (--next-hop-address=NEXT_HOP_ADDRESS
| --next-hop-gateway=NEXT_HOP_GATEWAY | --next-hop-instance=NEXT_HOP_INSTANCE
| --next-hop-vpn-tunnel=NEXT_HOP_VPN_TUNNEL) [--description=DESCRIPTION] [--network=NETWORK; default="default"] [--next-hop-instance-zone=NEXT_HOP_INSTANCE_ZONE] [--next-hop-vpn-tunnel-region=NEXT_HOP_VPN_TUNNEL_REGION] [--priority=PRIORITY; default=1000] [--tags=TAG,[TAG,…]] [GCLOUD_WIDE_FLAG …]

예시 )

gcloud compute routes create nat-route --network customNetwork \
--destination-range 0.0.0.0/0 --next-hop-instance privatenet-bastion \
--next-hop-instance-zone us-central1-c --tags nat-me --priority 800

--next-hop-instance : route 를 핸들링 할 instance 이름 (--next-hop-instance 을 사용할 경우 --next-hop-instance-zone 값도 필수로 넣어야 한다. )

--tags : route 를 적용할 instance 들의 모음

 

그 이외에 옵션에 대해서는 아래 참고 링크를 가보면 더 자세히 알수 있다. 


Network 관련된 IAM Role

 

Network Adminnetworks, subnetworks, addresses, routes등에 대한 create, modify, delete 권한 (제외 : firewall rule, SSL certificates - view)

Security Adminfirewall rule, SSL ceritifates 에 대한 create, modify 권한.

Network Viewer읽기만 가능한 권한



참고자료

https://www.qwiklabs.com/focuses/556?parent=catalog

https://cloud.google.com/sdk/gcloud/reference/compute/routes/create

728x90
반응형
반응형

HTTP(S) 에 대한 global Load Balancer 이다.

 

1. forwarding rule 은 다이렉트로 request 를 target proxy 로 전달한다.

2. target proxy 는 url map 을 통해서 적절한 backend service 로 라우팅 해준다.

3. backend service 는 request 를 서버 용량, 상태에 따라서 적절한 backend instance 로 전달한다. 각각의 backend instance는 health check 를 사용한다.

 

출처 : https://cloud.google.com/load-balancing/docs/https/

 

LoadBalancing 비교

Internal or external Load balancer type Regional or global Supported network  tiers Proxy or pass-through Traffic type
Internal Internal TCP/UDP Regional

Premium only Pass-through TCP or UDP
Internal HTTP(S) Proxy HTTP or HTTPS
External Network TCP/UDP Premium or Standard Pass-through TCP or UDP
TCP Proxy Global in Premium Tier Proxy TCP
SSL Proxy Proxy SSL
HTTP(S) Proxy HTTP or HTTPS

(출처 : https://cloud.google.com/load-balancing/docs/load-balancing-overview?hl=en)

 

다른글

2019/07/28 - [Development/GoogleCloud] - [GCP]Network TCP/UDP Load Balancing

 

참고 자료

https://cloud.google.com/load-balancing/docs/https/

https://google.qwiklabs.com/focuses/558?parent=catalog

https://cloud.google.com/sdk/gcloud/reference/compute/instance-groups/set-named-ports

728x90
반응형

'Development > GoogleCloud' 카테고리의 다른 글

[GCP] Google Cloud Storage Options.  (0) 2019.12.12
[GCP]VPC Network  (0) 2019.08.03
[GCP] Network  (0) 2019.08.01
[GCP]Network TCP/UDP Load Balancing  (0) 2019.07.28
[GCP] Google Cloud 컨테이너 레지스트리에 이미지 push 하기  (0) 2018.10.19
반응형

Network Load Balancer 는 같은 region의 vm 들의 트래픽을 분배해준다.

다시 말해 동일한 Network Load Balancer 를 사용하는 vm 들은 동일한 region에 존재한다.

 

다음과 같은 방법으로 Network Load Balancer 를 생성할 수 있다.

 

1. target pool 생성

target pool 은 forwarding rule 에 정의된 traffic을 받을수 있는 instance group 이다.

gcloud compute target-pools create nginx-pool

 

2. instance group 생성

gcloud compute instance-groups managed create nginx-group \
         --base-instance-name nginx \
         --size 2 \
         --template nginx-template \
         --target-pool nginx-pool

template 에 정의된 nginx-template 은 미리 만들어야 한다. 

 

3. forwarding rule  생성

gcloud compute forwarding-rules create nginx-lb \
         --region us-central1 \
         --ports=80 \
         --target-pool nginx-pool

 

다른글

2019/07/31 - [Development/GoogleCloud] - [GCP]Http Load Balancer

 

참고자료

https://google.qwiklabs.com/focuses/558?parent=catalog&qlcampaign=1c-ccace-12

https://cloud.google.com/load-balancing/docs/network/

 

728x90
반응형

'Development > GoogleCloud' 카테고리의 다른 글

[GCP] Google Cloud Storage Options.  (0) 2019.12.12
[GCP]VPC Network  (0) 2019.08.03
[GCP] Network  (0) 2019.08.01
[GCP]HTTP(S) Load Balancing  (0) 2019.07.31
[GCP] Google Cloud 컨테이너 레지스트리에 이미지 push 하기  (0) 2018.10.19
반응형

Pivotal 에서 개최한 Cloud-Native Day 세미나에 다녀왔다.

 

https://connect.pivotal.io/CND_Seoul_2019.html

 

Pivotal Cloud Native Day 2019 Seoul

Pivotal combines our cloud-native platform, developer tools, and unique methodology to help the world’s largest companies transform the way they build and run their most important applications. Our technology is used by Global 2000 companies to achieve str

connect.pivotal.io

요즘 관심을 갖고 있는 주제가 Cloud, Kubernetes, Microservice 였는데 마침 Pivotal 에서 Microservice  관련 해서 세미나를 해서 아주 기쁜 마음으로 다녀왔다.

클라우드 네이티브 IT를 위한 4가지 요소와 상관관계
- DevOps, CI/CD, Container, MSA

클라우드 네이티브로 가기 위한 4가지 요소로 DevOps, CI/CD, Container, MSA 를 꼽았다. 각각의 요소들은 다음과 같은 의미를 가지고 있다.

DevOps : 작은 단위의 조직. (보통 Two Pizza team 이라고 많이들 한다.)

CI/CD : 자동화, 시각화, 프로세스의 단순화

MSA : 컴포넌트 단위의 모듈화

Container : MSA를 활용할 수 있는 infra적 요소

 

현재 모놀리스 환경의 어플리케이션들이 클라우드 네이티브로 가기 위해서는 단순히 MSA 적용한다고 해서 되는것은 아니다. 그것을 운영, 개발하는 조직부터 시작해서 모든것이 그것을 잘 활용할 수 있도록 변해가야 가능한 일이다.

 

그리고 왼쪽 사진의 표에 보면 MSA 라면 한가닥 하는 회사들이 나와있다. 그 회사들의 어플리케이션 배포 주기, 배포 준비 시간을 보면 정말 놀랄만 하다. 대부분 실시간으로 사용자에게 서비스를 하는 회사들인대에도 불구하고 일단위로 배포 횟수가 상상을 초월한다. 우리 회사에서는 부끄럽지만 상상도 할수 없는 수치이다. 그런데 그보다 더 중요한 부분이 아래 빨간색으로 써있다. 배포 횟수가 중요한게 아니라 배포가 필요할때 즉시 배포 할수 있는 환경이 중요한 것이다. 여기서 말하는 배포는 무중단 배포를 의미한다. 배포때문에 사용자가 서비스를 사용하지 못하는 그런 배포를 의미하는게 아니다. (그런거 직접 경험 하면 뿌듯할것 같다... )


마이크로서비스 어떻게 디자인할 것인가.
- Pivotal AppTX

MSA를 할때 항상 고민이 되는게 Bounded Context 이다. 대체 어디까지를 하나의 서비스로 볼것인가. 

Pivotal 에서는 다음과 같은 절차로 진행을 한다고 한다. 

1. 목표설정

2. Event Storm

Event Storming 을 통해서 필요한 Event 들을 도출한다. 이건 개발자만 하는게 아니다. 개발자, 설계자, 운영자(현업?) 등이 모여서 실제 모습을 도출해 낸다. 여기에는 프로그래밍적 요소는 없다. 그리고 이것을 통해 서비스의Bounded Context를 설정한다. 

 

3. Thin Slice

Event Storming 을 통해 도출된 내용중 하나의 서비스를 선택한다. 

 

4. Boris

Boris Diagram 을 만든다. 서비스의 흐름에서 발생하는 이벤트 들을 도식화 한것이다. 이걸 함으로써 하나의 서비스에 대한 전체적인 아키택처를 확인할 수 있다. 

(화면에서 보면 포스트잇과 종이를 이용해서 했는데 툴을 사용하지 않는 이유는 툴을 사용하면 툴로 내용을 적는 사람이 말이 많아지며 다른 사람의 참여가 낮아지기 때문이라고 한다. 그리고 종이와 포스트잇을 가지고 하는것 보다 효율적인 툴을 아직까지는 보지 못했다고 한다. Event Storming 때에도 포스트잇과 종이를 이용한다고 한다. )

 

5. Snap-E

이 단계 에서는 각 단위의 api 를 정의하고 데이터 처리 및 로직을 정의한다.

 

6. 테스트 완료 및 코드 생성

7. 재사용 가능한 패턴 정리

 

이렇게 사이클이 마무리 되면 아래와 같은 흐림이 나오게 된다. 

오늘 들은 내용들 중에서 가장 기억에 남는 세션이었다. 요즘 회사에서 개발을 하면 그냥 화면 단위로 하나씩 쪼개서 맡아서 개발한다. 저렇게 서비스에 대한 내용을 다같이 모여서 그려본다든지 해본적은 거의 없었던것 같다. 단지 말로 전달 받고 그때그때 물어가면서 개발을 했다. 그런데 생각해보면 안한거지 못할 정도의 상황은 아닌것 같다. 그리고 이렇게 포스트잇으로 그려보면서 하면 좀더 재미있고 구체적인 설계가 가능하지 않을까 생각이 들었다.


마이크로서비스 어떻게 구현할 것인가.

구현의 측면에는 다른것도 다 쉽지는 않지만 특히 Database, Transaction 부분이 어렵다고 한다. 그래서 Cache, Event Sourcing 등을 사용해서 어려운 부분들을 해결한다고 한다. 


클라우드 네이티브 플랫폼의 미래
- Kubernetes 기반의 PCF 로드맵

PCF가 지향하려는 방향이 멀티 클라우드에서 벤더에 관계 없이 서비스를 사용할수 있게 해주고 개발자는 서비스 개발에만 집중할수 있도록 만들어주는 것이다. 그걸 위해서 Istio 와 Envoy 를 사용하고 있다고 한다. 이 두개는 전에 Google Cloud 세미나에서도 자주 언급되었던 건데 내용을 좀더 자세하게 살펴봐야겠다.

또 추가적으로 빌드팩에 대해서도 설명을 했다.

보통 도커 이미지를 만들려면 사용자가 필요한 라이브러리들을 Dockerfile에 정의하고 해야 하는데 빌드팩은 그런게 필요 없었다.

개발자가 서비스를 개발해서 PKS에 cf push 를 통해서 올리면 자동으로 필요한 라이브러리들을 찾아서 이미지를 만들어준다. 그리고 도커 이미지의 특정 레이어를 rebase 해서 교체를 할수 있다. (이게 좀 신기했다.)


Pivotal Concourse 를 활용한 CI/CD pipeline automated build-up & Workflow management solution 소개

CI/CD 툴로 Jenkins가 아닌 Concourse를 소개하는 세션이었다. 

Jenkins 가 UI 를 통해서 쉽게 Build pipeline을 만들 수 있는데 오히려 그 부분이 약점이 라고 한다. Concourse  는 특정 파이프라인을 만들고 지우고 또 새로 생성하는 모든 부분들을 yaml을 파일에 정의해서 자동으로 실행을 할수 있다. 그런데 yaml 파일 작성이 쉽지는 않다고 들었던것 같다. ^^;


숨겨진 마이크로서비스

캐시, 메세지 큐에 대한 내용이 많았다. 그리고 MSA를 위한 여러가지 아키텍처에 대한 설명도 있었는데 역시 마지막 시간은 집중력이 떨어졌다. ^^;; 특히 Kafka 를 로그를 위한 장치가 아닌 다른 용도로 응용해서 사용할수도 있는데 꼭 알아두라고 한다. 전에 개인 발표 때문에 Kafka 쓰다가 사리 나올뻔 했는데 이번 기회에 다시 한번 보는것도 좋을것 같다. 


 

언제나 그랬듯이 세미나를 들으면 공부 뽐뿌가 오게 된다. 일단 적어두고 차근차근 알아보자.!!!

Kafka, EvCache, Istio, Envoy

 

그리고 올해도 역시 spring one 행사가 열린다. 얼리버드는 할인을 해준다는데...정말 가고싶다. ㅠㅠ 언제쯤 한번 가볼수 있으려나...

 

728x90
반응형

+ Recent posts