상황 : Spring기반으로 짜여진 서버에서 한 클래스의 데이터를 모니터링 페이지에 띄우고자 합니다.


출력해야하는 클래스는 들고 있는 데이터의 가지수만 최소 5-7개에서 내부필드는 20-30개까지


하나하나 정성스레 포멧팅 해주면 되지만. 귀차니즘이 앞서서 어찌하면 이쁘게 String으로 뽑아낼수 있을까 하여


방법을 찾아보았습니다.








Q : 특정 클래스 A를 Json Format을 가지는 String Type로 출력하고자 합니다.


A.

- 구글에서 제공 하고 있는 GSON Library의 Pretty Format 메소드를 활용하여 출력.


GOOGLE GSON : http://code.google.com/p/google-gson/



#. Test Case

ObjClass.java

 import java.util.ArrayList;

public class ObjClass {
    String name;
    int age;
    String address;
    
    ArrayList<String> newArr;
    
}


Main.java 

 import java.util.ArrayList;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Main {
    public static void main(String[] args){
        ObjClass oc = new ObjClass();
        oc.address = "123";
        oc.age = 56;
        oc.name ="myname";
        oc.newArr = new ArrayList<String>();
        
        
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        String jsonOutput = gson.toJson(oc);

        System.out.println(jsonOutput);
    }
}


#.Output 

{
  "name": "myname",
  "age": 56,
  "address": "123",
  "newArr": []
}
 




필드의 값이 Null 일 경우에는 아에 출력에서 제외됩니다.





이어서 -


View 딴에 데이터를 전달해서 출력할 계획이기에


Javascript를 이용해서 Json Format에 Hightlight 해주는걸 찾아봐야겠습니다...



이 글을 Effective Java를 읽고 적는 글임을 미리 밝힌다. ( 서적에 정확하게 기록되어있다. )

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

아래의 간단한 코드를 보자.

String strInputValue = "I Love You";

System.out.println("["+strInputValue+"]");

if(strInputValue.equals("TRUE"))

{

System.out.println("True");

}


흔하디 흔한 String 변수선언 이후 변수를 출력하고  문자열과 비교 후 일치할 시에 True 라는 문구를 출력하는 코드이다..

너무 쉽다? 그렇다. 너무 쉬운 코드라면 코드다.. 

위 코드에서 strInputValue 의 값을 null 로 변환하면 어떤 일이 벌어질까?





String strInputValue = null;

System.out.println("["+strInputValue+"]");

if(strInputValue.equals("TRUE"))

{

    System.out.println("True");

}





결과

[null]

Exception in thread "main" java.lang.NullPointerException

at com.ncf.test.java.TestClass.main(TestClass.java:13)




읭?

출력에서 null은 잘 찍어놓고..

비교 구문에서 오류를?

 
대학 시절에는. 아래와 같은 구문으로 null 값에 대한 처리를 수행했었다.


if(strValue != null && strValue.equals("test"))
{
System.out.println("Success");
}


대충 위와 같은 코드다... 물론 이도 동작은 한다.

좀 더 깔끔한 코드를 원하는것 뿐이다.


String strInputValue = null;

System.out.println("["+strInputValue+"]");

if("TRUE".equals(strInputValue))

{

System.out.println("Pass");

}




그렇다면 이 코드는 어떤가?

에? 위하고 비교했을때 .. 비교값의 위치가 반대인 것이잖아?

그렇다면 결과는 어떨까?



글을 쓰고 있는 이유와 같이. Null pointer Exception 은 발생하지 않는다.

왜일까?

좌변의 값 떄문이다.

자바에서 비교는 일단 좌측의 값을 기반으로 비교를 행하는데.

상단의 코드의 경우 좌측의 값이 null 이다... 고로 비교 자체를 할수가 없다.


아래의 경우는 좌측의 값이 문자열 TRUE다.. 우측의 값이 null 이므로 다른값으로 간주하게 되는것이다.


간단한 트릭? 이지만, SI를 뛰고 있는 개발자 입장에서 유익하게 사용중이니

가벼운 마음으로 익혀두면 두고두고 나쁠일은 없지 않을까?






 

Java에서 오늘 날짜 출력하기..

TimeStampMillis 를 사용해도 되지만..


바로바로 뽑아서써야할 필요가 있을때에

이만한 메소드가 따로 없다;;



public String getDateTime()
    {
     Calendar oCalendar = Calendar.getInstance( );  

        return "" + oCalendar.get(Calendar.YEAR) + "."
        + (oCalendar.get(Calendar.MONTH) + 1) + "."
        + oCalendar.get(Calendar.DAY_OF_MONTH) + " "
        + oCalendar.get(Calendar.HOUR_OF_DAY) + ":"
        + oCalendar.get(Calendar.MINUTE) + ":"
        + oCalendar.get(Calendar.SECOND);
    }



이상 끝...


Finding Optimal Apache Conf.

아파치 튜닝 정리 

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

아파치 튜닝 정리

1. 웹 페이지 로딩시간 확인
#time -pa lynx -source http://www.gwise.com > /dev/null
real 0.74
user 0.16
sys 0.09
-------------
실제 접속시간 : 0.74-(0.16+0.09)=0.49초


2. 아파치 벤치 마킹 
#man ab 사용법 보기
-n requests 요청을 수행할 개수
-c concurrency 요청을 만들 개수로 동시 사용자 개념으로 이해하면 되겠다.
-v verbosity 얼마나 자세한 정보를 화면에 출력해 줄 것인지 결정
-w HTML 문서형식으로 테이블로 만들어 결과를 화면에 출력
-k HTTP 프로토콜의 지속연결 (KeepAlive) 기능을 사용

#./ab -n 100 -c 10 http://www.gwise.com:80/ 
10 명의 유저가 동시에 http://www.gwise.com/index.html 을 요청하는 것을 모의 실험.
각각의 시뮬레이트 유저는 요청을 10 번씩 하게 됩니다

# ab -n 1500 -c 50 http://www.apache.kr.net:80/
요청을 30 x 50 (50 명의 사용자가, 각각 30 번의 요청)

Requests per second: 80.48
초당 80.48개를 요청 했음.

'MaxRequestsPerChild’ 는 메모리 누수현상(?) 등이 발생하지 않는다면 가능한 이 값을 높게 설정하시고요(파라미터의 값을 0 으로 설정해 무한대로 하실수도 있습니다) StartServers’ 는 프로세스가 active 되어 있는 경우가 적을 경우 값을 낮게 설정하시고, 접속량이 아주 많을 경우는 MaxClients 에 가깝게 조절하시기 바라며, MaxSpareServers 를 MaxClients 와 같게 설정합니다. MaxClients 는 너무 낮게 설정하지 않도록 주의하시기 바라며, 그렇다고 또 너무 크게 잡으셔도 안됩니다


3. 웹 서버 삽질 막기
BrowserMatch "WebZip" go_out
BrowserMatch "Teleport" go_out
BrowserMatch "GetRight" go_out



....
Deny from env=go_out


4. 아파치 튜닝
일반 서버에서는 다른것은 그냥 Default 값으로 둔다.
(대형 서버의 경우 말고는 특히 쓸 일어 없을 것이다.)

증가 시킬 경우 배수로 한다. 꼭 이렇게 해야 한다가 아니라
이렇게 하면 좋다.

Timeout 300
클라이언트의 요청에 의해서 Server와 연결 되었을때
클라이언트와 서버간의 아무런 메시지가 발생하지 않았을때
오류로 처리하는 시간
네트워크 속도가 나쁠수록 수치값을 높게 한다.

KeepAlive on
지속적인 접속, 즉 서버 연결에 대하여 한번 이상의 요청을 허용 여부.

MaxKeepAliveRequests 100
클라이언트가 접속된 시간동안 아파치 서버에 요청할 수 있는 처리 process 개수

StartServers 5 X ? =20 -> 초반에 뜰 process 그 이상 그이하의 의미도 없다.
MinSpareServers 5 X ? =20 -> Spare 프로세스가 이것 이하 일때 끌어 올려 준다.
MaxSpareServers 10 X ? =40 -> Spare 프로세스가 이것 이상 일때 진정(?)시켜 준다.
말 그대로 Spare.... 언제 있을지 모를 요청에 대해서 컴퓨터 스스로가 
조절해 준다.

MaxClients 150
클라이언트들이 동시에 최대로 접속했을때 가능한 최대 서버이 수를 지정.
Ulimit -a ~~~ max process...이 수치 이상 증가 못함.
httpd.h
HARD_SERVER_LIMIT=250 조정해서 다시 컴파일 가능

MaxClient 150 -> 동시에 떠 있을수 있는 최대 process
더 많은 수를 원할시 httpd.h 소스 파일의 
HARD_SERVER_LIMIT 값을 수정 한 다음 다시 컴파일 해야 한다.

#ulimit -a
core file size (blocks) 0
data seg size (kbytes) unlimited
file size (blocks) unlimited
max memory size (kbytes) unlimited
stack size (kbytes) 8192
cpu time (seconds) unlimited
max user processes 2048
pipe size (512 bytes) 8
open files 1024
virtual memory (kbytes) 2105343
-----------------------
위의 max user processes 의 수를 초과 할 수 없다.

MaxRequestPerChild 100
한 프로세스가 몇 번의 서비스를 하고 소멸될 것인지 정한다.
M$계열에서는 별 의미가 없으므로 0을 한다.
하지만 Unix 계열은 0을 사용하지 않는 것이 좋다.

가장 중요한 것은Timeout 설정입니다. 위에서 keep-alive 를 설정해 놓은 
경우, 하나의 connection에서 계속해서 다음 request를 처리할 수 있기 때문에 효율적
이라고 하지만, 실제로는 그렇지 않습니다. keep-alive 를 허용하고 그 timeout을 
5초로만 설정해도, 하나의 request를 처리한 후 적어도 5초동안은 그 httpd가 다른 
작업을 하지 못하고 다음 request를 기다리게 됩니다.

보통 웹브라우저들은 서버로 동시에 4개의 connection을 만들게 됩니다. 한 페이지를 
보는데 이미지 등등 해서 보통 4개의 connection을 만드는 것은 기본이죠. 이렇게 되면 
httpd가 100개 떠 있다고 해도, 실제로는 동시에 25명의 방문자밖에 처리하지 못합니다.

그리고 keep-alive timeout이 5초인 경우, 한 명의 방문자를 처리한 후 적어도 5초동안은 
계속해서 기다리면서 httpd가 놀게 됩니다.(그렇다고 해서 httpd의 수를 늘여주면 앞의 
문제 때문에 load가 몰릴 때 순간적으로 부하가 지나치게 많이 걸리게 됩니다. 어떤 
request는 수초가 지난 후 답을 받는 등 quality of service가 많이 떨어지죠.)

결국 한 명의 방문자를 처리하는데 4개의 httpd가 5초동안 작업한다는 뜻이고, 100개의 
httpd를 띄워봐야 1초에 5명의 방문자밖에 처리하지 못하는 셈입니다. ( 1 명 / 5 sec / 
4 httpd = 5 / 1 sec / 100 httpd )

그래서 검색엔진 서비스 등 traffic이 많은 사이트에서는 keep-alive 옵션을 반드시 꺼 
놓게 됩니다. 그리고 connection timeout도 상당히 짧게 설정해 놓죠. 4~5초 이내로 말입니다


5. 아피치 튜닝-2(로그기록 로테이트로)
/home/apache/conf/httpd.conf
CustomLog /home/apache/logs/access_log common
TransferLog "|/home/apache/bin/rotatelogs /home/apache/logs/access_log 86400"
TransferLog "|/home/apache/bin/rotatelogs /home/apache/logs/error_log 86400"
--------------
24시간 마다 로그 화일을 갱신해 준다.
24X60X60=86400초


6. 아파치 에러 메시지 바꾸기
httpd.conf
Customizable error response (Apache style)
2) local redirects
ErrorDocument 404 /cgi-bin/missing404.pl

missing404.pl
---------------
#!/usr/bin/perl
print<<"(END_HTML)";
Content-type: text/htmlnn

요청하신 http://www.gwise.com$ENV{'REQUEST_URI'} 이 존재 하지 않습니다.
서버관리자 에게 문의 바랍니다.

(END_HTML)
exit;
---------------


7. 아파치 에러 코드 
HTTP 1.1 status codes [TOP] 
100 : Continue 
101 : Switching protocols 
200 : OK, 에러없이 전송 성공 
201 : Created, POST 명령 실행 및 성공 
202 : Accepted, 서버가 클라이언트 명령을 받음 
203 : Non-authoritative information, 서버가 클라이언트 요구 중 일부만 전송 
204 : No content, 클라언트 요구을 처리했으나 전송할 데이터가 없음 
205 : Reset content 
206 : Partial content 
300 : Multiple choices, 최근에 옮겨진 데이터를 요청 
301 : Moved permanently, 요구한 데이터를 변경된 임시 URL에서 찾았음 
302 : Moved temporarily, 요구한 데이터가 변경된 URL에 있음을 명시 
303 : See other, 요구한 데이터를 변경하지 않았기 때문에 문제가 있음 
304 : Not modified 
305 : Use proxy 
400 : Bad request, 클라이언트의 잘못된 요청으로 처리할 수 없음 
401 : Unauthorized, 클라이언트의 인증 실패 
402 : Payment required, 예약됨 
403 : Forbidden, 접근이 거부된 문서를 요청함 
404 : Not found, 문서를 찾을 수 없음 
405 : Method not allowed, 리소스를 허용안함 
406 : Not acceptable, 허용할 수 없음 
407 : Proxy authentication required, 프록시 인증 필요 
408 : Request timeout, 요청시간이 지남 
409 : Conflict 
410 : Gone, 영구적으로 사용할 수 없음 
411 : Length required 
412 : Precondition failed, 전체조건 실패 
413 : Request entity too large, 
414 : Request-URI too long, URL이 너무 김 
415 : Unsupported media type 
500 : Internal server error, 내부서버 오류(잘못된 스크립트 실행시) 
501 : Not implemented, 클라이언트에서 서버가 수행할 수 없는 행동을 요구함 
502 : Bad gateway, 서버의 과부하 상태 
503 : Service unavailable, 외부 서비스가 죽었거나 현재 멈춤 상태 
504 : Gateway timeout 
505 : HTTP version not supported

////////////////////////////////////////////////////////////////////
이부분은 트래픽 양이 큰 곳에서 사용하시면 좋습니다.
설정파일에서 참고할 부분들을 적은 것이니, 꼭 이렇게 바꾸실 필요는 없습니다.

MaxKeepAliveRequests 100 -> 10000 
웹서버 프로세스가 지속적으로 접속을 유지하면서 처리할 수 있는 요청 개수입니다.
KeepAliveTimeout 15 -> 30
서버에 접속시에 웹페이지 객체들의 전송시 새로운 프로세스를 생성하지 않고 지속적으로 접속을 유지하고 담당하며, 
이 클라이언트의 요청에 대한 타임아웃에 대한 값입니다.
StartServers 5 -> 20
MinSpareServers 5 -> 20 
MaxSpareServers 10 -> 40
폭주하는 서버일 경우 SpareServer가 많으면 빨리 대처할 수 있습니다.
스탠드얼론 방식일 경우 새로운 접속 요청을 받으면 기존의 Spare Child Process를 포크해 새로운 자식 프로세스를
만들어 내므로 적당히 있어주면 좋습니다.
MaxRequestsPerChild 0 -> 1000
웹서버 프로세스가 일정 횟수의 클라이언트 요청을 처리하고 종료되는 수치입니다.
※ MaxClients 256 -> 1024
동시에 실행될 수 있는 최대 프로세스 수를 제한 하는 것입니다.
하지만 옵션을 1024로 확장하려면 소스레벨에서 
아파치 설치전에 apache/src/include/httpd.h 파일에서
HARD_SERVER_LIMIT 256 으로 된것을 1280 으로 변경한후 컴파일 하여야 사용 가능하다.




Tomcat에서 세션 타임아웃 설정은 적용 우선순위 순서로 다음 세 곳에서 가능합니다. 

(1) 프로그램안의 session.setMaxInactiveInterval() 

(2) 웹어플리케이션의 WEB-INF/web.xml 

(3) Tomcat의 conf/web.xml



 "세션에 접근한 시간을 기준으로" 란 말은 session.setAttribute() 또는 session.getAttribute() 를 했을때 인가요?? 
--> 제가 오해하기 좋게 적었네요.  
Tomcat은 session cookie를 가진 request가 전달되면 해당 session 사용여부와는 관계없이 해당 세션의 last access time을 갱신합니다.
 즉 마지막 http 요청을 받은 시간이 기준이 됩니다.



J2 SE 1.4 이후론 Default Package에 대한 접근이 불가.
(여러 글에서 스펙에 나와있다 하였으나 정확하게 파악하지는 못한상태.)

다음과 같은 방법으로 가능은 함.;


 Class fooClass = Class.forName("FooBar");
 Method fooMethod = fooClass.getMethod("fooMethod", new Class[] { String.class });

String fooReturned =
      fooMethod.invoke(fooClass.newInstance(), new String[] { "I did it"}).toString();

출처.



뭐 여튼 한가지 배웠으니 :)


# 추가.

Sun 홈페이지에서 다음과 같은 문서 발견.



160 페이지에 보면

 It is a compile time error to import a type from the unnamed package



라는 문구..


unnamed package = default package 



찾았다.. 하악하악;

+ Recent posts