내배캠 65일차

·2023년 1월 17일
0

내일배움캠프

목록 보기
70/142
post-thumbnail

서버 이중화

Active - Active

서버 두 대를 모두 운영하는 방식을 active - active라고 부릅니다. 서버 두 대가 모두 활성화(active) 상태라는 개념이기 때문에 이해가 어렵진 않습니다. 두 서버 모두 일을 하다가 한쪽 서버에 문제가 발생하면 나머지 한쪽이 모든 트래픽을 처리합니다. 장애가 발생해도 시스템을 사용할 수 없는 시간인 다운타임(downtime)이 없습니다.

두 서버는 트래픽을 어떤 기준으로 나눠서 처리할까요? 이 질문에 대한 답을 로드밸런싱(load balancing)이라고 하며, L4 스위치 같은 하드웨어 장비가 로드밸런서 역할을 합니다. L4 스위치는 클라이언트로부터 받은 트래픽을 정해진 기준에 따라 서버 두 대가 나눠서 처리할 수 있도록 보내줍니다. 예를 들어, 기계적으로 양쪽 서버에 번갈아가면서 한 번씩 주는 방법, 커넥션이 작은 곳에 주는 방법, 두 개를 동시에 주고 응답이 빠른 곳을 선택하는 방법, 사용자 IP를 기준으로 접속시키는 방법 등이 있습니다. 참고로 L4 스위치는 OSI 7 계층 중 4번째 계층인 전송 계층(transport layer)에서 작동하는 장비이기 때문에 붙은 이름입니다.

Active - Standby

서버 두 대 중 하나만 운영 서버로 활용하고, 나머지 한 대는 장애 발생 시 운영 서버를 대체해서 작동하는 방식을 active - standby 방식이라고 부릅니다. 엑티브 서버에 장애가 발생하면 수동 또는 자동으로 스탠바이 서버를 작동시켜 대응합니다. 다만 스탠바이 서버가 액티브 서버를 문제없이 대체하기 위해선 평소 액티브 서버의 데이터를 스탠바이 서버의 데이터와 동기화하는 작업이 필요할 수 있습니다.

typescript

사용한 github주소

tsconfig.json 수정 및 package 셋팅

types 라이브러리

바로 전 날에 typescript파일에서 console.log를 사용하기 위해서 tsconfig.json파일에서
lib에 dom을 추가했었다.
이번엔 lib의 dom을 없애주고, types 라이브러리를 이용해서 console.log를 오류없이 사용할 것.

npm init -y
npm i @types/node

ts-node

전에는 typescript를 tsc로 javascript파일을 만들어서 실행했는데, 이번에는 ts-node를 이용해서 javascript파일을 따로 생성하지않고 변환만 해서 바로 실행을 시킬 수 있다!

npm i -g ts-node

ts-node 파일명.ts

기본 타입

1. 불리언 (Boolean)

가장 기본적인 데이터 타입은 JavaScript, TypeScript에서 boolean
값이라고 일컫는 참/거짓(true/false) 값입니다.

let isDone: boolean = false;

2. 숫자 (Number)

JavaScript처럼, TypeScript의 모든 숫자는 부동 소수 값입니다. 부동 소수에는 number
라는 타입이 붙혀집니다. TypeScript는 16진수, 10진수 리터럴에 더불어, ECMAScript 2015에 소개된 2진수, 8진수 리터럴도 지원합니다.

let decimal: number = 6; //6
let hex: number = 0xf00d; //61453 - 16진수
let binary: number = 0b1010; //10 - 2진수
let octal: number = 0o744; //484 - 8진수

3. 문자열 (String)

웹 페이지, 서버 같은 프로그램을 JavaScript로 만들 때 기본적으로 텍스트 데이터를 다루는 작업이 필요합니다. 다른 언어들처럼, TypeScript에서는 텍스트 데이터 타입을 string
으로 표현합니다. JavaScript처럼 TypeScript도 큰따옴표 (")나 작은따옴표 (')를 문자열 데이터를 감싸는데 사용합니다.

또한 템플릿 문자열 을 사용하면 여러 줄에 걸쳐 문자열을 작성할 수 있으며, 표현식을 포함시킬 수도 있습니다. 이 문자열은 백틱/백쿼트 (``) 문자로 감싸지며, ${ expr }`과 같은 형태로 표현식을 포함시킬 수 있습니다.

let color: string = "blue";
console.log(color);
color = "red";
console.log(color);

let fullName: string = `Bob Bobbington`;
let age: number = 37;
let sentence: string = `Hello, my name is ${fullName}.
I'll be ${age + 1} years old next month.`;
console.log(sentence);

// blue
// red
// Hello, my name is Bob Bobbington.
// I'll be 38 years old next month.

4. 배열 (Array)

TypeScript는 JavaScript처럼 값들을 배열로 다룰 수 있게 해줍니다. 배열 타입은 두 가지 방법으로 쓸 수 있습니다. 첫 번째 방법은, 배열 요소들을 나타내는 타입 뒤에 []를 쓰는 것입니다:

let list1: number[] = [1, 2, 3];
let list2: string[] = ["안", "녕", "하", "세", "요"];

두 번째 방법은 제네릭 배열 타입을 쓰는 것입니다. Array

let list3: Array<number> = [1, 2, 3];
let list4: Array<string> = ["안", "녕"];

5. 튜플 (Tuple)

튜플 타입을 사용하면, 요소의 타입과 개수가 고정된 배열을 표현할 수 있습니다. 단 요소들의 타입이 모두 같을 필요는 없습니다. 예를 들어, numberstring 이 쌍으로 있는 값을 나타내고 싶을 수 있습니다:

// 튜플 타입으로 선언
let x: [string, number];

// 초기화
x = ["hello", 10]; // 성공

// 잘못된 초기화
x = [10, "hello"]; // 오류

정해진 인덱스에 위치한 요소에 접근하면 해당 타입이 나타납니다.

console.log(x[0].substring(1)); // 성공 - ello
console.log(x[1].substring(1)); // 오류, 'number'에는 'substring' 이 없습니다.

정해진 인덱스 외에 다른 인덱스에 있는 요소에 접근하면, 오류가 발생하며 실패합니다.

x[3] = "world"; // 오류, '[string, number]' 타입에는 프로퍼티 '3'이 없습니다.
    
console.log(x[5].toString()); // '[string, number]' 타입에는 프로퍼티 '5'가 없습니다.

6. 열거 (Enum)

JavaScript의 표준 자료형 집합과 사용하면 도움이 될만한 데이터 형은 enum입니다. C# 같은 언어처럼, enum은 값의 집합에 더 나은 이름을 붙여줄 수 있습니다.

enum Color {Red, Green, Blue}
let c: Color = Color.Green;
//console.log(c) = 1

기본적으로, enum은 0부터 시작하여 멤버들의 번호를 매깁니다. 멤버 중 하나의 값을 수동으로 설정하여 번호를 바꿀 수 있습니다. 예를 들어, 위 예제를 0대신 1부터 시작해 번호를 매기도록 바꿀 수 있습니다.

enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;

또는, 모든 값을 수동으로 설정할 수 있습니다.

enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;

enum의 유용한 기능 중 하나는 매겨진 값을 사용해 enum 멤버의 이름을 알아낼 수 있다는 것입니다. 예를 들어, 위의 예제에서 2라는 값이 위의 어떤 Color enum 멤버와 매칭되는지 알 수 없을 때, 이에 일치하는 이름을 알아낼 수 있습니다

enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];
    
console.log(colorName); // 값이 2인 'Green'이 출력됩니다.

7. Any

애플리케이션을 만들 때, 알지 못하는 타입을 표현해야 할 수도 있습니다. 이 값들은 사용자로부터 받은 데이터나 서드 파티 라이브러리 같은 동적인 컨텐츠에서 올 수도 있습니다. 이 경우 타입 검사를 하지 않고, 그 값들이 컴파일 시간에 검사를 통과하길 원합니다. 이를 위해, any타입을 사용할 수 있습니다 => 근데 Any 타입을 쓰게되면 typescript를 쓰는 의미가 없기 때문에 지양하는 것이 좋음!

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // 성공, 분명히 부울입니다.

8. Void

void는 어떤 타입도 존재할 수 없음을 나타내기 때문에, any의 반대 타입 같습니다. void보통 함수에서 반환 값이 없을 때 반환 타입을 표현하기 위해 쓰이는 것을 볼 수 있습니다:

function warnUser(): void {
  console.log("This is my warning message");
}

void를 타입 변수를 선언하는 것은 유용하지 않은데, 왜냐하면 그 변수에는 null (--strictNullChecks을 사용하지 않을 때만 해당, 자세한 건 다음 섹션을 참고)또는 undefined 만 할당할 수 있기 때문입니다:

let unusable: void = undefined;
unusable = null; // 성공  `--strictNullChecks` 을 사용하지 않을때만

9. Null and Undefined

TypeScript는 undefined 과 null 둘 다 각각 자신의 타입 이름으로 undefinednull로 사용합니다. void처럼 그 자체로 유용한 경우는 거의 없습니다:

    // 이 밖에 이 변수들에 할당할 수 있는 값이 없습니다!
    // 타입이자, 값
    let u: undefined = undefined;
    let n: null = null;

10. Never

never 타입은 절대 발생할 수 없는 타입을 나타냅니다. 예를 들어, never는 함수 표현식이나 화살표 함수 표현식에서 항상 오류를 발생시키거나 절대 반환하지 않는 반환 타입으로 쓰입니다. 변수 또한 타입 가드에 의해 아무 타입도 얻지 못하게 좁혀지면 never 타입을 얻게 될 수 있습니다.

never타입은 모든 타입에 할당 가능한 하위 타입입니다. 하지만 어떤 타입도 never에 할당할 수 있거나, 하위 타입이 아닙니다.(never 자신은 제외) 심지어 any 도 never에 할당할 수 없습니다.

never를 반환하는 몇 가지 예제입니다:

    // never를 반환하는 함수는 함수의 마지막에 도달할 수 없다.
    function error(message: string): never {
        throw new Error(message);
    }
    
    // never를 반환하는 함수는 함수의 마지막에 도달할 수 없다.
    function infiniteLoop(): never {
        while (true) {
        }
    }

11. 객체 (Object)

object는 원시 타입이 아닌 타입을 나타냅니다. 예를 들어, 
numberstringbooleanbigintsymbolnull, 또는 undefined 가 아닌 나머지를 의미합니다.

    // **|** => union 타입 강의 찍을때 교차타입이라고 설명을 잘못했습니다.
    function create(o: object | null): void {}
    
    create({ prop: 0 }); // 성공
    create(null); // 성공
    
    create(42); // 오류
    create("string"); // 오류
    create(false); // 오류
    create(undefined); // 오류

12. 타입 단언 (Type assertions)

가끔, TypeScript보다 개발자가 값에 대해 더 잘 알고 일을 때가 있습니다. 대개, 이런 경우는 어떤 엔티티의 실제 타입이 현재 타입보다 더 구체적일 때 발생합니다.

타입 단언(Type assertions) 은 컴파일러에게 "날 믿어, 난 내가 뭘 하고 있는지 알아"라고 말해주는 방법입니다. 타입 단언은 다른 언어의 타입 변환(형 변환)과 유사하지만, 다른 특별한 검사를 하거나 데이터를 재구성하지는 않습니다. 이는 런타임에 영향을 미치지 않으며, 온전히 컴파일러만 이를 사용합니다. 타입 스크립트는 개발자가 필요한 어떤 특정 검사를 수행했다고 인지합니다.

타입 단언에는 두 가지 형태가 있습니다. 하나는, "angle-bracket" 문법입니다:

    let someValue: any = "this is a string";
    
    let strLength: number = (<string>someValue).length;

다른 하나는 as-문법 입니다.

    let someValue: any = "this is a string";
    
    let strLength: number = (someValue as string).length;

위 두 예제는 동일합니다. 어떤 것을 사용할지는 주로 선호에 따른 선택입니다. 하지만 TypeScript를 JSX와 함께 사용할 때는, as-스타일의 단언만 허용됩니다.

interface

인터페이스

인터페이스는 상호 간에 정의한 약속 혹은 규칙을 의미합니다. 타입스크립트에서의 인터페이스는 보통 다음과 같은 범주에 대해 약속을 정의할 수 있습니다.

  • 객체의 스펙(속성과 속성의 타입)
  • 함수의 파라미터
  • 함수의 스펙(파라미터, 반환 타입 등)
  • 배열과 객체를 접근하는 방식
  • 클래스
function printLabel(labeledObj: { label: string }) {
    console.log(labeledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

타입 검사는 printLabel 호출을 확인합니다. printLabel 함수는 string 타입 label을 갖는 객체를 하나의 매개변수로 가집니다. 이 객체가 실제로는 더 많은 프로퍼티를 갖고 있지만, 컴파일러는 최소한 필요한 프로퍼티가 있는지와 타입이 잘 맞는지만 검사합니다. TypeScript가 관대하지 않은 몇 가지 경우는 나중에 다루겠습니다.

이번엔 같은 예제를, 문자열 타입의 프로퍼티 label을 가진 인터페이스로 다시 작성해 보겠습니다:

interface LabeledValue {
    label: string;
}

function printLabel(labeledObj: LabeledValue) {
    console.log(labeledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

LabeledValue 인터페이스는 이전 예제의 요구사항을 똑같이 기술하는 이름으로 사용할 수 있습니다. 이 인터페이스는 여전히 문자열 타입의 label 프로퍼티 하나를 가진다는 것을 의미합니다. 다른 언어처럼 printLabel에 전달한 객체가 이 인터페이스를 구현해야 한다고 명시적으로 얘기할 필요는 없습니다. 여기서 중요한 것은 형태뿐입니다. 함수에 전달된 객체가 나열된 요구 조건을 충족하면, 허용됩니다.

타입 검사는 프로퍼티들의 순서를 요구하지 않습니다. 단지 인터페이스가 요구하는 프로퍼티들이 존재하는지와 프로퍼티들이 요구하는 타입을 가졌는지만을 확인합니다.

선택적 프로퍼티 (Optional Properties)

interface CraftBeer {
  name: string;
  hop?: number;
}

let myBeer = {
  name: "Saporo",
};

function brewBeer(beer: CraftBeer) {
  console.log(beer.name); // Saporo
}

brewBeer(myBeer);

읽기전용 프로퍼티 (Readonly properties)

일부 프로퍼티들은 객체가 처음 생성될 때만 수정 가능해야합니다. 프로퍼티 이름 앞에 readonly를 넣어서 이를 지정할 수 있습니다:

interface Point {
    readonly x: number;
    readonly y: number;
}

let p1: Point = { x: 10, y: 20 };
p1.x = 5; // 오류!

readonly vs const

readonly와 const 중에 어떤 것을 사용할 지 기억하기 가장 쉬운 방법은 변수와 프로퍼티중 어디에 사용할지 질문해 보는 것입니다. 변수는 const를 사용하고 프로퍼티는 readonly를 사용합니다.

함수 타입

인터페이스는 함수의 타입을 정의할 때에도 사용할 수 있습니다.

interface login {
  (username: string, password: string): boolean;
}

함수의 인자의 타입과 반환 값의 타입을 정합니다.

let loginUser: login;

loginUser = function(id: string, pw: string) {
  console.log('로그인 했습니다');
  return true;
}

클래스 타입

C#이나 자바처럼 타입스크립트에서도 클래스가 일정 조건을 만족하도록 타입 규칙을 정할 수 있습니다

interface CraftBeer {
  beerName: string;
  nameBeer(beer: string): void;
  // test: string;
}

class myBeer implements CraftBeer {
  beerName: string = "Baby Guinness";
  nameBeer(b: string) {
    this.beerName = b;
  }
  constructor() {}
}

인터페이스 확장

클래스와 마찬가지로 인터페이스도 인터페이스 간 확장이 가능합니다.

interface Person {
  name: string;
}

interface Developer extends Person {
  skill: string;
}

let fe = {} as Developer;

fe.name = 'josh';
fe.skill = 'TypeScript';

혹은 아래와 같이 여러 인터페이스를 상속받아 사용할 수 있습니다.

interface Person {
  name: string;
}

interface Drinker {
  drink: string;
}

// 다중상속도 가능
interface Developer extends Person, Drinker {
  skill: string;
}

let fe = {} as Developer;
fe.name = 'josh';
fe.skill = 'TypeScript';
fe.drink = 'Beer';

참고 문서

핸드북 영어 - https://www.typescriptlang.org/docs/handbook/intro.html

핸드북 한글- https://typescript-kr.github.io/pages/tutorials/ts-for-the-new-programmer.html

장기효 - https://joshua1988.github.io/ts/intro.html

profile
개발자 꿈나무

0개의 댓글