좋은 아키텍쳐가 한 순간에 욕먹을 때, 그 것에 대해서 최선을 다한 개발자에게 빗발치는 경우가 생겼다.
그것은 바로 관리자의 잘못된 습성이 아닌가 싶다.

해당 플랫폼의 데드락 문제를 제기할 때, 비공식 채널을 통해서 너무 크게 벌리지 말라고 조용히 의사소통을 하자고  했었다. 그 이후, 크리티컬 이슈가 생겨도 조용조용히 개발조직사이에서만 공유되는 상황이었다.

결국 그 문제가 터졌다.  데드락 문제에 대해서도 다음 적용할 때 적용이 되지 못했고, 오히려 이슈가 생겼다.
챙겨야 하는 부분까지 챙기지 않고, 조용 조용히 넘어가는 그 부분이 문제의 핵심은 아니었지만, 결과적으로 보면, 그 영향이 미치지 않았나 싶다.

외국처럼 버그질라나 이슈트래커처럼 공개하는 형태로 겸손하게 가면 좋을 텐데, 쉬쉬하는 플랫폼 개발팀이라.. 개발이나 아키텍쳐보다 상대방을 배려하는 마음이 먼저야 하지 않을까?
Posted by '김용환'
,

You may  meet java errors every day if you are a java developer. Especially if a lot of or critical error logs in web application get to meet, you will be panic. So, there is need to develop error log DB and error-collectiong log module.
I will introduce my idea about developing error log DB.
According to your company policies, methods are applied for error logging system.

Architecture of error logging system consists of
1) Error DB can be stored
2) Admin web application can show errors on error db
3) Java classes and log4j configuration to transfer logs to DB.



<Error DB>
In web application, there are many properties to save such as belows.
project-name, server-name, loginid(userid), access date-time, log level, url, form, cookie, referer, execpetionmessage 

You can specify those more concisely. For example, exceptionmessage is divided to head and body according to java.lang.Exception.

I made error log db, table. Specially I made indexing in mysql. And in mysql DB, I made a batch script to rotate log db.

#!/bin/sh
TODAY=`date -d "-1 day" +%Y%m%d`
TO_DELETE_DAY=`date -d "-30 day" +%Y%m%d`
mysql  -u userid -p password mysql db-schema-name << !


# rotate log table 
alter table lgt_logdata rename logdata_${TODAY}; 


drop table if  exists logdata_${TO_DELETE_DAY};

create table logdata (
  logid int(11) NOT NULL auto_increment,
  projectname varchar(30) ,
  servername varchar(20) ,
....
  KEY lgt_logdata_ix1 (projectname,loglevel)
)



<Error-collectiong>
Error-collecting log module is implemented by log4j in simple. You can change the properites to save several log-level like error, warning. So, you can make warning log DB as well.


Let us suppose to save the errors to mysql. 
<Log4j.xml>

<appender name="ERROR-OUT" class="org.apache.log4j.jdbcplus.JDBCAppender">
<param name="Threshold" value="ERROR"/>
<param name="dbclass" value="com.mysql.jdbc.Driver"/>
<param name="url" value="jdbc:mysql://in.log.google.com"/>
<param name="username" value="error"/> 
<param name="password" value="nobodynobodywantyou"/>
<param name="sqlhandler" value="com.google.kr.MySQLHandler"/>
<param name="Buffer" value="1"/>
</appender>


<logger name="com" additivity="false">
<level value="DEBUG"/>
            <appender-ref ref="ERROR-OUT"/>
</logger>


You have to save error-loging policy in your web application.
I think every logs have to store error log DB, so, I have policy to save all tomcat logs. Because every any kinds of errors can affect the performance of web application.

I have three policies to store the DB. I think those are very important to design error DB.
1. Using Interceptor in web work or struts2, web data such as url, form have to save MDC. (MDC is api of log4j framework)

Before web application meet java exceptions, the interceptor save the web information and after invoking action it checks the result of invoking action are failed(or throw exception). If the action throws the exception, those errors will sqlhandler (ERROR-OUT)

MDC.put("projectname", projectname);
MDC.put("cookie",cookie);

2. Use Servlet in web.xml. 

You may extend and implements extends javax.servlet.http.HttpServlet class. Through the implemented class to handle error, you can store errors.

<servlet>
<servlet-name>errorHandler</servlet-name>
<servlet-class>com.google.kr.ErrorHandlerServlet</servlet-class>
</servlet>
3. Adding some fuctions to sqlhandler.
Most of error cases occur in calling action from users, but in some case internal web application invoker can make errors. For example batch or cache or scheduling based on Thread could make fault, but belows method can not include saving error logs.
And then, when you implement sqlhandler, you can add those.
You've got to adds some exceptional case on the sqlhandler.

import org.apache.log4j.jdbcplus.JDBCSqlHandler;
public class ErrorHandler implements JDBCSqlHandler {
...
}


<web applicatiion for error log>
You can show the errors stored in DB in simple.

Posted by '김용환'
,

일일빌드 시스템을 만들고 나서, 어느 정도 시간을 지내고 나서, 이 시스템의 장점이 무엇인가 생각해보았다. 200여개나 되는 프로젝트를 관리를 기준으로 생각한 것이다.

 

장점

 

1. 소스의 검증

2. 소스의 검색 용이

   공통 모듈을 쓸 때, 이게 어디서 쓰는지, 참조하기가 어렵거나 잘못된 자바 스크립트나 자바 소스를 찾아낼 수 있다는 점이 아주 훌륭하다. 소스 검색은 역시 acl!!

3. 한번에 소스 commit이 용이

  200여개나 되는 프로젝트에서 특정 패턴에 맞는 DB 설정에 대해서 수정을 하려고 할 때, 담당자들에게 일일히 연락하지 않고, 직접 수정이 가능하다.

4. 소스 복잡도 측정 가능

 

단점

1. 서버의 사용률이 좀 적다.

서버를 여기저기 함께 사용해야 하나 싶다.

 

 

사실 허드슨과 같이 좋은 툴들이 있어서 과연 일일빌드 시스템이 의미가 있겠냐마는..

사실은 내가 원하는 형태로 구현가능하고, 일일빌드 시스템의 의미에 대해서 생각해 볼 필요는 있는 것 같다.

 

 

 

Posted by '김용환'
,

Quartz의 스케쥴링은 정말 훌륭한 솔루션이다.

또한 Job 스케쥴링의 신기술 Spring batch도 잘 만들어진 솔루션들이다.

그리고, Eclipse 플러그인...

 

 

그런데, 말이지..

 

결정적인 문제가 있다. 유지보수의 입장에서 보면, 상위 버젼으로 올라가면서 DB 설정이 바뀔 때, 바톤을 이어받는 사람은 좀 당황할 수 있다.

 

또한 전버젼에는 public class였는데, 상위버젼에서는 private class로 가면..

잘 되면 좋은 케이스이긴 하나. 잘 안되면, 공수로 private class를 복사해 와서 패치를 하는 방식을 사용한다. (내가 사용한 뜻은 똑같은 패키지, 클래스를 복사해서 해당 프로젝트에 넣는 일을 뜻한다.)

 

이렇듯 Backward Compatibility (과거와의 호환)이 지원이 되지 않으면 호감이 바로 비호감으로 변한다는 사실이다.

 

개발할 때는 편하지만, 유지보수입장에서는 그다지 썩 좋은 솔루션은 아닌 것 같다.

진짜로.. JDK는 이런 부분에서 최고로 칭찬을 받아야 할 마땅한 것이 아닌가 싶다.

 

API 디자인을 할 때, 간결성. 보안성, 유저빌리티등등 보다도 중요한 게 있는데, 바로 Backward Compatibility다. 과거의 버젼에서 동작되는 서버를 바로 상위의 버젼에서 돌려도 돌아갈 수 있는 시스템은 난 간절히 원한다.

 

또한 이러한 문제들을 여전히 개발자들은 놓친다. 최근 신기술과 화려한 테크닉때문에 기본적인 상식조차 까먹는 현실이 안타깝니다.

 

중요한 포인트는...

 

상위버젼에서도 돌아갈 수 있는 솔루션이 바로 진정한 솔루션이다.. 아키텍처의 킹왕짱?!

 

 

 

 

Posted by '김용환'
,

LVS 라는 게 있는데. L4의 대체 소프트웨어라고 하면 되겠다. 다양한 알고리즘도 쓸 수 있다.

사실 ,L4대신 LVS를 쓰고 싶은데..

 

다음에서 현재 사용중이고, 돈이 안되는 것들은 이녀석으로 쓰면 돈도 아껴쓸 수 있다. 생각해보면 L4를 사용하는 것은 정치적인 이슈일지도 모르겠다.

 

LVS 설치 좋은 예)

https://www.sulinux.net/bbs/board.php?bo_table=success_2&wr_id=49&page=2

http://jikime.tistory.com/290

 

L4가 LVS보다 좋은 이유는 상용 솔루션이고, 이에 맞는 소프트웨어가 쉽게 제공되고, 로깅기능이 좋다. 한 장비에서 여러 서비스를 관리할 수 있다는 점. 반면 비싸다.

하지만, LVS는 L4보다는 로깅이 쉽지 않지만, 시스템 관리자의 입장에서 보면 귀찮은 작업이 많지만, 가격이 싸다.

 

 

회사에서 사용하는 L4 설정은 아주 간단하다.

앞단에 L4 switch를 두고 웹 서버에 대해서 L7 헬쓰 체킹을 하도록 설정하고,

NAT가 아닌 directrouting 방법을 사용하고, loop back을 L4 ip로 설정한다.

그 이유는 부하를 줄이기 위해서이다.

 ifconfig lo:0 <l4ip> up

 

 

 

특히 수세리눅스의 나진이 아빠 글은 너무 좋은 글이라서 강추한다.

출처 : https://www.sulinux.net/bbs/board.php?bo_table=success_2&wr_id=49&page=2

 

http://www.linuxvirtualserver.org/


The Linux Virtual Server is a highly scalable and highly available server built on a cluster of real servers, with the load balancer running on the Linux operating system.

March 31, 2007 nazin


1. Linux Virtual Server(LVS)?


리눅스 가상 서버란, 한대의 서버로 증가하는 인터넷 사용자를 처리하기가 힘들어 지면서 고가용성 서버를 구축하기 위해 리눅스 머신을 로드 발랜스 하도록 해주는 운영시스템이다.

만약 하나의 노드에서 처리량이 너무 많아서 서비스가 불가능할 경우 간단히 하나의 노드를 병렬 구성으로 추가 함으로써 부하분산을 하도록 하는 것을 말한다. 공개소스로서 이러한 기능을 담당하고 있는 것이다.


2. Linux Virtual Server 스케쥴링


    1)라운드-로빈(round-robin)

    라운드-로빈 방식은 로드밸런서에 들어오는 요청 패킷들을 차례대로 실제 서버에 할당하는 방식이 다. 이 방식에서 실제 서버의 현재 부하 상황 등은 고려되지 않는다. 단지 차례대로 할당할 뿐이다. 하지만, 이렇게 하더라도 로드밸런싱을 위해 이전에 사용되던 라운드-로빈 DNS 방식에 의해 서버를 할당하는 방식에 비해서는 우수한데, DNS의 경우는 한번 서버가 지정되면 해당 서버에 수많은 요청 패킷이 몰릴 수 있기 때문이다.

    2)가중 라운드-로빈(weighted round-robin)

    가중 라운드-로빈 방식은 기본적으로 라운드-로빈 방식인데, 각 서버에 서로 다른 가중치를 주어서 할당하는 방식이다. 이 방식을 사용해야 하는 경우는 실제 서버들이 CPU의 수와 성능, 메모리 용량 등 서로 다른 성능을 가지고 있어서, 각 서버를 동등하게 취급할 수 없는 경우이다.

    3)최소 연결(least connection)

    최소 연결 방식은 실제 서버들 중에서 현재 가장 적은 수의 요청을 처리하고 있는 서버를 선택하여 요청 패킷을 할당하는 방식이다. 이 방식은 실제 서버의 현재 부하 상황을 동적으로 판단하여 요청을 처리하기 때문에, 앞의 두 방식에 비해서 동적으로 우수한 부하 분산 효과를 얻을 수 있다.

    4)가중 최소 연결(weighted least connection)

    가중 최소 연결 방식은 기본적으로 최소 연결 방식인데, 가중 라운드-로빈 방식과 마찬가지로 각 서버에 서로 다른 가중치를 주어서 할당하는 방식이다.


3. 시스템 구성 및 ipvsadm 설치


1)Load Balancer Server

운영체제 : SULinux1.5

커널 : kernel-2.6.9-42.0.2.ELsmp

IP : 210.224.223.1

가상IP : 210.224.223.10

2)Real Server1(RS1)

운영체제 : Sulinux1.5

커널 : kernel-2.6.9-12.0.2.ELsmp

IP : 210.224.223.11

IP : 192.168.0.11 [NAT 설정시 부여할 사설 ip]


3)Real Server1(RS2)

운영체제 : CentOS4

커널 : kernel-2.6.9-42.0.2.ELsmp

IP : 210.224.223.12

IP : 192.168.0.12 [NAT 설정시 부여할 사설 ip]


4)Load Balancer Server ipvsadm 설치

Load Balancer Server에서 ipvsadm을 다운로드 후 설치를 한다.

커널 2.4.x 이하 버젼에서는 커널 컴파일 및 hidden 패치를 해야 했으나 커널 2.6.x에서는

Virtual Server 기능들이 기본 포함되어 있으므로 아주 간단하다.

shell>wget http://mirror.centos.org/centos/4/extras/i386/RPMS/ipvsadm-1.24-6.i386.rpm


shell>rpm -ivh ipvsadm-1.24-6.i386.rpm


shell>ipvsadm

IP Virtual Server version 1.2.0 (size=4096)

Prot LocalAddress:Port Scheduler Flags

-> RemoteAddress:Port Forward Weight ActiveConn InActConn


설치가 정상적으로 되었다면 위와같이 나타날 것이다.여기서부터 ipvsadm을 이용하여 아래 방식 으로 설정하여 테스트 해보도록 하겠다.


  • Direct Routing

  • NAT 방식

  • IP Tunnling

A.Direct Routing 방식

실제 서버와 부하분산 서버에서 가상 IP 주소를 부여하여 서로 공유한다. 부하분산 서버에도

마찬가지로 가상 IP 주소를 설정한 인터페이스가 있어야하며 이 인터페이스를 이용, 요청

패킷을 받아들이고 선택한 서버에 직접 라우팅할 수 있게 된다.

모든 실제 서버는 가상 IP주소로 설정한 non-arp alias 인터페이스가 있거나 가상 IP 주소로

향하는 패킷을 지역 소켓으로 재지향한다. 그래서 실제 서버 에서 패킷을 지역적으로 처리할

수 있는 구조를 가지게 된다.


Direct Routing 방식의 구조도는 아래와 같다.



A-1.Load Balancer Server 설정법

/etc/sysctl.confnet.ipv4.ip_forward = 0 부분을 1로 변경후

shell>sysctl -p

커널파라미터 적용


shell>ifconfig eth0:1 210.224.223.10 up

가상아이피 등록


shell>ipvsadm -A -t 210.224.223.10:80 -s rr

라운드-로빈방식으로 설정


shell>ipvsadm -a -t 210.224.223.10:80 -r 210.224.223.11:80 -g

RS1 서버로 다이렉트 라우팅 설정


shell>ipvsadm -a -t 210.224.223.10:80 -r 210.224.223.12:80 -g

RS2 서버로 다이렉트 라우팅 설정



A-2.Real Server(RS1) 설정법

/etc/sysctl.confnet.ipv4.ip_forward = 0 부분을 1로 변경하여야 하며

#for ipvs

net.ipv4.conf.lo.arp_ignore = 1

net.ipv4.conf.lo.arp_announce = 2

net.ipv4.conf.all.arp_ignore = 1

net.ipv4.conf.all.arp_announce = 2

#end of ipvs

#for ipvs ~ #end of ipvs 부분을 추가한후

shell>sysctl -p

커널파라미터 적용

shell>ifconfig lo:0 210.224.223.10 up

가상아이피 등록


A-3.Real Server(RS2) 설정법

/etc/sysctl.confnet.ipv4.ip_forward = 0 부분을 1로 변경하여야 하며

#for ipvs

net.ipv4.conf.lo.arp_ignore = 1

net.ipv4.conf.lo.arp_announce = 2

net.ipv4.conf.all.arp_ignore = 1

net.ipv4.conf.all.arp_announce = 2

#end of ipvs

#for ipvs ~ #end of ipvs 부분을 추가한후

shell>sysctl -p

커널파라미터 적용

shell>ifconfig lo:0 210.224.223.10 up

가상아이피 등록


클라이언트에서 가상아이피 210.224.223.10으로 접속하면 우리는 느끼지 못하지만

rr(라운드-로빈)방식을 이용해서 RV1,RV2 서버에 접속하게 된다.

RV1 서버에 장애가 있다면 RV2 서버로 접속하게 된다.


B.NAT 방식

NAT는 특정한 IP 주소를 한 그룹에서 다른 그룹으로 매핑하는 기능이다.

클라이언트가 가상 아이피로 접근시 사설 아이피로 구성된 부하분산 서버 RS1,RS2로 패킷이 향 하게 된다. 사설 아이피로 구성된 부하분산 서버는 패킷의 목적지와 포트 번호를 검사한다.

NAT 방식의 구조도는 아래와 같다



B-1.Balancer Server 설정법


네트웍 디바이스 eth0,eth1 정보

DEVICE=eth0

onBOOT=yes

BOOTPROTO=static

IPADDR=210.224.223.11

NETMASK=255.255.255.0

GATEWAY=210.223.223.1

DEVICE=eth1

onBOOT=yes

BOOTPROTO=static

IPADDR=192.168.0.1

NETMASK=255.255.255.0


/etc/sysctl.confnet.ipv4.ip_forward = 0 부분을 1로 변경후

shell>sysctl -p

커널파라미터 적용


shell>ifconfig eth0:1 210.224.223.10 up

가상아이피 등록


shell>ipvsadm -A -t 210.224.223.10:80 -s lc

최소연결 방식으로 설정



shell>ipvsadm -a -t 210.224.223.10:80 -r 192.168.0.11:80 -m

RS1 서버로 NAT 설정


shell>ipvsadm -a -t 210.224.223.10:80 -r 192.168.0.12:80 -m

RS2 서버로 NAT 설정


B-2.Real Server(RS1,RS2) 설정법


RS1

DEVICE=eth0

onBOOT=yes

BOOTPROTO=static

IPADDR=192.168.0.11

NETMASK=255.255.255.0

GATEWAY=192.168.0.1


RS2

DEVICE=eth0

onBOOT=yes

BOOTPROTO=static

IPADDR=192.168.0.12

NETMASK=255.255.255.0

GATEWAY=192.168.0.1


클라이언트에서 가상아이피 210.224.223.10으로 접속하면 우리는 느끼지 못하지만

최소연결 방식을 이용해서 RV1,RV2 서버 중에 접속자가 작은 서버로 된다.

RV1 서버에 장애가 있다면 RV2 서버로 접속하게 된다.

NAT 방식의 경우 패킷 Load Balancer Server를 반드시 거쳐가야 하므로 20대 이상 구성해야

할때는 문제가 발생할 수 있는 단점이 있다.

C.IP Tunneling 방식

IP 터널링 (IP encapsulation)IP 데이터그램안에 IP 데이터그램을 넣는 기술로서, 어떤 IP 소를 향하는 데이터그램을 감싸 다른 IP 주소로 재지향할 수 있다. IP encapsulation은 현재 엑 스트라넷, 모빌-IP, IP-멀티캐스트, tunnled 호스트나 네트웍 등에 일반적으로 사용되고 있다.

IP Tunneling 방식의 구조도는 아래와 같다



C-1.Balancer Server 설정법

/etc/sysctl.confnet.ipv4.ip_forward = 0 부분을 1로 변경후

shell>sysctl -p

커널파라미터 적용


shell>ifconfig eth0:1 210.224.223.10 up

가상아이피 등록


shell>ipvsadm -A -t 210.224.223.10:80 -s wlc

가중치 최소연결 방식으로 설정



shell>ipvsadm -a -t 210.224.223.10:80 -r 210.224.223.11:80 -i

RS1 서버로 Tunneling


shell>ipvsadm -a -t 210.224.223.10:80 -r 210.224.223.12:80 -i

RS2 서버로 Tunneling


C-2.Real Server(RS1,RS2) 설정법

/etc/sysctl.confnet.ipv4.ip_forward = 0 부분을 1로 변경하여야 하며

#for ipvs

net.ipv4.conf.lo.arp_ignore = 1

net.ipv4.conf.lo.arp_announce = 2

net.ipv4.conf.all.arp_ignore = 1

net.ipv4.conf.all.arp_announce = 2

#end of ipvs

#for ipvs ~ #end of ipvs 부분을 추가한후

shell>sysctl -p

커널파라미터 적용


RS1

DEVICE=tunl0

onBOOT=yes

BOOTPROTO=static

IPADDR=210.224.223.10

NETMASK=255.255.255.0


RS2

DEVICE=tunl0

onBOOT=yes

BOOTPROTO=static

IPADDR=210.224.223.10

NETMASK=255.255.255.0


또는 각 리얼서버에서


RS1

shell>ifconfig tunl0 210.224.223.10 up

가상아이피를 IPIP Tunnel에 등록한다.

RS2

shell>ifconfig tunl0 210.224.223.10 up

가상아이피를 IPIP Tunnel에 등록한다.


클라이언트에서 가상아이피 210.224.223.10으로 접속하면 우리는 느끼지 못하지만

가중치 최소연결 방식을 이용해서 RV1,RV2 서버 중에 접속자가 작은 서버로 된다.

RV1 서버에 장애가 있다면 RV2 서버로 접속하게 된다.


4. 참고 문헌 & 사이트 정보


http://www.linuxvirtualserver.org

http://linux-ha.org/

http://eelco.maljaars.net/ultramonkey-rhel4.html

 

Posted by '김용환'
,

개발을 하다 보면, 늘 이렇게 짤까 저렇게 짤까 고민을 하기도 한다.

특히 Inheritance로 개발할지 composition으로 개발할지 고민은 여전히 지금까지도 있다.

 

Spring IOC을 쓰는 사람은 자연스럽게 interface 1개, 구현체 1개 이렇게 만들어서 bo와 dao를 쓰고 있는 현실을 보게 된다. 볼 때 마다. 나는 좀 갑갑스럽기 하다.

 

interface나 abtract class는 기본적으로 상속이기 때문에

super를 수정할려면 좀 귀찮다. (managability가 많이 떨어진다.) 재 사용성을 위해서 쓴다는 장점과 함께~

보통 이 정도 수정되면, 크게 바뀌는 개념이라 할 수 있겠다.

 

반면 Composition을 쓰면, 쓰기가 참 편한데. 재사용성이 떨어진다는 점. (polymophism은 기본적으로 reusability를 위해서 만들어짐 개념이다.) 이 가장 떨떨하다.

또한 더 많은 인스턴스를 양산할 수 있는 소지가 발생한다.

 

항상 이런 고민인데. Effective java의 authour인 Joshua는 이렇게 써놨다.

 

 

Inheritance is a powerful way to achieve code reuse, but it is not always the best tool for the job. Used inappropriately, it leads to fragile software. It is safe to use inheritance within a package, where the subclass and the superclass implementation are under the control of the same programmers. It is also safe to use inheritance when extending classes specifically designed and documented for extension (Item 15). Inheriting from ordinary concrete classes across package boundaries, however, is dangerous. As a reminder, this book uses the word
“inheritance” to mean implementation inheritance (when one class extends another).

The problems discussed in this item do not apply to interface inheritance (when a class implements an interface or where one interface extends another).

 

 

패키지 내에서 상속관계, 세부적인 디자인이나 확장을 위해서 상속을 쓰는 것이 안전하다고 했다.

최대한 상속의 개념은 제한적으로 쓰는 것이 좋다는 것이 그의 주장이다.

 

아티마의 글을 볼까나?

http://www.artima.com/designtechniques/compoinhP.html

http://www.artima.com/designtechniques/interfaces.html

 

어쩌면, 정확히 이럴 때는 이렇게 쓰는 것이야 라는 고민보다는 수많은 시행착오를 통해서 겪는 것들은 정말 우리에게 도전을 주는 거 같다. 시도해보고 자신만의 노하우를 습득하고 타인의 스킬들에 대해서 인정해보면서 생각해보는 것 외에는 특별한 방법이 없긴 하다.

 

 

Posted by '김용환'
,

작년 메일을 훝어보니.. 재미난 일들이 있었던 것 같다.

 

웹 어플리케이션 서버는 quartz를 이용하여 1분 주기적으로 데이터를 캐쉬 DB에 접근해서 가져오도록 하게 되어 있다. 캐쉬 DB는 캐쉬 어플리케이션에서 미리 지정한 쿼리를 통해서 cache DB에 저장하게 된다.

문제는 웹 어플리케이션에서 정상적인 데이터를 받지 못할 때가 많다라는 것이다.

 

이러한 상황에서 어떻게 하면 풀 수 있을까 생각해 봤다.

 

1. 웹 어플리케이션의 quartz가 DB를 부담을 줘서 1분에서 5분으로 quartz를 바꾸도록.

 

2. cache DB를 증설, 스케일이 커지면 커질 수록 1번처럼 5분이라는 주기는 결국 10분으로 넘어갈 수 밖에 없다.

 

3. oscache 를 주로 사용할 수 있도록 권장 cache DB없이 웹 어플리케이션 서버에서 자체적으로 사용할 수 있도록 한다.

 

 

'디자인-아키텍쳐' 카테고리의 다른 글

LVS 설치 및 사용기  (0) 2009.03.17
Inhertiance와 composition  (0) 2009.03.16
개발 프로세스 정립  (0) 2008.06.10
일일 빌드 시스템의 장점  (0) 2008.05.03
Powerful & Simple  (0) 2008.04.25
Posted by '김용환'
,

 

alpha, beta, 리얼 반영이라는 프로세스에서 새롭게 하나의 프로세스를 만들어가고 있다.

alpha, beta, gamma(새로 지칭, 성능 테스트), 리얼 반영 프로세스이다.

 

gamma 테스트는 과연 무엇인가?? 기존의 개발자들이 성능 테스트없이 바로 리얼에 반영하고 나서, 무거워져서 서비스 장애나 지연현상을 최소한 방지하고, 바틀렉을 찾아서 안전하게 리얼에 반영하는 것이다.

 

이를 위해서 시스템 관리자는 테스트 환경을 제공하면 되고, 개발자들은 단순히 배포하고 재시작만 하면 끝.. 나머지는 QA나 인프라지원을 통해서 테스트가 가능하다.

또한 개발자들이 linux 플랫폼에서의 바틀렉을 찾을 수 있도록 툴을 제공함으로서, 본인이 개발한 바틀렉을 찾을 수 잇는 것이다.

 

다음은 담당자들을 설득하는 과정에서 나온 메일이다.

 

-       테스트 과정중의 한 과정으로 리얼 환경에서의 테스트가 필요합니다.

n  현재는 alpha(소스 HEAD) 반영/ 테스트 -> beta(RC) 반영/테스트 -> 리얼 반영 이라는 프로세스를 거치고 있습니다.

n  beta때의 소스 브랜치는 RC 이긴 하나 alpha,beta 의 경우는 한대의 물리적인 서버에 수십 개의 자바 프로세스가 실행되고 있어서 실제 어느쪽에 바틀렉이 있는지 사실은 저희가 전혀 알기가 힘든 상황입니다. 그냥 기능 테스트만 하고 있습니다.

n  beta때까지 잘 동작되어서 리얼에 반영했더니, 서비스 지연 현상 및 장애를 일으키는 경우가 있었습니다.  따라서, 리얼에 바로 반영하기 전에 정상적으로 돌아갈 수 있는지 테스트가 필요합니다.

-       부하 테스트가 아닌 간단한 기능 테스트만을 통해서 바틀렉을 찾아낼 수 있습니다.

n  프로파일링 툴을 이용하면, 리얼 데이터를 이용하여 리쿼스트를 2,3회정도 보냄으로서 어느 자바 클래스(또는 쿼리에서 늦춰지는지, 또는 아파치 문제인지, 시스템 문제인지..)에서 얼마나 지연되는지 찾아낼 수 있습니다. 이를 통해서 대해서 웹 어플리케이션의 성능 문제를 향상시킬 수 있습니다.

n   참고로 beta에서는 불가능합니다. beta서버에서는 한 대에 수십 개의 자바 데몬이 사용되기 때문에 메모리를 일부러 작게 잡아두었습니다. 그러다 보니. 테스트를 해도 메모리의 스와핑이 많이 일어나 리얼 환경에서처럼 정확한 메모리 수치값이 나오지 않아서, 리얼 반영시에 문제가 많이 발견될 수 있는 소지가 있었습니다.

n  alpha, beta서버에서는 순전히 기능만을 테스트하지만, 어느 부분에서 시간이 소요되고 있는지를 알 수가 없는 구조였습니다. 해당 툴을 이용하여 문제를 파악할 수 있습니다. (성능 테스트는 개발자들이 본인 pc상에서 다 테스트가 가능하긴 합니다만..  alpha, beta에서는 전혀 메모리 특성)

 

 

 

'디자인-아키텍쳐' 카테고리의 다른 글

Inhertiance와 composition  (0) 2009.03.16
캐쉬 서버 - 웹 어플리케이션 서버간.  (0) 2008.08.26
일일 빌드 시스템의 장점  (0) 2008.05.03
Powerful & Simple  (0) 2008.04.25
How to design a great user experience  (0) 2008.04.25
Posted by '김용환'
,

 

1.     전체 시스템을 일일 백업을 해준다.

2.     매일 수행되는 버그를 빠르게 추적하여 수정할 수 있도록 하여 버그를 최대한 줄입니다.

A.     특히 common 모듈부분을 다 같이 쓰기 때문에 큰 도움이 될 것입니다.

B.      모듈 프로그래밍을 하시는 분들은 서로 다른 모듈 때문에 컴파일 에러가 나는 부분을 빨리 알아낼 수 있습니다.

3.     여러 명이 pool형태로 개발할 상황에서, 매일 빌드를 굳이 하지 않아도 자동으로 알려줘서 개발자들에게 편의를 제공할 수 있습니다.

4.     로그 DB를 이용해서 계속 에러의 이유들을 저장함으로서, 안정성을 높일 수 있습니다.

'디자인-아키텍쳐' 카테고리의 다른 글

Inhertiance와 composition  (0) 2009.03.16
캐쉬 서버 - 웹 어플리케이션 서버간.  (0) 2008.08.26
개발 프로세스 정립  (0) 2008.06.10
Powerful & Simple  (0) 2008.04.25
How to design a great user experience  (0) 2008.04.25
Posted by '김용환'
,

가장 강력하고 손쉬운 툴을 만드는 것이야 말로 정말 소프트웨어 개발자의 마인드라고 생각한다.

전보다 더 쉬고 편하게. 그리고 기능은 강력하게..

 

하지만, 실제로는 더 복잡해지고, 기능은 많아지고, 멀 해야될지 모를 정도로 복잡성이 늘고, 결국. 그것을 버리게 되는 일이 비일비재하다라는 것...

 

플랫폼 개발자는 상아탑에 있는 교수와 같다.

플랫폼 개발자는 서비스 개발자나 서비스 기획자로부터 피드백을 받는 곳에 있다면, 훌륭해 질 수 있으나, 대부분은 골방 개발자가 되는 것인 것 같다.

 

조직의 문제일까? 아니면, 개인의 문제일까??

 

디자인의 기본 원칙은 간단하면서도 강력한 것!!

 

출처

http://msdn2.microsoft.com/en-us/library/aa511332.aspx

 

 

Powerful and Simple

Powerful:

Powerful and simple:

The ideal Windows Vista®-based application is both powerful and simple. Of course you want your application to be powerful and of course you want it to be simple, but can you achieve both? There is a natural tension between these goals, but that tension is far from irreconcilable. You can achieve both power and simplicity through carefully balanced feature selection and presentation.

Powerful

What does "power" really mean in terms of software? An application might be considered powerful if it is jam-packed full of features, having a tremendous breadth of functionality in an attempt to be all things to all users. Such a design is not likely to be successful because an untargeted feature set is unlikely to satisfy the needs of anyone. This is not the type of power that we are after.

An application is powerful when it has the right combination of these characteristics:

  • Enabling. The application satisfies the needs of its target users, enabling them to perform tasks that they couldn't otherwise do and achieve their goals effectively.
  • Efficient. The application enables users to perform tasks with a level of productivity and scale that wasn't possible before.
  • Versatile. The application enables users to perform a wide range of tasks effectively in a variety of circumstances.
  • Direct. The application feels like it is directly helping users achieve their goals, instead of getting in the way or requiring unnecessary steps. Features like shortcuts, keyboard access, and macros improve the sense of directness.
  • Flexible. The application allows users complete, fine-grained control over their work.
  • Integrated. The application is well integrated with Microsoft® Windows®, allowing it to share data with other applications.
  • Advanced. The application has extraordinary, innovative, start-of-the-art features that are not found in competing solutions.

Some of these characteristics depend upon the perception of the user and are relative to users' current capabilities. What is considered powerful may change over time, so today's advanced search feature might be commonplace tomorrow.

All these characteristics can be combined into our definition of power:

An application is powerful when it enables its target users to realize their full potential efficiently.

Thus, the ultimate measure of power is productivity, not the number of features.

Different users need help in achieving their full potential in different ways. What is enabling to some users might harm versatility, directness, and control for others. Well-designed software must balance these characteristics appropriately. For example, a desktop publishing system designed for nonprofessionals might use wizards to walk users through complex tasks. Such wizards enable the target users to perform tasks that they otherwise wouldn't be able to perform. By contrast, a desktop publishing system for professionals might focus on directness, efficiency, and complete control. For users of such an application, wizards may be limiting and frustrating.

If you do only one thing...
Understand your target users' goals and craft a feature set that enables them to achieve those goals productively.

Simple

We define simplicity as follows:

Simplicity is the reduction or elimination of an attribute of a design that target users are aware of and consider unessential.

In practice, simplicity is achieved by selecting the right feature set and presenting the features in the right way. This reduces the unessential, both real and perceived.

Simplicity is dependent upon the perception of users. Consider how the effect of an automatic transmission depends on a user's perspective:

  • For the typical driver (the target user), an automatic transmission eliminates the need for a manual gear shift and clutch, making a car much easier to drive. A manual gear shift and clutch are not essential to the task of driving, so they are removed to achieve simplicity.
  • For a professional race car driver, having direct control over the transmission is essential to being competitive. An automatic transmission negatively affects the car's performance, so it is not regarded as resulting in simplicity.
  • For a mechanic, an automatic transmission is a more complex mechanism, and therefore isn't easier to repair or maintain than a manual transmission. Unlike the mechanic, the target user is blissfully unaware of this internal complexity.

While different users regard the automatic transmission differently, it's successful because it eliminates the need for unessential knowledge, skill, and effort from its target users. For the typical driver, automatic transmission is a great feature because it just works.

Simplicity vs. ease of use

Simplicity, when correctly applied, results in ease of use. But simplicity and ease of use are not the same concepts. Ease of use is achieved when users can perform a task successfully on their own without difficulty or confusion within a suitable amount of time. There are many ways to achieve ease of use, and simplicity—the reduction of the unessential—is just one of them.

All users, no matter how sophisticated, want to get their work done with a minimum amount of unnecessary effort. All users—even advanced users—are primarily motivated to get their work done, not to learn about computers or your application.

Simplicity is the most effective way to achieve ease of use, and ease of use equals use. Complex, hard-to-use features just don't get used. By contrast, simple, elegant designs that perform their function well are a joy to use. They invoke a positive, emotional response.

For example, consider the wireless networking support in Microsoft Windows XP. Microsoft could have added a wizard to walk users through the configuration process. This approach would have resulted in ease of use but not simplicity, because an unessential feature (the wizard) would have been added. Instead, Microsoft designed wireless networking to configure itself automatically. Users ultimately don't care about the configuration details, so long as it "just works" reliably and securely. This combination of power and simplicity in wireless networking technology has led to its popularity and rapid adoption.

If you do only one thing...
Start your design process with the simplest designs that do the job well.

If you're not satisfied with your current design, start by stripping away all the unessential elements. You will find that what remains is usually quite good.

Obtaining simplicity while maintaining power

Design principles

To obtain simplicity, always design for the probable, not the possible.

The possible

Design decisions based on what's possible lead to complex user interfaces like the Registry Editor, where all actions are equally possible and as a result require equal effort. Since anything can happen, user goals aren't considered in design decisions.

The probable

Design decisions based on the probable lead to simplified, goal- and task-based solutions, where the likely scenarios receive focus and require minimal effort to perform.

The simplicity design principle

To obtain simplicity, focus on what is likely; reduce, hide, or remove what is unlikely; and eliminate what is impossible.

What users will do is far more relevant to design than what they might do.

Design techniques

To obtain simplicity while maintaining power, choose the right set of features, locate the features in the right places, and reduce the effort to use them. This section gives some common techniques to achieve these goals.

Choosing the right feature set

"Perfection is achieved, not when there is nothing more to add,
but when there is nothing left to take away." —Antoine de Saint-Exupery

The following design techniques give your users the features they need while achieving simplicity through actual reduction or removal:

  • Determine the features your users need. Understand your users' needs through goal, scenario, and task analysis. Determine a set of features that realizes these objectives.
  • Remove unnecessary elements. Remove elements that aren't likely to be used or have preferable alternatives.
  • Remove unnecessary redundancy. There might be several effective ways to perform a task. To achieve simplicity, make the hard decision and choose the best one for your target users instead of providing all of them and making the choice an option.
  • Make it "just work" automatically. The element is necessary, but any user interaction to get it to work is not because there is an acceptable default behavior or configuration. To achieve simplicity, make it work automatically and either hide it from the user completely or reduce its exposure significantly.

Streamlining the presentation

"The ability to simplify means to eliminate the unnecessary
so that the necessary may speak." —Hans Hofmann

Use the following design techniques to preserve power, while achieving simplicity through the perception of reduction or removal:

  • Combine what should be combined. Put the essential features that support a task together so that a task can be performed in one place. The task's steps should have a unified, streamlined flow. Break down complex tasks into a set of easy, clear steps, so that "one" place might consist of several UI surfaces, such as a wizard.
  • Separate what should be separated. Not everything can be presented in one place, so always have clear, well-chosen boundaries. Make features that support core scenarios central and obvious, and hide optional functionality or make it peripheral. Separate individual tasks and provide links to related tasks. For example, tasks related to manipulating photos should be clearly separated from tasks related to managing collections of photos, but they should be readily accessible from each other.
  • Eliminate what can be eliminated. Take a printout of your design and highlight the elements used to perform the most important tasks. Even highlight the individual words in the UI text that communicate useful information. Now review what isn't highlighted and consider removing it from the design. If you remove the item, would anything bad happen? If not, remove it!
    Consistency, configurability, and generalization are often desirable qualities, but they can lead to unnecessary complexity. Review your design for misguided efforts in consistency (such as having redundant text), generalization (such as having any number of time zones when two is sufficient), and configurability (such as options that users aren't likely to change), and eliminate what can be eliminated.
  • Put the elements in the right place. Within a window, an element's location should follow its utility. Essential controls, instructions, and explanations should all be in context in logical order. If more options are needed, expose them in context by clicking a chevron or similar mechanism; if more information is needed, display an infotip on mouse hover. Place less important tasks, options, and Help information outside the main flow in a separate window or page. The technique of displaying additional detail as needed is called progressive disclosure.
  • Use meaningful high-level combinations. It is often simpler and more scalable to select and manipulate groups of related elements than individual elements. Examples of high-level combinations include folders, themes, styles, and user groups. Such combinations often map to a user goal or intention that isn't apparent from the individual elements. For example, the intention behind the High Contrast Black color scheme is far more apparent than that of a black window background.
  • Select the right controls. Design elements are embodied by the controls you use to represent them, so selecting the right control is crucial to efficient presentation. For example, the font selection box used by Microsoft Word shows both a preview of the font as well as the most recently used fonts. Similarly, the way Word shows potential spelling and grammar errors in place is much simpler than the dialog box alternative, as shown in the beginning of this article.

Reducing effort

"Simple things should be simple.
Complex things should be possible."—Alan Kay

The following design techniques result in reduced effort for users:

  • Make tasks discoverable and visible. All tasks, but especially frequent tasks, should be readily discoverable within the user interface. The steps required to perform tasks should be visible and should not rely on memorization.
  • Present tasks in the user's domain. Complex software requires users to map their problems to the technology. Simple software does that mapping for them by presenting what is natural. For example, a red-eye reduction feature maps directly to the problem space and doesn't require users to think in terms of details like hues and gradients.
  • Put domain knowledge into the program. Users shouldn't be required to access external information to use your application successfully. Domain knowledge can range from complex data and algorithms to simply making it clear what type of input is valid.
  • Use text that users understand. Well-crafted text is crucial to effective communication with users. Use concepts and terms familiar to your users. Fully explain what is being asked in plain language so that users can make intelligent, informed decisions.
  • Use safe, secure, probable defaults. If a setting has a value that applies to most users in most circumstances, and that setting is both safe and secure, use it as the default value. Make users specify values only when necessary.
  • Use constraints. If there are many ways to perform a task, but only some are correct, constrain the task to those correct ways. Users should not be allowed to make readily preventable mistakes.

Simplicity does not mean simplistic

"Everything should be made as simple as possible,
but not simpler."—Albert Einstein

We believe that simplicity is crucial to an effective, desirable user experience—but it is always possible to take a good thing too far. The essence of simplicity is the reduction or elimination of the unessential. Removal of the essential just produces a poor design. If your "simplification" results in users becoming frustrated, confused, unconfident, or unable to complete tasks successfully, you have removed too much.

Simplicity does mean more effort for you

"I have only made this letter longer because I have
not the time to make it shorter."—Blaise Pascal

Obtaining simplicity while preserving power often requires significant internal complexity. It is usually easier to design software that exposes all the technology plumbing than to design one that hides it—the latter requires an excellent understanding of your target users and their goals. Removing a feature requires discipline, as does deciding against adding that cool feature that really isn't practical. Simplicity requires making hard design choices instead of making everything configurable. Complex software often results from a misconception about users: that they value unused features or overly complex features they can't understand.

Powerful and simple

Power is all about enabling your users and making them productive. Simplicity is all about removing the unessential and presenting features the right way. By understanding your target users and achieving the right balance of features and presentation, you can design Windows Vista-based applications that do both.

Guidelines feedback 

 

 

Posted by '김용환'
,