Jun 5, 2019 - 자바 아키텍쳐 공부

아키텍쳐 : 프로젝트에 참여하는 개발자들이 설계에 대해 공유하는 이해를 반영하는 주관적인 개념

  • 중요한 것
  • 변경하기 어려운 것
  • 가급적이면, 일찍, 올바르게 바꾸고 싶은 것

레이어 아키텍쳐 : 유사한 관심사들을 레이어로 나눠서 수직적으로 배열 (간단하게 케익 같은 구조.)

  • 유사한 얘들은 한 레이어에 만들어두었으니 그 레이어를 빼서 다른 곳으로 바꾸는 것이 가능.
  • 프리젠테이션 레이어 : 화면 조작, 사용자의 입력을 처리하기 위한 관심사를 처리함.
  • 도메인 레이어 : 도메인적인 내용을 묶어서 처리
  • 데이타소스 레이어 : 데이터를 관리하기 위한 부분들을 전부 묶어서 처리

Jun 4, 2019 - 클라우드 온보드

Cloud OnBoard

클라우드 온보드 (Cloud OnBoard)는 하루동안 무료로 제공되는 교육 이벤트로서 GCP(Google Cloud Platform)의 기술적 측면을 강의식으로 세세하게 소개해준다고 하여 참석하게 되었습니다.

클라우드 온보드 - 서울이 2018년 12월 6일 목요일에 개최됩니다.

08:30 AM	행사 등록
10:00 AM	환영 인사 및 키노트
10:40 AM	모듈 1 - Google Cloud Platform 소개
11:20 AM	모듈 2 - Google Cloud Platform 시작하기
12:00 PM	점심식사
01:00 PM	모듈 3 - 클라우드 환경에서의 가상 머신
01:40 PM	모듈 4 - 클라우드 스토리지
02:30 PM	모듈 5 - 클라우드 컨테이너 서비스
03:00 PM	휴식 시간
03:30 PM	모듈 6 - 클라우드 애플리케이션
04:00 PM	모듈 7 - 클라우드 환경에서의 개발, 배포 그리고 모니터링
04:30 PM	모듈 8 - 클라우드 빅데이터 및 머신러닝
05:00 PM	폐회사 및 경품 추첨

개별 세션과 기술 시연을 통해 Google App Engine, Datastore, Storage, Container Engine, Compute Engine 및 네트워크, 빅데이터, 머신러닝에 처음 입문하시는 분들에게 길잡이가 되어준다고 하였습니다.

  • SDN
    • 지역에 개념을 띄어넘을 수 있게 되었다.
    • 하나의 네트워크에서 여러 지역을 묶을 수 있다. HUB을 건널필요가 없다. (라우터 개념이 없다.)
    • 전세계를 하나의 네트워크로 관리할 수 있다.

traceroute 외부 아이피를 요청할 경우, Internal 네트워크(사설망)을 연결했을 경우, 하나의 홉으로만 연결할 수 있게 됩니다. 홉이 훨씬 줄어들며 속도도 빨라진다.

Virtual Private Cloud 네트워크

  • VPC
    • subnets = 20 –> 각 리젼별로 존재함.

    스토리지에서 메모리로 갈때는 느리기 때문에 메모리와 스토리지를 떨어뜨리는것은 매우 어려운 일이입니다.

    1.3 Pbps (페타피트) Bisection Brandwidth 라고합니다. 우리 회사는 4gbps 인 IDC를 사용하고 있는데, 정말 놀랍습니다.
    실제 서버를 사용하다보면, 4 gbps 의 반도 사용하지 못해 스위치에 부담이 되어 지연이 발생하게 되는데, 실제 스위치라든가 해당 기능에 대해서 궁금합니다.

IaaS : 컴퓨팅, 스토리지, 네트워크 더 세부적으로 제어

PaaS : 런타임 사전 설정, 자바 Go, PHP, Pyhoen 등의 어플리케이션

쿠버네티스 : Kubernetes : K8S : 현재 표준화가 되었따. 하이브리드/멀티 클라우드 세상을 고려한 설계.

컨테이너가 많아 그걸 조절할 수 있는 기능이 만들어졌습니다. 그게 쿠버네티스

Jun 3, 2019 - 이펙티브 자바_01

«««< HEAD 아키텍쳐 : 프로젝트에 참여하는 개발자들이 설계에 대해 공유하는 이해를 반영하는 주관적인 개념

  • 중요한 것
  • 변경하기 어려운 것
  • 가급적이면, 일찍, 올바르게 바꾸고 싶은 것

레이어 아키텍쳐 : 유사한 관심사들을 레이어로 나눠서 수직적으로 배열 (간단하게 케익 같은 구조.)

  • 유사한 얘들은 한 레이어에 만들어두었으니 그 레이어를 빼서 다른 곳으로 바꾸는 것이 가능.
  • 프리젠테이션 레이어 : 화면 조작, 사용자의 입력을 처리하기 위한 관심사를 처리함.
  • 도메인 레이어 : 도메인적인 내용을 묶어서 처리
  • 데이타소스 레이어 : 데이터를 관리하기 위한 부분들을 전부 묶어서 처리

                    Pattern urlPattern = Pattern.compile("^(http[s]?):\\/\\/([^:\\/\\s]+)(:([^\\/]*))?((\\/[^\\s/\\/]+)*)?\\/([^#\\s\\?]*)(\\?([^#\\s]*))?(#(\\w*))?$");
                    Matcher mc = urlPattern.matcher(this.domain);
                    if (mc.matches()) {
                        this.domain = mc.group(2);
                    }
    

http 를 찾는 로직입니다.
urlPattern 이라는 String 을 정규표현식에서 문자열 형태를 확인하는 가장 쉬운 방법이지만, 성능이 중요한 상황에서는 반복해 사용하기에 적합하지 않다고 써져있습니다.
이 메서드가 내붕네서 만드는 정규표현식용 Pattern 인스턴스는, 한번 쓰고 버려져 곧바로 가비지 컬렉션 대상이 된다고 합니다.

Pattern은 입력받은 정규표현식에 해당하는 유한 상태머신(finite state machine)을 만듥기 때문에 인스턴스 생성 비용이 높다고 하여, 성능을 개선하기 위해서 정규표현식을 표현하는 (불변인) Pattern 인스턴스를 초기화(정적 초기화)과정에서 직접 생성해 캐싱해두고, 나중에 static 메소드로 반복하여 이 인스턴스를 재사용하는 방법을 가이드 주었습니다.

private static final Pattern URL_PATTERN = Pattern.compile("^(http[s]?):\\/\\/([^:\\/\\s]+)(:([^\\/]*))?((\\/[^\\s/\\/]+)*)?\\/([^#\\s\\?]*)(\\?([^#\\s]*))?(#(\\w*))?$");

public static String isUrlPattern(String url) {
  Matcher mc = URL_PATTERN.matcher(url);
  if (mc.matches()) {
    return mc.group(2);
  }
  try {
    String[] temp = url.split("\\?");
    return temp[0];
  } catch (Exception e) {
    return url;
  }
}

이렇게 처리했을 때, 빈번히 호출되는 상황에서 성능을 상당히 끌어올릴 수 있다고 합니다. 테스트를 위해 임시 테스트 클래스를 생성했습니다.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

    public static void main(String[] args) {
        long start = System.currentTimeMillis(); //시작하는 시점 계산
        for (int i = 0; i < 100000; i++) {
            PastternTest.isUrlPattern("www.daum.net");
        }
        long end = System.currentTimeMillis(); //프로그램이 끝나는 시점 계산
        System.out.println("실행 시간 : " + (end - start) / 1000.0 + "초"); //실행 시간 계산 및 출력


        start = System.currentTimeMillis(); //시작하는 시점 계산
        for (int i = 0; i < 100000; i++) {
            PastternTest.isUrlPattern2("www.daum.net");
        }
        end = System.currentTimeMillis(); //프로그램이 끝나는 시점 계산
        System.out.println("실행 시간 : " + (end - start) / 1000.0 + "초"); //실행 시간 계산 및 출력
    }


    private static class PastternTest {
        private static final Pattern URL_PATTERN = Pattern.compile("^(http[s]?):\\/\\/([^:\\/\\s]+)(:([^\\/]*))?((\\/[^\\s/\\/]+)*)?\\/([^#\\s\\?]*)(\\?([^#\\s]*))?(#(\\w*))?$");

        private static String isUrlPattern(String url) {
            Matcher mc = URL_PATTERN.matcher(url);
            if (mc.matches()) {
                return mc.group(2);
            }
            try {
                String[] temp = url.split("\\?");
                return temp[0];
            } catch (Exception e) {
                return url;
            }
        }

        private static String isUrlPattern2(String url) {
            Pattern URL_PATTERN2 = Pattern.compile("^(http[s]?):\\/\\/([^:\\/\\s]+)(:([^\\/]*))?((\\/[^\\s/\\/]+)*)?\\/([^#\\s\\?]*)(\\?([^#\\s]*))?(#(\\w*))?$");
            Matcher mc = URL_PATTERN2.matcher(url);
            if (mc.matches()) {
                return mc.group(2);
            }
            try {
                String[] temp = url.split("\\?");
                return temp[0];
            } catch (Exception e) {
                return url;
            }
        }
    }
}

100000 번 돌렸을 때 결과는 다음과 같았습니다.

실행 시간 : 0.029초
실행 시간 : 0.308초

대략 9~10배 정도의 성능향상이 생길 것으로 기대됩니다.