2011.10.21

기고 | 클라우드 코드 손상을 막는 방법 – 2부

David Tabler | CIO
클라우드 애플리케이션은 개발과 구성을 위한 다양한 매커니즘을 제공한다. 그들 중 일부는 다른 것들보다 깨지기 쉽게 만들어져 있다.

10월17일자 필자의 기고문에서 클라우드 애플리케이션을 확장하기 위해 개발된 코드를 평가하는 방법을 다뤘다. 이번에는 시간이 지날수록 시스템을 약화시키는 코딩과 시스템 수정 전략에 대해 알아보도록 하겠다. CRM 시스템이 갖는 요건은 끝없이 발전하는 것처럼 보이기 때문에 이런 시스템에서는 코드의 내구성이 장기적인 성공을 위한 핵심 요소가 된다.

하지만 시작하기에 앞서 필자가 예로 든 것들은 세일즈포스닷컴 환경에 적용한 사례를 활용한다는 점을 분명히 짚고 넘어가고 싶다. 다른 애플리케이션 환경과 플랫폼은 상이한 조건(과 심지어 상이한 개념)을 사용하지만 필자는 그런 것들을 모른다. 따라서 이것을 세일즈포스닷컴에 대한 특혜로 오해하지 말았으면 한다.

선언형 개발과 프로그래밍간의 갈등
클라우드 기반의 애플리케이션은 모호하고, 배우기 쉬우며, SaaS 환경에서 손쉽게 제어할 수 있기 때문에 IT업체들이 ‘선언형(declarative) 개발’이라 부르는 방향으로 치우치는 경향이 있다. 따라서 대부분의 클라우드 애플리케이션은 현업에서 타당성 검증 규칙을 빈번히 사용하고 현업과 표에서 제약을 사용하며 객체에 대한 작업흐름을 사용한다. 초기에는 이런 것들이 제대로 작동하고 놀라운 수준의 성능과 기능을 제공한다.

하지만 코드를 추가하면서 문제가 발생하며 특히 새로운 기록을 생성하는 코드들에서 심하게 나타난다. 새로운 트리거(Trigger), 클래스, 또는 통합 "리스너(Listener)" 서비스를 개발할 때 코드 작성자는 프로덕션 시스템(Production System)과 동일하게 설정되지 않은 개발 또는 샌드박스(Sandbox) 환경에서 작업을 하게 될 수 있다. 따라서 코드를 프로덕션 처리하면 모든 오류의 조건들이 발생하게 되고 이런 것들은 개발 환경에서 재생성하지 못할 수도 있다. 안타깝게도 오류 메시지는 사용자들에게 불쾌감을 줄 수 있으며 문제를 해결하려는 사람들에게 그리 많지 않은 단서를 제공하는 경우도 있다.

따라서 우선은:
1. 개발자들이 최근에 리프레시(Refresh)된 "샌드박스"에서 작업하여 프로덕션 환경의 설정 때문에 놀라는 일이 없도록 한다.

2. 가능한 한 통합 어댑터(Integration Adaptor)와 기타 플러그인(Plug-in)을 샌드박스에서 활성화해 개발자들이 상황 변동의 영향을 볼 수 있도록 한다. (특히, 외부 소스로부터 반환된 오류 조건의 "반영")

3. 일단 하나의 객체에 대한 확장기능과 기능을 개발하기 시작하면 모든 타당성 검증 규칙을 제거하고 이것들을 로우레벨(Low-level) 코드에 재이식하여 오류 조건을 잡아내고 통제할 수 있도록 한다.

4. 같은 맥락에서 필드 업데이트를 담당하는 작업흐름을 로우레벨 코드 이행으로 대체한다.

5. 새로운 타당성 검증 규칙이나 작업흐름 중심적인 필드 업데이트를 생성하는 것을 어렵게 하는 관리 정책을 설정한다.

6. 필드 또는 표 제한 앞에 보호책을 제공하기 위하여 코드를 삽입하되 특히 해당 값들을 사전에 확인하여 충돌을 미연에 방지한다.

7. 널(NULL)에 대한 모든 필드를 확인하고 엠티(EMPTY)에 대한 모든 세트(Set), 목록, 맵을 로직(Logic - 오류확인 로직도 포함)에 사용하기 앞서 확인한다.

8. 앞서 클라우드의 오류 취급부분에서도 언급했듯이 실시간으로 애플리케이션 오류를 처리하고 이것들을 클라우드의 다른 부분에 있는 중앙 집중식 오류 로깅 서비스에 메시지로 전송하는 클래스를 작성한다.

어느 정도는 표 중심으로
클래스 또는 트리거 중간의 하드코딩(Hard-coding) 값을 두는 것은 좋지 못하다는 것을 누구든 알고 있으며 모두들 이런 매개변수를 최소한 각 모듈(Module)의 선언 섹션에 있는 정적 최종 변수에 배치시켜야 한다. 그리고 이런 변수들을 룩업(Lookup) 표나 코드를 구동할 때마다 로드되는 리소스 파일로 옮기는 것이 더 낫다.

비록 데이터베이스는 정상화를 선호하고 거의 모든 것이 룩업으로 만들어질 수 있다 하더라도 과도하게 추상적이면서 포괄적이기 쉽다. 과도한 포인터 체이싱(Pointer Chasing)은 원 개발자가 아닌 사람의 이해를 떨어뜨릴 수 있으며 앱의 속도도 저하시킬 수 있다. (또는 심지어 클라우드 환경의 관리 한계로 밀어 붙이기도 한다.)

따라서 다음으로:
9. 룩업 표에 설정 매개변수(픽리스트(Pick-list) 값, 허용되는 상태, 또는 설정 옵션 등)를 넣는다. 각 표에는 사람이 읽고 이해할 수 있는 표와 값의 의미, 동작, 업데이트 히스토리와 함께 코멘트 칼럼(Comment Column)을 포함시킨다. 만약 클라우드 시스템이 지원할 경우 이 표를 온디스크(On-disk)가 아닌 지연율이 낮은 메모리(맞춤 설정)에 보관한다.

10. 이 룩업 표들을 설정 제어 하에 둔다. 최소한 접속을 차단하고 이 표들이 주기적으로 백업되도록 한다.

11. 표와 필드의 명칭을 반드시 설정한다. 이를 게을리 할 경우 문제해결 시 시간으로 그 대가를 치러야 한다. (예를 들어 "어리석음"이라는 이름의 표를 기억해 두기 바란다.)

클라우드는 ‘애자일 , XP, 또는 TDD 코딩 스타일’ 필요
필자는 실제로 대형 모듈, 폭포수 개발(Waterfall Development), 과도한 중첩/가지치기 등이 불가능한 클라우드 환경에 대해 들어본 적이 없다. 결국 누구든 종종 이런 것들을 발견할 수 있다는 뜻이다. 하지만 마지막으로 우리는 탄탄하면서 오랫동안 지속되는 코드를 개발하기 위해서 이런 스타일을 포기해야 한다.

12. 객체는 단지 UI를 위한 것이 아니다. 객체는 이해하기 쉽고, 재사용 가능하며, 재제작 할 수 있도록 지원하기 위해 존재하는 것이다. 하지만 여기에 너무 열중하지 말기를 바란다. 객체가 반드시 언더스탠더빌러티를 지원하도록 한다. 그렇지 않으면 다른 어떠한 혜택도 얻지 못할 것이다.

13. 모듈을 작고 단순하면서 분리할 수도 있도록 유지한다. 테스트와 디버그를 용이하게 하는 키스 원칙(KISSS Principle)을 확인하기 바란다

플랫폼의 한계를 넘지 말아야
클라우드 플랫폼은 데이터베이스 쿼리나 메모리 내의 표 생성 등의 특정 연산에 대한 관리 한계를 설정할 수 있다. 처음에 일부 기능을 개발할 때 초기 출시에서 한계치의 50% 이상을 사용하지 않도록 한다. 머지않아 새로운 요건과 파이어 드릴(Fire Drill)에 직면하게 될 것이고 결국 더 많은 리소스를 필요로 하게 될 것이다.

14. 데이터베이스에 매번 접속하기 보다는 인메모리(In-memory) 데이터 캐싱(벌키피케이션(Bulkification)과 다이나믹 SQL)을 사용한다. 규모가 큰 작업부하와 데이터 셋을 처리하기 위해서 퓨처(Future) 및 배치(Batch) 클래스를 사용한다.

15. 명백한 기술적 타당성이 없는 한 테스트 코드가100%의 코드 커버리에 다다르도록 한다. 단순한 아이들 코드(Idle Code) 연습뿐 아니라 (긍정적 & 부정적 테스트 경우에 대한 어썰트(Assert)를 이용해) 논리적 결과의 실제적인 테스트를 수행한다. 그리고 커버리지 통계(Coverage Statics)를 인위적으로 끌어올리기 위해서 조종이 불가능한 진술을 이용해 코드를 추가하지 않는다.

*David Taber는 ‘세일즈포스닷컴 성공의 비밀’의 저자이며 세일즈포스닷컴 관련 컨설팅 기업인 세일즈로지스틱스의 CEO다. ciokr@idg.co.kr



2011.10.21

기고 | 클라우드 코드 손상을 막는 방법 – 2부

David Tabler | CIO
클라우드 애플리케이션은 개발과 구성을 위한 다양한 매커니즘을 제공한다. 그들 중 일부는 다른 것들보다 깨지기 쉽게 만들어져 있다.

10월17일자 필자의 기고문에서 클라우드 애플리케이션을 확장하기 위해 개발된 코드를 평가하는 방법을 다뤘다. 이번에는 시간이 지날수록 시스템을 약화시키는 코딩과 시스템 수정 전략에 대해 알아보도록 하겠다. CRM 시스템이 갖는 요건은 끝없이 발전하는 것처럼 보이기 때문에 이런 시스템에서는 코드의 내구성이 장기적인 성공을 위한 핵심 요소가 된다.

하지만 시작하기에 앞서 필자가 예로 든 것들은 세일즈포스닷컴 환경에 적용한 사례를 활용한다는 점을 분명히 짚고 넘어가고 싶다. 다른 애플리케이션 환경과 플랫폼은 상이한 조건(과 심지어 상이한 개념)을 사용하지만 필자는 그런 것들을 모른다. 따라서 이것을 세일즈포스닷컴에 대한 특혜로 오해하지 말았으면 한다.

선언형 개발과 프로그래밍간의 갈등
클라우드 기반의 애플리케이션은 모호하고, 배우기 쉬우며, SaaS 환경에서 손쉽게 제어할 수 있기 때문에 IT업체들이 ‘선언형(declarative) 개발’이라 부르는 방향으로 치우치는 경향이 있다. 따라서 대부분의 클라우드 애플리케이션은 현업에서 타당성 검증 규칙을 빈번히 사용하고 현업과 표에서 제약을 사용하며 객체에 대한 작업흐름을 사용한다. 초기에는 이런 것들이 제대로 작동하고 놀라운 수준의 성능과 기능을 제공한다.

하지만 코드를 추가하면서 문제가 발생하며 특히 새로운 기록을 생성하는 코드들에서 심하게 나타난다. 새로운 트리거(Trigger), 클래스, 또는 통합 "리스너(Listener)" 서비스를 개발할 때 코드 작성자는 프로덕션 시스템(Production System)과 동일하게 설정되지 않은 개발 또는 샌드박스(Sandbox) 환경에서 작업을 하게 될 수 있다. 따라서 코드를 프로덕션 처리하면 모든 오류의 조건들이 발생하게 되고 이런 것들은 개발 환경에서 재생성하지 못할 수도 있다. 안타깝게도 오류 메시지는 사용자들에게 불쾌감을 줄 수 있으며 문제를 해결하려는 사람들에게 그리 많지 않은 단서를 제공하는 경우도 있다.

따라서 우선은:
1. 개발자들이 최근에 리프레시(Refresh)된 "샌드박스"에서 작업하여 프로덕션 환경의 설정 때문에 놀라는 일이 없도록 한다.

2. 가능한 한 통합 어댑터(Integration Adaptor)와 기타 플러그인(Plug-in)을 샌드박스에서 활성화해 개발자들이 상황 변동의 영향을 볼 수 있도록 한다. (특히, 외부 소스로부터 반환된 오류 조건의 "반영")

3. 일단 하나의 객체에 대한 확장기능과 기능을 개발하기 시작하면 모든 타당성 검증 규칙을 제거하고 이것들을 로우레벨(Low-level) 코드에 재이식하여 오류 조건을 잡아내고 통제할 수 있도록 한다.

4. 같은 맥락에서 필드 업데이트를 담당하는 작업흐름을 로우레벨 코드 이행으로 대체한다.

5. 새로운 타당성 검증 규칙이나 작업흐름 중심적인 필드 업데이트를 생성하는 것을 어렵게 하는 관리 정책을 설정한다.

6. 필드 또는 표 제한 앞에 보호책을 제공하기 위하여 코드를 삽입하되 특히 해당 값들을 사전에 확인하여 충돌을 미연에 방지한다.

7. 널(NULL)에 대한 모든 필드를 확인하고 엠티(EMPTY)에 대한 모든 세트(Set), 목록, 맵을 로직(Logic - 오류확인 로직도 포함)에 사용하기 앞서 확인한다.

8. 앞서 클라우드의 오류 취급부분에서도 언급했듯이 실시간으로 애플리케이션 오류를 처리하고 이것들을 클라우드의 다른 부분에 있는 중앙 집중식 오류 로깅 서비스에 메시지로 전송하는 클래스를 작성한다.

어느 정도는 표 중심으로
클래스 또는 트리거 중간의 하드코딩(Hard-coding) 값을 두는 것은 좋지 못하다는 것을 누구든 알고 있으며 모두들 이런 매개변수를 최소한 각 모듈(Module)의 선언 섹션에 있는 정적 최종 변수에 배치시켜야 한다. 그리고 이런 변수들을 룩업(Lookup) 표나 코드를 구동할 때마다 로드되는 리소스 파일로 옮기는 것이 더 낫다.

비록 데이터베이스는 정상화를 선호하고 거의 모든 것이 룩업으로 만들어질 수 있다 하더라도 과도하게 추상적이면서 포괄적이기 쉽다. 과도한 포인터 체이싱(Pointer Chasing)은 원 개발자가 아닌 사람의 이해를 떨어뜨릴 수 있으며 앱의 속도도 저하시킬 수 있다. (또는 심지어 클라우드 환경의 관리 한계로 밀어 붙이기도 한다.)

따라서 다음으로:
9. 룩업 표에 설정 매개변수(픽리스트(Pick-list) 값, 허용되는 상태, 또는 설정 옵션 등)를 넣는다. 각 표에는 사람이 읽고 이해할 수 있는 표와 값의 의미, 동작, 업데이트 히스토리와 함께 코멘트 칼럼(Comment Column)을 포함시킨다. 만약 클라우드 시스템이 지원할 경우 이 표를 온디스크(On-disk)가 아닌 지연율이 낮은 메모리(맞춤 설정)에 보관한다.

10. 이 룩업 표들을 설정 제어 하에 둔다. 최소한 접속을 차단하고 이 표들이 주기적으로 백업되도록 한다.

11. 표와 필드의 명칭을 반드시 설정한다. 이를 게을리 할 경우 문제해결 시 시간으로 그 대가를 치러야 한다. (예를 들어 "어리석음"이라는 이름의 표를 기억해 두기 바란다.)

클라우드는 ‘애자일 , XP, 또는 TDD 코딩 스타일’ 필요
필자는 실제로 대형 모듈, 폭포수 개발(Waterfall Development), 과도한 중첩/가지치기 등이 불가능한 클라우드 환경에 대해 들어본 적이 없다. 결국 누구든 종종 이런 것들을 발견할 수 있다는 뜻이다. 하지만 마지막으로 우리는 탄탄하면서 오랫동안 지속되는 코드를 개발하기 위해서 이런 스타일을 포기해야 한다.

12. 객체는 단지 UI를 위한 것이 아니다. 객체는 이해하기 쉽고, 재사용 가능하며, 재제작 할 수 있도록 지원하기 위해 존재하는 것이다. 하지만 여기에 너무 열중하지 말기를 바란다. 객체가 반드시 언더스탠더빌러티를 지원하도록 한다. 그렇지 않으면 다른 어떠한 혜택도 얻지 못할 것이다.

13. 모듈을 작고 단순하면서 분리할 수도 있도록 유지한다. 테스트와 디버그를 용이하게 하는 키스 원칙(KISSS Principle)을 확인하기 바란다

플랫폼의 한계를 넘지 말아야
클라우드 플랫폼은 데이터베이스 쿼리나 메모리 내의 표 생성 등의 특정 연산에 대한 관리 한계를 설정할 수 있다. 처음에 일부 기능을 개발할 때 초기 출시에서 한계치의 50% 이상을 사용하지 않도록 한다. 머지않아 새로운 요건과 파이어 드릴(Fire Drill)에 직면하게 될 것이고 결국 더 많은 리소스를 필요로 하게 될 것이다.

14. 데이터베이스에 매번 접속하기 보다는 인메모리(In-memory) 데이터 캐싱(벌키피케이션(Bulkification)과 다이나믹 SQL)을 사용한다. 규모가 큰 작업부하와 데이터 셋을 처리하기 위해서 퓨처(Future) 및 배치(Batch) 클래스를 사용한다.

15. 명백한 기술적 타당성이 없는 한 테스트 코드가100%의 코드 커버리에 다다르도록 한다. 단순한 아이들 코드(Idle Code) 연습뿐 아니라 (긍정적 & 부정적 테스트 경우에 대한 어썰트(Assert)를 이용해) 논리적 결과의 실제적인 테스트를 수행한다. 그리고 커버리지 통계(Coverage Statics)를 인위적으로 끌어올리기 위해서 조종이 불가능한 진술을 이용해 코드를 추가하지 않는다.

*David Taber는 ‘세일즈포스닷컴 성공의 비밀’의 저자이며 세일즈포스닷컴 관련 컨설팅 기업인 세일즈로지스틱스의 CEO다. ciokr@idg.co.kr

X