달력

22025  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

[js] 풀스크린

DHTML 2004. 8. 9. 12:35
<Script>
 function fullScreen(){
  window.open('./full_1_main.html','','fullscreen=yes');
  //self.opener = self;
  //self.close();
 }
</script>
Posted by tornado
|


 

ㅋ 귀염~~

'이것저것 > 낙서장' 카테고리의 다른 글

[펌] 므흣  (0) 2004.08.13
[펌] Evergreen - 카펜터스  (0) 2004.08.12
[펌] Il est trop tard - Georges Moustaki  (0) 2004.08.04
[펌] 내 MSN 그룹들...  (0) 2004.08.04
[책] 대망..... 강추강추  (0) 2004.08.04
Posted by tornado
|

http://otn.oracle.co.kr/products/jdev/htdocs/jdevcategory.jsp

 

Oracle9i JDeveloper 기술 정보

제품 개요
Oracle9i JDeveloper Reviewer's Guide (ZIP)
이 문서는 Oracle9i JDeveloper의 실습을 통해 평가하는 문서입니다. 여기에는 Oracle9i JDeveloper의 개요 및 특징,Oracle9i JDeveloper를 이용하여 J2EE 애플리케이션과 웹 서비스를 개발하는 방법에 대해 자세히 설명되어 있습니다.
9.0.29.0.3.x
Oracle9i JDeveloper 신기능9.0.29.0.3.x
Oracle9i JDeveloper 백서 (PDF) 9.0.2 
Oracle9i JDeveloper 9.0.3.x 신기능 (Broadband Demos)
New features in the IDE
Support for EJBs and BC4J
Modeling, Web services & SCM
Database Integration
View Technologies, ANT and JUnit
  
Oracle9i JDeveloper FAQ (Java 유저 그룹에서 나온 질문과 답변)   

기술
IDE
Oracle9i JDeveloper - Hands on Labs
이 문서는 Oracle9i JDeveloper 9.0.3을 바탕으로 구성되었으며 일부 실습에 필요한 추가 요구 사항은 실습 자체 안에 설명되어 있습니다. 요구 사항과 설명은 반드시 읽어 보시기 바랍니다.
Developing Custom JSP Tag Libraries in Oracle9i JDeveloper
이 문서는 Oracle9i JDeveloper를 이용하여 사용자 JSP 태그 라이브러리를 생산적으로 구축하는 방법에 대해 설명합니다.
편리해진 Oracle9i JDeveloper로의 마이그레이션
이 문서는 기존 소스를 Oracle9i JDeveloper로 마이그레이션하는 방법에 대한 가이드라인을 제공합니다. 또한 개발자들이 좋아할만한 생산성 향상을 위한 힌트를 제공합니다.
JDeveloper extension for developing J2ME applications
Oracle9i JDeveloper 9.0.3 설치 가이드
 
J2EE 개발
Using Struts with Oracle9i JDeveloper - Hands On Exercises
Business Components for Java Statement of Direction
이 문서는 BC4J의 현재 상황에 대한 개요 및 오라클의 향후 전략에 대한 프레임워크를 제공합니다.
BC4J Performance Report: Sample Response Times Under Load
이 문서는 BC4J와 오라클 J2EE 프레임워크의 성능 및 확장성에 대해 알 수있는 벤치마크 결과를 제공합니다.
BC4J Business Rules in BC4J (PDF)
이 문서는 BC4J의 모델링 및 구현 비즈니스 법칙에 대한 메소드를 제공합니다.
Introduction to JClient: A Guide for Forms Developers
이 문서는 Oracle9i JDeveloper를 이용하여 Java Clients를 구축하고자 하는 Oracle Forms 개발자를 위한 문서입니다.
Overview of Temporary Tables Used by BC4J
이 문서는 임시 데이타들을 저장하기 위해 BC4J를 사용하는 데이타베이스 테이블에 대해 설명합니다.
Configuring OC4J to work with BC4J
Simplifying J2EE and EJB Development with BC4J
이 문서는 오라클의 J2EE 호환 BC4J 프레임워크를 어떻게 하면 간소화할수 있는지에 대해 설명합니다.
Business Components for Java Feature Overview
Java Client Statement of Direction
Introduction to JClient: A Simplified Guide
Business Components for Java Whitepaper
Business Components for Java 기술 백서(PDF)
 
웹 서비스
Oracle9i JDeveloper를 이용한 웹 서비스의 개발 및 구축 (PDF)
Web Services Tutorials
자바와 데이타베이스 웹 서비스를 구축 및 게시하기 위한 15개 이상의 스텝 바이 스텝 튜토리얼 자료입니다.
Automated Invocation of a .NET Web Service
Oracle9i JDeveloper와 .NET 웹 서비스와의 연동 가이드
Database Web Services
데이타베이스 웹 서비스의 게시 및 소비에 대한 예제 및 문서
Web Services Center
웹 서비스에 대한 샘플, 기술자료, 라이브 데모 및 튜토리얼 리소스
 
UML 모델링
모델링 툴 안내서
Oracle9i Designer 및 Oracle9i JDeveloper 등의 모델링 툴에 대한 방향
Optimizing Development Productivity Using UML in Oracle9i JDeveloper (PDF)
이 문서는 모델링이 개발 환경에 추가될 수 있는 가치에 대해 설명합니다. JDeveloper에 소개된 UML 클래스 모델링 및 액티비티 모델링 등의 특정 기술과 개발자에게 이 모델러가 왜 중요한지에 대해서도 설명하고 있습니다.
 
데이타베이스 개발
Oracle9i JDeveloper 9.0.3 announces support for PL/SQL development and debugging
이 문서는 PL/SQL 개발을 위한 기능 및 Oracle9i JDeveloper 9.0.3에 포함된 일반 데이타베이스 개발에 대해 설명합니다.
 
확장(Extensions)
Developing Business Intelligence applications using BI Beans within Oracle9i JDeveloper
 
이전(Migration)
WebGain Developer Center
WebGain 사용자에게 제공하는 JDeveloper의 이점을 알고 싶으십니까? VisualCafe에서 Oracle9i JDeveloper로의 손쉬운 마이그레이션에 대한 리소스 및 VisualCafe 플러그인을 확인해보십시오.
편리해진 Oracle9i JDeveloper로의 마이그레이션
이 문서는 기존 소스를 Oracle9i JDeveloper로 마이그레이션하는 방법에 대한 가이드라인을 제공합니다. 또한 개발자들이 좋아할만한 생산성 향상을 위한 힌트를 제공합니다.
Forms Application을 J2EE로 마이그레이션
Java 및 J2EE 플랫폼은 웹 애플리케이션 구축의 표준으로 알려져있습니다. 이러한 개방형 표준 아키텍처로의 움직임과 함께 조직은 어떤 개발 툴을 사용할 것인가 그리고 기존 Oracle Forms 애플리케이션을 J2EE 플랫폼으로 이전할 것인지에 대해 결정해야합니다.
 
기타 리소스
Explore the Oracle9i JDeveloper Handbook
Chapter 3, "Creating BC4J Applications with the IDE Tools."
Chapter 9, "Introducing Business Components for Java."
Buy the Oracle9i JDeveloper Handbook from Oracle Press.
Read our conversation with the authors.
FAQ on JSR 198 and Eclipse related announcement
New Free Internet Seminar Series: "Oracle9i JDeveloper - Meet The Developers"
Oracle9i JDeveloper Team과 개발자 간의 토의 내용을 들어보세요.
J2EE Web Apps Tutorial
 


 

 

Posted by tornado
|

정리가 무쟈 깔끔~~

 

 

http://blog.empas.com/inter999/

 

 

 

'JAVA > JSP_Servlet' 카테고리의 다른 글

[펌] JSP 에서의 파일 업로드  (3) 2004.08.12
java.sun.com ===&gt; web Service  (0) 2004.08.09
[struts] &lt;html:options /&gt; 태그 ...  (0) 2004.08.03
[펌] &lt;bean:size .. /&gt;  (0) 2004.07.20
[펌] Struts Tips  (0) 2004.07.20
Posted by tornado
|
 

 

                                            Il est trop tard

너무 늦었어

- Georges Moustaki


Pendant que je dormais

내가 잠자던 동안

Pendant que je rêvais

내가 꿈꾸던 동안

Les aiguilles ont tourné

시계 바늘은 돌아갔지

Il est trop tard

너무 늦었어

Mon enfance est si loin

내 어린 시절은 아득히 멀리 있고

Il est déjà demain

이제는 벌써 내일이야

Passe passe le temps

시간은 흘러 흘러가고

il n'y en a plus pour très longtemps

아주 오래동안 이라는 것은 더 이상 없어


Pendant que je t'aimais

내가 너를 사랑하던 동안

Pendant que je t'avais

내가 너와 함께 있던 동안

L'amour s'en est allé

사랑은 가버렸지

Il est trop tard

너무 늦었어

Tu étais si jolie

너는 무척이나 예뻤지

Je suis seul dans mon lit

나는 홀로 내 침대 속에 있네

Passe passe le temps

시간은 흘러 흘러가고

il n'y en a plus pour très longtemps

아주 오래동안 이라는 것은 더 이상 없어


Pendant que je chantais

내가 노래하던 동안

Ma chère liberté

나의 소중한 자유를

D'autres l'ont enchaînée

다른 사람들은 그것을 사슬로 묶어버렸지

Il est trop tard

너무 늦었어

Certains se sont battus

어떤 사람들은 투쟁했어

Moi, je n'ai jamais su

나, 나는 전혀 몰랐지

Passe passe le temps

시간은 흘러 흘러가고

il n'y en a plus pour très longtemps

아주 오래동안 이라는 것은 더 이상 없어


Pourtant je vis toujours

그렇지만 나는 여전히 살아가고 있고

Pourtant je fais l'amour

그렇지만 나는 사랑을 나누고

M'arrive même de chanter

노래를 부르는 일조차 있지

Sur ma guitare

내 기타를 치며

Pour l'enfant que j'étais

지난 날 내 어린 시절을 (나였던 어린이를) 위해

Pour l'enfant que j'ai fait

내(가 만든) 아이를 위해

Passe passe le temps

시간은 흘러 흘러가고

il n'y en a plus pour très longtemps

아주 오래동안 이라는 것은 더 이상 없어


Pendant que je chantais

내가 노래하던 동안

Pendant que je t'aimais

내가 너를 사랑하던 동안

Pendant que je rêvais

내가 꿈꾸던 동안

Il était encore temps

그때는 아직 늦지 않았지

 

'이것저것 > 낙서장' 카테고리의 다른 글

[펌] Evergreen - 카펜터스  (0) 2004.08.12
정말정말!!!!!  (0) 2004.08.07
[펌] 내 MSN 그룹들...  (0) 2004.08.04
[책] 대망..... 강추강추  (0) 2004.08.04
[펌] 낚시줄을 바늘에 묶는 방법  (0) 2004.08.02
Posted by tornado
|
 
일전에 어떤뇬이 내 컴터를 잠시 쓴다길래 OK 한적이 있다.
근데... 그뇬이 "있으나마나한것들" 그룹에 있던 뇬인데...
봤을까?

Posted by tornado
|



< 출처 : 리브로 >

도쿠가와 이에야스 1 - 제1부 대망 : 출생의 비밀
야마오카 소하치 지음 / 이길진 옮김
 
 
요즘 읽고 있는 책....
생각보다 무지 재미있음.....
 
이거 다 읽고.... 삼국지를 다시 한번 읽을 예정
Posted by tornado
|
Dear All
Can any body complete this oode , I mean to say that what needs to be done in
configuration file struts-config, where ARRAY information must be kept.. Can any body
complete the code that it will be directly a working code .I have  successfully
completed select using simple options .

<html:select  name="StudentForm" property="passwd" >
<html:options name="StudentForm" property="languages" />
</html:select>

But want to learn using collections I am suing struts1.1.
I am trying from so many days ...pl. help
Many many thanks in advance pl. help..

Kind Regards
Strutsguy
If nay boy needs all code for  above I can send all with java class and config file .

<html:options>
ARRAY information
ArrayList prod = new ArrayList();
prod.add( new org.apache.struts.util.LabelValueBean( "Widget", "20" ) );
prod.add( new org.apache.struts.util.LabelValueBean( "Sprocket", "29-2a" ) );
prod.add( new org.apache.struts.util.LabelValueBean( "Cog", "29s" ) );
prod.add( new org.apache.struts.util.LabelValueBean( "Dunsel", "943" ) );

LabelValueBean takes the first String argument as the displayed name and the second as
the value returned. We’ll see more about this in a bit.
Now that you have prod set up, you pass that as a session or request bean to the JSP.
request.setAttribute( Constants.PRODUCT_KEY, prod );
(the Constants.PRODUCT_KEY is set to our bean name: "products"; we use this to
centralize bean name management)
To use the data in the JSP, add the following code:
  <html:select property="product_id" styleClass="prodselect" >
    <html:options collection="products" property="value" labelProperty="label" />
  </html:select>
Notes: product_id is the variable the JSP will set to the product ID value of the
product selected by the user. products is the name of the bean (it must match what is
in Contants.PRODUCT_KEY -- we probably could've said
... collection="<%= Constants.PRODUCT_KEY %>" ...
in place of hard-coding the name. The choice is up to you.
property="value" and labelProperty="label" are automatically set by
org.apache.struts.util.LabelValueBean, so only use the values shown here.
The resulting HTML will look something like:
<select name="product_id" size="1">
<option value="20">Widget</option>
<option value="29-2a">Sprocket</option>
<option value="29s">Cog</option>
<option value="943">Dunsel</option>
</select>

Posted by tornado
|

Posted by tornado
|

1. 당근이지 You bet./ Absolutely. It is natural that...
2. 썰렁하군 That's a lame joke.
3. 분위기 망치게 (조지게) 하지마. 초치지마 Don't spoil the mood!
Don't rain my parade "Look before you leap"
4. 너나 잘 해 Why don't you mind your own business?
None of your business.
5. 내 성질 건드리지 마 Don't hit my nerve.
6. 뒷북치지마 Thanks for the history lesson.
7. 잘났어 정말 / 너 잘났다 You are something else!
8. 어제 필름이 끊겼어 I got blacked out yesterday.
9. 그 사람 그거 참 잘~ 됐다. 쌤통이다 It serves him right./He deserves it.
10. 그래 니 팔뚝 (또는 니 X) 굵다 Okay, You are the boss!
11. 죽을만큼 마셔보자 Let's go all the way!
12. 니가 나한테 어떻게 그럴 수 있니? How could you do that to me?
13. 놀구 있네~~ 삽질 하네~~ Yeah. Right~ / Looking good~
14. 거기 물 좋다 That place rocks! That place kicks!
15. (문제의 답 등이) 너무 쉽네. 애개개 그게 다야? Is that it? That's it?
16. 너도 내 입장이 되어봐 Put yourself in my shoes.
17. 저리 가, 꺼져!, Take a hike!
18. 너 정말 치사하다 You are so cheap.
19. 음식 잘 먹었습니다. I've never eaten better.
20. 몇 시에 퇴근해요? What time do you call it a day?
21. 이 짓이 지겨워 죽겠어 This sucks!
22. 야, 친구 좋다는 게 뭐야? Come on, what are friends for?
23. 너무 감격해서 눈물이 난다 .It was so touching, I almost cried.
24. 미안해 할 것까지는 없어. There's nothing to be sorry about.
25. 내게 고마워할 것까지는 없어. There's no need to thank me.
26. 이보다 더 좋을 순 없다 It couldn't be better than this!
27. 메롱 Neh Neh Neh Boo Boo
28. 섭섭하지 않게 해드리겠습니다! You won't be disappointed!
29. 나를 만만하게 보지마 Don't you think I am that easy. (you에 강세)
30. 니가 하는 일이 다 그렇지 뭐 That's what you always do.
31. 분위기 파악 좀 해라, 인간아 Consider your surroundings, you fool.
32. 두고보자. Just wait! I'll get (또는 pay) you back.
33. 가만히 있으면 중간이나 가지 You should've kept quiet.
34. 이번 한 번만 봐준다 I'm gonna let it slide only this time.
35. 쟤는 어디가도 굶어죽진 않겠다. He will never starve anywhere.
36. 너무 많은 걸 알려고 하면 다쳐 You'll get hurt if you try to know too much.
37. 제발 잘난 척 좀 그만해 Stop acting like you're all that. (all that은 최근에 많이씀)
38. 네가 없으니 뭔가 허전한 기분이야 I feel like something is missing
39. 장난이 좀 심하군 The joke is too harsh.
40. 말장난 그만 합시다. Let's stop playing word games
41. 내가 만만하게 보여? Do I look like I am easy?
42. 다 엎어버리고 뛰쳐 나가고싶다. I just want to throw everything and run away
43. 여기 분위기 엄청 살벌하다.(삭막하다) The environment here is very heavy(hostile)
44. 몸이 찌뿌둥하다 I feel heavy
45. 오해 하지 마세요 Don't get me wrong.
47. 몸이 날아갈 것 같애./가뿐해 I feel light.
46. 기가막혀 말이 안나오네. It's so outrageous I can't say a word
48. 니 맘대로 하세요 Suit yourself.
49. 괜히 나만 실없는사람 되었잖아. It just made me look irresponsible
50. 허리가 삐걱했어. I hurt my back
51. 허리를 다쳤어요. I threw out my back.
52. 아직 옛날 실력 안 죽었어 I've still got it. (it은 옛날 실력을 의미)
53. 넌 이제 죽었어 You are dead meat!
54. 너 들으라고 한 소리 아냐 Don't take it personally.
55. 까꿍! Peekaboo! (삐까부; "삐"자에 강세: 아기들 얼를 때나 놀라게 할 때))
56. 알랑거리지마 Don't try to butter me up.
57. 배째 Sue me!
58. 그게 어딘데? That's better than nothing
59. 머리뚜껑이 열렸다. My head is about to open
60. 그녀는 이중 성격을 가졌어 She has a multi-personality (또는 split personality)
61. 내 일에 간섭하지 않았으면 좋겠어. I hope you mind your own business
62. 어디론가 멀리 훌쩍 떠나고 싶다 I just want to go somewhere far away.
63. (나에게) 너무 심한 것 아니예요? Don't you think you are too harsh?
64. 그렇게까지 할 필요는 없어. You don't have to do all that
65. 나도 맘이 편하지는 않아. I don't feel well about it, either.
66. 그다지 썩 내키지는 않는데.I don't feel right doing it (feel like로 바꾸면 단순한 감정)
67. 생각보다 '별로'인데... It's not as good as I thought (expected)
68. 몸살에 걸려 온몸이 쑤신다. My whole body aches.
69. 그 사람 똥배가 나왔어. He has a big belly.
70. 넌 내 밥이야 You are my food!
71. 저 사람은 인간이 왜 저래? What's wrong with him?
72. 바늘로 꼭꼭 찌르는 것 같다. It feels like a needle poking me
73. 걔 원래 그런 애야 He's usually like that.
74. 너 삐졌니? Are you mad at me? Are you pissed off?
75. 이 싸가지 없는 녀석아 You have no respect.
76. 그는 밥만 축낸다 You are not worth feeding.
77. 그는 성격이 털털하고 시원시원하다. He has an easy-going and cool attitude.
78. 있는 척 좀 하지 마. Don't act like you are rich.
79. 사람보면 아는척 좀 해봐라. Why don't you act like you know me?
80. 쟨 정말 짜다! 어떻게 밥 한번 안사니? He's so cheap. How can he not buy lunch once?
81. 너 공주병이구나.. You think you are all that? (필수 암기 구문)
82. 저 애는 내가 찍었어. That boy is mine. He is on my list.
83. 쟤는 날나리야... He is a player.
84. 그는 앞뒤가 꽉 막혔어. He is so stubborn.
85. 내 입장이 정말 난처해. My position is very uncomfortable.
86. 그 사람은 건방지게 굴어 He acts like he's all that. (all that 또 나왔죠?)
87. 쟤 손 좀 봐 줘야겠다 He needs a lesson.
88. 이 시계 참 신기하다 This watch is unique
89. 잘난체 하는 걸 아니꼬와서 못 보겠군! I can't look at him acting like he is all that.
90. 그녀는 마음을 잘 주지 않고 튕겨. She's playing hard to get
91. 그는 뒤로 호박씨 깐다. He does something in people's back
92. 야~~. 신난다... Yeah! This is fun!
93. 놔둬 그냥 그러다가 말겠지 뭐 Leave him alone. He'll stop it eventually.
94. 이 숙제 정말 짜증난다 This homework is very tedious
95. 그 사진 너무 야하다.. That picture is too sexy
96. 너무 오바 하지마 Don't go too far.
97. 쟤랑 걔랑 그렇고 그런 사이래. They are said to have a relationship
98. 걘 늘 요리조리 빠져나간단 말이야. He always gets away with stuff.
99. 그냥 그렇다고 해, 뭘 자꾸 따져? Just say it, don't argue
100.넌 왜 맨 날 그 모양이니? Why are you always like that?
101.뭐 이런 놈이 다 있어~! What kind of person is this!
102.저 사람 변태 아니야? Isn't he a pervert?
103.보자보자 하니 해도 너무 한다 I let it go, but this is too far
104.애들은 싸우면서 크는 거야 Kids grow up fighting all the time.
105.어휴~ 난 이제 죽었다 Man.. I'm dead now.
106.걔 생각하면 지금도 가슴이 아프다. When I think about him, it hurts even now.
107.옷이 촌스럽다 Those clothes are out of style.
108.기본부터 돼 먹지 않았다. It was wrong from the beginning
109.지나가던 개도 웃겠다. A passing dog would even laugh
110.나 나이 헛 먹은 거 아냐! Do you think I've aged uselessly?
111.누구 맘대로? With whose permission?
112.니가 잘나면 얼마나 잘났니? If you're all that, how big could you be?
113.아! 사는 게 왜 이럴까. Why is my life like this?
114.그 여자는 너무 코가 높아 (콧대가 세다/도도하다). She's too snobby.
115.내 일은 내가 알아서 다 할거야. I'll take care of my business.
116.뭐 찔리는 거라도 있는 거야? Are you hiding something?
117.니 입만 입이냐? Do you think your mouth is the only mouth here?
118.내 방은 지저분해서 발 디딜 틈이 없어 My room is so messy, there is no place to step.
119.좋은 게 좋은 거지. If it nice, then it's nice
120.넌 꼭 그런 말만 골라 하는군. You always choose that type of words
121.찍어둔 사람 있습니까? Do you have someone in mind? (anyone: 있는지 없는지 모를 때)
122.너 시치미 떼지마. Don't you try to lie. (you 에 강세)
123.친구랑 정이 많이 들었어요. I feel very close to my friend.
124.그거 수상한 냄새가 나는데. There's something fishy about it.
125.느낌이 오는데. / 감이 잡히는데. I got a hunch.
126.그는 자신감으로 똘똘 뭉쳤다 He is full of self-confidence
127.좋은 사람 있으면 소개 시켜 줘. Hook me up if there's a good person.
128.팀웍이 중요하다혼자너무 튀지 마라. Teamwork is important, don't try to stick out.
129.난 쓸데없는 오해받기 싫어. I don't want to be accused unfairly.
130.네가 보고 싶으면 어떻게 참지? How do I control myself if I miss you?
131.우정이 갈수록 부실해진다. Our friendship is falling apart as time passes.
132.모든 게 귀찮어 Everything is a hassle.
133.누가 니 성격을 받아주겠니. Who would put up with your attitude?
134.감쪽같이 (사귀는 관계를) 속이다니... You hid your relationship to everyone.
135.결코 고의가 아니었다. I didn't mean to do that. / It's not what I mean.
136.넌 배신자다. You are a traitor!
137.다 티 난다. Everything shows./ It's too obvious. / You can't hide it.
138.과연 얼마나 버틸 수 있을까? How long could it last?
139.좀 봐 주면서해라 (불쌍하다..) Be a little gentle with him.
140.너하곤 게임이 안 된다 (상대가 안 된다.) There is no game with you.
141.그래서?내가 어떻게 하길 바라니? So? What do you want me to do?
142.이젠 돌이킬 수가 없다. (소용없다) You can't turn back now.
143.농담도 (장난도) 사람 봐가면서 해라. Look who you are joking with.
144.네게 섭섭하다. I'm disappointed.
145.사랑이 식었구나 The love has died.
146.우리 사이가 애매하다.. I don't know what kind of relationship we have
147.이 엄살쟁이... You baby..
148.너의 잘못을 남에게 떠넘기지 마 Don't try to put your mistakes on others.
149.까불고 있어, 다음부터는 까불지마. Don't try to joke anymore
150.야! 너 인물이 훤해졌구나 Hey, your face looks a lot better.
151.도대체가 끝이 안 보이네, 끝이... I don't see the end of this.
152.내 말 안 듣더니, 그래 꼴 좋다 You didn't listen to me, now look at you!
153.(비행기를 탔을때) 귀가 멍멍하다 My ears are muffled.
154.얌전한 남자아이. Calm and reserve boy. Sissy boy. (Sissy = sister-like)
155.화장 잘 받았다! Your make-up looks good!
156.너, 화장 떳어! Your make-up doesn't look good!
157.그렇게 함부로 말하면 안 돼 You're not supposed to talk like that
158.전 간지럼을 잘 타요 I am ticklish.
159.마음이 붕 떠 있어서 일이 손에 안 잡혀. I'm so excited, I can't work.
160.행복한 고민 하시네요 You have pleasant worries.
161.잔머리 돌리지 마 Don't try to take the easy way out.
162.친구 지간에 그런 게 어딨니? What is that between friends?
163.어휴! 넌 아무도 못 말린다니까~~~! Ah, nobody can stop you.
164.입에 침이나 바르고 거짓말해라. Lick your lips before you lie.
165.그 사람 참 분위기 있더라 He has a lot of charisma. / She has class. (무관사)
166.그 넘은 화를 자초했군 He asked for it!
167.외유내강 A steel hand in a velvet glove.
168.무게 잡지마 Don't try to act tough (최민수 같이)
169.수고하세요 Have a nice day! (더 나은 표현 있으면 알려주세요)
170.내 모든 걸 걸었어 I put everything into it
171.골라먹는 재미가 있다. It's fun picking out my favorite.
172.너에겐 내가 있잖아 But you've got me.
173.원샷! Bottoms up!
174.강심장이군 His heart is made of steel. (비슷하네요)
175.오늘은 내가 쏜다 Today, it's on me!
176.왜 너 찔리니? Why? You feel guilty?
177.여기서 지척에 살아 I live a stone's throw away from here.
178.난 원래 피자를 좋아해. Pizza is in my blood. (Poker is in my blood)
179.그녀에게 뿅갔어 I got a crush on her!
180.왜 나한테 화풀이야? Why are you taking it out on me?
181.말이 청산유수로군 He's a good talker
182.내숭 떨지마 Don't play innocent!
183.흔들리면 안돼. Don't waffle.
184.남자는 여자하기 나름이야 The woman makes the man.
185.쪽 팔리는 줄 좀 알아라 Shame on you!
186.그래도 그만하길 다행이다 It could've been worse than that.
187.그는 골칫 덩어리야 He's a pain in the neck (속어로는 neck 대신 ass).
188.모든 일엔 다 때가 있다 There is a time for everything.
189.그걸 꼭 말로 해야되니? Do I have to make it explicit?
190.좀 책임감을 가져라. Live a responsible life.
191.너 많이 컸다! You've come a long way!
192.기분 짱인데 I feel like a million!
193.난 타고난 체질이야 I was born for this.
194.아까워라! What a waste!
195.음매 기죽어! That hurts! What a blow to the ego!
196.맞장구 좀 쳐 주라. Back me up here.
197.괴롭히지 좀 마세요! Hey, get out of my hair!
198.잠깐만 시간 좀 내주실 수 있으세요? Have you got a minute to spare?
199.너 제정신이니? Are you out of your mind?
200.너 뭔가 믿는 구석이 있구나. You've got somebody behind you, huh?
201.이거 장난이 아닌데! Man, this isn't a joke!
202.간뎅이가 부었군 What a nerve!

Posted by tornado
|

<logic:present name="searchForm" property="results">

<hr width="100%" size="1" noshade="true">

<bean:size id="size" name="searchForm" property="results"/>
<logic:equal name="size" value="0">
<center><font color="red"><b>No Employees Found</b></font></center>
</logic:equal>

<logic:greaterThan name="size" value="0">
<table border="1">
<tr>
<th>Name</th>
<th>Social Security Number</th>
</tr>
<logic:iterate id="result" name="searchForm" property="results">
<tr>
<td><bean:write name="result" property="name"/></td>
<td><bean:write name="result" property="ssNum"/></td>
</tr>
</logic:iterate>
</table>
</logic:greaterThan>

</logic:present>

 

http://otn.oracle.com/oramag/oracle/04-may/o34dev_struts_l1.html

Posted by tornado
|

 

 

  [ Go-> ]를 누르면 시작합니다.

  잘 보시면, 우선 가운데 밑에 종이뭉치가 있습니다. 그리고, 그 왼쪽이나 오른쪽에 선풍기가 있을 겁니다. 그리고, 정 중앙에 휴지통이 있죠.

  종이뭉치를 휴지통에 넣기만 하면 됩니다. 하지만, 방해물인 선풍기가 있습니다. 선풍기 바람의 세기는 휴지통에 화살표로 적혀있습니다. 0.0부터 6.0까지의 세기이구요. ( 해보시면 아시겠지만, 3.0만 되어도, 종이뭉치가 의외로 많이 꺾인다라는 느낌을 받게 됩니다. )

  선풍기의 바람에 대항하기 위해 종이뭉치에는 던질 각도가 표기가 됩니다. 이 정도 각도면, 들어가겠다 싶을 때, 종이뭉치를 클릭.

 

  점수 계산법은 의외로 짜증납니다. 실수 없이 연속적으로 몇번이나 넣는가 입니다. 즉, 8점이면, 8번 연속으로 성공시켰다 입니다.

 

  잘 하는 수준          3점

  아주 잘 하는 수준  10점

  최고 수준            30점

 

   세계 최고 점수가 3500대라더군요. ㅠ.ㅠ

Posted by tornado
|

Tata Young - Sexy, Naughty, Bitchy

 

 

I pick all my skirts to be a little too sexy
Just like all of my thoughts they always get a bit naughty
When I'm out with my girls I always play a bit bitchy
Can't change the way I am sexy naughty bitchy me

I'm the kind of girl that girls don't like
I'm the kind that boys fantasize
I'm the kind that your momma
and your daddy were afraid you'd turn out to be like
I may seem unapproachable
but that's only to the boys who don't have the
Right approach or ride that makes a girl like me
wanna hop in and roll

People think it's intimidating
when a girl is cool with her sexuality
I'm a 180 to the stereotype girls like staying home
and being innocent

[ Chorus ]

My mouth never takes a holiday
I always shock with the things I say
I was always the kid in school
who turned up to each class bout an hour late and
When it comes to the guys I'd lay,
I'd always pick the ones who won't figure out that
I was clearly rebel to the idea of monogamy

People think it's intimidating
when a girl is cool with her sexuality
I'm 180 to the stereotype girls like staying home
and being innocent

[ Chorus ]

Sexy...naughty...bitchy...me

People think it's intimidating
when a girl is cool with her sexuality
I'm 180 to the stereotype girl like staying home
and being innocent

[ Chorus ]

I like all of my shorts to be a little too shorty
Unlike all of my guys I like them tall with money
I love all of my nights to end a little bit nasly
Can't change the way I am sexy naughty bitchy me

I pick my Skirts to be sexy
Just like my thoughts a bit naughty
When I'm out with my girls...bitchy
Can't change I am
Sexy naughty bitch me

 

 

Posted by tornado
|
..

 

 

요즘 한창재밌게 보는 프로그램 중 하나이다.

 

블랑카....진짜 외국인 노동자인줄 알았는데...한국사람이였다니...!!!

 

ㅋㅋㅋㅋㅋㅋㅋ 정말 진짜 같다..;;

 

 

Posted by tornado
|
  
..
 

 

 

 

멋있다!!!!

 

 

Posted by tornado
|

[펌] Struts Tips

JAVA/JSP_Servlet 2004. 7. 20. 09:57
Posted by tornado
|

후다닭이넹 ^0^
Posted by tornado
|

 

 

                             * 출처: http://ahaline3.com.ne.kr

Posted by tornado
|
RSS란?

RSS는 뉴스, 블로그 등 자주 갱신(update)되는 성격의 사이트를 위한 XML 기반의 포맷입니다. A라는 사이트 (또는 사용자)가 B라는 사이트의 RSS 파일을 정기적으로 수집하면 B 사이트의 갱신된 컨텐츠 제목, 링크, 발췌 내용을 자동화된 과정에 의해 자신의 사이트에 올려놓을 수도 있고, 개인 사용자는 RSS 리더 (reader) 프로그램을 사용해 B 사이트를 직접 방문하지 않고도 최신 컨텐츠를 편리하게 볼 수 있습니다.

블로그 사이트들을 지나다 보면 'Syndicate this site (XML)' 또는 과 같은 아이콘이 있는 것을 보셨을 겁니다. 이것은 모두 RSS 파일의 링크를 표시하는 것으로서 보통 파일명은 index.xml, index.rdf, rss.xml 등이고, RSS는 'RDF Site Summary' 또는 'Really Simple Syndication'의 약자입니다.

RSS 규격들은?

'RSS' 하나에 대해 두 가지의 용어가 있는 이유는, 최초 개발은 Netscape사에 의해 이루어졌으나 Netscape사가 개발을 포기하고 난 후 두 개의 개발 주체에서 규격 개발이 진행되어 왔기 때문입니다. 현재는 RSS-DEV Working Group의 RSS (RDF Site Summary) 1.0UserLand의 RSS (Really Simple Syndication) 2.0이 업계 표준 채택을 위한 경합을 벌이고 있습니다. 두 개의 규격이 기능상 약간씩의 차이가 있지만 UserLand의 2.0이 좀 더 상세한 기능을 제공하고 있습니다.

RSS의 활용분야는 앞에서 설명했듯이 현재 크게 두 가지로 볼 수 있습니다. 사이트의 컨텐츠 배급 [신디케이션, syndication] 또는 수집 [어그리게이션, aggregation], 그리고 개인 사용자의 컨텐츠 사용 편리성 제공이 바로 그것입니다.

사이트에서 활용하려면?

A 사이트가 B 사이트의 컨텐츠를 배급하기로 했다면 A 사이트는 B 사이트의 RSS 파일이 저장된 주소(URL) 파악, 갱신 주기 결정 등을 하고 이 컨텐츠가 표시될 A의 웹 페이지를 구성합니다.

그 후 A 사이트의 RSS 수집/발행 시스템이 작동하면 해당 시스템은 자동적으로 B 사이트 컨텐츠의 제목, 링크, 발췌 내용을 결정된 주기에 따라 갱신하여 A 사이트에 보여주게 됩니다.

또는 A 사이트가 특정 주제에 대한 블로그나 뉴스를 모두 수집하여 서비스하고 싶다면, 그 주제에 관한 컨텐츠를 제공하는 C, D, E 사이트의 RSS 파일을 수집하여 같은 방식으로 서비스하면 됩니다.

이 단계 이전에 B 사이트는 자신의 사이트에서 RSS 파일을 제공해야 하는데 무버블 타입 (Movable Type), 라디오 유저랜드 (Radio UserLand), 블로거 (Blogger), 뉴클리어스 (Nucleus) 등의 블로그 출판 시스템들은 대부분 이 기능을 제공하고 있습니다. 이 시스템들에서는 새 글을 올리면 지정된 RSS 템플릿에 따라 RSS 파일이 자동으로 생성되어 지정한 위치에 저장됩니다.

개인이 활용하려면?

개인 사용자의 경우 웹브라우저를 이용해 B, C, D, E 사이트를 하나씩 방문해서 최신 컨텐츠를 확인하기에는 시간도 많이 걸리고 불편합니다. 이 경우 역시 RSS 리더 프로그램에 각 사이트의 RSS 파일 URL과 갱신 주기를 저장해 놓습니다. 그러면 RSS 리더 프로그램를 이용해 각 사이트의 최신 컨텐츠를 한 눈에 파악하고 어떤 것을 읽어야 할 지 파악할 수 있습니다.

RSS 리더 프로그램은 윈도우, 맥 OS 등 각각의 플랫폼마다 무료 또는 상용 버전들이 개발되어 있습니다. 각자의 필요에 따라 선택해서 사용하면 되겠습니다. 개인적으로는 제가 사용하고 있는 SharpReader (윈도우용)를 추천합니다. 무료이고 RSS 사이트의 분류, 한글 처리, 속도, 사용편이성, 필수 기능 등에 있어서 만족할만 합니다. [스크린샷 보기]

상용으로 많이 쓰이는 것으로는 NewzCrawler가 있습니다. 시험판을 사용해 본 소감은 불필요하게 느껴지는 고급 기능들이 좀 많은 것 같습니다. 다양한 기능들을 원하시는 분은 사용해 보셔도 괜찮을 듯 합니다.

국내에서는 어떻게 쓰이고 있나?

국내 블로그 서비스 업체들은 한미르를 제외하고는 RSS 파일을 제공하지 않고 있습니다. 몇몇 사이트가 제공하고 있는 '링블로그', '다른 블로그 구독' 등의 서비스는 해당 블로그 서비스 내에서만 가능하므로 RSS의 활용 범위와 목적과는 너무나도 큰 차이가 있습니다.

이후 서비스 업그레이드 범위에 이 부분도 포함시키는 것을 서비스 업체들께 권유하고 싶습니다. 블로그는 개별 업체 서비스의 울타리 안에 가둬둔 채로 활성화 시키기에는 아까울 뿐 아니라 적합하지 않은 서비스라고 생각합니다. 이 틀을 깨는 업체가 블로그 서비스 업계에서 앞서나갈 수 있지 않을까 하는 생각이 듭니다.

국내 뉴스 사이트의 경우 RSS를 공개하는 곳은 전무합니다. 외국의 경우 BBC, 뉴욕 타임즈, 가디언, 와이어드 등 유명 언론들이 RSS를 제공, 공개하고 있는 것과 비교했을 때 큰 차이가 있습니다. 빠른 시일 내에 많은 국내 사이트들도 RSS를 제공하게 되기를 기대해 봅니다.

현재 RSS를 제공하고 있지 않은 개인 블로그 사이트들도 이것을 제공한다면 블로그 간의 활발한 커뮤니케이션과 네트워크를 형성하는 데 큰 도움이 되지 않을까 합니다. 아직까지 국내에는 BlogdexMetaFilter와 같은 메타 블로그 서비스가 없는 관계로 개인 블로그들이 그 진가를 발휘하지 못하고 있다는 느낌도 있지만 이후 이런 서비스들이 반드시 생겨날 것이고, 그 때에는 국내 블로그들의 가치가 RSS를 통해 빛을 더할 것이라고 예상해 봅니다.

☞ 관련 링크



/최호찬 기자 (choi@hochan.net)
덧붙이는 글
PS. 국내 사용자들도 RSS 관련 기술에 대해 많이 파악하고 있는 것 같습니다. 하지만 검색을 해보면 해당 국내 자료는 매우 부족한 상황입니다. 관련 전문가들께서 정보 및 자료 제공을 해주신다면 국내에서도 풍부한 논의와 환경을 갖추게 되지 않을까 하고 생각해 보았습니다.

이 기사는 기자의 홈페이지인 HOCHAN.NET에도 함께 실립니다.

Posted by tornado
|

펌...

http://tunelinux.pe.kr/sysadmin/iskim/linux-window-7.html



7. 기업 환경을 위한 리눅스 블랙박스 만들기[7]

7.1 20만통의 메일과 sendmail

이번달에는 webmin등을 이용한 서버 설정에서 잠시 벗어나 본격적인 서버 설정에 대해서 알아보자. 아무리 기업환경을 대상으로 한다고 해도 리눅스에 대한 개념을 갖추지 못한 사용자만이 있는 것은 아니며 유닉스에 익숙한 관리자들도 많을 것인데 이들은 유닉스에 익숙하고 리눅스를 유닉스 중의 하나로 보고 일반적인 관리방법만을 적용하고 있다. 왜냐하면 현재 인터넷등에서 리눅스에 대한 글은 초보와 중급 정도의 독자를 대상으로 하고 있으며 대부분의 글이 처음 설치와 제대로 동작하기 정도에서 멈추기 때문이다. 여기저기 흩어져 있는 설정 방법들을 모두 섭렵하기에는 관리자들이 시간이 없으며 그런 문제를 전문적으로 해결해 줄 곳도 없기 때문이다. 또한 아무리 오픈소스가 인기가 있고 리눅스 열풍이 한반도를 휘몰아쳐도 여전히 나는 남의 정보를 얻어 오지만 내 것은 줄 수 없다는 생각이 지배적이기 때문이다.

필자는 여기 저기서 특별한 개발이 진행되고 있다는 소식을 주워 듣고는 있는데 제품화가 진행되고 있다는 소리는 있지만 이 것을 공개하고 있다는 이야기는 듣지 못하고 있다. 아무리 리눅스가 바람을 타더라도 이런 상황에서는 아무도 도약할 수 없다. 리눅스 마케팅의 대상은 한국이 아니라 전세계 시장이며 이런 마케팅은 정보의 공개에 의해서 그 힘을 얻을 수 있다. 각자 알고 있는 것을 일단 공개하자. 얻은 만큼 주어야 클 수 있고 보답이 돌아온다는 것을 명심해야 하지 않을까? 이 글은 필자가 대규모 메일 중계 서버를 관리하면서 알게된 경험을 바탕으로 쓴 글이다. webmin으로 하는 서버 설정을 기대하고 이 글을 읽는 독자들에게는 다소 어려운 글이겠지만 나중에는 결국 도움을 줄 수 있는 글이 될 것이다.

한 개의 서비스가 대규모화 되고 소위 엔터프라이즈급의 처리가 가능하기 위해서는 소규모일 때에는 전혀 문제가 되지 않던 것들이 엄청난 문제를 일으키게 된다. 리눅스가 대규모 서버로서 제대로 설 수 있기 위해서는 어떤 것들을 고려해야 하는지에 대해 알아보자. 이 글에서는 메일서버에 대해서만 언급하고 있지만 꼭 그 것에만 국한 된 것은 아니며 웹서버나 삼바등에서도 활용가능하다.

7.2 숙제풀이

지난 달에 sendmail이 가능하면 처리할 메일을 즉시 보내기를 하도록 하는 방법에 대해 물었다. 그 방법은 다양한데 가장 빠른 방법은 실제로 과중한 부담을 받는 메일서버를 관리하면서 고쳐 나가보는 것이다. 숙제의 답은 본문 속에서 찾아 볼 수 있다. 리눅스에서 하루에 20만통의 메일을 전송, 수신, 중계를 해야할 때 생길 수 있는 문제에 대해서 생각하다보면 이 정도의 문제는 쉽게 답을 낼 수 있을 것이다.

7.3 이글의 범위

이 글은 sendmail을 인스톨하고 설정하는 법에 대한 설명이 아니다. 기본적인 설정에 대해서는 언급하지 않는다. 네임서버 설정과 MX 레코드등에 대해서도 언급하지 않는다. 사용자명 재지정을 위한 alias, 수신 메일의 도메인을 처리할 것인가 여부를 결정하는 sendmail.cw, 수신 메일의 도메인과 사용자명을 바꿔치기하는 virtusertable, 변경전의 도메인을 새 도메인과 일치시키는 domaintable, 송신메일에서 사용자와 도메인명을 바꿔치기하는 genericstable, 상태편 사이트의 메일서버 문제를 처리하는 mailertable, 메일을 처리해 주는데 문제가 없는 사이트로 인정하는 sendmail.ct 등에 대해서 구체적으로 언급하지 않는다. 독자적인 sendmail.cf를 만들기 위해서 필요한 m4 프로그램 사용법도 마찬가지이다. 알고 싶으면 /usr/lib/sendmail-cf를 조사해 보기 바란다. 배포본의 설정은 /usr/lib/sendmail-cf/cf/redhat.mc에 들어 있다. m4 사용법은 이 글의 주제가 아니며 자세한 관련 문서가 같은 디렉토리에 있고 인터넷을 통하면 쉽게 한글문서도 구할 수 있다.

이 글에서 언급하는 대부분의 프로그램에 대한 사용법은 알고 있어야 한다. 모른다면 프로그램 예가 나올 때 마다 메뉴얼 페이지를 조사할 것을 권한다. sendmail 자체에 대해서 잘 모르는 사용자들이나 하루에 100개 미만의 메일을 처리하는 서버를 다룬다면 이 글을 읽지 않아도 좋다. 일반적인 sendmail의 옵션을 알고 싶으면 소스에 함께 배포되는 설명파일을 읽던지 인터넷을 뒤지던지 관련 서적을 구입할 것을 권한다. 시스템 설정 과정에 대한 사항도 자세히 설명하지 않는다. 이 글의 목적은 엔터프라이즈급 환경에서 리눅스를 운용할 때, 특히 메일서버로 사용할 때 제기될 수 있는 문제에 대해서 쓰는 글이며 메일서버 설정법에 대한 초보적이고 지루한 강의가 아니기 때문이다.

7.4 필요한 것들

리눅스를 메일서버로 사용하기 위해서는 sendmail 패키지가 필요하다. 물론 대부분의 배포본에는 기본적으로 메일서버가 인스톨되도록 만들어져 있다. 대규모 사이트가 아니라면 기본적인 설정으로 문제가 없다. 대규모 사이트에서 메일분산을 위해서는 sendmail 소스 배포본의 프로그램이 필요하므로 소스도 가져오기 바란다. 자체 네임서버도 필요하다. 배포본의 캐싱만 하는 네임서버를 인스톨해 둘 것. 그외 syslogd와 logrotate, top, killall 프로그램 사용법에 대한 지식도 필요하다. 하드웨어는 하루 전송량 1000통이하라면 팬티엄200, 메모리 64메가정도, 그 이상이라면 팬티엄II-450, 메모리 128혹은 256이상이 필요하다. 서버라면 스카시 하드 디스크를 사용하고 있을 것이다. IDE도 상관없지만 속도가 문제라면 스카시 하드 디스크가 적당할 것이다. 네트웍은 가능한한 빠른 것이 좋으며 트래픽을 감시하면서 메일서버의 처리량이 한계를 넘어가면 네트웍 속도를 업그레이드 하던지 속도에 맞게 메일서버의 처리량을 조절하면 될 것이다.

7.5 1천통의 이메일

하루에 1천통 이하의 메일을 처리하는 사이트가 있다. 사용자들은 윈도우에서 메일을 전송하고 리눅스의 계정으로 메일을 받는다. 사용자는 1-200명 정도이고 각 사용자는 10개 정도의 메일을 주고 받는다. 보내는 메일은 리눅스서버가 중계해 주고 받는 메일은 사용자들이 5분 단위로 pop3나 IMAP으로 가져 간다. 이 정도의 부담이라면 기본 배포본의 설정과 팬티엄 정도의 하드웨어 56K-128K정도의 네트웍 속도에서도 부담이 없다. 한 사람당 메일 쿼타로 5M를 준다면 1G 정도의 하드 디스크 여유가 있으면 된다. 파일서버, 프린터서버, 웹서버로 같이 사용해도 된다. 자체 네임서버를 구축할 필요도 없으며 메일 큐 디렉토리의 크기에도 신경 쓸 필요가 없다. 로그파일도 크지 않을 것이다. 90퍼센트 이상의 사이트에서 이 정도의 부담으로 리눅스를 사용하고 있는데 시스템 관리자도 거의 필요 없고 서버를 구석에 놓고 그냥 쓰면 된다. 정전이 되었거나 무심코 리셋키를 눌러서 하드디스크에 문제가 생기지 않는다면 일년이상 신경쓰지 않아도 된다.

sendmail의 기동은 /etc/rc.d/init.d/sendmail에 의해서 시작된다. 중요부분은 다음과 같을 것이다.

     start)        # Start daemons.        echo -n "Starting sendmail: "        daemon /usr/sbin/sendmail -bd -q1h        echo        touch /var/lock/subsys/sendmail

sendmail은 데몬 모드(-bd)로 큐는 한 시간에 한 번씩 뒤져 보게(-q1h) 되어 있다. sendmail은 메일 접속을 받으면 자식 프로세스를 생성하여 처리하며 1시간에 한 번씩, 전송이 되지 않은 메일을 다시 보내기를 시도한다. 1천통의 메일은 이 방식으로 별 문제 없이 처리가 될 것이다. 이런 시스템 관리자는 복잡한 sendmail에 대해서 신경 쓰지 말고 다른 작업에 시간을 투자하기를 권한다.

7.6 1만통의 이메일

1만통의 메일은 사용자가 500명 정도, 1-2개의 메일링 리스트, 그리고 중계해 주어야 할 윈도우 클라이언트가 50-100대 정도 있게 된다. 한 개의 도메인 전체에 대한 메일을 담당하는 메일서버로 사용하는 경우일 것이다. 기본 설정으로 사용하기에는 몇가지의 문제가 발생한다. 500명의 사용자가 5분에 한 번씩 pop3을 사용하고 큐에는 평균 100통 이상의 메일이 저장되어 있게 된다. 가장 문제가 되는 것은 한 개의 데몬이 주고 받는 메일을 처리하기에는 힘들게 된다. 이제 데몬을 구분하도록 하자. 중계와 수신을 위해서, 그리고 큐에 쌓여 있는 메일을 처리할 두 개의 데몬으로 나눈다.

        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에 설정되지 않으므로 변경하고 싶으면 #를 제거하고 값을 바꾸어 준다. 이제 sendmail은 동시에 128개(수신, 중계 sendmail 64, 큐처리 64)까지 뜰 수 있다. 수신메일은 최대 64개 까지 동시에 처리되며 중계나 수신은 64개 까지는 거부없이 받아 들인다. 물론 메일 거부는 부하가 많이 걸릴 때 발생하며 상대편 메일서버는 이 때에 메일 전송에 실패하지만 잠시 후에는 접속이 가능하게 되기 때문에 일시적 메일 서버 접속 거부는 아무런 문제가 없다. 잘못된 주소로 메일을 보내거나 이 메일 서버가 전송을 시도하는 상대편 메일서버가 다운되어 메일을 보낼 수 없을 때만 메일이 큐에 쌓인다. 큐에 쌓인 메일은 큐처리 전용의 메일서버가 계속해서 전송을 시도하게 되며 정말로 갈 수 없는 메일이 아니라면 몇 시간 안에 메일은 보내지게 될 것이다. 한 개의 메일이 계속 전송이 불가능 할 때 최대로 큐에 저장될 수 있는 값은 5일이다. 그 후에는 큐처리 메일서버가 이 메일을 강제로 삭제하게 된다. 이 값은 sendmail.cf에 있으며 바꾸기를 원하면 직접 찾아 보기 바란다.

7.7 5만통의 이메일

5만통의 메일을 주고 받게 되면 sendmail이 아닌 다른 부분에서 문제가 발생한다. 우선 수신, 중계 전용의 sendmail이 serial하다는 것이 문제가 된다. 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초).

이 문제를 해결하고자 단순히 빠른 서버를 구입한다고 했을 때 하드웨어 업그레이드에 비해서 전송효율이 같은 비율로 올라가는 것은 아니다. 이 것은 마치 99미터를 1초만에 달리고 나머지 1미터를 10초에 달리는 선수와, 99미터를 2초에 달리고 나머지를 같은 10초에 달리는 100M 경주와 비슷하다. 평균적으로 빠르지 않으면 결과는 차이가 거의 없는 것이다. 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개의 메일을 처리하는 것이다. 즉 수신 메일이 분당 32개의 메일을 큐에 쌓는 정도의 부하(하루 총 메일량 46080개)에서는 평균적으로 큐처리 메일이 32개 정도가 뜨게 된다. 수신 전용의 데몬은 평균 10개 이내로 떠있게 되는데 그 이유는 한 개의 메일을 단순히 큐에 쌓는 행위는 거의 시간이 걸리지 않기 때문에 뜨는 즉시 메일을 처리하고 죽게 되기 때문이다.

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

sendmail의 소스 배포본의 contrib 디렉토리에는 이 문제를 해결하는데 도움을 주는 프로그램 re-mqueue.pl이 있다. 이 프로그램은 perl로 만들어져 있으며 어떻게 사용하는지는 그 프로그램 안에 자세한 설명이 있다. perl과 관련한 사항은 설명하지 않는다. 소스를 보고 어떻게 활용할 것인지는 스스로 판단하기 바란다.

큐에 쌓이는 메일은 방금 받은 메일과 1시간 전에 받았지만 아직 처리 되지 못한 메일, 그리고 여러 시간 혹은 며칠 전에 받았지만 전송할 수 없는 메일들이 함께 들어 있다. 우선 1-2시간 안에 모든 메일은 큐 처리 데몬이 한 번씩 전송을 시도하기 때문에 1-2시간 전에 받았지만 아직 한 번도 전송이 시도된 적이 없는 메일은 없다고 가정한다. 그러므로 cron을 돌려서 2시간(64개의 데몬이 각각의 메일 전송을 2번 시도한 시간)안에 처리되지 못한 메일은 일차 큐에서 분리하여 다른 큐에 보내고 이 이차큐에 있는 메일을 처리하는 sendmail 데몬을 돌려서 그 메일들을 전송 하도록 한다. 우선 데몬을 다른 방식으로 띄운다.

        /usr/sbin/sendmail -bd -ODeliveryMode=defer        /usr/sbin/sendmail -q1m -OMaxDaemonChildren=64 \                           -OQueueDirectory=/var/spool/mqueue        /usr/sbin/sendmail -q10m -OMaxDaemonChildren=32 \                           -OQueueDirectory=/var/spool/mqueue2

/var/spool/mqueue2를 만들고 여기에는 2시간이 지난 메일을 처리하는 데몬을 최대 32개 까지 띄울 수 있도록 한다. 전송 지연이 있는 메일은 문제가 있는 것이므로 새로운 프로세스는 10분 정도의 시간 간격으로 뜨게 하면 별로 시스템 부담이 없게 될 것이다.

이제 mqueue의 일차 큐에서 mqueue2의 이차 큐로 메일을 보내는 것은 crontab을 사용해서 처리한다.

 # crontab -e 1-59/10 * * * * /usr/sbin/re-mqueue.pl /var/spool/mqueue /var/spool/mqueue2 7200

10분 단위로 mqueue에서 mqueue2로 2시간(7200초)가 지난 메일을 이동시킨다. 이제 일차 큐에는 전송 중이거나 전송을 기다리는 메일들만 남게 되고 악성메일(현재 보낼 수 없는 메일)은 제거되므로 효율이 눈에 띄게 증가하게 된다. redhat-5.2 이상의 설정이 이와 유사하지만 큐디렉토리간의 파일 이동을 위한 프로그램 설정이 되지 않았다. reahat-5.2 이상을 인스톨 했다면 re-mqueue.pl을 사용해 볼 것을 권한다.

7.8 10만통의 이메일

10만통의 메일을 하루에 처리하는 서버는 거의 엔터프라이즈급이라고 볼 수 있다. 하드웨어는 펜티엄II-dual, 메모리는 256M이상이 필요하고 네트웍은 1M급이 되어야 할 것이다. 리눅스의 사용자 계정은 현재 65536명까지 가능하지만 userid를 공유하는 서로 다른 사용자명을 사용할 수 있다. 또한 쉽게 사용자를 추가하고 제거하는 방법이 고려되어야 하고 사용자 인증 자체도 한 번의 메일을 위해서 64K를 뒤지는 비효율적인 방법이 아닌 다른 방법이 사용되어야 한다. 그러나 이 것은 이 글의 주제가 아니다. 10만통의 메일을 주고 받는 서버는 B급 도메인의 메일서버가 될 것인데 이 글에서는 계정 사용자보다는 주로 하위 클라이언트의 메일 중계를 중심으로 설명한다.

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


Apr xx xx:xx:xx mail sendmail[24543]: XAA24543: from=<xxx@xxx.com>, \ size=2909, class=0, pri=32909, nrcpts=1, \ msgid=<45672:phj650:99xxxx_23:45:57>, proto=SMTP, relay=[210.108.5.10]Apr xx xx:xx:xx mail sendmail[24543]: XAA24543: to=<xxxxx@xxxmail.net>, \ delay=00:00:00, mailer=esmtp, stat=queuedApr xx xx:xx:xx mail sendmail[26062]: XAA24543: to=<xxxxx@xxxmail.net>, \ claddr=<xxxxxxx@xxxinc.com> (504/504), delay=00:09:27, xdelay=00:00:01,\ mailer=esmtp, relay=r-xxxxx.xxxmail.net. [xxx.xxx.152.76], \ stat=Sent (AAA06884 Message accepted for delivery)

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

메일계정이 1000명이라고 할 때 각각의 사용자가 5분마다 한 번씩 메일을 체크한다. 한 번의 메일 체크 로그는 아래와 같다.


Apr xx xx:xx:15 mail ipop3d[22650]: port 110 service init from 210.xxx.x.xApr xx xx:xx:18 mail ipop3d[22650]: Login user=xxxxx host=[210.xxx.x.xx] nmsgs=7/7Apr xx xx:xx:24 mail ipop3d[22650]: Logout user=xxxxx host=[210.xxx.x.xx] nmsgs=0 ndele=7

한 번에 약 0.2k의 로그가 쌓인다. 윈도우에서 pop3을 사용해 메일을 가져가고 근무 시간 이후에는 컴퓨터를 끈다고 가정하면 하루에 8시간 근무하는 사용자는 192K의 로그를 만들어 내고, 1000명은 192M를, 일주일에는 1.3G의 로그를 생성시킨다. 메일 서버에 하드 디스크가 넉넉하다면 로그 파일의 크기가 커지더라도 하드 디스크 용량 때문에 문제가 생기지는 않을 것이다. 한 사용자당 5M씩 할당하면 메일을 저장할 영역으로 5G가 필요하고 로그를 위해서 2G이상이 필요하다(logrotate값이 4라면 8G.)

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


    x:xxxx  up 1 day,  2:05,  2 users,  load average: 0.22, 0.05, 0.02  49 processes: 46 sleeping, 3 running, 0 zombie, 0 stopped  CPU states: 78.6% user,  5.7% system,  0.0% nice, 15.8% idle  Mem:  192896K av, 189948K used,   2948K free, 283288K shrd,  12496K buff  Swap: 104416K av,      0K used, 104416K free                133384K cached    PID USER     PRI  NI  SIZE  RSS SHARE STAT  LIB %CPU %MEM   TIME COMMAND   4688 root      11   0   580  580   232 S       0 79.4  0.3   0:06 gzip   4687 root       4   0   532  532   432 R       0  3.9  0.2   0:00 tar   4689 root       2   0   708  708   548 R       0  0.9  0.3   0:00 top

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

배포본에 있는 로그 파일 처리는 하루에 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분 대기 프로세스가 남겨둔 메일을 다시 전송 시도 하도록 하면 된다. 그 때문에 한 개의 큐 디렉토리를 대상으로 하는 두 개의 데몬을 띄운 것이다.

두 시간 동안 모든 메일은 최소한 한 번의 전송 시도를 할 수 있게 되며 그럼에도 전송되지 못하고 남겨진 악성 메일은 2차 큐로 이동된다. 일차큐는 항상 효율적으로 사용할 수 있다.

7.9 20만통의 메일

20만통의 메일을 한 개의 큐 디렉토리에 받게 되었을 때 시간당 약 1만통의 메일이 쌓인다. 일차큐에 있는 메일은 2시간 후에 이차큐로 옮겨지기 때문에 2시간 동안 약 2만통의 메일이 쌓이게 되고 메일 전송 효율이 70 퍼센트라면 일정 시점에 큐에 쌓이는 파일의 수는 약 6000개이다. 한 개의 메일은 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

각 디렉토리는 최대한 3000개의 정도의 메일을 보유하게 된다. 일차큐에서는 한 개의 메일에 대해서 최대 10분 동안 전송을 시도한 후에 전송에 실패했거나 미처 처리하지 못하고 남은 것은 각각 10분 단위로 다른 큐로 보내진다. 옮겨진 각 큐에서 2시간을 시도해 본 후에 전송이 되지 않았으면 6개의 이차큐에 남은 메일은 모두 mqueue2로 보내진다. 여기서 2시간 지난 후의 소위 악성 메일에 대한 또다른 처리는 고려하지 않았다. 모든 큐 디렉토리의 부하를 줄이기 위해서는 re-mqueue.pl을 사용하여 2,4,8시간 1,2,3,4일 단위의 큐를 따로 생성하는 것이 좋을 것이다.

위와 같이 했을 때 최대로 뜰 수 있는 메일 서버 프로세스의 갯 수는 268개이다. 이제 시스템에서 처리할 수 있는 프로세스 갯수와 열 수 있는 오픈 파일의 갯수가 문제가 된다. 기본적으로 한 개의 sendmail 프로그램이 기동하면서 여는 파일은 다음과 같다.

   0 -> /dev/null   1 -> /dev/null   2 -> /dev/null   3 -> /var/spool/mqueue/qfVAA14282   4 -> socket:[590]   5 -> /etc/mail/aliases.db   6 -> /etc/mail/access.db   7 -> /etc/mail/virtusertable.db   8 -> /etc/mail/domaintable.db   9 -> /etc/mail/genericstable.db  10 -> /etc/mail/mailertable.db  11 -> /var/spool/mqueue/xfVAA14282  12 -> /var/spool/mqueue/dfVAA14282  13 -> socket:[814754]

이 자료는 ps를 실행하고 현재 전송 중인 메일의 프로세스 번호(예를 들어 235번)에 따라 "ls -l /proc/235/fd" 라고 실행하면 볼 수 있다. 268개의 메일 프로세스가 각각 13개씩의 파일을 열면 모두 3484개의 파일이 열린다. 서버에는 메일 데몬만 떠 있는 것이 아니므로 실제로 열려 있게 되는 파일 수는 이 값을 훨씬 넘어 간다. 현재 리눅스에서 동시에 열 수 있는 파일의 디폴트값은 4096이다. 그 값은 아래의 파일에서 정의되어 있는데 이 것을 고치고 커널을 재컴파일 하면 변경 가능하다.

   /usr/src/linux/include/linux/fs.h     #define   NR_FILE    4096

같은 헤더 파일에 한 개의 프로세스가 열 수 있는 파일의 최대값(NR_OPEN)이 1024로 정해져 있는데 이 값은 변경하지 않아도 좋다. 물론 원하면 변경해도 된다. 그 결과는 각자 테스트 해 볼 것. NR_FILE과 NR_OPEN을 크게하면 주기억장치가 크지 않은(64M이하) 시스템의 경우에는 부팅도 불가능하게 되니 주의 할 것.

커널 컴파일이 귀찮다면 동적으로 이 값을 변경해 줄 수도 있다. /proc/sys/fs/file-max가 그 것인데 아래 명령으로 현재의 최대값과 할당된 값을 볼 수 있다.

   # cat /proc/sys/fs/file-max   4096   # cat /proc/sys/fs/file-nr   1143  274 4096   # cat /proc/sys/fs/inode-max   12288   # cat /proc/sys/fs/inode-nr   8340 34

이들 값의 의미와 읽는 방법은 /usr/src/linux/Documentation/proc.txt를 참고할 것. 커널 컴파일 없이 시스템에서 열 수 있는 최대값을 변경하기 위해서는 다음 명령을 사용하면 된다.

   echo 8192 >/proc/sys/fs/file-max   echo 24576 >/proc/sys/fs/inode-max

inode-max값은 file-max값의 3배수 이상으로 하라고 proc.txt에서 조언하고 있다. 항상 이렇게 하고 싶으면 /etc/rc.d/rc.local에 적어 두면 될 것이다.

메일서버가 200개 이상 뜨거나 웹서버가 동시에 400개 이상 떠있어야 하는 대형 사이트에서는 최대값을 크게 하는 것이 최종적인 해결책일 수 있다. 그러나 이렇게 최대값을 크게 하여 문제를 해결하기 이전에 가능한 현 상태에서 최적화에 우선 신경을 쓰는 것이 더 좋은 방법이다. 왜냐하면 최대값 증가는 더많은 메모리를 요구하고 더 많은 자원 할당을 요구하기 때문이다. 200개 이상의 sendmail을 위해서 쓸 수 있는 최적화 방법으로는 한 개의 sendmail이 여는 파일의 갯수를 줄이는 것이다. 위에서 보듯이 virtusertable.db등은 가상 도메인을 사용하지 않으면 전혀 필요가 없다. 그러나 사용하지 않는 빈 파일인 /etc/mail/virtusertable을 그대로 둔다면 sendmail이 기동하면서 db파일을 만들게 되고 모든 프로세스가 이 파일을 열어 두게 된다. 그러므로 사용하지 않는 파일을 아예 없애버리면 sendmail이 db파일을 만들지 않고, 그에 따라 각 프로세스는 이 파일을 위해 파일 핸들을 할당하지 않으니까 열린 파일 갯수가 줄어든다. 한 개의 열린 파일의 갯수를 줄이면 268개의 파일을 닫는 효과가 있다. 사용하지 않는 domaintable, access, genericsable, mailertable 5개의 파일을 지워버리면 1340개의 열린 파일 수를 절약할 수 있으며 한 프로세스의 열린 파일 갯수가 적어지면 메일을 체크할 때 이 파일을 뒤지지 않아도 되기 때문에 그 만큼 프로세싱 타임이 줄어 들 것이다.

큐에 쌓인 메일을 처리하는 sendmail 프로세스는 메일을 보내기 위해서 네임서버와 교신해야 한다. 메일 서버가 서브네트웍 바깥에 있다면 한 개의 메일을 보내기 위해서 외부까지 교신을 해야 하기 때문에 시간이 많이 걸린다. 한 시간에 1만번의 조회를 시도하면 아마 외부 메일서버도 견디지 못하고 다운될 확률이 있다. 또한 네트웍 자원은 네임서버와의 교신에 모두 소모되고 다른 사람들이 외부로 나가거나 들어오는 것초차 힘들게 된다. 네임서버가 로컬 네트웍의 다른 서버에 있어도 마찬가지이다. 내부 네트웍은 거의 네임서버 접속에 이용되므로 회사 전산망이 마비되고 네임서비스를 하는 서버가 다운된다. 실제로 필자가 내부 네트웍의 다른 서버에 네임서버를 두고 메일서버가 네임 조회를 이 서버 쪽으로 하도록 했었는데 네임서버에 메모리가 고갈되어 named, httpd, cron등이 죽었다. 그 후에 데몬이 죽은 것을 알고 named와 httpd만 살리고 cron이 죽은 것은 알지 못하고 재실행하지 않았더니 cron으로 돌던 log파일 처리 프로그램이 동작하지 않아 로그 파일이 커지는 바람에 시스템이 움직이지 않을 정도로 부하가 걸린 적이 있었다. 필자는 외부에 의한 해킹으로 의심하고 보안관련 문서를 뒤적이느라고 시간을 소비해야 했다. 이렇게 한 개의 메일서버가 연속적으로 다른 서버들에게 영향을 미칠 수 있음을 염두에 두어야 할 것이다.

그러므로 가능하면 메일서버 자체에 메일 전송을 위한 네임서버를 띄우는 것이 좋다. 이 때의 네임서버는 단순한 캐싱만을 하는 네임서버만으로 족하다. 처음에는 네임서버 자체가 외부로 조회를 해야 하기 때문에 시간이 걸리겠지만 계속 사용한다면 중복되는 IP는 같은 메모리 안에서 처리가 가능하기 때문에 외부에 영향을 주지 않으며, 로컬 네트웍의 tcp/ip 자원도 소모시키지 않고 신속한 조회가 이루어 질 수 있다. 캐싱만 하는 네임서버는 간단히 다음과 같이 만들 수 있다.


  /etc/named.conf    options {        directory "/var/named";        check-names master warn;         datasize 20M;  };  zone "." IN {        type hint;        file "root.hint";  };  zone "localhost" IN {        type master;        file "localhost";        check-names fail;        allow-update { none; };        allow-transfer { any; };  };  /var/named/root.hint    #dig >/var/named/root.hint  /var/named/localhost    @  IN  SOA  @ root (                  42              ; serial (d. adams)                  3H              ; refresh                  15M             ; retry                  1W              ; expiry                  1D )            ; minimum       NS     @    1   A     127.0.0.1  /etc/resolv.conf   nameserver 127.0.0.1

이렇게 최소한의 네임서버만으로 네트웍 자원의 낭비를 막을 수 있으므로 20만개의 메일을 처리하기 위해서는 회사내의 공식 네임서버가 있다고 해도 독립적으로 메일서버에 설치하는 것이 좋을 것이다.

7.10 100만통의 이메일 처리를 위하여

소규모 처리를 담당하는 서버에서 대규모 서버로 진화하기 위해서 어떤 것이 필요하고 그 과정에서 중요한 단계마다의 병목은 무었인지 그리고 이 것을 어떻게 해결할 수 있는지에 대해서 알아 보았다. 한 개의 서비스가 커지면 가능한 옵션을 모두 다시 검토하여야하고, 하드웨어 자원을 추가로 요구하며, 로그 파일 처리등의 관련 프로그램의 효율성이 증대되어야 하고, 네임서버와 같은 또다른 서비스까지 자신에게 맞추어 줄 것을 요구한다. 또한 한 개의 서버가 문제를 일으키면 주변의 다른 서버까지 문제가 파급된다는 것도 보았다. tcpdump같이 다른 컴퓨터 사이의 동작을 감시하는 프로그램에 대한 사용법도 익혀 줄것을 부탁한다. 이모두는 서로 보완적이므로 한 개의 서비스를 위해서 그 프로그램만을 들여다 보아서는 안되고 전체를 볼 줄 알아야 할 것이다.

이 글에서는 TCP/IP 포트 재지정에 의한 분산, 메일 전송 정보가 들어 있는 qf* 파일을 분석하여 각각의 전송 실패 이유에 따른 큐디렉토리 분산, 전송할 수 없는 메일에 대한 처리, sendmail.cf의 각각의 옵션에 대한 관찰등은 하지 않았다. 관심있는 독자들은 sendmail 책과 /var/spool/mqueue/qf* 파일에 대해 조사해 보기 바란다.

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

필자가 최종적인 해결책으로 보고 있는 것은 IP-tunneling을 사용한 리눅스 virtual-sever(vs)를 사용하는 것이다. 이 방법은 한 개의 frond-end가 각각의 접속을 받아서 실제 서비스를 하는 back-end 서버에게 접속을 넘겨 주는 것이다. 한 번 접속이 이루어 지고 나서는 client와 back-end간에 직접 접속이 이루어지게 되므로 frond-end는 바로 다음 접속을 처리할 수 있다. vs 리눅스를 개발하는 팀에 의하면 한 대의 frond-end가 1G 급의 부하를 처리할 수 있었다고 한다. 관심있는 사람은 vs홈페이지(http://proxy.iinchina.net/ wensong/ippfvs/)를 방문해 보기 바란다. 최근 외국의 개발업체에서 이 기능을 특화시킨 분산 서버를 제작해서 상업화 시켰다는 이야기도 들은 바가 있다.

이미 리눅스의 메일서버로서의 기능은 신뢰할 만하고 추가 비용이 전혀 필요 없다. 사용자 수 추가에 따라 비싼 라이센스 비용을 지불해야 하는 상용 서버가 설 자리가 없어 지고 있다. 여기에 더해서 사용자 인증, 삭제, 추가 기능을 간편하게 할 수 있는 프로그램이 개발되어 100만통의 메일을 처리할 수 있는 분산 서버와 결합하게 되면 인터넷의 거의 모든 메일서버는 리눅스가 점령하게 될 것이다.

7.11 이 달의 숙제

메일서버와 마찬가지로 웹서버도 많은 히트수를 기록하게 되면 로그 파일이 커질 것이다. /var/log/httpd에 가보았더니 access_log가 30M였다. sendmail을 위해서 설명한 logrotate.conf와 같이 설정 파일을 만들고 하는 것이 시간이 걸려서 잠시 미루고 일단 수동으로 로그 파일을 빨리 정리하고 싶다. 어떻게 하면 될까? 참고로 "rm access_log"라고 해도 로그 파일이 줄어 들지는 않는다. 이건 또 왜 그런 것일까?


다음 이전 차례

'OS > LINUX' 카테고리의 다른 글

한글 putty  (0) 2004.08.13
[펌] temp..정리하기전..  (0) 2004.08.11
[허접] 내부 IP MSN 차단 .... ㅡㅡ  (0) 2004.07.07
[펌] 프로세스죽이기  (0) 2004.07.07
간단하게 ftp 에 접속하는법  (0) 2004.07.06
Posted by tornado
|