IT


세션 클러스터링은 WAS가 2대 이상 설치되어 있을 경우 동일한 세션으로 세션관리 하는 것을 의미합니다. 예를 들면 L4 스위치를 통해 2대 이상의 WAS가 연결되어 있을 경우 일반적으로는 사용자는 접속했던 WAS로 L4 스위치가 접속을 유도해주지만 하나의 WAS에서 허용된 동접수를 초과한 접속이 발생할 경우 다른쪽으로의 접속을 유도해주게 됩니다 그럴 경우 기존 WAS의 세션이 아닌 새로이 접속된 WAS로 세션이 이루어지고 그럴 경우 세션에 대한 처리 불일치가 발생하죠..그래서 각 WAS에 대한 세션을 하나의 세션으로 관리하게 함으로써 설사 사용자가 기존에 접속했던 WAS가 아닌 새로운 WAS로 접속하더라도 세션은 하나로 관리되기땜에 세션에 대한 불일치가 발생하질 않습니다.

 

Posted by sinpk

javax.servlet.jsp.JspException cannot be resolved to a type


에러 발생


톰캣 타겟이 안되어 있어서 그런가보다.


이클립스에서 Project > Properties > Targeted Runtimes



톰캣을 타겟팅 해주자.


 

'IDE > Eclipse' 카테고리의 다른 글

Task View 활용  (0) 2013.11.26
이클립스에서 한글 폰트 변경  (0) 2013.08.01
ISO-8859-1 형식의 *.properties  (0) 2013.07.02
제티,JSP,스프링 연동  (0) 2013.04.27
이클립스 주석 템플릿 설정  (0) 2013.04.27
Posted by sinpk

1. JVM heap 메모리 크기 변경

- $CATALINA_HOME/bin/catalina.sh 파일에 아래 내용을 추가한다.

JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+DisableExplicitGC"

(*) JVM의 기본 heap 메모리 사이즈는 64MB 이므로 최소한 -server, -Xms, -Xmx 옵션은 설정해야 한다.

(*) JVM 옵션 목록: http://blogs.sun.com/watt/resource/jvm-options-list.html

(*) Blog2Book, 자바 성능을 결정짓는 코딩 습관과 튜닝 이야기 추천함.




2. JRE 메모리 누수 처리

- Tomcat 6.0.26부터 메모리 누수를 탐지하는 기능이 추가되었다.

- $CATALINA_HOME/conf/server.xml 파일에서 아래 코드를 찾아 주석을 해제한다.

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />




3. 스레드 풀(thread pool) 설정

- 클라이언트의 요청을 처리하는 스레드 수 설정. 기본 값은 200이며 그 이상의 요청이 있을 경우 "connection refused" 메시지를 리턴한다.

- $CATALINA_HOME/conf/server.xml 파일에서 <Connector />의 속성을 수정한다.

<Connector port="8080" address="localhost" maxThreads="250" maxHttpHeaderSize="8192" emptySessionPath="true" protocol="HTTP/1.1" enableLookups="false" redirectPort="8181" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" />

- 만약 maxThreads 값이 최대 값인 750을 넘을 경우 두 대의 Tomcat을 이용해 클러스터링 구성을 하는 것이 좋다. 하나의 Tomcat에 maxThreads=1000을 설정하지 말고 두 개의 Tomcat에 각각 maxThreads=500 설정을 하라는 뜻이다.

(*) 잘 모르겠으면 대충 설정하지 말고 Tomcat을 기본값으로 운영하면서 숫자를 조금씩 조정해야 함.




4. 압축

- 특정 mime-type에 대해 데이터를 압축하여 전송할 수 있다.

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8181" compression="500" compressableMimeType="text/html,text/xml,text/plain,application/octet-stream" />

- compression="500"은 500 bytes 이상의 파일만 압축하라는 뜻이다.

- 닥치고 압축하려면 compression="on"으로 설정한다.

(*) HTTP compression: 서버에서 파일을 압축한 뒤 클라이언트로 전송하는 기능임. Tomcat의 고유한 기능이 아니라 HTTP 스펙에 있는 기능임.




5. 데이터베이스 성능 튜닝

- NamedQuery를 쓴다면 애플리케이션 초기화할 때 모두 로드할 것.

(*) JDBC를 사용한다면 try...catch...finally를 사용하여 반드시 DB connection을 close 할 것.




6. Tomcat Native Library

- Apache Portable Runtime(APR)이라는 게 있는데 이게 성능 향상이 많은 도움을 줌.

- 설치방법: http://www.techbrainwave.com/?p=1017(영어)

(*) 설치방법: Tomcat Native Library – Apache Portable Runtime(APR) 설치(한글)

(*) 굳이 Apache httpd와 연동할 필요가 없는 이유임.

(*) 진실 혹은 거짓: Tomcat과 Apache httpd를 연동하는게 항상 성능을 향상시키는가?




7. 기타

- 웹 브라우저 캐시 사용함으로 설정할 것.

- 서버 재시작시 반드시 자동으로 Tomcat이 재시작 되도록 설정할 것.

- HTTPS가 HTTP에 비해 약간 느리긴 하지만 보안이 중요하다면 HTTPS를 사용할 것

Posted by sinpk

웹 프로그래밍을 끝내고 나면, web server에 디플로이를 해야하는데, 여기서는 사람들이 가장 많이 쓰고, 대중적으로 사용하고 있는 tomcat 그중에서 버전 7에 어떻게 디플로이하는가를 설명하도록 한다

 

 

1. 먼저 tomcat 7을 다운로드 받는다.

http://tomcat.apache.org/download-70.cgi 에서 본인의 PC에 맞는 tomcat을 다운로드 받는다.

 

2. 톰캣은 설치용 프로그램이 아니기 때문에(windows register와 상관없다는 뜻), 특정한 directory에 다운로드 받은 zip파일 압축을 푼다 (예를 들어 나는 D:\server\apache-tomcat-7.0.37-windows-x64)에 압축해제를 했다.

 

3. bin 디렉토리에 있는 startup.bat파일을 통하여 톰캣을 실행시킨다. (windows => cmd 를 통해서 실행시키자.)

만약 jdk나 jre 파일을 찾을수 없다는 메시지가 나오면, 환경변수에 다음과 같이 추가한다.

 

변수이름 : CATALINA_HOME

변수 값 : D:\server\apache-tomcat-7.0.37-windows-x64\apache-tomcat-7.0.37 (본인이 설정한 디렉토리)

 

변수이름 : JAVA_HOME

변수 값 : C:\Program Files\Java\jdk1.7.0_13 (본인이 설정한 디렉토리)

 

4. startup.bat 파일을 통해 톰캣 실행이 정상적으로 된다면, 

localhost:8080 을 익스플로러(크롬, 파이어폭스 등등)를 통하여 실행시킨다. 

Apache 톰캣 화면이 나오면 성공이다. (apache_home.png)

 

5. manager 화면을 활성화 한다.

D:\server\apache-tomcat-7.0.37-windows-x64\apache-tomcat-7.0.37\conf\tomcat-user.xml 을 편집한다.

 

<role rolename="manager-gui" />

<user username="admin" password="admin" roles="manager-gui" /> 

 

를 추가한다.

 

6. 아래와 같이 설정후 톰캣 서버를 재시작하면 

locathost:8080/manager로 접근이 가능하다.

 

7. manager화면에서 war파일을 WAR file to deploy 를 통해서 디플로이 해주면 끝...

 

p.s Application의 path 쪽을 보면 여러개를 디플로이 할수 있는데, 그땐 localhost:8080/path 해주면 본인이 개발한 웹서버를 확인할 수 있다.

 

Posted by sinpk

1. 개요 : Custom_Scheme이란것은 스마트 폰의 web에서 해당 app을 실행시키는 것을 말한다.

 

2. 정확히 만들려는게 모야 :

1) 입력창과 버튼이 있는 web 페이지를 하나 만들고 모바일 web에서 접속한다. 

2) 입력창에 아무 값이나 입력한 후 전송 버튼을 누르면 앱이 실행된다.

3) app이 실행되고 web에서 입력했던 값이 app에서 출력된다.

 

3. jsp페이지 생성 : one.jsp, two.jsp

안드로이드 프로젝트 수정:  AndroidManifest.xml, csmail.xml csActivity.java

 

4. 사용기술 : jsp, javascript(ajax, jquery), android

 

5. 소스

[one.jsp]

<script type="text/javascript" src="./jqeury/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
 function checkApplicationInstall() {
   var id = idCheck(); //생성된 세션값 가져옴.
   document.checkframe.location = "testurl://aa/?input="+id; 
   /*
   iframe에 걸린거... 여기서 앱이 설치 되어 있지 않을 경우 testurl"// 이 안먹힐 거고 창이 닫히지 않는다. */
  
   /* 웹 페이지가 닫히지 않을시 어플 다운로드 페이지로 이동 1초 후에 다음 function을 수행 */
   /* setTimeout(method, delay, optional);
   (반복호출할 함수명, 반복시간(1초=1000밀리세컨드), 스크립트 언어 타입(javascript, VBScript, JScript)))*/
   setTimeout("checkApplicationInstall_callback()", 1000);
 }
 
 function checkApplicationInstall_callback() {
  
   try {
    //iframe부분에 해당하는 앱 호출하는 url 실행
    var s = document.checkframe.document.body.innerHTML;
     
   } catch (e) {
   // 어플리케이션 설치 안 되어 있으면 설치페이지로 연결
    alert("Custom_Scheme 앱이 설치 되어 있지 않습니다. 설치 페이지로 이동합니다.");
    location.href = "http://blog.naver.com/dearjune7/memo/130167378345";
   }
 }  
 
 function idCheck(){
  var id=$("#test").val();
  $.ajax({
   type:"POST"
   ,url:"two.jsp" //세션 생성페이지 (setAttribute...)
   ,data:"id="+id
   ,success:function(){
    $("#result").html("테스트 성공");
   }
  });
  return id;
 }
</script>   

<body>
<h3>Custom_Scheme App으로 입력한 데이터 전달</h3>
 
 <input type="text" id="test" />
 <input type="button" value="app으로 전송" onclick="checkApplicationInstall()"/><br/>
 
 <!-- html에서 iframe 을 이용하여 앱을 호출하는걸 아이프레임에 넣어놓고 호출시에는 브라우저가 닫히고 앱이 실행되고 아이프레임상에서 오류페이지가 뜰경우 부모 html에 스크립트로 setTimeout 몇초간 줘서 브라우저가  0.5초동안 닫히지 않을시 어플다운로드 페이지로 이동하도록 해서 처리하였습니다. -->
 
 <iframe id="checkframe" name="checkframe"  src="check.html" width="1" height="1"></iframe>
 <div id="result"></div><p>
 생성된 세션값 : <%=session.getAttribute("id") %> <!--확인용일뿐...-->
</body>

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

[two.jsp]

<%
String id = request.getParameter("id");
System.out.println("넘어온 id :"+id);

session.setAttribute("id", id);

request.getSession().getAttribute("id");
System.out.println("session id:"+id);

%>

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

 

[AndroidManifest.xml]

...

<!-- activity태그 안에 intent-filter추가 -->

<intent-filter>
                <action android:name="android.intent.action.VIEW" />
    <!-- url scheme을 사용하기 위한 준비 -->
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <!-- 자신만의 url scheme 등록 -->
                <!-- scheme은 http같은 프로토콜 부분, host는 www.daum.net 같은 경로부분 -->
                <data android:scheme="testurl" android:host="aa"/>
</intent-filter>

...

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

[csmain.xml]

<!-- 텍스트 표시 -->

    <TextView
        android:id="@+id/result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="웹에서 전송 받은 값 보여주기" />

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

[csActivity.java]

public class reActivity extends Activity {
 
 private TextView txtresult; 
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  txtresult = (TextView)findViewById(R.id.result);
  
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
     
  //AndroidManifest 읽음.
  
  getMenuInflater().inflate(R.menu.main, menu);
  Intent intent = getIntent();
  Log.d("getIntent() : "+getIntent(), "  Intent안 ");
  
  if(intent.ACTION_VIEW.equals(intent.getAction())){
   Uri uri = intent.getData(); 
   Log.d("uri : " + uri ,"  Action_view안 "); //uri : testurl://aa/?input=%E3%84....
   
   String input = uri.getQueryParameter("input");
   //input : jg
   Log.d("input : " + input , "  input안 "); //uri에서 ?input= 뒤에 받아온 값
   
   //앱에서 출력
   txtresult.setText("받은 값 : " + input);
   
  }
  return true;
 }

}


Posted by sinpk