페이지

2014년 8월 27일 수요일

[tomcat]서버에서 한글 인식 못할때

와스에서 한글파일명을 인식 못하는 경우가 있다

이럴땐 서버의 캐릭터 셋과 와스의 캐릭터 셋을 맞춰 주어야 한다


1. 서버
export $LANG로 현재 캐릭터 셋을 확인한다

그리고 만약 원하는 캐릭터 셋이 아니라면 다음 파일에서 내용을 바꿔준다

vi /etc/sysconfig/i18n 

LANG="ko_KR.UTF-8"
#LANG="en_US.UTF-8"
#LANG="ko_KR.eucKR"
SUPPORTED="en_US.UTF-8:en_US:en:ko_KR.eucKR:ko_KR:ko"
SYSFONT="latarcyrheb-sun16"




2. 와스
URIEncoding="utf-8"을 Connector부분에 추가한다

vi server.xml 

 <Connector port="8090" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="82443" URIEncoding="utf-8"/>


<Connector port="8709" protocol="AJP/1.3" redirectPort="82443" URIEncoding="utf-8"/>


그런데 한글은 이제 잘 나와도 터미널에서 안나올 경우가 있다
secureCRT기준으로 Character부분을 바꾸어주고 터미널 재접하면 된다








참조 : http://jmnote.com/wiki/%EB%A6%AC%EB%88%85%EC%8A%A4_%EC%89%98_%ED%95%9C%EA%B8%80_%EA%B9%A8%EC%A7%90

2014년 8월 22일 금요일

postgresql 설치

설정 파일
/var/lib/pgsql/9.3/data


실행
service postgresql-9.3 start



1.유저 생성
su postgres
createuser -P hamadm

2.db생성
createdb -O hamadm db_ham


3.table space 생성
CREATE TABLESPACE tbs_ham
  OWNER hamadm
  LOCATION '/home/hamadm/tablespace';

다음과 같은 에러시 다음 참조
ERROR:  could not set permissions on directory "/home/hamadm/tablespace": 허가 거부

groupadd ham
chmod -R 770 hamadm/
usermod -a -G ham postgres
chown hamadm:ham hamadm
마지막으로  postgresql  재시작




만약 접속이 안된다면 iptable에서 방화벽 설정을 확인한다
/etc/sysconfig/iptables

다음과 같이 넣어준다
-A INPUT -p tcp -m state --state NEW -m tcp --dport 5432 -j ACCEPT

2014년 7월 3일 목요일

[sendmail]domain setting

도메인 설정
# ... define this only if sendmail cannot automatically determine your domain
#Dj$w.Foo.COM
Djspi.lguplus.co.kr

2014년 6월 23일 월요일

sendmail 발송 정리

메일설정 및 속도 증가

-서버쪽-

1. sendmail.mc수정 addr을 안바꿔주면 로컬에서만 메일이 나감

vi /etc/mail/sendmail.mc

define(`SMART_HOST', `localhost')dnl
DAEMON_OPTIONS(`Port=smtp,Addr=0.0.0.0, Name=MTA')dnl

m4명령으로 sendmail.cf 생성
m4 /etc/mail/sendmail.mc > /etc/sendmail.cf




2. sendmail.cf에서 수정사항
O DeliveryMode=defer    //즉시 큐에 담는다
O Timeout.queuereturn=1h    //1시간후에 해당 메일 삭제
O QueueLA=512             //현재 처리하고 있는 메일 프로세스 512되면 전송중단
O RefuseLA=512            //메일 처리 프로세스 수가 512개 이상이면 접속을 거부
O MaxDaemonChildren=64    //메일서버가 만들 수 있는 자식서버 수

DSlocalhost -> DS
O Timeout.ident=0s

# queue directory 변경
#O QueueDirectory=/var/spool/mqueue
O QueueDirectory=/var/spool/mqueue/q*
#다음 L값을 다음과 같이 수정
Msmtp,          P=[IPC], F=mDFMuX, S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, E=\r\n, L=2990,
                T=DNS/RFC822/SMTP,
                A=TCP $h
Mesmtp,         P=[IPC], F=mDFMuXa, S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, E=\r\n, L=2990,
                T=DNS/RFC822/SMTP,
                A=TCP $h
Msmtp8,         P=[IPC], F=mDFMuX8, S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, E=\r\n, L=2990,
                T=DNS/RFC822/SMTP,
                A=TCP $h
Mdsmtp,         P=[IPC], F=mDFMuXa%, S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, E=\r\n, L=2990,
                T=DNS/RFC822/SMTP,
                A=TCP $h
Mrelay,         P=[IPC], F=mDFMuXa8, S=EnvFromSMTP/HdrFromSMTP, R=MasqSMTP, E=\r\n, L=12040,
                T=DNS/RFC822/SMTP,
                A=TCP $h




3. queue directory를 병렬로 만들 것
/var/spool/mqueue > # mkdir q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 q16
sendmail.cf 파일 내에 QueueDirectory 값도 같이 변경


병렬처리의 이점은

하나의 디렉토리 안에 몇 천 ~ 몇 만개의 파일들이 존재할 경우 ext3부터는 상당부분 개선 되었지만,

ext2에서는 어마어마한 부하가 유발 하게 되는데 이를 분산시켜서 인덱싱에서 발생하는 불필요한 로드를 방지할 수 있게 된다.

메일발송 될때도 큐에 들어간 메일들이 처리 될때 병렬처리 되어 보다 빠른 처리속도를 보여준다.

갯수에 대한 제한은 확인되지 않지만, 그렇다고 무한정 늘리는 것만이 능사는 아니다.



4. 큐 발송 프로세스 생성
다음을 대략 설명해보면 -bd는 데모모드로 실행하고 -ODeliveryMode는 메일을 받자마자 큐로 넣으라는 듯이다
그리고 -q10s이런거는 10초에한번 큐를 뒤져보라는 것이다

vi demon
/usr/sbin/sendmail -bd -ODeliveryMode=defer


vi queue1
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q1 -OMaxDaemonChildren=32 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s


/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q1 -OMaxDaemonChildren=4


vi queue2
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q2 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q2 -OMaxDaemonChildren=4


vi queue3
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q3 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q3 -OMaxDaemonChildren=4


vi queue4
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q4 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q4 -OMaxDaemonChildren=4

vi queue5
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q5 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q5 -OMaxDaemonChildren=4


vi queue6
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q6 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q6 -OMaxDaemonChildren=4



vi queue7
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q7 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q7 -OMaxDaemonChildren=4




vi queue8
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q8 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q8 -OMaxDaemonChildren=4


vi queue9
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q9 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q9 -OMaxDaemonChildren=4


vi queue10
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q10 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q10 -OMaxDaemonChildren=4


vi queue11
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q11 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q11 -OMaxDaemonChildren=4



vi queue12
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q12 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q12 -OMaxDaemonChildren=4


#chmod u+x daemon queue*



5. /etc/resolv.conf에서 자체 dns사용 그렇지 않으면 smpt접속시 속도가 안나옴
이때 named가 설치 되지 않았다면 직접설치
nameserver 168.126.63.1 -> 127.0.0.1


6. 큐 삭제 데몬 생성

#vi pdel

for FILE in /var/spool/mqueue/q*/[dq]f*;
do
      echo -ne \\r"Deleting $FILE... ";
      rm $FILE -f;
      echo -n ok;
done;

echo

#chmod u+x pdel

#crontab -e

*/60 * * * * /agent/shell/pdel




-클라이언트쪽-
1. 메일 발송프로세스를 멀티 쓰레드로 할것, 보통 메일은 여러 클라이언트에서 들어오는데 여기선 한개의 서버에서만 들오기때문에 속도가 안나옴
 - 현재 쓰레드 10개로 나누어서 돌림








-참고문서 정리-

대규모 사이트가 아니라면 기본적인 설정으로 문제가 없다. 대규모 사이트에서 메일분산을 위해서는 sendmail 소스 배포본의 프로그램이 필요하므로 소스도 가져오기 바란다. 자체 네임서버도 필요하다.


-------------------------------------------
하루 1천통의 이메일
-------------------------------------------
하루에 1천통 이하의 메일을 처리하는 사이트가 있다.
이정도면 파일서버, 프린터서버, 웹서버로 같이 사용해도 된다.
자체 네임서버를 구축할 필요도 없으며 메일 큐 디렉토리의 크기에도 신경 쓸 필요가 없다. 로그파일도 크지 않을 것이다.
90퍼센트 이상의 사이트에서 이 정도의 부담으로 리눅스를 사용하고 있는데 시스템 관리자도 거의 필요 없고
서버를 구석에 놓고 그냥 쓰면 된다. 정전이 되었거나 무심코 리셋키를 눌러서 하드디스크에 문제가 생기지 않는다면 일년이상 신경쓰지 않아도 된다.


-------------------------------------------
1만통의 이메일
-------------------------------------------
가장 문제가 되는 것은 한 개의 데몬이 주고 받는 메일을 처리하기에는 힘들게 된다.
이제 데몬을 구분하도록 하자. 중계와 수신을 위해서, 그리고 큐에 쌓여 있는 메일을 처리할 두 개의 데몬으로 나눈다
daemon /usr/sbin/sendmail -bd
/usr/sbin/sendmail -q30m

수신,전송을 위한 데몬은 몇가지 제한 사항에 따라 메일을 직접 전송할 것인지 큐에 쌓아 놓고 나중에 보낼 것인지 결정한다.

해당 옵션은 /etc/sendmail.cf에 있는데 다음과 같은 것이다.
# load average at which we just queue messages
#O QueueLA=8

# load average at which we refuse connections
#O RefuseLA=12

# maximum number of children we allow at one time
#O MaxDaemonChildren=12

LA란 Load Average라는 뜻인데 오렐리의 sendmail 책에 보면 복잡한 식으로 설명되어 있지만 경험적으로는 동시에 처리하고 있는 메일 프로세스의 수와 일치하는 것으로 보인다.
QueueLA=8이란 현재 처리하고 있는 메일 프로세스의 수가 8개 이상이면 전송을 중단하고 일단 큐에 쌓은 다음에 나중에 처리하라는 뜻이다.
또한 RefuseLA=12란 메일 처리 프로세스 수가 12개 이상이면 접속을 거부하라는 의미가 된다
 마찬가지로 MaxDaemonChildren=12란 한개의 sendmail 데몬이 만들어 낼 수 있는 자식 프로세스의 수를 12개로 제한한다는 뜻이다
 이제 이 값을 바꾸어 준다. 큐에 메일을 쌓지 않고, 네임서버에 의뢰한 결과 보낼 주소가 유효한 것이고 상대편 메일서버가 전송을 허가해 준 메일이라면 즉시 전송을 시도하도록 한다. 그리고 가능한한 지연 없이 메일을 받아 들이고 원하는 모든 접속을 수용할 수 있도록, 접속 거부를 시작할 프로세스 수와 자식 프로세스의 최대값을 큰 값으로 유지한다.
 O QueueLA=128
O RefuseLA=128
O MaxDaemonChildren=64
 이제 sendmail은 동시에 128개(수신, 중계 sendmail 64, 큐처리 64)까지 뜰 수 있다. 수신메일은 최대 64개 까지 동시에 처리되며 중계나 수신은 64개 까지는 거부없이 받아 들인다
 큐에 쌓인 메일은 큐처리 전용의 메일서버가 계속해서 전송을 시도하게 되며 정말로 갈 수 없는 메일이 아니라면 몇 시간 안에 메일은 보내지게 될 것이다.


-------------------------------------------
5만통의 이메일
-------------------------------------------
5만통의 메일을 주고 받게 되면 sendmail이 아닌 다른 부분에서 문제가 발생한다.
sendmail은 메일을 수신하면 이 메일이 로칼에 있는 사용자에게 오는 메일인지 중계를 해야 하는 것인지 판단해야 한다. 중계를 해야 하는 것이라면 네임서버에게 헤더에 적힌 메일 주소값을 보내 실제 숫자 IP 주소로 바꾸어 줄 것을 요청한다.
그 동안 이 프로세스는 다른 메일은 받아들이지 않는다. 또다른 메일을 받아들이기 위해서는 자식 프로세스가 fork되어야 하고 64개의 메일 프로세스는 각각 네임서버에게 주소값을 의뢰하는 시간 지연이 있다.
네임서버가 신속히 반응하지 않으면 그 프로세스는 최대 5분까지 1개의 메일 때문에 대기해야 한다.
그 동안 계속 메일이 전송되면 네임서버의 지연으로 대기하는 프로세스는 제외한 프로세스들이 처리해야 하므로 여러개의 프로세스가 네임서버 지연으로 묶이게 되면 금방 64개의 자식 프로세스가 생성되고 그 이상 생성될 수 없으므로 나머지 전송 메일은 전송 시도조차 할수 없게 된다.
즉 1분에 70개의 메일이 전송되고 그 중에서 5개의 메일이 네임서버 지연으로 묶여 있게 될 때는 그 중에서 59개만 처리되고 대기 메일이 5개, 나머지 6개는 전송 실패를 하게 된다.
또한 중계를 요청한 메일 주소가 잘못되어 있을 경우에는 5분의 지연이 있게 된다. 그래서 평균적으로 목적지 주소가 잘못된 중계메일이 30%정도의 메일서버 수행 성능 손실을 가져올 수 있다. 서버를 빠른 하드웨어로 대체해도 이 문제는 해결되지 않는다.

정상적으로 전송될 수 있는 메일은 1M 네트웍 환경에서, 크기가 10k 이내라면 3초 안에 네임서버 조회, 상대편 서버와 접속, 사용자 인증, 메일 본문 전송의 모든 작업이 끝나게 된다. 100개의 메일을 300초 동안에 모두 전송 할 수 있음을 뜻한다. 좀 더 빠른 하드웨어와 네트웍에서 같은 메일을 2초 만에 전송할 수 있다면 200초가 걸린다. 그러나 그 중에서 1개의 메일이 잘못되었다면 이 메일이 5분(300초)간의 전송 지연을 유발하게 되고 총 걸린 시간은 600(300+300)분과 500(200+300)분의 차이가 된다. 9개의 정상 메일과 1개의 비정상 메일에 대해서 이야기 했지만 1000개의 메일에서 20개의 메일이 이상하다면 총 걸린 시간은 거의 차이가 나지 않는다(11960초와 12940초).

이 문제를 해결하고자 단순히 빠른 서버를 구입한다고 했을 때 하드웨어 업그레이드에 비해서 전송효율이 같은 비율로 올라가는 것은 아니다
serial 방식의 메일 전송의 병목은 시스템의 수행 성능이 아니라 잘못된 메일이 점유하는 프로세싱 타임에 있다.

5만통의 메일을 처리하기 위해서는 이런 serial 문제를 해결해야 한다.
수신, 중계 메일은 메일을 받아들이는 순간에는 네임서버에 유효한 주소인지 의뢰하는 등의 지연을 가져올 수 있는 모든 행위를 하지 않도록 하고 무조건 메일을 큐에 쌓도록 하는 것이다. 큐에 쌓인 메일은 큐 처리 전용의 메일서버가 병렬적으로 메일을 전송할 수 있도록 만든다.


/usr/sbin/sendmail -bd -ODeliveryMode=defer
/usr/sbin/sendmail -q1m -OMaxDaemonChildren=64

DeliveryMode는 4가지가 있다. 각각은 sendmail 책에 있으므로 관심있는 사용자는 찾아 보기 바란다. 그 중에서 defer 모드는 수신 메일을 그 즉시 직접 전송을 하지도 않을 뿐 아니라 받은 메일이 유효한 것인지 네임서버에 의뢰하는 등의 시간지연이 있을 수 있는 행위를 전혀 하지 않고 큐에 쌓기만 한다. -q1m란 큐처리 데몬은 1분 단위로 자식 프로세스를 만들고 이 프로세스가 처리할 메일이 있는지 확인하게 하는 것이다. 메일이 큐에 없을 때는 자식 프로세스가 뜬 후에 처리할 메일이 없음을 확인하고 스스로 죽게 된다. 만약 메일이 많이 수신되어 큐에 메일이 쌓이기 시작하면 1분에 한 번씩 큐 전용 메일서버가 자식 프로세스를 만들어 내고 이 들은 각자 메일 전송을 시작한다.

64개의 메일 프로세스가 뜨기까지는 64분이 걸리는데 처음 뜬 프로세스가 1분에 2개의 메일을 처리한다고 하면 평균적으로 64분 동안 64개의 프로세스가 각각 64개의 메일을 처리하는 것이다

그러나 이런 수치상의 결론이 실제와는 일치하지 않는데 그 이유는 전송될 수 없는 메일이 큐에 쌓이게 되면서 전체적인 성능을 떨어뜨리기 때문이다. 64분 동안 주소가 잘못된 1개의 메일은 각각의 프로세스가 1번씩 전송을 시도하므로 총 64번 시도된다. 전송될 수 없는 메일은 한 개의 프로세스를 5분동안 잡아 놓고 있으므로 10개의 메일이 전송될 수 없도록 하는 효과가 있고 64개의 프로세스에 대해서는 640개의 메일을 보낼 수 없도록 하는 것이다. 하루 동안 계산하면 총 15000여통의 메일을 보내지 못하게 만드는 결과를 낳는다. 한 개의 메일은 5일 동안 살아 있으므로 이런 메일이 다른 방식으로 처리되지 않는다면 메일서버는 엄청난 비효율에 시달려야 한다. 나중에는 큐에는 거의 이런 악성 메일로만 가득차 있고 정작 바로 보낼 수 있는 메일이 이들 속에 묻혀 전송이 되지 못하고 그대로 쌓이는 것을 보게 될 것이다.

그래서 잘못된 메일은 즉시 삭제하는 크론탭을 만든다
*/20 * * * * /agent/shell/pdel

vi pdel
for FILE in /var/spool/mqueue/q*/[dq]f*;
do
      echo -ne \\r"Deleting $FILE... ";
      rm $FILE -f;
      echo -n ok;
done;

echo


-------------------------------------------
10만통의 이메일
-------------------------------------------
10만통의 메일을 하루에 처리하는 서버는 거의 엔터프라이즈급이라고 볼 수 있다.

10만통의 메일을 처리하는 서버는 또다른 문제에 직면하게 된다. sendmail은 메일을 전송하면서 그 결과 메세지를 syslogd를 통해서 /var/log/maillog에 저장한다. /var/log/maillog에는 pop3를 사용하여 클라이언트가 메일을 가져가는 기록과 한 개의 메일이 전송될 때마다의 기록을 남긴다. maillog는 cron 이 작동하여 한 주마다 크기를 줄이게 되어 있다(/etc/logrotate.conf참조). 그 크기를 계산해 보자. 아래는 성공적으로 메일 중계가 이루어진 한 개의 메일에 대한 로그이다

한 개의 정상적인 메일이 전송될 때 나오는 메세지는 560여 바이트가 된다.
이 것은 정상적으로 전송된 메일의 경우에만 그렇고 여러가지 이유에 의해서 전송되지 않는 메일은 하루에 여러번 전송 시도를 하기 때문에 여기에 더해서 그 때마다 에라 메세지가 쌓인다.
그러므로 평균적으로 한 개의 메일이 1k정도의 메세지를 뿌린다고 하자. 하루에 10만개의 메일을 전송하니까 로그는 100M가 된다. 일주일 동안 로그 파일의 크기는 700M로 커진다.

문제는 여기에 있지 않다. syslogd는 한 개의 파일, maillog를 열어 놓고 계속해서 로그 메세지를 쌓게 되는데 이 때 1M이상을 넘어가면 1개의 로그 메세지를 처리하기 위해서 시스템 자원을 10 퍼센트 이상 사용하며, 10M를 넘어가면 40 퍼센트 이상, 100M 메가를 넘어가면 거의 80퍼센트 이상의 시스템 자원을 사용하게 된다. 로그 파일이 커질 수록 점점 시스템 자원이 고갈 되어서 나중에는 메일 전송 보다는 로그 쓰기 작업에 모든 프로세싱 타임을 사용해야 한다.

시스템 자원을 10퍼센트 이상 사용하고 있는 프로세스가 있다면 필시 하드 디스크를 접근하고 있는 프로그램일 것이다. 컴퓨터에서 하드 디스크를 빈번하게 사용하는 작업이 여러개 떠 있다면 성능은 급격하게 하락하게 된다. 메일서버 뿐만 아니라 웹서버와 같은 데몬들의 성능이 느려 졌다면 필시 이런 문제가 개입되어 있을 확률이 높다.

/etc/logrotate.mail

daily
size 100k
rotate 2
errors root
create

/var/log/maillog {
postrotate
/usr/bin/killall -HUP syslogd
endscript
}

/var/log/messages {
postrotate
/usr/bin/killall -HUP syslogd
endscript
}

maillog, messages 외에 /var/log에 있는 파일 중에서 시간 별로 그 크기가 1M 이상씩 증가하는 것이 있다면 여기에 첨가한다. 로그 파일은 가능한한 작게 유지하는 것이 좋다. 위에서 로그 파일의 크기가 100k 이상이 되면 무조건 작게 만들도록 설정을 했다. 로그를 줄일 때 이전 로그는 log.1이 되고 log.1은 log.2가 된다. 여기서 rotate를 2로 만들었기 때문에 log.2는 삭제되고 log.1은 log.2가 되며 log는 log.1이 되고 새 파일 log가 만들어져 syslogd가 여기에 쓰기를 한다. cron 작업은 다음과 같이 설정한다.


#crontab -e

1-59/10 * * * * /usr/sbin/logrotate /etc/logrotate.mail

10분 마다 로그를 점검하여 그 크기를 줄인다. 이렇게 10분마다 로그처리를 위해 프로세싱 타임을 소모하더라도, 로그의 크기를 줄여서 얻는 효과가 더 크기 때문에 빈번한 로그 처리 작업에 드는 프로세싱 타임을 상쇄하고 남는다. 여러분의 웹서버가 오래 켜 놓으면 시간이 지날 수록 점점 느려지는 이상한 증상은 없는가? 이런 증상 때문에 메모리를 늘이거나 대용량의 하드웨어를 구입할 계획을 세우고 있었다면 /var/log/httpd 디렉토리를 점검해 보기를 바란다. access_log가 10M 이상은 아닌가?

10만통의 메일을 처리하는 서버에는 일차큐에 시간당 5천통의 메일이 쌓인다. 이제 64개의 메일 프로세스로는 감당을 할 수 없다. 한개의 메일은 2시간 동안 큐에 대기하게 되는데 2시간 동안 1만통의 메일이 쌓이게 되므로 그 동안에 각각의 메일을 처리 할 수 있을 확률이 낮아 진다. 이렇게 64개의 큐처리 메일 서버가 동작하면서 두시간 안에 모든 메일을 한 번씩이라도 전송 시도 하기가 어려워지는 상황에서 더욱 상황을 나쁘게 만드는 것은 5퍼센트(500개)악성메일이 프로세싱 타임을 늘게 만드는 것이다. 이 문제를 해결하기 위해서 다음과 같은 방법을 사용할 수 있다. 즉 최대 자식 프로세스 숫자를 높이고 각각 다른 제한을 가진 프로세스를 띄운다.


usr/sbin/sendmail -bd -ODeliveryMode=defer

/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue \\
-OMaxDaemonChildren=96 \\
-OTimeout.initial=1m -OTimeout.connect=1m \\
-OTimeout.iconnect=1m -OTimeout.helo=1m \\
-OTimeout.mail=1m

/usr/sbin/sendmail -q1m -OQueueDirectory=/var/spool/mqueue \\
-OMaxDaemonChildren=16

/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue2 \\
-OMaxDaemonChildren=32

mqueue2에는 2시간 안에 처리되지 못한 메일이 있으므로 악성메일이라고 판단하여 프로세스 수를 늘이지 않았다. 일차큐인 mqueue에는 두개의 각기 다른 데몬이 떠 있는데 첫번째 것은 96개까지 자식 프로세스를 만들어 낼 수 있고 두 번째 것은 16개 까지 만들어 낼 수 있다. 시스템에 생길 수 있는 총 메일서버 프로세스의 갯수는 수신 중계 전용(64+1), 일차큐(96+1, 16+1), 이차큐(32+1)로 212개이다. 이 때 쯤이면 각 경우에 맞추어 /etc/sendmail.cf의 변수를 조절해야 한다는 것은 스스로 알게 될 것이다. 지금은 아래와 같이 하면 된다.


O QueueLA=256
O RefuseLA=256
O MaxDaemonChildren=64

mqueue에 실행되는 두 개의 각기 다른 큐전용 메일 프로세스의 차이는 무엇일까? 우선 한 개는 네임서버 그리고 상대편 메일서버와 교신하는 시간제한을 모두 1분으로 정하고 실행하도록 했다. RFC1123에 의하면 각각의 시간제한은 5분으로 설정하도록 되어 있지만 정상적인 메일은 거의 1분이 되기 전에 상대편과 교신하고 메일 본문 전송에 들어가게 되므로 초기 교신 과정에서 1분 이상의 시간 지연이 있으면 느린 네트웍에 있는 메일서버라고 판단하거나 상대편이 전송 불능 상태라고 간주하여 메일 전송을 중단하고 신속히 다음 메일을 처리하도록 한다.

이 프로세스는 10초 마다 한 개씩 자식을 만들게 되므로 메일이 쏟아져 들어오기 시작한 지 960초(16분)이 지나면 96개의 자식 프로세스가 전송이 되든 안되든 1분 안에 1개의 메일을 처리할 수 있으므로 한 시간에 들어오는 5000개의 메일과 거의 비슷한 양의 메일을 처리 할 수 있게 된다. 즉 각각의 메일을 큐에 쌓은 후에 반드시 한 번 이상의 전송 시도를 할 수 있다는 것이다. 악성 메일이 아니지만 상대편 메일서버의 속도가 느려서 1분 이상의 지연 후에 메일이 갈 수 있음에도 전송을 중단당한 메일이 쌓일 수 있는 문제가 있다. 이런 부적절한 처리를 해결하기 위해서 정상 대기 시간을 가진 16개의 메일 프로세스가 1분 대기 프로세스가 남겨둔 메일을 다시 전송 시도 하도록 하면 된다. 그 때문에 한 개의 큐 디렉토리를 대상으로 하는 두 개의 데몬을 띄운 것이다.



-------------------------------------------
20만통의 메일
-------------------------------------------
20만통의 메일을 한 개의 큐 디렉토리에 받게 되었을 때 시간당 약 1만통의 메일이 쌓인다
한 개의 메일은 dfxxxxxx라는 메일 본문과 qfxxxxxx라는 헤더 부분이 각각의 파일로 존재하므로 12000개의 파일이 한 개의 디렉토리에 생성되고 전송 중임을 나타내는 xfxxxxxx라는 파일이 최대 112개가 생긴다. 한 디렉토리에 12112개의 파일이 있다면 그 중에서 한 개의 파일을 열기 위해서는 허용하기 힘든 시간을 소모해야 한다. 지금 한 디렉토리에 10000개의 파일을 만들고 ls 라고 실행해 보기 바란다. 아마 10초 이상의 시간을 기다려야 겨우 그 결과를 볼 수 있을 것이다.

이제 큐에 쌓인 메일 파일의 갯수가 병목이 된다. 한 시간에 1만통의 메일이 쌓인다면 10분에 평균 1700개의 메일 즉 3400개의 실제 파일을 한 디렉토리에 생성하는 것이다. 물론 생성되는 순간에 즉시 전송 되는 경우가 많겠지만 여전히 프로세싱 타임은 한계를 넘어 가게 된다.

이를 위해서는 6개의 큐디렉토리를 새로 만들고 매 10분 마다 각각의 디렉토리에 파일을 옮겨서 전송을 시도하는 것이 좋다. 다음과 같이 할 수 있을 것이다.
/usr/sbin/sendmail -bd -ODeliveryMode=defer

# 일차큐
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue \\
-OMaxDaemonChildren=32 \\
-OTimeout.initial=1m -OTimeout.connect=1m \\
-OTimeout.iconnect=1m -OTimeout.helo=1m \\
-OTimeout.mail=1m

/usr/sbin/sendmail -q1m -OQueueDirectory=/var/spool/mqueue \\
-OMaxDaemonChildren=4

# 이차 큐 1번
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue_1 \\
-OMaxDaemonChildren=16 \\
-OTimeout.initial=1m -OTimeout.connect=1m \\
-OTimeout.iconnect=1m -OTimeout.helo=1m \\
-OTimeout.mail=1m

/usr/sbin/sendmail -q1m -OQueueDirectory=/var/spool/mqueue_1 \\
-OMaxDaemonChildren=4

# 이차 큐 2,3,4,5번
....

# 이차 큐 6번
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue_6 \\
-OMaxDaemonChildren=16 \\
-OTimeout.initial=1m -OTimeout.connect=1m \\
-OTimeout.iconnect=1m -OTimeout.helo=1m \\
-OTimeout.mail=1m

/usr/sbin/sendmail -q1m -OQueueDirectory=/var/spool/mqueue_6 \\
-OMaxDaemonChildren=4


# 3차 큐 : 2시간 지난 메일 처리
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue2 \\
-OMaxDaemonChildren=32
cron은 다음과 같이 구성할 수 있다.


# crontab -e

0 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue /var/spool/mqueue_1 600
10 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue /var/spool/mqueue_2 600
20 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue /var/spool/mqueue_3 600
30 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue /var/spool/mqueue_4 600
40 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue /var/spool/mqueue_5 600
50 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue /var/spool/mqueue_6 600

1-50/10 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue_1 /var/spool/mqueue2 7200
1-50/10 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue_2 /var/spool/mqueue2 7200
1-50/10 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue_3 /var/spool/mqueue2 7200
1-50/10 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue_4 /var/spool/mqueue2 7200
1-50/10 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue_5 /var/spool/mqueue2 7200
1-50/10 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue_6 /var/spool/mqueue2 7200


큐에 쌓인 메일을 처리하는 sendmail 프로세스는 메일을 보내기 위해서 네임서버와 교신해야 한다. 메일 서버가 서브네트웍 바깥에 있다면 한 개의 메일을 보내기 위해서 외부까지 교신을 해야 하기 때문에 시간이 많이 걸린다. 한 시간에 1만번의 조회를 시도하면 아마 외부 메일서버도 견디지 못하고 다운될 확률이 있다. 또한 네트웍 자원은 네임서버와의 교신에 모두 소모되고 다른 사람들이 외부로 나가거나 들어오는 것초차 힘들게 된다. 네임서버가 로컬 네트웍의 다른 서버에 있어도 마찬가지이다. 내부 네트웍은 거의 네임서버 접속에 이용되므로 회사 전산망이 마비되고 네임서비스를 하는 서버가 다운된다
그러므로 가능하면 메일서버 자체에 메일 전송을 위한 네임서버를 띄우는 것이 좋다. 이 때의 네임서버는 단순한 캐싱만을 하는 네임서버만으로 족하다. 처음에는 네임서버 자체가 외부로 조회를 해야 하기 때문에 시간이 걸리겠지만 계속 사용한다면 중복되는 IP는 같은 메모리 안에서 처리가 가능하기 때문에 외부에 영향을 주지 않으며, 로컬 네트웍의 tcp/ip 자원도 소모시키지 않고 신속한 조회가 이루어 질 수 있다. 캐싱만 하는 네임서버는 간단히 다음과 같이 만들 수 있다


-------------------------------------------
100만통의 이메일 처리를 위하여
-------------------------------------------
100만통의 메일을 하루에 처리할 수 있는 초대규모 메일서버는 한 개의 서버로는 한계가 있다.
각각 20만통의 메일을 처리하는 5대의 메일서버가 필요하게 될 것이다.
문제는 이들을 묶어서 단일한 서버로 보이게 하는 방법이 필요하게 된다. 수백대의 서버를 묶어 놓고 IP 라운드로빈 방법을 사용할 수 있다.
IP 라운드 로빈은 1.2.3.4,1.2.3.5가 같은 a.b.c.d 도메인명을 가지도록 하고 네임서버 조회 때마다 한 번씩 다른 숫자 IP를 넘겨 주는 방법을 사용한다

2014년 6월 20일 금요일

[linux]change user home directory

usermod -d /data/newUser userName

그리고 원래 userhome에서 .bashrc같은 환경설정 복사
cp 원래 유저 홈 /data/newUser

[altibase] lock 잡고 있는 세션 강제 종료

Lock 잡고 있는 세션을 강제로 종료하는 방법입니다. 

sys 계정으로 접속하셔서 수행하셔야 합니다. 

1. v$lock 에서 table 이름과 transaction ID, lock 종류를 확인한다.
Select a.table_name, b.trans_id, b.lock_desc
From system_.sys_tables_ a, v$lock b
Where a.table_oid = b.table_oid;

2. 위에서 얻은 trans_id 를 이용하여 session 을 찾는다.
Select session_id, execute_flag, total_time, execute_time, rpad(query,400) 
From v$statement
Where tx_id = 위에서 얻은 trans_id;

3. session_id 를 이용하여 session 정보를 확인한다.
Select comm_name, client_app_info
From v$session
Where id = 위에서 얻은 session_id;

4. session 을 끊는다.
Alter database mydb session close session_id;
mydb 는 database name 으로 $ALTIBASE_HOME/conf/altibase.properties 파일을 열어보면
DB_NAME 항목설정으로 확인하시면 됩니다.
Session_id 는 물론 위에서 획득한 session_id 를 주시면 되구요.

위의 v$ 뷰라든가 system_ meta table 의 컬럼에 대한 정보는 저희 A5 admin 매뉴얼을 보시면 잘 나와있습니다.

감사합니다.

2014년 6월 18일 수요일

[java]printStackTrace를 로그에 넣기


StringWriter errors = new StringWriter();
ie.printStackTrace(new PrintWriter(errors));
LLog.err.println(errors.toString());

jsp에 반영할땐 맨위 위에 다음을 넣어준다
<%@ page import="java.io.*" %>

2014년 6월 15일 일요일

[sendmail]host map: lookup (gmail.com): deferred) 나올때 해결법

다음으로 sendmail처리과정 살펴본다
sendmail -v -d8.32 -qI<qid>

보통 네임서버 문제 이기때문에
/etc/resolv.conf에서 네임서버 설정


sendmail 재시작

shell 재시작(queue발송 데몬 별도로 뛰었을시)

2014년 5월 28일 수요일

[linux] 5분단위 파일만들기

#d=date +'%Y%m%d%H%M'
#insDate=`date --date='' '+%Y%m%d%H%M'`
insDate=`date '+%Y%m%d%H%M'`
insDateForDir=`date '+%Y%m%d'`

#echo ${insDate:10:3} 
strForMinute=${insDate:11:1}
echo "분단위 마지막 한 자리=> "  ${strForMinute}

lastDate=${insDate:0:11}
echo "11번째자리가지 자른 날자=>" ${lastDate}

fileNameForLstMinute=0


case "${strForMinute}" in
0)
        fileNameForLstMinute=0
        ;;
1)
        fileNameForLstMinute=0
        ;;
2)
        fileNameForLstMinute=0
        ;;
3)
        fileNameForLstMinute=0
        ;;
4)
        fileNameForLstMinute=0
        ;;
5)
        fileNameForLstMinute=5
        ;;
6)
        fileNameForLstMinute=5
        ;;
7)
        fileNameForLstMinute=5
        ;;
8)
        fileNameForLstMinute=5
        ;;
9)
        fileNameForLstMinute=5
        ;;
*)      echo "there is no value"
        ;;
esac

echo "가공된 분자리 =>" ${fileNameForLstMinute} 

lastDate=${lastDate}${fileNameForLstMinute}

echo "최종날자=>" ${lastDate}

serverNum="001"
serviceGubn="service"

#ohp
logDir="/logs/test/"${serviceGubn}"/"${insDateForDir}"/"                                                       
logFile="OHP."${serverNum}"."${lastDate}".log"                                                                    
logOhp=${logDir}${logFile}                                                                                        
mkdir -p -- "${logDir%/*}" && touch  ${logOhp}                                                                    
                                                                                                                  
echo ${logOhp} 

[postgresql] execute function in shell using crontab

1. register the account information

vi ~/.pgpass
localhost:portnumber:db_name:username:password

2. create shell script

vi shell.sh

#!/bin/sh

dbname="dbname"
username="username"

/opt/postgres/9.3/bin/psql $dbname $username<<EOF
select function_name();
EOF


3. register into the crontab

*/1 * * * * /home/shell/shell.sh > /log/errlog.log 2>&1

[altibase]execute altibase procedure every 1 minute using crontab

export ALTIBASE_HOME='/altibase/altibase_home'
export PATH=./:$PATH
ISQL="/altibase/altibase_home/bin/isql -s localhost -u user-p pass-port 20300"

${ISQL} << EOF
        exec PROC_NAME;
        quit
EOF

[linux] here-document at line 10 delimited by end-of-file (wanted `EOF')

remove any character before and after "EOF"

meaning remove all tabs, whitespaces, special characters etc. before and after the EOF,

[linux] when crontab does not working


  1. use absolute path
  2. check error message using following script
    1. */1 * * * * /test/test.sh > /tmp/test.log 2>&1
  3. set environmet variable in the script file





2014년 5월 26일 월요일

[altibase]using bind variable


[altibase]create partition table


  • CREATE TABLE

CREATE TABLE TESTADM.TB_TEST_PART
(
    SEQ NUMBER(13) NOT NULL,
    NAME VARCHAR(20),
    AGE VARCHAR(20),
    --PARTITION_ID SMALLINT DEFAULT MOD(DATEDIFF(TO_DATE('20140501','YYYYMMDD'),SYSDATE,'MONTH'),60) NOT NULL
    PARTITION_ID SMALLINT DEFAULT MOD(DATEDIFF(TO_DATE('20140525','YYYYMMDD'),SYSDATE,'DAY'),14)  NOT NULL
)
PARTITION BY RANGE (PARTITION_ID)
(
    PARTITION P_00 VALUES LESS THAN  ( 1 ),
    PARTITION P_01 VALUES LESS THAN  ( 2 ),
    PARTITION P_02 VALUES LESS THAN  ( 3 ),
    PARTITION P_03 VALUES LESS THAN  ( 4 ),
    PARTITION P_04 VALUES LESS THAN  ( 5 ),
    PARTITION P_05 VALUES LESS THAN  ( 6 ),
    PARTITION P_06 VALUES LESS THAN  ( 7 ),
    PARTITION P_07 VALUES LESS THAN  ( 8 ),
    PARTITION P_08 VALUES LESS THAN  ( 9 ),
    PARTITION P_09 VALUES LESS THAN  ( 10 ),
    PARTITION P_10 VALUES LESS THAN  ( 11 ),
    PARTITION P_11 VALUES LESS THAN  ( 12 ),
    PARTITION P_12 VALUES LESS THAN  ( 13 ),
    PARTITION P_13 VALUES LESS THAN  ( 14 ),
    PARTITION P_DEF VALUES DEFAULT
)
TABLESPACE TS_TEST_DISK_DAT
;



  • CREATE PK

ALTER TABLE TESTADM.TB_TEST_PART add constraint PK_TB_TEST_PART primary key(PARTITION_ID, SEQ) using index local
(
partition PK_TB_TEST_PART_P_00 on P_00 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_01 on P_01 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_02 on P_02 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_03 on P_03 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_04 on P_04 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_05 on P_05 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_06 on P_06 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_07 on P_07 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_08 on P_08 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_09 on P_09 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_10 on P_10 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_11 on P_11 tablespace TS_TEST_DISK_IDX,
partition PK_TB_TEST_PART_P_12 on P_DEF tablespace TS_TEST_DISK_IDX
);



  • CREATE SEQUENCE

CREATE SEQUENCE SEQ_TEST
START WITH 1
MINVALUE 1
MAXVALUE 9223372036854775806;



  • INSERT TEST DATA

insert into TB_TEST_PART (seq, name, age)
select seq_test.nextval, 'aa', '33' from dual
CONNECT BY LEVEL <= 100
;


  • RETRIEVE DATE USING SPEC. PARTITION TABLE

SELECT * FROM TB_TEST_PART PARTITION (P_01); -->



  • RETRIEVE DATE USING SPEC PARTITION TABLE WITH WHERE CLAUSE

SELECT * FROM TB_TEST_PART
WHERE PARTITION_ID IN ('1','2')




[linux]how to view the hardware info


  • product info
    • dmidecode  | more



  • count of physical CPU
    • # grep 'physical id' /proc/cpuinfo | sort | uniq | wc -l
  •  count of logica CPU 
    • # grep ^processor /proc/cpuinfo | wc -l


  • count of core
    • # grep 'cpu cores' /proc/cpuinfo



  • meminfo
    • cat /proc/meminfo


  • disk 정보
    • fdisk -l | grep Disk


2014년 5월 21일 수요일

[altibase]table space add


1. add datafile

ALTER TABLESPACE TS_SPI_DISK_IDX
ADD DATAFILE 
'/disk0/disk_idx/Test_dist_idx_04.dbf'
SIZE 4096M
AUTOEXTEND OFF; 



2014년 5월 19일 월요일

[sendmail]메일 발송시 속도 높이기


sendmail에서 폼메일을 통해서 다량의 소식지 등을 발송하는 경우 시간이 굉장히 오래걸리는 모습을 보여준다.
처리속도가 느리니 오래 걸리는 수밖에..



그래서 Mail의 queue의 병렬처리를 이용해 발송속도를 높혀보자.

mqueue 폴더에 자신이 원하는 만큼의 큐 폴더를 생성한다. (아래 내용은 5개까지만 만들었다)

[rubi] / > # cd /var/spool/mqueue/
[rubi] /var/spool/mqueue > # mkdir q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12



sendmail.cf 파일 내에 QueueDirectory 값을 아래와 같이 수정 해준다.

[rubi] /var/spool/mqueue > # vi /etc/mail/sendmail.cf

# queue directory

#O QueueDirectory=/var/spool/mqueue

O QueueDirectory=/var/spool/mqueue/q*



설정적용 (재시작)

[rubi] /var/spool/mqueue > # /etc/init.d/sendmail restart





병렬처리의 이점은

하나의 디렉토리 안에 몇 천 ~ 몇 만개의 파일들이 존재할 경우 ext3부터는 상당부분 개선 되었지만,

ext2에서는 어마어마한 부하가 유발 하게 되는데 이를 분산시켜서 인덱싱에서 발생하는 불필요한 로드를 방지할 수 있게 된다.

메일발송 될때도 큐에 들어간 메일들이 처리 될때 병렬처리 되어 보다 빠른 처리속도를 보여준다.

갯수에 대한 제한은 확인되지 않지만, 그렇다고 무한정 늘리는 것만이 능사는 아니다.



출처 - http://blog.rubi.kr/sendmail-%EC%A0%84%EC%86%A1%EC%86%8D%EB%8F%84%EB%A5%BC-%EB%86%92%EC%97%AC%EB%B3%B4%EC%9E%90-multi-queue/







추가사항

smtp 붙을때는 localhost로 붙는다 <- 속도차이 엄청 남
->telnet localhost 25

그러나 다음과 같이 수정하면 원격도 빠르다

vi /etc/resolv.conf에서 네임서버 없애기



sendmail.cf에서 수정사항

다음과 같이 수정
O DeliveryMode=defer
O Timeout.queuereturn=1h
O QueueLA=256
O RefuseLA=256
O MaxDaemonChildren=64

DSlocalhost -> DS
O Timeout.ident=0s

다음과 같은 데몬 생성
vi demon
/usr/sbin/sendmail -bd -ODeliveryMode=defer






vi queue1
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q1 -OMaxDaemonChildren=32 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s


/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q1 -OMaxDaemonChildren=4


vi queue2
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q2 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q2 -OMaxDaemonChildren=4

~

vi queue3
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q3 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q3 -OMaxDaemonChildren=4


vi queue4
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q4 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q4 -OMaxDaemonChildren=4

vi queue5
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q5 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q5 -OMaxDaemonChildren=4


vi queue6
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q6 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q6 -OMaxDaemonChildren=4



vi queue7
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q7 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q7 -OMaxDaemonChildren=4




vi queue8
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q8 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q8 -OMaxDaemonChildren=4


vi queue9
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q9 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q9 -OMaxDaemonChildren=4


vi queue10
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q10 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q10 -OMaxDaemonChildren=4


vi queue11
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q11 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q11 -OMaxDaemonChildren=4


~


vi queue12
/usr/sbin/sendmail -q10s -OQueueDirectory=/var/spool/mqueue/q12 -OMaxDaemonChildren=16 \
-OTimeout.initial=30s -OTimeout.connect=30s -OTimeout.iconnect=30s -OTimeout.helo=30s \
-OTimeout.mail=30s

/usr/sbin/sendmail -q30s -OQueueDirectory=/var/spool/mqueue/q12 -OMaxDaemonChildren=4





삭제 데몬
*/20 * * * * /agent/shell/pdel

vi pdel
for FILE in /var/spool/mqueue/q*/[dq]f*;
do
      echo -ne \\r"Deleting $FILE... ";
      rm $FILE -f;
      echo -n ok;
done;

echo


다음은 sendmail.mc

define(`SMART_HOST', `localhost')dnl
DAEMON_OPTIONS(`Port=smtp,Addr=0.0.0.0, Name=MTA')dnl

m4 /etc/mail/sendmail.mc > /etc/sendmail.cf

2014년 5월 16일 금요일

[linux]logrotate

/tomcat/logs/catalina.out {
 copytruncate
 daily
 rotate 30
 compress
 missingok
 notifempty
 dateext
 create 0664 spiwas spiwas
}



//설정경로
/etc/logrotate.d
vi tomcat

//강제로 실행
# logrotate -f /etc/logrotate.d/tomcat # 로그파일 순환 테스트

//디버깅
logrotate -d /etc/logrotate.d/tomcat

//보낸 내역
/var/lib/logrotate.status

//설정
/etc/logrotate.conf

2014년 5월 14일 수요일

[altibase]character set

--캐릭터 셋 확인
select * from v$nls_parameters

환경 변수
 - ALTIBASE_NLS_USE : 데이터 검색 시, 사용자에게 보여주는 문자 셋


v$nls_parameters
    iSQL> select * from v$nls_parameters;
    SESSION_ID                : 122      
    NLS_USE                   : US7ASCII                 -- 접속 client  캐릭터 셋
    NLS_CHARACTERSET          : MS949       -- DB 캐릭터 셋                                  
    NLS_NCHAR_CHARACTERSET    : UTF8 --DB national 캐릭터셋                                  
    NLS_COMP                  : BINARY
    NLS_NCHAR_CONV_EXCP       : FALSE  
    NLS_NCHAR_LITERAL_REPLACE : FALSE  

2014년 5월 13일 화요일

[linux]kill or logout a user

skill -KILL -u user

or

find the pid using ps -ef grep 'name'  command
and kill all process retlated with user account

2014년 4월 28일 월요일

create log periodically using crontab and shell script

when I need to create log file periodically, i can use this script

in this script, every 5 minute, a new file is created



vi createLogPeriodically.sh

#d=date +'%Y%m%d%H%M'
#insDate=`date --date='' '+%Y%m%d%H%M'`
insDate=`date '+%Y%m%d%H%M'`
insDateForDir=`date '+%Y%m%d'`

echo "날짜=>" $insDate
#echo ${insDate:10:3} 
strForMinute=${insDate:11:1}
echo "분단위 마지막 한자리=> "  ${strForMinute}

lastDate=${insDate:0:11}
echo "11번째자리가지 자른 날자=>" ${lastDate}

fileNameForLstMinute=0

case "${strForMinute}" in
0)
        fileNameForLstMinute=0
        ;;
1)
        fileNameForLstMinute=0
        ;;
2)
        fileNameForLstMinute=0
        ;;
3)
        fileNameForLstMinute=0
        ;;
4)
        fileNameForLstMinute=0
        ;;
5)
        fileNameForLstMinute=5
        ;;
6)
        fileNameForLstMinute=5
        ;;
7)
        fileNameForLstMinute=5
        ;;
8)
        fileNameForLstMinute=5
        ;;
9)
        fileNameForLstMinute=5
        ;;
*)      echo "there is no value"
        ;;
esac

echo "가공된 분자리 =>" ${fileNameForLstMinute} 

lastDate=${lastDate}${fileNameForLstMinute}

echo "최종 날자=>" ${lastDate}

serverNum="001" //직접 수정
serviceGubn="service"   //직접 수정

#LOG1
logDir="/logs/"${serviceGubn}"/"${insDateForDir}"/"
logFile="LOG."${serverNum}"."${lastDate}".log"
log1=${logDir}${logFile}
mkdir -p -- "${logDir%/*}" && touch  ${log1}

#LOG2
logDir="/logs/"${serviceGubn}"/"${insDateForDir}"/"
logFile="LOG."${serverNum}"."${lastDate}".log"
log2=${logDir}${logFile}
mkdir -p -- "${logDir%/*}" && touch  ${log2}


echo ${logOms}
echo ${logCom}



register this file on crontab
#crontab -e

*/1 * * * * /home/account/createLogPeriodically.sh

2014년 4월 23일 수요일

[altibase]modify colmnun

UPDATE TEST_TABLE SET COL3=''

ALTER TABLE TEST_TABLE
        MODIFY (COL3 VARCHAR(20) DEFAULT 'TEST');

2014년 4월 18일 금요일

[linux]how to install and config haproxy(load balance)


  • get the haproxy rpm
    • haproxy-1.4.22-3.el6.x86_64.rpm
  • set the configure file
# vi /etc/haproxy/haproxy.cfg 



#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------

frontend  nameOfPort1*:18001
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js

    use_backend static          if url_static
    default_backend            nameOfPort1

frontend  nameOfPort1*:18002
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js

    use_backend static          if url_static
    default_backend            nameOfPort2
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend nameOfPort1
    balance     roundrobin
    server  app1 123.456.789.123:25500 check
    server  app2 123.456.789.124:25500 check
    server  app3 123.456.789.125:25500 check

backend nameOfPort2
    balance     roundrobin
    server  app1 123.456.789.123:25501 check
    server  app2 123.456.789.123:25501 check
    server  app3 123.456.789.123:25501 check



  • if you want to see log file, set the rsyslog
# vi /etc/rsyslog.conf


# Provides UDP syslog reception
$ModLoad imudp
$UDPServerAddress 127.0.0.1
$UDPServerRun 514
SYSLOGD_OPTIONS="-m 0 -r"

local2.*                                                /var/log/haproxy.log


  • restart rsyslog and haproxy

# service rsyslog restart
# service haproxy restart

2014년 4월 15일 화요일

[java]split the string with key value

split the string with key value

   public void appendData() {
        String str= "key1=value1;key2=value2;key3=value3";
//      String[] kvPairs = str.split("\\|"); 
        String[] kvPairs = str.split(";"); 
        
        for (String kvPair : kvPairs) {
            String[] kv = kvPair.split("=",-1);
            String key = kv[0];
            String value = kv[1];
            
            System.out.println(key + " -> " + value);
        }
    }

2014년 4월 14일 월요일

if you have timeout in sendmail read that

The standard mail troubleshooting steps apply here... From the log, we see that you're able to resolve the MX/DNS records for the gmail.com destination you're sending to. So this isn't a DNS or routing issue.
Since this is a basic SMTP delivery, try using telnet to port 25 to make sure you're able to connect to the destination host...
I'd follow this sequence:
dig mx gmail.com
# Look for the mail destination IP in the output - "209.85.225.27" in this case

telnet 209.85.225.27 25
# This is an attempt to telnet to port 25 (smtp) on the recipient's server...
You should see something similar to:
Trying 209.85.225.27...
Connected to iy-in-f27.1e100.net (209.85.225.27).
Escape character is '^]'.
220 ***************************************
If you do not see the above, your outbound port 25 smtp traffic is being blocked either at the machine level (check iptables, etc.) or at the network level (check network firewall or ISP policies).
If you do see a similar message, then you're able to pass mail and shouldn't be receiving timeout errors



source : http://serverfault.com/questions/386432/sendmail-connection-timeout

2014년 4월 10일 목요일

[linux]tar

*tar.gz
tar는 압축을 하는 툴이 아니다 단지 여러개의 파일을 하나의 파일로 모아주기만 한다.
만약에 압축을 하고 싶으면 옵션에 z를 넣고 파일 이름에 확장자를 tar.gz로 한다. (그냥 tar로 해도 상관은 없다..)
-z옵션은 GNU tar에서만 제공하는 기능이다. (리눅스는 GNU tar를 사용한다)

 - 압축하기
    tar zcvf test.tar.gz test

 - 압축풀기
    tar zxvf test.tar.gz

search and replace in < vi >


Vi: Search and Replace

Change to normal mode with <ESC>.


  • Search (Wrapped around at end of file):
    •  Search STRING forward :   / STRING.
    •  Search STRING backward:   ? STRING.
      •  Repeat search:   n
      •  Repeat search in opposite direction:  N  (SHIFT-n)





  • Replace: Same as with sed, Replace OLD with NEW:
    • First occurrence on current line:      :s/OLD/NEW
    • Globally (all) on current line:        :s/OLD/NEW/g
    • Between two lines #,#:                 :#,#s/OLD/NEW/g
    • Every occurrence in file:              :%s/OLD/NEW/g








[altibase]create user

  • create user
CREATE USER TMPADM IDENTIFIED BY TMPADM
DEFAULT TABLESPACE TS_TMP_DISK_DAT 
ACCESS TS_TMP_DISK_DAT ON
ACCESS TS_TMP_DISK_IDX ON 
ACCESS TS_TMP_MEM_DAT ON;


  • grant access to tablespace
alter user TMPADM access TS_TMP_DISK_DAT on;
alter user TMPADM access TS_TMP_DISK_IDX on;
alter user TMPADM access TS_TMP_MEM_DAT on;


  • change user password

ALTER USER TMPADM IDENTIFIED BY 1234;

2014년 4월 9일 수요일

[altibase]db backup using aexport

백업전에 다음을 먼저 수행하여 ./명령어 없이 쉘들이 수행되도록 한다
export PATH=./:$PATH

// 데이터베이스 구조 추출

1. 스크립트 생성
# aexport -s 127.0.0.1 -u iscp -p iscp1 -NLS_USE KO16KSC5601
(환경설정에서 ALTIBASE_NLS_USE을 해주면 뒤에 -NLS_USE옵션은 필요없음)

2.  데이터 추출
# sh run_il_out.sh

======================================================

3. 대상 데이터베이스에 데이터베이스 구조 생성
# sh run_is.sh

4. 대상 데이터베이스에 데이터 로딩
# sh run_il_in.sh

5. 대상 데이터베이스에 인덱스 및 외래키 생성
# sh run_is_index.sh
# sh run_is_fk.sh

가장 중요한 것 - 다음을 하지 않으면 한글땜에 개고생함
export ALTIBASE_HOME='/altibase/altibase_home'
export PATH=./:$PATH
export ALTIBASE_NLS_USE='KO16KSC5601'

- 케릭터셋 조회법
select * from v$nls_parameters

- NLS_USE 데이터베이스 저장 또는 검색시 사용되는 클라이언트 캐릭터 셋이다
  (US7ASCII,KO16KSC5601, MS949, BIG5, GB231280,UTF8, SHIFT-JIS, EUC-JP)
  생략 시 환경변수 ALTIBASE_NLS_USE, altibase.properties를 차례로 참조하며, 설정되지 않았을 경우에는 기본 캐릭터 셋(US7ASCII)을 사용한다.

  즉 다음과 같다
a. NLS_USE 옵션을사용하지않는경우US7ASCII사용한다.
b. UTF8쓰는 경우 NLS_USE 옵션을지정해야한다.
우선순위
방법
1
-NLS_USE 옵션
2
환경변수등록
3
altibase.properties 파일수정



다음은 데이터 백업시 쉘 스크립트에 대한 설명이다

스크립트
용도
사용구분
run_il_out.sh
데이터다운로드스크립트
백업
run_il_in.sh
데이터업로드스크립트
업로드
run_is.sh
스키마생성스크립트
업로드
run_is_fk.sh
외래키생성스크립트
업로드
run_is_index.sh
인덱스생성스크립트
업로드
run_is_repl.sh
이중화생성스크립트
업로드
run_il_out.sh 스크립트만백업절차에서사용하고나머지는업로드절차에서사용된다.

장의내용은ALTIBASE_버전간_마이그레이션_가이드의내용을정리한것으로보다자세한내용은마이그레이션가이드를참고한다.

1.    data migration 전체 절차

data migration대략적인절차는다음과같다.

1.1.    백업 절차

a. 체크포인트수행
b. 데이터건수확인
c. DB 객체다운로드
d. data 다운로드
e. data 확인
f. altibase_home 백업

1.2.    업로드 절차

a. altibase 설치
b. DB 객체확인
c. DB 객체생성
d. 데이터생성


2.    백업

2.1.    백업디렉터리생성

altibase 데이터를백업해디렉터리를생성한다. /user1/altibase하위디렉터리는가급적피한다. root 밑에만들어사용할것을권장한다.
# mkdir alti_backup

2.2.    altibase 중지

a) altibasestop/start 한다.

# server stop
# server start


2.3.    체크포인트수행

다음명령으로아직플러쉬되지않은페이지들을디스크에반영한다.
isql> alter system checkpoint;


2.4.    데이터건수확인

a. 다음쿼리를통해전체table 목록을확인한다.
isql> select * from tab;

b. table 목록을이용하여다음과같은스크립트를만든다
# vi count_source_tb.sql

select count(*) from TABLE_NAME; 
select count(*) from table1;
select count(*) from table2;
select count(*) from table3;
…..(중략)
select count(*) from tablen;


c. 다음명령을통해table데이터count파일에기록한다.
# is -f count_ source_tb.sql -o count_ source_tb.log


2.5.    데이터베이스객체다운로드

a. sys 계정으로aexport수행한다.
b. sys 계정이아닌사용자 계정으로aexport수행할경우 사용자 계정으로생성한테이블스키마데이터만백업된다.
c. sys 계정으로aexport수행하면 사용자계정에대한passwordaexport 수행도중따로물어본다그때입력한다.

2.6.    데이터다운로드

a. aexport수행하면6가지스크립트파일이생성된다.
b. run_il_out.sh 스크립트를수행하여생성된모든데이터를다운로드받는다.
# sh run_il_out.sh


2.7.    백업데이터확인

a. 백업받은디렉터리에생성된테이블명.log” 파일과count_source_tb.log 파일을비교하여전체데이터가백업되었는지확인한다.

2.8.    altibase_home 백업

a. server stop 명령으로구동중인altibasestop 한다.
b. /user1/aitlbase/ 밑의altibase_home 디렉토리의이름을변경하여백업해둔다.
#:/user1/altibase ] mv altibase_home altibase_home_ver4




3.    업로드

3.1.    생성할데이터베이스객체확인

a. altibase일반적으로/user1/altibase/altibase_home설치한다만약다른경로에설치를했다면  ALL_CRT_TBS.sql 스크립트를수정하여경로를변경한다.
# vi  ALL_CRT_TBS.sql
..(전략)
DATAFILE '/user1/altibase/altibase_home/dbs/test.dbf'
..(후략)


3.2.    데이터베이스객체생성

a. aexport 스크립트에의해생성된run_is.sh 스크립트를이용하여데이터베이스객체를생성한다.

3.3.    데이터생성

a. aexport 스크립트에의해생성된run_il_in.sh 스크립트를이용하여데이터를생성한다.
b. 백업절차확인해두었던전체데이터건수와run_il_in.sh 스크립트로생성된데이터건수가일치하는지확인한다.

3.4.    기타작업

a. aexport 스크립트에의해생성된다음스크립트를이용하여필요한작업을한다.
run_is_fk.sh
외래키생성스크립트
run_is_index.sh
인덱스생성스크립트
run_is_repl.sh
이중화생성스크립트



4.    주의사항

4.1.    암호화테이블사용불가

a. 데이터를암호화해서넣은경우마이그레이션이불가능하다.
b. 암호화데이터가있을경우복호화하고백업/업로드를수행한다시암호화를수행해야한다.

4.2.    NLS_USE 지정

a. NLS_USE 옵션을사용하지않는경우US7ASCII사용한다.
b. UTF8쓰는 경우 NLS_USE 옵션을지정해야한다.
우선순위
방법
1
-NLS_USE 옵션
2
환경변수등록
3
altibase.properties 파일수정


4.3.    기타

a. 기타다른주의사항은altibase에서제공하는마이그레이션가이드를참고한다.

image

image