본문 바로가기

정보처리기사 실기/02. 응용SW엔지니어링

[2020 정보처리기사 실기 - 애플리케이션 테스트 관리] 3. 애플리케이션 성능 개선하기

 

 

 

 

* 애플리케이션 성능 분석

 

1) 애플리케이션 성능 점검의 개요

- 사용자의 요구 기능을 해당 애플리케이션이 최소의 자원을 사용하면서 얼마나 빨리 많은 기능을 수행하는가를 점검

- 애플리케이션의 성능을 측정하기 위한 지표

   처리량 : 애플리케이션이 주어진 시간에 처리할 수 있는 트랜잭션의 수로, 웹 애플리케이션의 경우 시간당 페이지 수로 표현

   응답 시간 : 입력 후 출력까지 시간을 의미, 웹 애플리케이션의 경우 메뉴 클릭 시 해당 메뉴가 나타나기까지 걸리는 시간

   경과 시간 : 사용자가 요구를 입력한 시점부터 트랜잭션 처리 후 출력이 완료할 때까지 걸리는 시간

   자원 사용률 : 애플리케이션이 트랜잭션 처리하는 동안 사용하는 CPU 사용량, 메모리 사용량, 네트워크 사용량

- 유형별 서능 분석 도구

   성능/부하/스트레스 점검 도구 : 가상의 사용자를 점검 도구 상에서 인위적으로 생성하고

                                                             시스템의 부하나 스트레스를 통해 성능 측정지표인 처리량, 응답 시간, 경과 시간을 점검하는 도구

   모니터링 도구 : 실행 시 자원 사용량을 확인하고 분석 가능한 도구

                                성능 모니터링, 성능 저하 원인 분석, 시스템 부하량 분석, 장애 진단, 사용자 분석, 용량 산정 등의 기능 제공

 

2) 애플리케이션 성능 저하 원인 분석

- DB연결 및 쿼리 실행 시 발생되는 성능 저하 원인

   DB에 연결하기 위해 CONNECTION객체를 생성하거나 쿼리를 실행하는 애플리케이션 로직에서 성능 저하 또는 장애 많이 발견됨

   데이터베이스 락 : 대량의 데이터 조회, 과도한 업데이트, 인덱스 생성 시 발생하는 현상이고 작업은 락의 해제까지 대기나 타임아웃

   불필요한 데이터베이스 패치 : 실제 필요한 데이터보다 많은 대량의 데이터 요청이 들어올 경우

                                                          또는 결과 세트에서 마지막 위치로 커서를 옮기는 작업이 빈번한 경우 응답 시간 저하 현상 발생

   연결 누수/부적절한 커넥션 풀 크기 : 연결누수는 DB연결과 관련한 JDBC 객체를 사용하고 종료하지 않은 경우

                                                                      또는 커넥션 풀 크기를 너무 작거나 크게 설정한 경우 성능 저하 현상이 발생

   기타 : 트랜잭션이 확정되지 않고 커넥션 풀에 반환

               잘못 작성된 코드로 인해 불필요한 COMMIT이 자주 발생하는 경우 성능이 저하될 가능성이 존재

- 내부 로직으로 인한 성능 저하 원인

   웹 애플리케이션의실행 시 인터넷 접속 불량으로 서버 소캣 쓰기는 지속되나 클라이언트에서 읽기가 수행되지 않아서 성능저하

   대량의 파일을 업로드하거나 다운로드할 경우 처리시간이 길어져 어플리케이션의 성능이 저하

    오류처리로직과 실제 처리로직부분을 분리하지 않고 코딩하거나 예외가 발생할 경우에 제대로 처리되지 않아서 행이 걸림

- 외부 호출(HTTP, 소캣 통신)로 인한 성능 저하 원인 

   임의의 트랜잭션이 수행되는 동안 외부 트랜잭션이 장시간 수행되거나

   타임아웃이 일어나는 경우 성능 저하 현상이 발생

- 잘못된 환경 설정이나 네트워크 문제로 인한 성능 저하 원인

   환경설정으로 인한 성능 저하 : 스레드 풀, 힙 메모리의 크기를 너무 작게 설정하면 Heap Memory Full현상 발생

   네트워크 장비로 인한 성능 저하 : 라우터 L4 스위치 등 네트워크 관련 장비 간 데이터 전송 실패 또는 

                                                                전송 지연에 따른 데이터 손실 발생 시 애플리케이션의 성능 저하 또는 장애가 발생할 수 있음

 

 

 

* 애플리케이션 성능 개선

 

1) 소스코드 최적화의 이해

- 소스 코드 최적화는 읽기 쉽고 변경 및 추가가 쉬운 클린 코드를 작성하는 것

   소스 코드 품질을 위해 기본적으로 준수해야 할 원칙과 기준을 정의

- 나쁜코드 : 다른 개발자가 로직을 이해하기 어렵게 작성된 코드

                      스파게티 코드의 경우 잦은 오류가 발생할 수 있고, 소스 코드 이해가 안 되어 계속 덧붙이기 할 경우 복잡도 증가

  클린코드 : 잘 적성되어 가독성이 높고 단순하고 의존성을 줄이고 중복을 최소화하여 깔끔하게 잘 정리된 코드

                      중복 코드 제거로 애플리케이션의 설계가 개선되며,

                      가독성이 높아서 애플리케이션의 기능에 대해 쉽게 이해하고 버그를 찾기 쉬우며 프로그래밍 속도가 빨라짐 

- 코드리팩토링 : 외부동작을 바꾸지 않으면서 내부 구조를 개선하는 방법

                              SW 시스템을 변경하는 프로세스

                              겉으로 보이는 SW의 기능을 변경하지 않으면서 SW를 더 이해하기 쉽고 수정하기 쉽도록 만드는 기법

 

 

* 코드 리팩토링 종류

 

1) 메소드 정리

 - Extract Method : 그룹으로 함께 묶을 수 있는 코드 조각이 있으면, 코드의 목적이 잘 드러나도록 이름을 별도로 지어 뽑아냄

 - Inline Method : 메서드의 몸체가 메서드의 이름만큼 명확할 때, 호출하는 곳에서 메서드 몸체를 넣고 메서드 삭제

 - Inline Temp : 간단한 수식의 결과값을 가지는 임시변수가 있음

                               임시변수가 다른 리팩토링을 하는데 방해가 되면, 잉 임시변수를 참조하는 부분을 모두 원래의 수식으로 바꿈

 - Replace Explaining Variable :  복잡한 수식이 있으면 수식의 결과나 일부에 목적을 설명하는 이름의 임시변수를 사용

 - Split Temporary Variable : 루프 안에 있는 변수나 collecting temporary variable도 아닌 임시변수에 값을 여러번 할당할 경우

                                                         각각의 할당에 대해 따로따로 임시변수를 만듦

 - Replace Method with Method Object :  긴 메서드가 있는데, 지역변수 때문에 extract를 적용할 수 없는 경우

                                                                                  메서드를 그 자신을 위한 객체로 바꿔서 모든 지역변수가 그 객체의 필드가 되도록 함

 - Substitute Algorithm : 알고리즘을 더 명확한 것으로 바꾸고 싶을 때, 메서드의 몸체를 새로운 알고리즘으로 바꿈

 

2) 객체간 기능 이동

 - Move Method : 정의된 클래스보다 다른 클래스의 기능을 더 많이 사용한다면

                                  이 메서드를 가장 많이 사용하고 있는 클래스에 비슷한 몸체를 가진 새로운 메서드를 만들고 

                                  이전 메서드는 간단한 위임으로 바꾸거나 완전히 제거함

 - Movie Field : 필드가 자신이 정의한 클래스보다 다른 클래스에서 더 많이 사용되고 있다면 

                             타겟 클래스에 새로운 필드를 만들고 기존 필드를 사용하고 있는 모든 부분을 변경

 - Extract Class : 두개의 클래스가 해야 할 일을 하나의 클래스가하고 있는 경우

                                새로운 클래스를 만들고 관련 있는 필드와 메서드를 이전 클래스에서 새로운  클래스로 옮긴다

 - Inline Class : 클래스가 하는 일이 많지 않은 경우, 해당 클래스에 있는 모든 변수와 메서드를 다른 클래스로 옮기고 그 클래스 제거

 - Hide Delegate : 클라이언트가 객체의 위임 클래스를 직접 호출하는 경우, 서브클래스에 메서드를 만들어서 대리객체를 숨김

 - Remove Middle Man : 클래스가 간단한 위임을 너무 많이하는 경우, 클ㄹ이언트가 대리객체를 직접 호출하도록 함

 - Introduce Foreign Method : 사용하는 서버 클래스에 부가적인 메서드가 필요하지만 클래스를 수정할 수 없는 경우

                                                           첫번째 인자로 서버 클래스의 인스턴스를 받는 메서드를 클라이언트에 만듦

 - Introduce Local Extension : 사용하는 서버 클래스에 여러 메서드를 추가할 필요가 있지만 서버클래스를 수정할 수 없는 경우

                                                           필요한 메서드를 갖는 새로운 클래스를 만들고 이 확장 클래스를 원래클래스의 서브 클래스로 만듦

 

3) 데이터 구성

 - Self Encapsulate Field : 필드에 직접 접근하는데 필드에 대한 결합이 이상해지면 그 필드에 대한 get set메서드를 만들고 접근

 - Replace Data Value with Object : 추가적인 데이터나 동작을 필요로 하는 데이터 아이템이 있을 경우

                                                                       데이터 아이템을 객체로 바꿈

 - Change Value to Reference : 동일한 인스턴스를 여러개 가진 클래스가 있고

                                                             여러 동일한 인스턴스를 하나의 객체로 바꾸고 싶으면 그 객체를 참조 객체로 바꿈

 - Change Reference to Value : 불변성을 띄고 관리하기 어려운 참조 객체는 값을 객체로 바꿈

 - Replace Array with Object : 배열의 특정 요소가 다른 뜻을 가지고 있다면

                                                           배열을 각각의 요소에 대한 필드를 가지는 객체로 바꿈

 - Duplicate Observed Data : GUI컨트롤에서만 사용 가능한 도메인 데이터가 있고 도메인 메서드에서 접근이 필요한 경우

                                                         그 데이터를 도메인 객체로 복사하고 옵저버를 두어 데이터를 동기화함

 - Change Unidirectional Association to Bidirectional : 서로의 기능을 필요로 하는 클래스가 있는데 링크가 한방향인 경우

                                                                                                             반대 방향 포인터를 추가, 수정자가 양쪽세트를 모두 업데이트하게 변경

 - Change Bidirectional Association to Unidirectional : 서로 링크를 갖는 두개의 클래스에서 한쪽이 다른 한쪽을 더 이상

                                                                                                             필요로 하지 않을 때 불필요한 링크 제거

 - Replace Magic Number with Symbolic Constant : 특별한 의미를 갖는 숫자가 있으면 상수를 만들고 이름을 지음

 - Encapsulate Field public : 필드가 있는 경우 그 필드를 private으로 만들고 접근자 제공

 - Encapsulate Collection : 컬렉션을 리턴하는 메서드가 있으면 

                                                      그 메서드가 읽기전용 뷰를 리턴하도록 만들고 add/remove 메서드를 제공

 - Replace Record with Data Class : 레코드 구조에 대한 인터페이스가 필요할 때 그 레코드를 위한 데이터 객체를 만듦

 - Replace Type Code with Class : 클래스의 동작에 영향을 미치지 않는 숫자로 된 타입코드가 있으면 숫자를 클래스로 만듦

 - Replace Type Code with Subclass : 클래스 동작에 영향을 미치는 변경 불가능한 타입 코드가 있으면 서브클래스로 바꿈

 - Replace Type Code with State/Strategy : 클래스의 동작에 영향을 미치지만 서브클래싱을 할 수 없을 때

                                                                                      타입 코드를 스테이트 객체로 바꿈

 

4) 조건문 단순화

 - Decompose Coditional : 복잡한 조건문이 있으면 조건, then, else 부분에서 메서드를 추출

 - Consolidate Conditional Expression : 같은 결과를 나타내는 일련의 조건 테스트가 있는 경우

                                                                               그것을 하나의 조건 식으로 결합하여 뽑아냄

 - Consolidate Duplicate Conditional Fragments : 동일한 코드 조각이 조건문의 조건 분기 안에 있는 경우

                                                                                                    동일한 코드를 조건문 밖으로 옮김

 - Remove Control Flag : 일련의 boolean 식에서 컨트롤 플래그 역할을 하는 변수가 있는 경우

                                                 break 또는 return 을 대신 사용

 - Replace Nested Conditional with Guard Clauses : 메서드가 실행 경로를 불명확하게 하는 조건 동작을 가지고 있는 경우

                                                                                                       모든 특별한 경우에 대해 보호절을 사용

 - Replace Condiitonal with Polymorphism : 객체의 타입에 따라 다른 동작을 선택하는 조건문을 가지고 있는 경우

                                                         조건문의 각 부분을 서브클래스에 있는 오버라이딩 메서드로 옮기고 원래메서드를 abstract로 만듦

 - Introduce Null Object null : 체크를 반복적으로 하는 것은 null값은 null객체로 대체

 - Introduce Assertion : 코드의 한 부분이 프로그램의 상태를 나타내고 있으면 assertion을 써서 가정ㅇ르 명시적으로 만듦

 - Rename Method : 메서드의 이름이 그 목적을 드러내지 못하면 메서드의 이름을 바꿈

 

5) 일반화

 - Pull Up Field : 두 서브클래스가 동일한 필드를 가지고 있다면 그 필드를 수퍼클래스로 옮김

 - Pull Up Method : 동일한 일을 하는 메서드를 여러 서브클래스에서 갖고 있다면 이 메서드를 수퍼클래스로 옮김

 - Pull Up Constructor Body : 서브클래스들이 대부분 동일한 몸체를 가진 생성자를 갖고 있다면

                                                           수퍼클래스에 생성자를 만들고 서브클래스 메서드에서 이것을 호출

 - Push Down Method : 수퍼 클래스에 있는 동작이 서브클래스 중 일부에만 관련되어 있다면

                                               그 동작과 관련된 서브클래스로 옮긴다

 - Push Down Field : 어떤 필드가 일부 서브클래스에 의해서만 사용된다면, 그 필드를 관련된 서브클래스로 옮김