사용자 삽입 이미지

휴가 갔다오니 그새에도 책이 많이 팔렸더군요.
여러 의견들이 있지만, 겸허히 받아 들여야죠.
누구나 바라보는 View가 다르고, 완벽한 책은 없으니...

이제 날씨도 좋아졌는데, 시간적, 경제적 여유가 조금이라도 있으면,
나들이좀 갔다 오세요.
저도 바람 한번 쐬고 오니 좋더군요.


사용자 삽입 이미지

Posted by tuning-java
,

책이 나온지 거의 두달 되어가니 여러분들의 이야기들이 블로그에 올라와 있다.

좋은 리뷰도 있고, 좋지 않은 리뷰도 있네요. 모든 의견이 중요하다고 생각합니다.

단지, 이 책에서 부족하다고 생각들 하시는 튜닝의 기법이라든지, 툴에 대한 자세한 내용은 다음 책을 위해서 아껴 두었다고 너그럽게 생각해 주시면 감사하겠습니다.

이 책을 사려는 분들이나, 다양한 의견을 공유하시려는 분들은 아래의 링크를 클릭해 보시면 됩니다. ^^;

<<<<< Yes24 사이트의 주옥같은 리뷰들 보기 >>>>>

최종 update date : 2008. 05. 10.

Posted by tuning-java
,

전에 IIS 기반의 서버 로그를 분석하기 위한 Log Parser에 대해서 아주~~ 간단히 정리를 해 놓았었다.

Access log가 뭐고, 어떤 데이터가 있는지에 대해서는 제 책에 자세히 정리해 놓았으니 그 부분을 참조하시기 바랍니다.

그럼 이 Access log들을 어떻게 분석해야 할까?

보통 웬만큼 사용자가 있다는 사이트의 웹 로그는 1Gb가 넘는다. 그 1Gb가 넘는 데이터를 일일이 수작업으로 분석하기엔 너무 힘들다. (불가능하다.)

나는 필요한 데이터를 뽑아내기 위해서 로그 분석기를 직접 만들었는데, 그 분석기는 특정 데이터만 분석하기 때문에 다른 분들이 사용하기에는 적합하지 않아 여기에 올리진 않겠다. 그럼 어떤 분석 프로그램들이 있을까 ? 아래의 링크를 따라가 보면 여러 종류의 웹 로그 분석 툴의 목록을 볼 수 있을 것이다.
http://www.uu.se/Software/Analyzers/Access-analyzers.html 
직접 만드는 것 보다는 여기에 만들어 놓은 툴을 사용하는 것이 훨씬 낫다.

내가 가장 좋아하는 웹 로그 분석 툴은 다음과 같다.
awstat : http://awstats.sourceforge.net/ 
Analog : http://www.analog.cx
Webalizer : http://www.mrunix.net/webalizer

이 중 가장 최근까지 업데이트 된 툴은 awstat이다.  각 툴의 사용법은 각 사이트의 튜토리얼 문서를 참조하면 쉽게 알 수 있을 것이다.

Posted by tuning-java
,

IBM developerWorks 뉴스레터를 보다가 괜찮은 글을 하나 발견했다. 링크는 아래에...

http://www.ibm.com/developerworks/kr/library/dwclm/20080408/

내 생각도 이 글의 필자와 크게 다르지는 않다. 

예전부터 해온 생각이 "굳이 이렇게 자바를 확장할 필요가 있을까? "라는 것이다.

지금까지의 자바를 보다 안정적이고, 보다 빠르게 개선하는 것이 더 중요하다고 생각한다.

프로그래밍 언어의 버젼이 개발툴 버젼처럼 지속적으로 빠르게 올라갈 필요는 없다고 생각한다.

오히려 그 언어를 사용하는 "프레임웍"들을 보다 더 좋게 향상 시키는 것이 낫지 않을까?

Posted by tuning-java
,

이제 메인 화면에서 다른 화면으로 전환하는 Activity를 만들어보자.

(아마도 제가 쓰는 글을 계속 읽어오신 분들은 이 부분에 대해서 많이 궁금해 하셨을 것이라 생각한다. 그리고 물론 쉽지도 않다.)

다음과 같이 클래스를 하나 맹근다.

이제, 다음과 같이 소스를 작성하자.

package com.min.summary.layouts;

import android.app.Activity;
import android.os.Bundle;

import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.RelativeLayout;
public class RelativeTest extends Activity {
    RelativeLayout relativeLayout;
    LayoutParams lpFillFill=new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        relativeLayout=new RelativeLayout(this);
        relativeLayout.setLayoutParams(lpFillFill);
        setContentView(relativeLayout);
    }
}

그럼 바로 앞서 만든 MainButtonManager 클래스의 setButtons() 메소드에 다음과 같은 버튼을 만들자.

        Button relBut=new Button(parent);
        relBut.setText("Show relative layout");
        relBut.setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                Intent intent = new Intent(parent,com.min.summary.layouts.RelativeTest.class);
                parent.startActivity(intent);

            }
        });
        parentLayout.addView(relBut, lpFillWrap);

intent 객체를 만들어서 부모에서 startActivity 메소드에 intent 객체를 넘겨주면 된다.
(정확하게 이렇게 intent객체를 만드는 이유에 대해서는 좀더 공부해 봐야겠다.)


이제 한번 실행해 볼까?

새로 추가된 버튼이 추가되었다. ㅋㅋ

한번 눌러보자.

어라? 이게 뭐야?
에러가 난다. 에러를 잘 읽어보자.


AndroidManifest.xml 파일에 내가 추가한 클래스를 선언한걸 못찾겠단다.
하래면 해야지머...

AndroidManifest.xml 파일을 더블클릭하면, 안드로이드 어플리케이션 설정 화면이 나타난다.
거기서 두번째 탭에 있는 Application을 클릭하자.
하단에 있는 Appilcation Nodes 에서 "Add..." 버튼을 클릭하자.
그 다음 나타나는 팝업 화면에선 Activity를 클릭하자.

여기서 일단 돌아가게하려면 입력해야 하는건 달랑 하나~~ "Class Name*" 이라고 되어 있는 곳에서 "Browse" 버튼을 클릭한다.

마지막으로 해야하는 것은 새로 만든 .layouts.RelativeTest 를 추가하는 것 뿐이다.

결과는 다음과 같다.

까만화면이닷~~~. - -;

왜냐하면, 아무것도 RelativeLayout에 추가하지 않았기 때문이다.

그러면 다음 글에는 RelativeLayout을 사용하는 방법에 대해서 알아보자.

Posted by tuning-java
,

참고로 이 설명은 [Blog2Book 자바 성능을 결정짓는 코딩 습관과 튜닝 이야기] 책을 읽는 독자분들이 부록으로 제공되는 Jennifer를 보다 쉽게 사용할 수 있도록 작성되었으며, 설치시 임시 라이센스는 자동으로 생성되지 않고, Jennifer 사이트에서 요청하셔야 합니다. 요청 방법은 부록 CD에 정리되어 있습니다. 

제니퍼의 설치법을 알아보겠습니다. 뭐 매뉴얼 보면서 하시면 되겠지만, 보다 간단하게 설치할 수 있도록 알려 드리겠습니다. 왜냐하면, 제니퍼 설치 설명 파일을 보면 20 페이지가 넘게, 각 서버별 설정법이 나와 있습니다. 하나 하나 따라가기가 굉장히 짜증나는 작업이죠.

제니퍼의 버전이 2.5.X 에서 최근에 3.2 버전이 바뀌었습니다. 2.5.X 대의 버전과 3.X 대 버전의 가장 큰 차이점은 데이터를 DB에 넣는다는 점과 UI를 맘대로 커스터마이징 할 수 있도록 되어 있다는 것입니다. 그런데, 제 개인적으로는 2.5.X 대의 버전이 가장 안정화 되어 있다고 생각합니다.

제니퍼를 설치하려면 적어도 두대의 서버가 있어야 합니다. 제니퍼 서버(모니터링 데이터를 처리하는 서버)와 WAS 서버(모니터링되는 서버)가 필요합니다. 먼저 제니퍼 서버를 설정하는 방법을 알아보겠습니다.

-제니퍼 DB 설정

제니퍼 설치 위치의 /derby/bin/env.sh 파일을 열어 다음의 세팅을 합니다.
JAVA_HOME=/usr/jsdk142
제니퍼 설치 위치의 /derby/start.sh 파일을 수행하면, 제니퍼 DB가 수행됩니다.

 

-제니퍼 서버 설정

제니퍼 설치 위치의 /server/bin/tomcat.sh 파일을 열어 다음의 두가지 세팅을 합니다.
JAVA_HOME=/usr/jsdk142
JENNIFER_HOME=/home/Jennifer (2.5.X 대의 버전에서는 세팅할 필요 없음)

 

위의 설정을 마치셨으면, 제니퍼 설치 위치의 /server/bin/startup.sh 파일을 수행합니다.
정상적으로 설치를 완료 했을 경우 인터넷 익스플로러를 기동하여 아래의 url을 입력하면 제니퍼 서버로그인 화면이 나타납니다.

http://제니퍼서버IP:7900/

제니퍼 서버 설정이 완료되었으므로, 이제 WAS 설정을 알아보겠습니다.

 

1. WAS 서버 설정

제니퍼의 버젼이 2.X 대 거나 3.X 대 거나, WAS 서버가 어떤 것이든지 설치법은 그리 크게 차이 나지 않습니다. WAS 서버를 기동하기 위한 설정파일에 다음의 내용이 반드시 포함되도록 합니다. 반드시 이 세팅을 할 때에는 제니퍼를 사용하지 않고 서버가 기동되는 세팅을 반드시 백업해 놓으셔야 합니다.

2. jennifer.jar설정 : 어떤 jar 파일보다 앞에 jennifer.jar 파일을 클래스 패스에 지정한다.

3. Jennifer 구성파일설정 : w11.conf (구성 파일)을 자바 커맨드의 -Djennifer.config=/ 옵션을 사용하여 위치를 지정한다.

4. lwst30.jar 및 jennifersys.jar : 자바 커멘드의 -Xbootclasspath/p: 옵션을 사용하여 이 두가지 파일의 위치를 지정한다.

5. jennifer library 모듈설정 : 서버에 맞는 so파일을 libjennifer20.so로 파일명을 변경하여 서버의 수행 디렉토리로 복사한다.

 

이러한 설정이 완료되면, WAS를 restart하면 됩니다.

이러한 세팅이 완료되면, 이제 제니퍼를 사용하는 기본 환경 설정은 완료됩니다.

마지막으로 몇가지 팁을 알려드리겠습니다.

팁1)

제니퍼 서버와 WAS 서버 사이에 통신을 해야 하기 때문에, 두 서버 사이에 방화벽이 있을 경우 다음 Port를 열어야 합니다.
클라이언트 -->  제니퍼서버 : 7900(TCP) - 관리콘솔 서비스 용,  6701(TCP) - 애플릿 소켓통신용
제니퍼에이전트 --> 제니퍼서버 : 6901(UDP) - 실시간 데이터 전송, 6902(UDP) - (1초)데이터 전송, 6703(UDP) - 트랜잭션 데이터 전송
제니퍼서버 --> 제니퍼에이전트 : 머신내 유일포트 (7750 ~ ) 각 에이전트는 제니퍼서버 요청에 대한 작업을처리하기 위해 유일한 TCP포트를 바인딩 해야 합니다.

여기서 가장 밑에 있는 7750 port는 한 장비에 여러 컨테이너가 동작할 경우 w11.conf 파일과 같은 설정 파일을 여러 개 만들어 각 컨테이너당 유일한 포트를 사용하도록 수정해야 합니다.

 

팁2) w11.conf 파일 설정 - 1
agent_name : agent의 이름을 설정하며, 영어를 포함한 3단어만 사용 해야 합니다. 반드시하나의 제니퍼 서버당 유일한 값이어야 합니다.
agent_tcp_port : 각 WAS 장비당 유일한 포트 번호여야 합니다. 컨테이너가 여러 개일 경우만 변경하면 됩니다. 여러 WAS가 같은 값을 써도 상관 없습니다.
udp_server_host : 제니퍼 서버가 기동중인 IP를 명시해줍니다.

 

팁3) w11.conf 파일 설정 – 2
만약 X-internet이나 프레임웍을 쓸 경우 모든 요청이 aaa.do 나 requestName 과 같이 하나로 보이는 경우가 있습니다. 만약 요청 파라메터의 키가 cmd와 value라는 것이 있을 경우 w11.conf 파일의 다음 설정의 주석을 해제하고 설정하면 됩니다.
url_additional_request_keys=cmd,value

 

다음에는 Jennifer의 각 기능 소개를 해 드리겠습니다.

Posted by tuning-java
,

Eclipse를 사용하여 Spring MVC 을 구현하는 것에 대해서 알아보자.

일단 가장 먼저 Eclipse에서 Dynamic Web Project를 맹글자.
(이 부분은 다 알고 있으리라 생각하고 패쑤~~)

그 다음 맹글어진 프로젝트에서 WebContents 밑에 있는 web.xml을 열자.
web.xml 파일의 </web-app> 태그 위에 아래의 내용을 복사하여 붙이자.
-------------------------------------------------------------------
<servlet>
  <servlet-name>action</servlet-name>
  <servlet-class>
   org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
  <init-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>
    /WEB-INF/action-servlet001.xml
   </param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>action</servlet-name>
  <url-pattern>*.do</url-pattern>
 </servlet-mapping>
------------------------------------------------------------------------
잘 붙였으면, 간단하게 내용을 살펴보자.
DispatcherServlet은 말 그대로 Servlet 클래스이기 때문에 web.xml에 추가한 것이고,
앞으로 모든이름.do를 호출하면 이와 관련된 클래스가 호출될 것이다.
중간에 action-servlet001.xml이라는게 아직 없다.
없으니 만들자...

WEB-INF 디렉토리 하단에 action-servlet001.xml 을 다음과 같이 만들자.
------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-2.5.xsd">

 <bean id="handlerMapping"
  class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
 
 <bean name="/test.do"   class="test.TestController">
  </bean>

</beans>
-----------------------------------------------------------------------------------
내용은 모른다고 치더라도 test.TestController 라는 클래스가 필요하다고 느낄것이다.
웹에서 test.do를 수행하면 해당 컨트롤러 클래스가 호출될 것이다.

test.TestController 클래스는 다음과 같다.
----------------------------------------------------------------------------------
package test;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class TestController implements Controller {
 public ModelAndView handleRequest(HttpServletRequest request,
   HttpServletResponse response) throws Exception
{
  System.out.println("TestController ==> handleRequest");
  return new ModelAndView("redirect:/index.html");
 }
}
-------------------------------------------------------------------------
이 소스에서는 다른 일은 안하고 "TestController ==> handleRequest"를 프린트하고
index.html로 forwarding 하도록만 되어있다.
그럼 마지막으로 이클립스의 WebContents 폴더 하단에 index.html을 하나 생성하자.
html의 body에는 다음과 같이 한번 넣어볼까?
-------------------------------------------------------------------------
<body>
Thank you for follow this tutorial. hahaha.
</body>
-------------------------------------------------------------------------
그럼 이제 코딩해야 할일은 다 끝났다.

하지만 두가지 일이 남아있다.
만든 클래스가 이클립스의 build 폴더에 생성이 되어있지 않으니,
eclipse 메뉴에서 Project --> Build All을 클릭하여 클래스를 빌드해야 한다.
(뭐~ 이게 자동으로 될 수도 있다.)

또 한가지 남은 것은
WEB-INF 하단의 lib 폴더에 Spring framework과 관련된 모든 jar를 집어 넣어 줘야 한다.
(이 방법도 여러분만의 방법이 있을 테니 자세한건 패스하고...
가장 간단한 것은 익스플로러에서 모든 jar를 선택하고 eclipse에 끌어 넣어주면 된다.)

정상적으로 작업이 되었다면
tomcat을 띄워서 해당WebApp/test.do 를 실행해보자.
Tomcat의 console에
"TestController ==> handleRequest"
가 출력되고,
화면에
Thank you for follow this tutorial. hahaha.
가 나타났다면,
초 간단 Spring MVC Framework 실습이 완료된 것이다.

이제 천천히 어려운 부분을 공부해 보자.

Posted by tuning-java
,

일단 본론에 들어가기 전에 MVC에 대해서는 다 알꺼라 생각한다. 몇줄만 적어보면

MVC는 Model, View, Controller의 약자로 예전의 UI, DB처리, 비즈니스 로직을 하나의 클래스나 파일에서 처리하던 것을 분리하는 것을 말한다.

간단하게 몇줄만 적었다. ㅋㅋ
그럼 Spring MVC 프레임웍에서 어떻게 사용자 요청이 처리되는지 알아보자.

1. 사용자의 요청이 오면 DispatcherServlet이라는 것이 받는다. 얘를 앞단 중계자라는 의미로 Front Controller라고 부른다.
2. 받은 것을 뭔가 매핑이 되어 있는 곳에서 적절한걸 찾아서 다른 곳으로 전달한다. 이 것을 핸들러라고 한다.
3. 전달 받은 데이터를 기반으로 DB에서 데이터를 얻어온 다음에 ModelAndView라는 객체에 저장해서 넘긴다고 한다.
4. 그 다음 DispatcherServlet이라는 놈에서 화면에 보여줄 View 와 Model 정보를 View Resolver라는 것을 통해서 View를 결정한다.
5. 해당 View에 데이터를 넘기고, View에서는 화면을 처리한 결과를 DispatcherServlet으로 넘긴다.
6. 마지막으로 화면으로 보내준다.

이 내용을 그림으로 표현한 것이 바로 아래 링크에 있다.
http://static.springframework.org/spring/docs/2.0.x/reference/mvc.html
마우스 스크롤이 어떻게 되어 있느냐에 따라서 다르겠지만, 한 3번 정도 스크롤하면 볼 수 있다. ^^;

자세한 구현 방법은 다음 글에 올리도록 하겠다.

Posted by tuning-java
,
만약 여러분의 클립보드에 다음의 내용이 있다고 치죠. (아래의 내용을 복사하거나 Ctrl-C 를 누른 경우)
//내용 시작
package test;
public class Test {
}
//내용 끝

이클립스에서 src 를 누른 후 Ctrl-V를 눌러보자.

그럼 짜잔~~~
하고 여러분의 이클립스에 클래스가 하나 추가되면서, 그 내용이 에디터에 나타날 것입니다.


Posted by tuning-java
,
자바의 어노테이션이란 것이 JDK 5.0 부터 생겨났기 때문에,
예전부터 자바를 하신분들은 이해하기가 다소 어려울 수 있다.
그럼 어노테이션이란건 왜 만들어서 사람을 귀찮게 할까 ?
궁금하다면, 다음의 글을 읽어보자.
(참고로 한글이다....)

http://www.ibm.com/developerworks/kr/library/j-annotate1/index.html


http://www.ibm.com/developerworks/kr/library/j-annotate2.html
Posted by tuning-java
,
* Test.*(..)
[리턴타입] [패키지.클래스].[메소드명](매개변수의 타입])
여기서는 모든 리턴타입을 갖는 Test 클래스의 모든 매개변수 타입의 모든 클래스에 적용하라.

여기서 *은 all 이라는 의미가 된다. 즉 Test.* 이라는 것은 Test 클래스의 모든 메소드를 처리하라는 의미가 되고, 다음과 같이 사용할 수 있다.

void Test.hello(..)
void Test.hello*(..)
void Test.hello(int,String)

hello* 이라는 것을 보면, 모든 hello로 시작하는 메소드에 대해서 처리하라는 의미가 된다.

그리고 매개 변수의 타입에서 ..을 쓰면 모든 매개변수 타입에 대한 처리를 하게 되고, 원하는 타입을 명시할 수도 있다.
Posted by tuning-java
,
먼저 아래의 간단한 소스를 읽어 보자.

package proxytest;
public interface ITempLogic {
 public String greet();
}
----------
package proxytest;
public class TempLogicImpl implements ITempLogic {
 public String greet() {
  return "Hi";
 }
}
----------
package proxytest;
public class TempLogicProxy implements ITempLogic {
 private ITempLogic itl=null;
 public TempLogicProxy(ITempLogic l) {
  itl=l;
 }
 public String greet() {
  System.out.println("before");
  String r=itl.greet();
  System.out.println("after");
  return r;
 }
 public static void main(String args[]) {
  ITempLogic l=new TempLogicProxy(new TempLogicImpl());
  System.out.println(l.greet());
 }
}
----------
 간단하게 소스에 대해서 설명을 하자면,
 ITempLogic이라는 인터페이스를 하나 만들고,
 해당 인터페이스를 구현한 TempLogicImpl 이라는 클래스를 하나 만들었다.
 구현된 TempLogicImpl 이라는 클래스를 감싸주는 TempLogicProxy라는 클래스를 만들어 주어서 그 클래스에서 TempLogicImpl을 대행하여 수행해준다.

Posted by tuning-java
,

AOP : Aspect Oriented Programming

관점지향 프로그래밍이다. 어플리케이션을 OOP 관점으로 모듈화하여 작성해도 다른 모듈에서 발생하는 횡단 관심을 해결하기 위한 방법이다.

횡단 관심 : 로깅 보안, 트랜젝션등 부가 기능을 의미하며,
기존의 프로그램을 최대한 수정하지 않고 원하는 부가기능을 처리하고자 하는것이다.

AOP로 구현시 핵심 모듈을 건들지 않기 때문에 재사용성과 유지보수성이 쉬워진다.

여기서 AOP의 단점은 성능에 영향을 준다는 것이다.

참고로 횡단 관심을 해결하기 위한 시점은 다음과 같다.

  1. 메소드 호출 이전 시점
  2. Exception이 발생된 시점
  3. 메소드 호출 이후 시점

여기서 시점을 point cut 이라고 하고, 포인트 컷에서 해야하는 동작을 Advice라고 한다.
point cut과 advice를 모아놓은 것을 Aspect 라고 한다.

advice의 종류

  • around advice : org.aopalliance.intercept.MethodInterceptor - 메소드 수행 전후, Exception을 모두 처리할 수 있다.
  • before advice : org.springframework.aop.MethodBeforeAdvice - 메소드 수행전 작업을 처리할 수 있다.
  • after advice : org.springframework.aop.AfterReturningAdvice - 메소드 수행후 작업을 처리할 수 있다.
  • throws advice : org.springframework.aop.ThrowsAdvice - Exception 발생시 작업을 처리할 수 있다.


결론적으로 AOP를 사용하게되면,
원하는 proxy 기반의 interceptor 를 XML 기반으로 지정할 수 있게 되고,
XML에 지정된 bean을 사용하도록 소스를 변경해 주면 proxy에서 처리하는 부분을 사용할 수 있다.

참고로 Spring 에서는 이러한 Aspect를 Java로 구현하기 위해서 다음과 같은 방법을 사용한다.
방법 1 : 스키마 기반의 구현
방법 2 : Anotation을 이용한 구현

Posted by tuning-java
,