2007년 2월 21일 수요일

4:3? 3:2? 16:9? 디지탈 카메라의 화면 비율

디지탈, 특히 영상 기기를 보면 사진이나 동영상에서 화면 비율이라는 단어를 접할 때가 있습니다. 또한 디지탈 카메라나 캠코더, TV 제조사에서는 16:9와 같은 숫자를 명시하면서 와이드 비전, HDTV 영상이라는 광고 문구를 전면에 내걸기도 합니다. 오늘은 디지탈 기기에서 사용되는 화면 비율과 각각의 효과에 대해 알아보겠습니다.

1. 4:3

디지탈 영상을 포함해 일반적인 영상에서 가장 많이 접하는 화면 비율이 4:3입니다. 4:3비율은 가로:세로의 비율이 4:3인 것을 말하며 "Academic Standard"라고도 불렸습니다. 초창기 무성영화 시절부터 사용하던 화면 비율로, 1917년 영화기술자 협회(Society of Motion Picture Engineers)에서 채택되었습니다. 4:3비율은 영상이 한 눈에 들어오는 안정적인 구도를 제공했기 때문에 당시 대부분 영화에 공통적으로 적용됐으며, 이후 TV에서도 영화의 화면 비율을 적용해 4:3비율로 제작 됐습니다. TV 화면비율은 곧 PC 모니터 규격으로까지 확대됐으며, 이에 따른 디지탈 영상 기기 역시 현재 4:3 화면 비율을 기본으로 채택하고 있습니다.

디지탈 카메라에서는 렌즈 교환식 DSLR 카메라를 제외한 일반적인 컴팩트 / 슬림 / 하이엔드 디지탈 카메라에서 4:3 비율을 지닌 이미지 센서를 탑재합니다. 렌즈 교환식 DSLR 카메라는 35mm 필름의 화면비율을 따라 3:2 비율로 설계된 이미지 센서를 장착하지만, 올림푸스 E시스템 DSLR 카메라는 디지탈 전용 포맷을 강조한 4:3비율 이미지 센서를 탑재하고 있기도 합니다.


<4:3비율 이미지 센서를 탑재한 올림푸스 E-시스템 DSLR 카메라>


2. 3:2

3:2 화면비율은 인쇄나 출판물에 주로 사용되는 화면 비율로, 황금 분할법에서 기인한 형식입니다. 사진 인화(35mm 필름 기준)에도 3:2 화면 비율이 표준으로 채택되고 있습니다.

3:2 화면 비율은 4:3비율보다 가로로 더 긴 형태로 감상할 때 4:3 비율보다 더 안정적인 느낌을 전달하는 효과가 있습니다.

디지탈 카메라 분야에서는 렌즈교환식 DSLR 카메라를 제외한 대부분 모델이 4:3 비율로 제작된 이미지 센서를 탑재하고 있지만, 기종에 따라 해상도 메뉴에서 3:2 비율 해상도를 제공하기도 합니다. 하지만 이는 4:3비율로 제작된 이미지 센서로 받아들인 화면의 상하를 잘라내서 만드는 경우가 많아 화소 손실이 있습니다.




<보급형 디지탈 카메라는 4:3 화면에서 상하 영역을 잘라내 3:2, 4:3, 16:9 화면비 제공>



반면, 필름 화각과 동일한 컨셉을 추구하는 DSLR 카메라는 이미지 센서 자체가 3:2로 제작돼 화소 손실없이 35mm 필름 카메라와 동일한 화면 비율을 지닌 이미지를 출력합니다.


3. 16:9

16:9 화면 비율은 이른 바 '와이드 비전'이라는 타이틀로 HDTV를 비롯한 영상기기에서 채택하고 있습니다. 16:9 역시 황금 분할법에 기인해 제작된 화면 비율이지만 3:2 화면보다 가로로 더욱 긴 형태입니다.



<16:9 화면 비율을 기준으로 적용된 4:3, 3:2 화면 비율>


현대 영화는 1.85:1이나 2.35:1 화면 비율로 제작되고 있습니다. 16:9는 이중 1.85:1 비율과 가깝습니다. 디지탈 영상에서 갈수록 와이드 비율을 선호하는 이유는 사람의 시야와 관계있습니다. 일반적으로 가로로 긴 화면이 사람의 시야에 적합해 영상을 감상할 때 더 안정적이고 한 눈에 알아보기 쉬운 것으로 알려져 있습니다.

보통 16:9 화면 비율은 TV와 캠코더와 같은 영상 분야에서 다루고 있었지만 근래들어 디지탈 카메라의 정지화상이나 동영상에서도 16:9 비율을 지원하기 시작했으며, 2005년에는 16:9 비율로 제작된 이미지 센서를 탑재한 제품도 출시돼 주목을 받았습니다.



<16:9비율로 제작된 파나소닉 루믹스 DMC-LX1의 CCD>


*황금분할?

- 황금분할(Golden Section) 혹은 황금비율(Golden Ration)은 예로부터 입증된 가장 안정적이고 조화로운 아름다움을 표현하는 비율로, 1:1.618 또는 5:8을 일컫는 말입니다. 황금분할은 건축과 미술, 사진에 지대한 영향을 줬는데, 사진 구도에서도 황금분할로 피사체를 배치하면 안정감 있는 구도를 얻을 수 있습니다.

정확한 황금분할은 1:1.618 비율이지만 사진을 찍을 때 이를 일일이 계산하기 어려우므로, 일반적인 촬영에서는 1:1.618 비율보다 간단한 삼분법을 사용합니다. 삼분법은 보통 화면을 가로 세로 삼등분 해서 만나는 교차점 4개에 피사체를 위치하게 만드는 것으로, 안정적인 구도를 표현합니다.




<디지탈 카메라에서는 액정 모니터에 삼등분 격자 그리드를 제공한다>




황금비는 고대 그리스에서 발견되었고, 르네상스의 볼로냐의 수도승 루카 파치올리(Luca Pacioli)에 의하여 ‘신성비례(神 聖 比 例)’라고 이름할 정도로 중요시되었습니다.

특히 시각적인 분야에서 많이 이용돼 건축·조각·회화·공예 등, 조형예술 분야에서는 다양한 통일 원리로서 널리 활용되고 있을 뿐만 아니라 엽서, 담배갑이나 명함의 치수 등 일상생활에서도 쉽게 접할 수 있습니다.


출처: http://dcinside.com

2007년 2월 19일 월요일

ASP.NET 가이드 1. 자바 스크립트 사용하기

ASP.NET 가이드 1. 자바 스크립트 사용하기
저자
: 한동훈
0. 소개
웹 프로그래밍을 하는 경우 자바 스크립트를 사용하는 경우가 종종 발생한다. 자바 스크립트를 사용하는 데 있어 문제는 같은 문제에 대해 늘 인터넷을 찾아보고, 스크립트를 작성하는 일을 반복하는 데 있다. 때문에, 웹 개발자들은 자주 이용하는 자바 스크립트 사이트나 관련된 책을 책상에 항상 구비해 두고 있을 것이다.
ASP나 PHP와 같은 언어와 달리 ASP.NET은 객체지향 언어이고, 다양한 컨트롤들을 사용하고 있기 때문에 자바 스크립트 사용법에 차이점이 있다.
여기서는 앞으로 여러회에 걸쳐서 기본적인 자바 스크립트들을 ASP.NET에서 사용하는 방법들을 살펴볼 것이다. 그 이후에는 데이터그리드에서 다중 체크박스 처리와 같은 보다 심도 있는 내용을 다루도록 할 것이다.
1. 꼭 알아야 할 자바 스크립트
자바 스크립트를 잘 모르거나 기억이 흐릿한 분들을 위해 이 글을 이해하는데 꼭 필요한 기본적인 자바 스크립트를 설명할 것이다.(아주 기초적인 것만 다룬다)

위와 같은 HTML이 있다고 하자. 자바 스크립트는 script 태그 안에 위치한다.
자바 스크립트의 변수 선언은 var로 할 수 있으며, str과 str2의 선언에서 볼 수 있는 것처럼 문자열에는 " 또는 '을 모두 사용할 수 있다. HTML에서 속성이름="값"과 같은 형식으로 사용하기 때문에 자바 스크립트에서 문자열을 사용할 때는 '을 선호한다.
FORM 태그에 있는 요소들을 접근할 때는 document.forms[0]과 같은 형식을 사용한다. 하나의 페이지에 FORM 태그가 둘 이상 있는 경우에는 document.forms[0], document.forms[1]과 같은 형식으로 사용할 수 있다.
<form id=Forms1> 태그와 같이 ID가 지정된 경우에는 document.forms.Forms1, document.forms["Forms1"], document.forms.namedItem( "Forms1" )과 같은 형식으로 사용할 수 있다.
document.forms[0].txtName.value는 첫번째 폼에 있는 txtName 요소의 값을 가져오거나 설정하는 데 사용한다.
ASP.NET의 <ASP:TextBox runat=server id=txtID>는 브라우저에 <input type=text id=txtID>로 표시된다. 따라서, 스크립트에서 ASPX 페이지에 있는 텍스트 박스의 값을 이용하기 위해서는 document.forms[0].txtID.value과 같은 형태로 사용한다.
focus() 함수는 해당 텍스트 박스에 커서의 포커스를 이동시킨다. 여러분이 검색 사이트를 방문했을 때 키워드만 입력해서 검색할 수 있는 것도 focus() 함수 때문이다.
스크립트 축약하기
매번 document.forms[0].컨트롤ID 형태로 사용하는 것은 번거롭기 때문에 다음과 같은 형태를 더 빈번하게 사용한다.
<script language=javascript>
var theForm = document.forms[0];
theForm.txtName.value = 'Hello';
theForm.txtName.focus();
</script>
이 코드는 이전의 코드와 완전히 동일한 역할을 한다.
컨트롤 알아내기
ASP.NET에서는 대부분 하나의 FORM 태그만 있다는 가정하에 작업을 한다. 즉, ASP/PHP에서 처럼 여러 개의 FORM 태그를 두고 작업하지 않고 하나의 FORM 태그안에서 작업을 하는 경우가 대부분이다. 그러나, ASP.NET에서도 경우에 따라 여러 개의 폼을 사용할 수 있다. document.forms[0]나 document.forms.폼이름 과 같은 형태로 사용하는 것은 당장 자바 스크립트를 작성할 수 있게 해주나 자바 스크립트를 라이브러리로 사용하는 것을 어렵게 만든다.
원하는 컨트롤에 포커스를 주는 함수를 만들고 싶다고 할 때 어떤 FORM 태그안에 있는 컨트롤에 포커스를 주어야 할지, 또는 데이터 그리드안에 만든 텍스트박스에 어떻게 포커스를 주어야 할지 결정하기 어렵다.
즉, 동적으로 생성되는 컨트롤을 자바 스크립트로 제어하려면 document.forms[0]나 document.forms.Forms1과 같이 폼 인덱스나 폼 이름을 이용하는 자바 스크립트를 작성해서는 안된다.
<script language=javascript>
var ctl = document.getElementById( 'txtName' );
if( ctl != null )
{

ctl.value = 'Hello, cruel world';

ctl.focus();
}
</script>
위 예제에서는 컨트롤을 알아내기 위해 document.getElementById() 함수를 사용한다. 이 함수는 현재 브라우저에 있는 문서에서 ID를 사용해서 해당 컨트롤에 대한 참조를 얻어온다. 이 함수를 사용하기 위해서는 HTML에서 ID 속성만 사용하면 된다. ASP.NET에서는 웹 컨트롤의 ID 속성을 HTML의 ID 속성으로 변환해준다. - 대소문자를 구분하므로 ID 이름의 대소문자도 반드시 일치해야 한다.
현재 브라우저가 갖고 있는 문서에 ID에 해당하는 컨트롤이 없으면 null을 반환하기 때문에 반드시 null을 확인한 이후에 원하는 작업을 수행해야 한다. 그렇지 않으면, 자바 스크립트 오류가 발생한다.
getElementById의 호환성 문제
document.getElementById() 함수는 웹 표준안을 제정하고 있는 W3C의 DOM에 의해 정의된 것이며 오늘날 FireFox, Opera, IE 6+ 같은 대부분의 브라우저에서 잘 동작한다. 그러나 오래된 운영체제를 사용하고 있는 경우 이 함수가 동작하지 않는다. 특히, IE 5.5 이전 버전은 DOM Level 1을 완전히 지원하지 않는다. 때문에, 자바 스크립트의 기본적인 getElementById() 함수 대신에 이를 대체할 getElement() 함수를 작성하고, 이를 앞으로 BasePage의 모든 자바 스크립트에서 사용할 것이다.
<script language=javascript>
function getElement( id ) {

if( document.all ) return document.all( id );

if( document.getElementById ) return document.getElementById( id );
}
</script>
getElement()를 사용하여 작성하는 방법은 하위 버전 브라우저에 대한 동작을 보장하는 것 뿐만 아니라 비호환 브라우저가 등장하는 경우에 해당 브라우저를 지원하기 위해 모든 스크립트를 수정하는 대신 getElement() 스크립트만 수정하면 될 것이다.
이번 글을 이해하기 위해 알아야하는 자바 스크립트의 내용은 이것이 전부다. 자바 스크립트의 나머지는 C/Java/C#의 문법과 대부분 비슷하다. 차이점은 브라우저와 상호 작용하기 위해 document와 같은 몇 가지 객체들을 제공하고 있다는 점 뿐이다.
BasePage 소개
일반적으로 자바 스크립트를 작성하거나 어떤 기능들을 작성했을 때 각각의 페이지에 이러한 내용들을 추가해 주어야하는 번거로움이 있다. filename.js와 같은 외부 자바스크립트 파일을 작성한 경우에도 매번 이 스크립트를 사용할 것이라고 추가해 주어야한다.
게다가, 이렇게 사용하는 자바 스크립트는 ASP.NET의 서버측 코드(C#, VB.NET 소스)에서 사용할 수 없다. 개발자가 직접 태그에 이러한 코드들을 추가하기 위해 Control.Attributes.Add() 함수를 사용해야하고, 이 함수를 사용하기 위해 자바 스크립트의 정확한 이름까지 알고 있어야 한다.
이러한 불편함을 해소하기 위해 BasePage 클래스를 작성한다.
보통의 ASP.NET 페이지는 그림1의 왼쪽과 같이 System.Web.UI.Page 클래스를 상속한다. 여기에 자바 스크립트 지원을 비롯해서 사용자 인증, 예외 처리등을 위한 확장을 용이하게 하기 위해 그림1의 오른쪽 그림과 같이 클래스를 확장하였다.

[그림 1] BasePage 상속구조
BasePage 기본구조
먼저 해야 할 일은 Visual Studio .NET을 실행하고 [새 프로젝트]에서 그림2와 같이 [클래스 라이브러리] 프로젝트를 작성한다.

[그림2] 클래스 라이브러리 프로젝트 생성
그림1과 같이 System.Web.UI.Page 클래스를 상속하여 기능을 확장할 것이기 때문에 System.Web.dll에 대한 참조를 추가해야 한다.

[그림3] 참조 추가하기

[그림4] System.Web.dll 참조 추가
이와 같은 설정을 마치고 Mona.Web.UI.BasePage 클래스의 기본 뻐대를 다음과 같이 작성한다.

[그림5] Mona.Web.UI.BasePage
네임스페이스는 Mona.Web.UI로 정의하고 BasePage 클래스는 Page 클래스를 상속하였다. OnInit은 Page 클래스에서 각 컨트롤의 이벤트를 초기화하는 함수이며 이를 재정의하였다.
함수를 재정의할 때는 필요한 처리를 하고, 나머지 처리에 대해서는 상속 클래스에서 처리할 수 있도록 base.OnInit()과 같이 상속 클래스의 메서드를 호출하는 것을 잊지 말아야 한다. 완전히 재정의하는 경우에는 관계없지만 여기서의 목적은 완전히 재정의하는 것이 아니라 그 기능을 확장하는데 있기 때문에 이와 같이 한다.
자바스크립트: getElement 추가하기
페이지가 로딩되고 브라우저에 전달되기 전에 이벤트가 발생하는 PreRender 이벤트가 자바 스크립트를 추가하기 적합하다.
따라서, 다음과 같이 PreRender 이벤트를 정의한다.

[그림6] PreRender 이벤트 정의
앞으로 추가하게 될 다양한 스크립트 등록을 한 곳에 모아두기 위해 RegisterClientScript() 함수를 작성하였고, BasePage_PreRender()에서 이를 호출하도록 하였다.
자바 스크립트를 추가하기 위해 AddGetElementScript()를 추가하였다. 하나의 자바 스크립트에 대해서는 하나의 함수로 독립시켰다. 필요에 따라 특정 스크립트의 추가와 제거를 손쉽게 하기 위해 이와 같이 스크립트를 나누었다.
앞에서 설명한 것처럼 getElement() 함수는 ASP.NET 페이지의 컨트롤과 상호 작용할 필요가 없기 때문에 단순히 스크립트를 등록하기만 한다. 다음은 AddGetElementScript()의 정의다.
AddGetElementScript() 함수

[그림7] AddGetElementScript() 함수 정의
자바 스크립트 함수 이름과 스크립트를 등록하기 위한 이름을 각각 GetElementFunctionName과 GetElementScriptName 문자열 상수로 만들었다. 다른 스크립트에서도 __getElement() 라는 스크립트를 직접 이용하는 대신 GetElementFunctionName이라는 문자열 상수를 참조하여 작성할 것이다.
자바 스크립트를 등록하기 전에 IsClientScriptBlockRegistered()를 사용하여 스크립트 등록 여부를 확인하고, 등록되어 있지 않은 경우에 RegisterClientScriptBlock()을 사용하여 스크립트를 등록한다. 이와 같은 방법은 Mona.Web.UI.BasePage를 상속하여 클래스를 확장하는 경우에 충돌없이 자바스크립트를 등록하고 사용할 수 있게 해준다.(예를 들어, 사용자 요청을 처리하는 동안 피드백을 보여주거나 에러 처리에 대한 정보를 처리하기 위해 BasePage 클래스를 상속하여 확장하는 경우가 발생할 수 있다)
다음은 원하는 컨트롤에 커서를 위치시키기 위한 자바 스크립트 등록과 SetFocus()를 만들어 볼 것이다.
AddSetFocusScript() 함수
이 자바 스크립트를 사용하는 목적은 원하는 텍스트 박스에 커서를 위치 시키기 위해 반복적으로 자바 스크립트를 작성하지 않기 위한 것이다. 또한, 사용자가 쿠키에 ID를 저장한 경우에 비밀번호를 바로 입력할 수 있게 비밀번호 입력상자에 커서를 위치시키고, 쿠키에 ID를 저장하지 않은 경우 ID 입력 상자에 커서를 위치시키는 것과 같은 동적 스크립팅 처리를 하기 위한 것이다.

[그림8] RegisterClientScript()에 AddSetFocusScript() 추가
RegisterClientScript() 함수에 AddSetFocusScript()를 추가한다.

AddSetFocusScript() 함수 역시 SetFocusScriptName과 SetFocusFunctionName 문자열 상수를 이용해서 스크립트 이름과 함수 이름을 정의한다. 빨간 테두리로 되어 있는 부분이 __setFocus() 함수를 정의하는 부분이다. 노란색 테두리는 사용자가 원하는 컨트롤에 커서를 이동시킨다. 웹페이지에서는 __setFocus( 'txtName' ); 과 같이 된다.
아직, focusedControl 변수를 선언하지 않았다는 것을 알 수 있다. 실제로, 코드에서 사용할 SetFocus() 함수는 이 컨트롤의 이름을 전달받아 내부변수 focusedControl에 설정하는 역할만 한다.
SetFocus() 함수

먼저 focusedControl 변수를 선언하고 생성자에서 내부 변수의 값을 초기화한다. 초기화하지 않으면 NullReferenceException이 발생하므로 주의하기 바란다.
RegisterStartupScript()와 RegisterClientScriptBlock()의 차이
AddGetElementScript()와 AddSetFocusScript()에서 자바 스크립트를 등록하기 위해 서로 다른 함수를 사용했다.
얼핏 생각하기에 두 함수간에 차이점은 없다.(정말?)
RegisterClientScriptBlock() 함수는 시작 FORM 태그(<FORM>) 다음에 스크립트가 생성되지만, RegisterStartupScript() 함수는 닫는 FORM 태그(</FORM>) 바로 앞에 스크립트가 생성된다.
이 두 스크립트의 차이점을 이해하기 위해 자바 스크립트를 설명하며 살펴본 예제를 다시 살펴보자.

여기서는 자바 스크립트에서 이미 있는 txtName 요소를 사용하기 때문에 문제가 발생하지 않는다. 그러나 스크립트와 태그의 순서를 다음과 같이 변경하면 txtName 요소가 선언되기 전에 자바 스크립트가 위치하기 때문에 오류가 발생한다.

마찬가지로 BasePage에서 SetFocus()와 같이 폼 요소들을 참조하는 스크립트를 작성하는 경우에 해당 요소들이 모두 화면에 출력된 다음에 자바 스크립트가 작성되어야 참조 오류가 발생하지 않는다.
앞으로 소개하게 될 자바 스크립트는 모두 폼 요소들을 참조하기 때문에 RegisterStartupScript()를 사용하여 스크립트를 등록한다.
BasePage 테스트: TestBasePage
새로운 ASP.NET 웹 프로젝트를 BasePage 프로젝트에 추가한다.
참조에는 BasePage 프로젝트 참조를 다음과 같이 추가한다.

참조를 추가했으면 TestBasePage.aspx 페이지를 만들고 다음과 같이 폼을 작성한다.

TestBasePage.aspx.cs 소스

소스 코드에서 직접 작성해야 하는 부분은 빨강 테두리로 표시했으며, Mona.Web.UI.BasePage를 상속하고 있다.
이와 같이 작성하고 테스트 해보면 페이지를 처음 로딩할 때는 첫번째 텍스트 박스에 포커스가 위치하고 버튼을 클릭하면 두번째 텍스트 박스에 포커스가 위치하는 것을 알 수 있다.
마찬가지로, 생성된 HTML에서 GetElement와 SetFocus 자바 스크립트의 생성위치를 비교해보기 바란다.
BasePage 버전 관리
System.Web.UI.Page를 BasePage로 대체하기로 결정했다면 여러 프로젝트에서 같은 DLL을 참조하여 사용하게 될 것이다. BasePage의 개선이 자주 발생하지 않는다해도 매번 컴파일시 변경되는 버전은 참조 오류를 일으킨다. 따라서 BasePage 프로젝트의 AssemblyInfo.cs 에서 AssemblyVersion 특성을 다음과 같이 변경하여, 고정된 버전번호를 부여하도록 한다.
[assembly: AssemblyVersion("1.0.0.0")]
SetFocus() 함수와 ASP.NET 2.0
반가운 소식은 앞서 구현한 SetFocus() 함수의 역할을 대신할 함수가 ASP.NET 2.0에 포함되었다는 것이다. 현재 .NET Framework 2.0 베타에서도 이 함수를 사용할 수 있다. System.Web.UI.Page.SetFocus( string controlName )이 바로 그 함수다. ASP.NET 2.0이 도입될 경우에도 BasePage의 SetFocus() 함수를 그대로 사용할 수 있으며, 원한다면 AddSetFocusScript() 함수를 제거하는 것으로 ASP.NET 2.0에 대비할 수 있을 것이다.
다음시간에는 자동탭 넘김, 숫자 입력 텍스트 박스, 문자 입력 텍스트 박스 등에 대해서 살펴볼 것이다.
참고자료
BasePage 소스코드 다운로드

Build Your ASP.NET Pages on a Richer Bedrock

JavaScript: The Definitive Guide, 4th Edition, Ch. 17
JavaScript & DHTML Cookbook, Ch. 8

출처 : Tong - 夢魂™님의 # 기술 자료통

웹서버 부하 분산을 위한 허접한 로드밸런싱 ^^;

웹서버가 그렇게 성능(Xeon 2.4, 스카시HDD, 1G RAM)이 떨어지는 것도 아닌데... 60만명이 넘는 회원을 가진 다음카페 회원들한테 메일한번 쏜 이후로 엄청난 접속에 거의 서버가 멎을 뻔 하였던 경험을 하였습니다.

그래서 생각한 것이 로드밸런싱인데... 허접한 제 실력에 로드밸런싱이란 것은 하기 힘든 작업이었죠.^^

그래도 어디서 들어본 것은 있는지 문득 생각난 것이 rsync와 Round-Robin이였습니다.^^

하지만 들어보기만 했지 직접 해 본적은 없어서... 어떻게 해야 할 지 난감하더군요..^^

어째든 맨땅에 헤딩은 그렇게 시작이 되었습니다.^^

여기서 많은 분들께 질문도 하고... 여기 저기 문서도 많이 찾아 봤습니다.^^



아직 완벽하지는 않은 듯 하니... 참고로 보시고..

물론 더 뛰어난 실력을 갖추신 분들은 더 좋은 로드밸런싱을 사용하시기 바랍니다. (skip... ^^)



그럼 하나 하나 제가 한 방법을 적어보도록 하겠습니다. 이하 존댓말 생략입니다.^^;





기존의 웹서버 A와 새롭게 추가하고자 하는 웹서버 B가 있다고 보자.



A서버의 아이피 : 192.168.1.1

B서버의 아이피 : 192.168.1.2



우선은 두 서버가 하나의 서버로 인식하기 위해서는 두 서버 모두 하나의 도메인을 가지고 있어야 한다. 따라서 DNS의 설정은 필수적이다.





1. DNS 설정(Round-Robin)



$TTL 86400

@ IN SOA ns.localhost.com. root.localhost.com. (

2003052901

21600

1800

1209600

86400)

IN NS ns.localhost.com.

IN A 192.168.1.1

www IN A 192.168.1.1

www IN A 192.168.1.2

www1 IN A 192.168.1.1

www2 IN A 192.168.1.2





위와 같이 zone 파일을 설정한다. 물론 named는 restart 해야 한다. 그러면 www.localhost.com이란 도메인은 192.168.1.1과 192.168.1.2 두개의 아이피를 가지게 된다. 이 상태에서 nslookup www.localhost.com이라고 하면... 다음과 같이 나온다.





Server: 168.126.63.1 --> 질의한 서버 아이피

Address: 168.126.63.1#53



Name: www.localhost.com

Address: 192.168.1.1 --> 결과값1

Name: www.localhost.com

Address: 192.168.1.2 --> 결과값2



이와 같이 나온다면 네임서버는 잘 설정한 것이다.^^





2. 웹서버의 설정



우선 두대 모두다 apache의 httpd.conf파일에 www.localhost.com 도메인을 설정해 두어야 한다. 만일 이미 다른 것으로 사용하고 있다면 apache의 가성서버 설정을 이용해야 한다.(물론 여기서 가상호스트 설정까지 살펴보지는 않겠다.^^) 기본적으로 두 서버의 DocumentRoot가 틀려도 되지만, 손 쉬운 관리를 위해서 경로를 같게 두는 것이 좋을 것이다.



ex)

A서버의 DocumentRoot - /usr/local/localhostSource

B서버의 DocumentRoot - /usr/local/localhostSource





3. rsync의 설정



이제 두대의 서버가 갖춰지고 두대 모두 동일한 도메인을 가지게 되었다면 두 서버의 소스가 동일하도록 할 차례이다. 이러한 것을 위해서 바로 rsync가 필요하다. rsync와 관련된 많은 참고문헌들을 뒤졌는데 결론적으로 '질주본능'님의 조언으로 성공하게 되었다. 이 자리를 빌어 감사하다는 말씀을 전한다. '질주본능'님이 쓰신 rsync 관련 내용을 보시고 싶으신 분은 http://www.phpschool.com/bbs2/inc_view.html?id=9985&code=tnt2&start=0&mode=search&field=title&search_name=&operator=and&period=all&category_id=&s_que=rsync 를 참고하기 바란다.



우선 rsync 는 ssh를 이용한 방법과 873 포트를 이용한 방법이 있다. ssh를 이용한 방법이 조금더 안정성 면에서 좋을 것이라는 생각에 시도하였지만 번번히 실패하게 되었고 결국에는 873포트를 이용한 rsync를 성공하게 되었다. ssh를 이용한 rsync에는 비밀번호를 물어보게 되는데 파일을 이용하여 비밀번호를 자동으로 입력할 수 있다고 하는데 잘 되지 않았다.(성공한 분은 비결좀 알려주시길...^^)





그럼 873포트를 이용한 rsync 설정 방법을 알아보도록 하자.



우선은 xinetd를 이용하여 rsync가 구동되므로 다음과 같이 설정을 해 줘야 한다.



#vi /etc/xinetd.d/rsync



# default: off

# description: The rsync server is a good addition to an ftp server, as it

# allows crc checksumming etc.

service rsync

{

disable = no

socket_type = stream

wait = no

user = root

server = /usr/bin/rsync

server_args = --daemon

log_on_failure += USERID

}





그 다음 rsync의 설정파일을 수정해 줘야 한다. rsync의 설정 파일은 rsyncd.conf 파일이다. 물론 이 파일은 원래 존재하지 않는다.(원래 존재하는데 필자만 없었을 수도 있다.) 한가지 주의할 것은 설정파일 이름이 rsync.conf가 아니라 rsyncd.conf란 것이다. 일부 tip에서 rsync.conf라고 하는데 이렇게 할 경우에는 rsync가 되지 않았다.



#vi /etc/rsyncd.conf



[www]

path = /usr/local/localSource

comment = webservice-dir

uid = root

gid = root

use chroot = yes

read only = yes

hosts allow = 192.168.1.2

max connections = 1

timeout = 300



여기서 [www] 은 닉네임이다. 즉 아래 설정 내용을 한번에 호칭하기 위해 사용하는 것이다. path는 rsync를 받고자 하는 소스가 존재하는 디렉토리를 정해주면 된다.

uid와 gid는 root로 하는 것이 좋다. nobody로 할 경우에는 일부 기능을 사용하지 못하는 경우가 발생했다.^^(정확한 이유는 모르겠다.^^)

hosts allow는 어느 아이피에서 rsync 서버에 붙어 소스를 가져가도록 허락할 것인지 설정해 주는 것이다.





rsync의 설정을 모두 마쳤다면 xinetd 데몬을 재 시작한다.



/etc/rc.d/init.d/xinetd restart





설정을 마치고 xinetd도 재시작했다면 873 포트가 열려 있는지 테스트 해보자.



#telnet localhost 873

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

@RSYNCD: 26

Localhost rsync server

sysadmin = root@localhost.com



위와 같이 나온다면 정상적으로 설정이 된 것이다. 물론 2번째로 소스를 받아갈 B서버에서도 테스트를 해 봐야 한다.





#telnet 192.168.1.1 873

Trying 192.168.1.1...

Connected to 192.168.1.1.

Escape character is '^]'.

@RSYNCD: 26

Localhost rsync server

sysadmin = root@localhost.com





이렇게 되었다면 이제 rsync는 완전히 성공한 거나 다름 없다.

다음과 같이 테스트 해보자...^^



rsync -avzrt --delete 192.168.1.1::www /usr/local/localSource/





-a는 아카이브 모드. 심볼릭 링크, 속성, 퍼미션, 소유권 등 보존

-v 전송 상태를 보여줌

-z 전송시 압축을 함.

-r recursive (하위 디렉토리까지 포함)

-t 변경시간 전송 (이것이 없으면 전송한 시간으로 바뀜)



--delete A서버에는 없는데 B서버에 있다면 지우라는 명령



::는 873포트를 이용한 rsync에서 사용하며 ssh나 rsh를 사용할 경우에는 : 라고 써야 한다. 우리는 873 포트를 이용하므로 :: 라고 써야 한다.

www는 rsync 서버의 /etc/rsyncd.conf 파일에서 준 닉 이다. 바로 그 곳에서 설정한 path의 소스들을 /usr/local/localSource/ 디렉토리 밑으로 가져온다는 의미이다.



이해를 다 하셨다면 'Enter'를 힘차게 눌러보자.. 화면이 주르륵 하면서 소스를 가져오는 것이 보일 것이다.(안보이면 대략 낭패..-.-;)

처음에는 모든 파일을 다 가져오기에 조금 시간이 걸릴 것이다. 하지만 그 다음부터는 변경된 파일만 가져올 것이므로 그다지 부하는 걸리지 않을 것이다.^^ (예상하건데...)



이 명령어를 수동으로 매번 타이핑할 수 없으므로 /etc/cron.hourly/ 밑에 shell script 파일 하나를 만들자.



#vi rsync.sh



rsync -avzrt --delete 192.168.1.1::www /usr/local/localSource/



그리고 나서 chmod 700 rsync.sh 하면...^^ rsync 완료...





4. nfs의 설정



사이트에 소스만 있다면 이것으로 끝날 수 있다. 하지만 어찌 소스만 있으랴... nobody 권한으로 생성되는 각종 파일들(로그기록, 그림파일, 업로드 되는 파일들... 기타 등등)을 어떻게 두 서버에서 공유할 수 있단 말인가?

사용자가 운좋게 Round-Robin에서 잘 걸려서 A서버로 붙은 후 파일을 업로드 했다면 rsync로 샥~~ 파일을 가져오면 되는데... B서버에 붙어서 파일을 올렸다면 어찌 해 볼 도리가 없다. 그렇다고 B서버에 rsync 서버를 설치하고 거꾸로 다시 가져오는 것도 바보같은 짓이다.^^(설마 이렇게 하는 분들은 안계시겠죠?)



그래서 나온 것이 nfs이다. Network File System의 약자로 원격지에 있는 하드디스크를 마치 자신의 하드디스크인양 mount 해서 쓸 수 있는 것이다.

따라서 A서버에 있는 디렉토리를 B서버에서 마운트 한다면 어느 서버에서 파일을 올리던 한곳에 파일이 기록되게 되는 것이다. 물론 파일서버를 하나 더 두고 A, B 서버 모두 마운트 해서 사용해도 될 것이다(이렇게는 해 보지 않았다^^)



한가지 주의할 사항은 파일이 쌓이는 곳이 DocumentRoot 밖에 있어야 한다는 것이다. 그래야지만 rsync와 상관없이 실시간으로 파일을 공유할 수 있기 때문이다.



필자는 /localData 란 디렉토리를 하나 만들고 이곳에 nobody 권한으로 생기는 모든 파일을 잘 정리해서 사용하고 있었다.

그럼 nfs의 설정을 하나하나 살펴보도록 하자.





우선은 rsync와 마찬가지로 어느 디렉토리를 어떤 아이피와 공유할 것인지를 설정해야 한다. 따라서 A서버에서 다음과 같이 설정해 줘야 한다.



#vi /etc/exports



/localData 192.168.1.2(rw,no_root_squash)





여기서 /localData란 마운트 당할(?) 디렉토리명... 192.168.1.2는 접근 허용할 아이피, rw는 일고 쓰기 가능토록 권한을 주는 것..., no_root_squash는 B서버의 root도 해당 디렉토리에서 A서버의 루트 권한을 주는 것(맞나?)이다. 참고로 아이피는 도메인으로 설정해 줘도 되는데... 우리는 A서버와 B서버의 도메인이 같으므로 아이피로 하도록 한다.

이렇게 설정을 한 다음... nfs 데몬을 재시작 한다.



#/etc/rc.d/init.d/nfs restart



이렇게 하면 5개인가의 데몬이 주르륵 재시작된다.(stop, start 합치면 10개의 ok 사인이 떨어진다.^^)



이상태에서 바로 B 서버에서 mount를 하면 대략 난감이다. ^^(이거때문에 몇일을 헤메었는지 모른다.^^;;)

이렇게 다 했다면 가장 중요한 데몬 하나를 죽여줘야 한다.^^



#/etc/rc.d/init.d/nfslock stop



이놈이 뭐하는 놈인지 모르겠는데, 이 데몬이 살아 있다면 죽어도 B서버에서 A서버의 /localData를 mount 하지 못할 것이다.(하는 분이 나타난다면... 안되는데..^^;;)

어째든 여기까지 했다면 거의 다 성공한 것이다.



하지만 B서버에서도 설정해 줘야 할 것이 몇개 있다.^^



다음과 같이 dns에 질의하지 않고 바로 연결할 수 있도록 hosts파일을 편집해 줘야 한다.(성능상 좋다고 한다^^, hosts파일의 역할을 모르시는 분은 검색..^^)



#vi /etc/hosts



192.168.1.1 localhost.com localhost.com





그다음 마운트!!!



#mount -t nfs localhost.com:/localData /localData/



한번 마운트가 잘 되었는지 확인해 보자...^^



#cd /localData

#ls -al

drwxr-xr-x 8 nobody nobody 4096 2월 23 17:57 .

drwxr-xr-x 20 nobody nobody 4096 2월 24 13:10 ..

drwxr-xr-x 2 nobody nobody 4096 2월 25 10:44 adminCharge

drwxr-xr-x 2 nobody nobody 4096 2월 26 16:48 cafeConn

drwxr-xr-x 38 nobody nobody 4096 2월 11 13:23 history

drwxr-xr-x 38 nobody nobody 4096 7월 22 2003 ipLog

drwxr-xr-x 2 nobody nobody 8192 2월 27 2004 joinWord

drwxr-xr-x 2 nobody nobody 4096 1월 2 00:06 userAgent



이 다음 B서버에서 접속한 경우 nobody 권한으로 기록되는 파일들이 /localData에 제대로 기록되는지 테스트만 해 보면 된다.





마침...



현재 이런 셋팅에서 테스트 해본 결과 잘 되고 있습니. 다만 로드밸런싱을 하는 프로그램이 따로 없고 네임서버를 이용한 Round-Robin을 이용하다 보니 A, B 서버의 사양에 상관없이 균등하게 배분이 되며 한번 A서버에 붙은 사람은 B 서버로 잘 옮겨오지 못하는 경우가 발생합니다.

그렇게 큰 문제는 아니라고 생각되지만, 불편하신 분들은 더 좋은 로드밸런싱 프로그램을 사용하길 바랍니다. 아마도 돈을 조금 지불해야 되지 않을까 십네요^^

그리고 더 좋은 무료 로드밸런싱 제품이 있다면 저한테도 좀 알려주시기 바랍니다.^^





참고로 이 글은 제가 직접 쓴 글이므로(물론 많은 분들의 도움이 있었지만..^^) 옮겨가실 때에는 출처를 밝혀 주시고... 이대로 따라 하시다가 서버가 맛이 간다거나 해도 저의 책임이 없음을 미리 밝히는 바입니다.^^;



그럼 즐프하시고...

좋은 시간 되세요.



참 덧글도 좋은거 있어서 붙입니다.



덧글..



DNS를 사용해서 로드를 구성하신다면 보다 효율적인 분산을 위해서 TTL값이 작게 잡는것이 좋지 않을까요

www 60 IN A 192.168.1.1

www 60 IN A 192.168.1.2

- PHP 스쿨에서 공간사랑님이.. ^^



요즘 서버들 랜카드가 두개잖아요.

랜 포트 하나는 IP 공유기나 허브에 연결하시구.

NFS 는 사설아이피로만 허가하세요.

나머지 포트는 웹으로 사용하시구요.

그리고 DNS 를 . 1,2 번 웹서버에 각각 2번 찍으면 됩니다.

전 이방법으로 서버 4대 돌리고 있는데 트레픽도 내부적으로 하니까 좋습니다. 전 작년 10월부터 지금까지 이상없이 잘 사용하고 있습니다.

- PHP 스쿨에서 영완님이 ^^



NFS 가 편리하긴 하지만, 락이 걸릴 경우 시스템이 그대로 뻗어 버리는 경우가 종종 있습니다. 그래서 실시간으로 공유해야 할 부분에만 NFS를 사용하고, 그외에는 rsync 등을 사용해서 replication 을 해 주는 게 좋습니다. 그리고 서버가 여러대일 경우 NFS로 묶으면 IO쪽 부하가 심해지므로 고려해야 합니다. 만약 NFS를 구지 사용해야 한다면, TCP 기반의 NFS를 사용하는 게 여러가지 특성상 유리합니다.

- PHP 스쿨에서 Samuel Oh님이 ^^



일전에 로드밸런싱을 위하여 제가 작업했던 방식은 일단 l4에서 rr(라운드 로빈)로 각 웹서버의 접속세션을 분산시켜주고 해당 웹서버에서는 nfs서버의 웹파일들을 사용합니다. nfs서버와 웹서버와의 통신은 내부망을 통해서 연결되어 있고요.

이렇게 사용되면 디스크 쓰기 i/o나 읽기 i/o등이 nfs 서버로 분산 되어 웹서버 자체의 시스템적 부하는 줄어들고 서버 파일 관리가 용의해지겠지요. (만약 파일을 한곳에 모아 놓지 않는다면 완벽한 미러링 시스템이 필요하겠지요.)

nfs서버 자체가 그다지 미덥지 못하다면 데이터센터에서

스토리지 서비스를 받는 방법도 좋습니다. 스토리지 서비스를

받는다면 보안이나 운용에 큰 도움이 되겠지요.

- PHP 스쿨에서 santana님이 ^^

----------------------------------------------------------------------------> 다 좋지만 요 밑부분 괜찮습니다. ^^

실제로 운영한 것을 경험으로 정리해본다면..

L4로 웹서버 로드 밸런싱..

DB서버는 Replication 을 통한 로드 밸런싱..

웹소스는 NFS(개별서버) 를 통한 데이터 공유,

웹소스 백업은 rsync OR NFS서버에서의 백업후 백업서버로 이동

DB 백업은 개별 Slave DB(Repliction)에서의 백업후 백업서버로 이동

이와 같이 썼었습니다. 단점으론 서버가 좀 많이 듭니다.

실시간으로 웹소스 및 DB소스를 운용 가능하구요..

사용자가 늘어나면 늘어날수록 해당하는 웹서버와 DB서버를 증설하고.. 캐쉬기능을 보강하구.. 하면 꽤 좋은 성능을 내주더군요..

- PHP 스쿨에서 꾹꾹이 님이 ^^

<---------------------------------------------------------------------------- 요기까지? ^^.. ㅋㅋ



물론 저도 안해봤으니 책임 못집니다. ㅋㅋ

PHPSCHOOL 보다가 좋은글 있길래 뽑아왔습니다. 출처를 밝히시라네요 ^^

근데 자세히 안나와서 나온데로 밝히겠습니다. ^^



출처 : PHPSCHOOL에서 체리필터 님이.. ^^

웹해킹 대응을 위한 Nikto 사용법


nikto의 기능 및 특징



nikto는 웹 서버 설치시 기본적으로 설치되는 파일과 웹 서버의 종류와 버전 등을 스캔하며, 특히 방대한 DB를 이용해 취약한 CGI 파일을 스캔하는 기능이 매우 뛰어나다.



다운로드  : http://www.cirt.net/code/nikto.shtml



1. nikto는 취약하다고 알려진 3100여개의 방대한 CGI 파일에 대한 정보를 갖고 있으며 625개가 넘는 서버에 대한 버전 정보를 갖고 있다. nikto는 서버에서 보안적으로 잘못 설정된 부분(misconfigurations)이나 웹 서버 설치시 기본으로 설치되는 파일이나 스크립트의 존재 유무, 안전하지 못한 파일이나 스크립트의 유무, 오래되어 취약성을 가지고 있는 프로그램의 유무 등을 검색한다.



2. 취약성 DB는 수시로 업데이트가 되며 원격지에서도 쉽게 업데이트가 가능하다.



3. 취약성 점검 결과는 html이나 txt, csv 등으로 저장할 수 있다.



옵션



-Cgidirs : 스캔을 진행할 cgi 디렉토리를 지정할 수 있다. 통상적으로 all로 지정한다.

# ./nikto.pl --Cgidirs all -h www.dduri.net



-generic : 스캔시 'Server:' 문자열에 보이는 정보와 관계없이 스캔을 진행하도록 한다.



-findonly : 웹서버가 사용하는 웹 포트를 스캔하기 위한 옵션이다. 이를테면 80번이 아닌 다른 포트에서 웹 서비스를 하는 포트를 찾을 경우에 사용된다.



#./nikto.pl -findonly -h www.dduri.net



-Format : 스캔 결과를 파일로 저장할 때 어떤 형식으로 남길지 지정한다.

#./nikto.pl -Format html -output dduri.html -h www.dduri.net



-id : 만약 해당 웹서버가 HTTP Authentication으로 보호되고 있을때 ID/PW 인증이 필요한다 이때 userid:password 형식으로 넣어준다.



-update : 업데이트가 필요할 경우 사용한다.



불법이니 자기 컴퓨터나 허가된 서버에만 사용하길 바란다.



출처 : http://cafe.naver.com/jeonghee1004.cafe































Can't display this flash media







점을 끌어서 교차되는 선을 없애면 다음 판으로 넘어간다.

Iperf-꽁짜 네트워크 퍼포먼스 측정툴 소개


iperf는 일단, 돈이 안들고 간단하게 측정할수 있기 때문에 좋은것 같습니다.



현재 iperf는 ipv4, ipv6, multicast에 대한 사용가능한 최대 대역폭을 측정해주는 프로그램입니다. 또한, 윈도사이즈도 변경가능하고 udp 또한 가능합니다.



예를들어서 iperf클라이언트~iperf서버로 실행을 하면 클라이언트측에서 서버쪽으로 보낼수


있는 최대한의 패킷을 보냅니다. 마치 스마트비트처럼 말이죠..


그러면 정해진 시간(디폴트 10초)동안 보낸후 사용가능한 클라이언트~서버구간의 최대 대역폭을 알수가 있습니다.



패킷을 엄청 생성해서 보내는 것이기 때문에 실제로 사용하고 있는 네트워크에서 사용하는 것은



돌리는 시간 동안 네트워크의 많은 대역폭을 소모함으로 인하여 자칫 네트워크가 먹통이 될수 있으므로 업무 끝나고 사람들이 안쓰는 시간대에 하실 것을 권장합니다.


원래 나온것이 리눅스에서 잘 굴러가도록 나온것입니다만..

윈도에서도 대충 굴러가는 것 같습니다. 자세한 것은 아래 주소를 참조하시길..


디폴트값으로 port 번호: 5001/tcp, 시간: 10초


http://dast.nlanr.net


아래 방법은 윈도용을 받아서 사용한 방법입니다.


그냥 화일하나만 달랑 받은후 아무데나 갖다놓고 하면 됩니다.


서버와 클라이언트의 화일은 똑같습니다.



아래에서 서버는 10.206이며.. 클라이언트는 20.201 입니다.


[1] 서버실행


C:\Documents and Settings\zero\바탕 화면> iperf -s

------------------------------------------------------------

Server listening on TCP port 5001

TCP window size: 8.00 KByte (default)

------------------------------------------------------------


[2] 클라이언트 측


(1) 10초간(디폴트)의 성능측정


C:\Documents and Settings\zero\바탕 화면> iperf -c 192.168.10.206

------------------------------------------------------------

Client connecting to 192.168.10.206, TCP port 5001

TCP window size: 8.00 KByte (default)

------------------------------------------------------------

[884] local 192.168.20.201 port 1036 connected with 192.168.10.206 port 5001

[ ID] Interval       Transfer     Bandwidth

[884]  0.0-10.0 sec   113 MBytes  94.5 Mbits/sec


(2) window size 변경



C:\Documents and Settings\zero\바탕 화면> iperf -w 100k -c 192.168.10.206

------------------------------------------------------------

Client connecting to 192.168.10.206, TCP port 5001

TCP window size:  100 KByte

------------------------------------------------------------

[884] local 192.168.20.201 port 1048 connected with 192.168.10.206 port 5001

[ ID] Interval       Transfer     Bandwidth

[884]  0.0-10.0 sec   113 MBytes  94.9 Mbits/sec


(3) 시간을 100초로 지정


C:\Documents and Settings\zero\바탕 화면> iperf -t 100 -c 192.168.10.206

------------------------------------------------------------

Client connecting to 192.168.10.206, TCP port 5001

TCP window size: 8.00 KByte (default)

------------------------------------------------------------

[884] local 192.168.20.201 port 1051 connected with 192.168.10.206 port 5001

[ ID] Interval       Transfer     Bandwidth

[884]  0.0-100.0 sec  1.10 GBytes  94.6 Mbits/sec



출처 : http://cafe.naver.com/neteg (제로님의 글)


경상도의 아름다운 길 18선

먼저 경상북도의 아름다운 길입니다. 길에 대한 특징 및 설명은 건설교통부의 보도자료를 참고한 것입니다.





▲ 무섬 외나무다리 : 경북 영주시 문수면 수도리 무섬마을(무섬외나무다리)



문수면 수도리 무섬마을은 자연과 고가(古家)가 그대로 보존된 전통마을로서 내성천(乃城川)이 마을의 3면을 감싸 듯 흐르고 있으며, 그 가운데 섬(島)처럼 떠 있는 육지 속 섬마을입니다.



30년 전만 해도 마을 사람들은 나무를 이어 다리를 놓아 내성천을 건너 뭍의 밭으로 일하러 갔다고 합니다. 장마가 지면 불어난 물에 다리는 휩쓸려 떠내려가 마을 사람들은 해마다 다리를 다시 놓았다고 합니다.

지난 30여년간 마을과 뭍을 이어준 유일한 통로였던 무섬 외나무다리. 현재도 30년전 방식으로 그대로 주민들이 나무를 잘라 만든 것이라고 합니다.








▲ 죽령옛길 : 경북 영주시



죽령옛길은 2,000년의 유구한 역사를 자랑하는 길입니다. 청운의 뜻을 품은 과거 길의 선비, 공무를 띈 관원들, 장사꾼들로 붐비고, 길손들의 숙식을 위한 주막, 마방이 죽 늘어서 있어 사시사철 번잡했던 고개길이었다고 합니다.



영주시에서 옛 자취를 되살려 보존하기 위해 이 길(2.5km)을 다시 뚫고 안내판을 설치한 것이라고 합니다. 현재는 자연탐방로로 개발되어 야생화 등을 볼 수 있다고 합니다.








▲ 울릉도 일주도로 : 경북 울릉군(지방도 926호선)



이 도로로 인해 산간지역 마을의 접근성이 좋아져 농민들의 특산물 판매량 증대에 기여하였다고 합니다. 기암절벽과 아름다운 해안선이 어우러진 도로라 관광객들이 붐빈다고 합니다.



울릉도는 일주도로로 인해 사동 흑비둘기 자생지, 불교진각종 성지, 사자암, 태하 성하신당, 북면 바다위의 코끼리바위, 송곳산, 삼선암, 관음도, 나리분지, 너와집, 용출소, 신령수 등 울릉도 관광명소에 대한 접근성도 크게 향상되었다고 합니다.








▲ 영덕대게로 : 경북 영덕군 축산면 ~ 강구면(국지도20호선)



영덕대게로는 39ha 면적에 이르는 해변공원, 해맞이공원과 인접하여 영덕군을 찾는 사람들에게 수려한 해안풍경과 해맞이 등 멋진 볼거리를 제공하고 있다고 합니다.

300여 미터에 이르는 공원의 시작과 끝 지점에는 파고라, 의자, 주차장, 나무계단 등이 설치되어 있으며, 부채꽃, 패랭이꽃, 야생화, 향토수종 꽃나무 900여 그루가 잘 조성되어 있다고 합니다. 또한 인근에 풍력발전단지가 조성되어 있어 바다경관과 어우러진 이국적 정취를 느끼며 드라이브 할 수 있는 도로이기도 하다고 합니다.








▲ 문경새재 옛길 : 경북 문경시 문경읍 상초리 문경새재 1관문~3관문



조선시대부터 영남에서 한양으로 통하는 가장 큰 길(영남대로)인 문경새재 옛길은 예로부터 영남과 한양을 잇는 길목이었으며, 군사적 요충지, 문물의 교류지 역할을 했다고 합니다.



현재 문경새재 1관문에서 3관문에 이르는 6.5km의 문경새재 옛길은 황토길로 보존되어 있으며, 관광과 역사체험의 현장 역할을 하고 있다고 합니다.








▲ 황악로 : 경북 김천시 다수동(국도 4호선)



황악로에 위치한 영남제일문(높이 12m, 길이 50m)은 6차로 도로와 잘 어우러져 한 폭의 그림과 같은 장관을 이룬다고 건설교통부는 평가했습니다.



옛 영남의 첫 관문에 위치한 영남제일문은 한식구조로 건립된 전통 구조물입니다. 중앙에 걸려있는 현판은 서예대가 여초 김응현 선생과 각장자 이수자인 고원 김각한씨의 작품이며, 특히 무형문화재 기능자인 단청장 조정우 선생이 직접 단청한 현판 좌우 8폭의 비천상을 징, 장고, 꽹과리, 포도 등 김천의 상징물을 함께 그려 품위와 고전미를 더하여 김천의 명물이 되고 있다고 합니다.








▲ 팔공산 한티재 : 경북 칠곡군 동명면 남원리 ~ 득명리(국지도 79호선)



팔공산은 전국의 10대 명산중 하나로서 동화사, 부인사 등의 명성사찰과 천주교 한티성지, 신숭겸장군 유적지 등 많은 유적과 전설이 서려있어 4계절 내내 등산객과 탐방객이 넘치는 전국적 관광명소라고 합니다.



팔공산의 아름다운 전경과 신선함을 굽이굽이 휘감아 돌다보면 도로의 굴곡을 따라 펼쳐지는 수려한 주변경관에 감탄과 탄성을 자아낸다고 건설교통부는 평가했습니다.








▲ 김유신장군묘 진입로 : 경북 경주시 충효동(시도 58호선)



삼국통일의 위업을 달성한 김유신장군묘로 연결되는 흥무로 벚꽃길은 하늘이 보이지 않을 정도로 벚꽃 터널을 이루어 경주 내에서도 가장 최고로 손꼽히는 곳이라고 합니다.



건설교통부는 경주를 찾는 관광객에게 주간뿐만 아니라 야간에도 볼거리를 제공하고자 지중 등을 설치하여 야간경관이 매우 아름답다고 평가했습니다.





다음은 경상남도의 아름다운 길입니다.




▲ 지안재 : 경남 함양군 마천면 의탄리~함양읍 구룡리(지방도 1023호선)



지안재와 오도재는 옛날 내륙지방 사람들이 남해안쪽 사람들과 물물교환을 하고자 지리산 장터목으로 가기 위해 반드시 넘어야했던 고개였다고 합니다.

굽이굽이 고갯길을 휘감아 오르면 지리산으로 갈 수 있다고 합니다.

이 곳은 낮에 보아도 아름답지만 특히, 야경이 아름답다고 합니다. 또한 여름밤에는 반딧불을 볼 수 있을 정도로 공기가 맑다고 합니다.



이곳은 ‘가루지기’전의 주인공 변강쇠와 옹녀의 전설이 깃든 곳이기도 합니다. 오도재 정상에는 그 옛날 장사를 하던 상인들이 무사히 재를 넘고 장사가 잘 되도록 산신령에게 기원하였다는 비석이 서있다고 합니다.



아래는 2005년 5월 말 독자 '후루룩'님이 '이니셜D 코스??'라는 제목으로 제보했던 것으로 낮에 찍은 지안재 사진입니다.







▲ 가야의 거리 : 경남 김해시 봉황동 ~ 구산동(시도 2-23호선)



김해시는 금관가야의 발상지로서 시가지 전역에 산재한 역사문화자원을 종합적으로 정비하고자 가야문화의 주요 유적지들을 연결하는 가로공원의 성격으로 가야의 거리를 조성했다고 합니다.

철기문화를 상징하는 상징분수와 야간경관조명, 타원형의 바닥분수, 가야인의 생활환경이 함축된 주제정원, 소광장, 쉼터 들이 조성되어 있다고 합니다.








▲ 천자봉 산길 : 경남 진해시 태백동 안민도로 ~ 장천동 대발령 고개(임도, 천자봉 산길)



이 도로는 산불방지와 산림자원의 보호증식을 위해 개발된 것이라고 합니다.

길 양쪽으로 벚나무가 심어져 해마다 봄이면 장관을 이루며 산길 주변에는 철쭉, 배롱나무 등 25만여 본의 꽃길이 조성되어 있어 사계절 다양하고 색다른 풍경을 보여준다고 건설교통부는 평가했습니다.








▲ 대천로 : 경남 진해시 시민회관~북원로타리(대로 3-1)



경남 진해는 국내 최고·최대의 벚꽃 행사인 군항제가 개최되는 곳이죠, 대천로는 진해 내에서도 최고로 꼽는 벚꽃길이라고 합니다.

이 벚꽃길은 2002년에 방영된 MBC 드라마 '로망스' 촬영지로도 유명합니다.








▲ 해안관광도로 : 경남 진해시 웅천동 ~ 웅동1동(중로 3-21 및 중로 3-22)



진해시 웅천동 사도마을에서 영길마을까지의 해안변을 따라 약 20㎞에 이르는 해안관광도로는 자연경관이 수려하여 진해지역의 새 관광 명소로 각광받는 곳입니다. 낚시하기가 좋은 곳으로 알려지기도 해 인근 부산, 창원등지의 낚시꾼들도 즐겨 찾는 낚시 명소라고 합니다.



도로 양쪽으로 벚나무, 아열대 식물 등이 식재되어 있어 해안도로의 아름다움을 더하며, 이용자의 편의를 위해 도로 중간 중간에 휴게소(Scenic Point)와 주차공간, 자전거도로 등이 조성되어 있다고 합니다.








▲ 동진대교가 있는 해안도로 : 경남 고성군 동해면 양촌리 ~ 마산시 진전면 창포리(국도77호선)



고성군 동해면과 마산시 진전면을 잇는 동진대교는 바다로 향하는 길로서 국도77호선(국지도67호선과 중용)상의 교량이며, 동해면 해안일주도로의 일부구간입니다.

이 곳은 리아스식 수려한 해안경관과 조화를 이루어 지역명소가 되고 있으며, 동진대교가 개통되면서 낚시꾼과 관광객들이 줄을 잇고 있다고 합니다.








▲ 산양관광도로 : 경남 통영시 산양읍 영운리 ~ 남평리(지방도 1021호선)



도로변에는 동백꽃이 심어져 있어 동백이 피는 11월부터 이듬해 2월까지 반짝이는 동백 잎 뒤로 핀 꽃을 보며 드라이브를 즐길 수 있는 곳으로 유명합니다.



건설교통부는 차창 밖으로 펼쳐지는 푸른 바다와 한려수도의 크고 작은 섬들이 연출하는 해안경치가 일품이며, 한적한 바닷가 어촌마을들과 조그만 포구가 정겹게 비춰지고 차창을 열면 상큼한 갯바람이 차안을 가득 메우는 최상의 드라이브 코스로 많은 관광객이 찾고 있다고 설명했습니다.








▲ 학동·해금강 해안도로 : 경남 거제시 남부면 ~ 장승포동(국도 14호선)



학동·해금강 해안도로는 시원스러운 바다풍경과 해안절경이 아름다운 드라이브 코스로 2월 말에서 3월 초에 이곳을 찾으면 아름다운 해안절경과 함께 붉게 물든 동백숲과 도로변에 핀 갖가지 야생화로 더욱 아름다운 풍경을 감상할 수 있다고 합니다.



학동몽돌해수욕장의 몽돌이 바닷물에 쓸리는 소리는 우리나라의 아름다운 소리 100선에 선정될 만큼 운치를 더하며, 학동해수욕장부터 해금강까지 형성되어 있는 학동동백림과 팔색조 번식지는 천연기념물 제233호로 지정·보호되고 있어 새로운 볼거리를 제공합니다.



또한 함목 삼거리에서 해금강마을 가기 전에 있는 도장포마을에는 신선대와 바람의언덕이 있으며, 이곳 주변도 시원스러운 바다풍경과 아름다운 해안절경으로 찾는 이에게 즐거움을 더 한다고 합니다.








▲ 남면해안도로 : 경남 남해군 남면(지방도 1024호선)



평산고개를 넘어 유구마을로 접어들면서 시작되는 남면해안도로는 바다와 작은 섬, 기암괴석, 해안마을이 조화를 이루어 이국적 정취를 자아내는 남해군의 대표적인 해안관광도로입니다.



남면해안도로는 남해섬의 서쪽에 위치하여 해질녘 낙조에 비치어 보석처럼 빛나는 바다가 일품이며, 장항숲이나 구미숲에서 보는 일몰도 장관이라 건설교통부는 평가했습니다. 또한, 홍현에서 향촌까지 해안절벽을 따라 놓여진 도로의 양쪽에는 깎아지른 산과 해안절벽이 절경을 이루며, 우리나라에서 가장 물살이 잔잔하다는 앵강만도 찾는 이에게 잊지 못할 볼거리를 제공한다고 합니다.








▲ 남해대교 : 경남 남해군 설천면 ~ 하동군 금난면(국도19호선)



한국의 금문교라 불리는 남해대교는 1973년 개통되었으며 길이 660m, 높이 80m의 국내 최초 현수교라고 합니다.



건설교통부는 남해대교가 가로지르는 노량해협의 거센 물살은 남해의 역사를 고스란히 간직한 산 증인으로 임진왜란의 마지막 전투인 노량해전이 시작된 곳이며, 고려에서부터 조선시대에 이르는 무수한 유배객들이 자신의 적소로 건너오기 위해 나룻배를 탔던 한 맺힌 곳이기도 하다고 설명했습니다.



부식으로 인해 잿빛을 띄던 남해대교는 2003년 산뜻한 선홍색 빛으로 새단장하였고, 창선·삼천포대교와 함께 섬으로 가는 남해군 최고의 관광자원이다라고 건설교통부는 덧붙였습니다.



사진제공 = 건설교통부






원본출처: 네이버 인조이재팬 (http://enjoyjapan.naver.com/tbbs/read.php?board_id=ptravel&nid=23578&st=writer_id&sw=gusan311)

Personal Web Server를 활용하자

Cassini ???
대부분은 개발자들은 ASP.NET 1.x 환경에서의 웹사이트 개발시에 기본 웹사이트의 경로를 이리저리 바꾸신 경험이 있을 겁니다.
개발환경의 운영체제가 서버버전이 아니면 IIS를 설치하셨더라도 새로운 웹사이트의 추가가 되지 않기 때문이죠.
덕분에 웹프로젝트는 대부분 가싱디렉토리를 생성하여 개발하게 되는데, 페이지, 이미지 등을 루트경로를 지정하는 경우에는 결과물을 확인하는 것이 힘들었습니다.
이러한 불편함을 해소하기 위해 저는 Cassini를 사용했습니다. 주위의 많은 개발자분들이 Cassini 자체를 모르시고, 활용하는 분들도 거의 없었습니다. Cassin를 간략히 설명하자면 IIS 없이 웹사이트를 운영할 수 있는 Personal Web Server입니다(VS.NET 2005에 ASP.NET Development Server라는 이름으로 포함되어 있습니다.) 단순히 가상디렉토리를 대체하는 수단이라면 대부분의 개발환경이 IIS를 포함하기 때문에 큰 메리트가 없다고 생각될 수 있지만, 잘 활용하면 개발시의 경로문제를 해결할 수 있는 좋은 수단이 됩니다.



Personal Web Server를 활용하자.
자 그럼 VS.NET 2005의 Personal Web Server인 ASP.NET Development Server(이하 개발웹서버)를 활용해보도록 하죠. VS.NET 2005에서 웹사이트를 생성하고 이를 실행하면 IIS에 가상디렉토리가 추가되지 않은 상태에서 웹페이지의 결과물을 확인할 수 있습니다. 하단 트레이를 보시면 새로운 아이콘이 추가되고, 아래와 같은 화면을 보실 수 있습니다.



이러한 설정이 ASP.NET 2.0의 기본설정이기 때문에 많은 분들이 동일한 환경하에서 개발하실 것 같네요. 개발웹서버는 동적으로 port를 할당하고, 경로를 아래와 같이 설정합니다.
http://localhost:4686/Web
이건 제가 원하는 바가 아닙니다. 제가 개발하는 웹응용프로그램은 독립된 웹사이트로 운영될 예정입니다. 따라서 루트경로를 사용하는 것이 여러모로 편하지만, 개발시에 위와 같은 환경이 설정된다면 개발자가 결과물을 확인하면서 개발하는 것이 좀 힘든 일이 되겠네요. 웹프로젝트에서 /Web경로를 제거하고 싶지만, 웹프로젝트 속성에서 할 수 있는 일은 port를 변경하는 일 뿐입니다.








설정을 바꿀 수 없다면 이 글을 쓰는 이유가 없겠죠? ^^ 자~ 그럼 시작해볼까요? 개발웹서버가 돌아가는 상태에서 작업관리자를 실행해서 프로세스를 확인해봤더니 WebDev.WebServer.EXE 라는 것이 있네요.





C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 경로에서 해당화일을 확인할 수 있습니다. 그럼 바탕화면에 바로가기(Shotcut)를 추가해서 한번 실행해봅시다. 인자값은 포트번호, 물리경로, 가상경로입니다.







바로가기의 속성을 열어서 대상의 내용을 인자값에 맞게 입력합니다. 인자값 중 vpath는 “/”로 설정합니다.
예) C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.EXE /port:4686 /path:"D:\My Solutions\isBoard2005\Web" /vpath:"/"






바로가기를 실행한 후 개발웹서버를 확인합니다. 트레이에서 개발웹서버의 상세보기를 실행하면 아래 화면을 확인할 수 있습니다. 경로가 원하는 데로 바뀌었지요? ^^






그럼 VS.NET 2005로 돌아가서 솔루션 탐색기를 통해 웹프로젝트의 Property Pages를 열어서 Start Options > Server > Use customer server를 선택하신후 Base URL을 위에서 설정한

http://localhost:4686으로 직접 지정하실 수 있습니다.






개발웹서버에 대한 바로가기를 여러 개 설정하여 개발사이트별로 관리가 더욱 편리해집니다.






어려운 내용은 아니지만, 글을 쓰는데 별다른 내용이 없어서 글로 채웠습니다 ^^; 저와 비슷한 환경에서 개발하셨던 분들에게 경로설정 하는데 도움이 되었으면 합니다. MSDN의Cutting Edge 컬럼을 살펴보시면 Personal Web Server에 대한 좀더 많은 내용을 확인하실 수 있습니다.

P.S> 위 내용은 Cassini를 이용하여 ASP.NET 1.x 개발시에도 동일하게 적용할 수 있습니다. 그림을 통해 확인할 수 있지만, Cassini와 ASP.NET Development Server는 거의 동일한 프로그램으로 생각됩니다.