﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-jojo's blog－－快乐忧伤都与你同在-文章分类-每日一记</title><link>http://www.blogjava.net/ruoyoux/category/39508.html</link><description>为梦想而来，为自由而生。
性情若水，风起水兴，风息水止，故时而激荡，时又清平……</description><language>zh-cn</language><lastBuildDate>Fri, 14 Aug 2009 00:10:59 GMT</lastBuildDate><pubDate>Fri, 14 Aug 2009 00:10:59 GMT</pubDate><ttl>60</ttl><item><title>每日一记 2009/08/11 Top 100 Blogs for Development Managers (Q3 2008)</title><link>http://www.blogjava.net/ruoyoux/articles/290700.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Tue, 11 Aug 2009 10:13:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/290700.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/290700.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/290700.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/290700.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/290700.html</trackback:ping><description><![CDATA[http://www.noop.nl/2008/09/top-100-blogs-for-development-managers-q3-2008.html<br />
<br />
Nr&nbsp;&nbsp; &nbsp;Site / Author&nbsp;&nbsp; &nbsp;PR&nbsp;&nbsp; &nbsp;TA&nbsp;&nbsp; &nbsp;AR&nbsp;&nbsp; &nbsp;Hits&nbsp;&nbsp; &nbsp;Cmts<br />
1&nbsp;&nbsp; &nbsp;Joel on Software Joel Spolsky&nbsp;&nbsp; &nbsp;7&nbsp;&nbsp; &nbsp;2357&nbsp;&nbsp; &nbsp;40364&nbsp;&nbsp; &nbsp;6090&nbsp;&nbsp; &nbsp; <br />
2&nbsp;&nbsp; &nbsp;Coding Horror Jeff Atwood&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;3472&nbsp;&nbsp; &nbsp;54474&nbsp;&nbsp; &nbsp;3870&nbsp;&nbsp; &nbsp;1916<br />
3&nbsp;&nbsp; &nbsp;Seth's Blog Seth Godin&nbsp;&nbsp; &nbsp;7&nbsp;&nbsp; &nbsp;8757&nbsp;&nbsp; &nbsp;93669&nbsp;&nbsp; &nbsp;14600&nbsp;&nbsp; &nbsp; <br />
4&nbsp;&nbsp; &nbsp;Paul Graham: Essays Paul Graham&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;2382&nbsp;&nbsp; &nbsp;49839&nbsp;&nbsp; &nbsp;2750&nbsp;&nbsp; &nbsp; <br />
5&nbsp;&nbsp; &nbsp;blog.pmarca.com Marc Andreesen&nbsp;&nbsp; &nbsp;7&nbsp;&nbsp; &nbsp;1169&nbsp;&nbsp; &nbsp;95439&nbsp;&nbsp; &nbsp;3350&nbsp;&nbsp; &nbsp; <br />
6&nbsp;&nbsp; &nbsp;Rough Type Nicholas Carr&nbsp;&nbsp; &nbsp;7&nbsp;&nbsp; &nbsp;1114&nbsp;&nbsp; &nbsp;109196&nbsp;&nbsp; &nbsp;4910&nbsp;&nbsp; &nbsp;111<br />
7&nbsp;&nbsp; &nbsp;Scott Hanselman's Computer Zen Scott Hanselman&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;1284&nbsp;&nbsp; &nbsp;51568&nbsp;&nbsp; &nbsp;4040&nbsp;&nbsp; &nbsp;155<br />
8&nbsp;&nbsp; &nbsp;Martin Fowler's Bliki Martin Fowler&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;376&nbsp;&nbsp; &nbsp;79142&nbsp;&nbsp; &nbsp;2240&nbsp;&nbsp; &nbsp; <br />
9&nbsp;&nbsp; &nbsp;Rands in Repose Michael Lopp&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;565&nbsp;&nbsp; &nbsp;199191&nbsp;&nbsp; &nbsp;1610&nbsp;&nbsp; &nbsp;401<br />
10&nbsp;&nbsp; &nbsp;Stevey's Blog Rants Steve Yegge&nbsp;&nbsp; &nbsp;7&nbsp;&nbsp; &nbsp;182&nbsp;&nbsp; &nbsp;201319&nbsp;&nbsp; &nbsp;1270&nbsp;&nbsp; &nbsp;912<br />
11&nbsp;&nbsp; &nbsp;Bokardo: Social Design Joshua Porter&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;448&nbsp;&nbsp; &nbsp;105072&nbsp;&nbsp; &nbsp;1990&nbsp;&nbsp; &nbsp;122<br />
12&nbsp;&nbsp; &nbsp;Eric.Weblog() Eric Sink&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;161&nbsp;&nbsp; &nbsp;219875&nbsp;&nbsp; &nbsp;1820&nbsp;&nbsp; &nbsp;183<br />
13&nbsp;&nbsp; &nbsp;Lambda the Ultimate (various)&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;197&nbsp;&nbsp; &nbsp;172624&nbsp;&nbsp; &nbsp;2150&nbsp;&nbsp; &nbsp;90<br />
14&nbsp;&nbsp; &nbsp;Otaku, Cedric's Weblog Cedric&nbsp;&nbsp; &nbsp;7&nbsp;&nbsp; &nbsp;107&nbsp;&nbsp; &nbsp;209562&nbsp;&nbsp; &nbsp;942&nbsp;&nbsp; &nbsp;274<br />
15&nbsp;&nbsp; &nbsp;PragDave Dave Thomas&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;56&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;1700&nbsp;&nbsp; &nbsp;158<br />
16&nbsp;&nbsp; &nbsp;High Scalability (various)&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;611&nbsp;&nbsp; &nbsp;67614&nbsp;&nbsp; &nbsp;749&nbsp;&nbsp; &nbsp;57<br />
17&nbsp;&nbsp; &nbsp;The Berkun Blog Scott Berkun&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;224&nbsp;&nbsp; &nbsp;150787&nbsp;&nbsp; &nbsp;1120&nbsp;&nbsp; &nbsp;42<br />
18&nbsp;&nbsp; &nbsp;UIE Brain Sparks Jared Spool&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;128&nbsp;&nbsp; &nbsp;73839&nbsp;&nbsp; &nbsp;913&nbsp;&nbsp; &nbsp;34<br />
19&nbsp;&nbsp; &nbsp;Raganwald Reginald Braithwaite&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;286&nbsp;&nbsp; &nbsp;295168&nbsp;&nbsp; &nbsp;591&nbsp;&nbsp; &nbsp;120<br />
20&nbsp;&nbsp; &nbsp;J.D. Meier's Blog J.D. Meier&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;106&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;446&nbsp;&nbsp; &nbsp;32<br />
21&nbsp;&nbsp; &nbsp;Stack Overflow Jeff Atwood&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;234&nbsp;&nbsp; &nbsp;99548&nbsp;&nbsp; &nbsp;119&nbsp;&nbsp; &nbsp;292<br />
22&nbsp;&nbsp; &nbsp;Stevenf.com Steven Frank&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;211&nbsp;&nbsp; &nbsp;431730&nbsp;&nbsp; &nbsp;711&nbsp;&nbsp; &nbsp; <br />
23&nbsp;&nbsp; &nbsp;secretGeek Leon Bambrick&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;109&nbsp;&nbsp; &nbsp;279144&nbsp;&nbsp; &nbsp;382&nbsp;&nbsp; &nbsp;78<br />
24&nbsp;&nbsp; &nbsp;CodeBetter.Com (various)&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;804&nbsp;&nbsp; &nbsp;55474&nbsp;&nbsp; &nbsp;140&nbsp;&nbsp; &nbsp;53<br />
25&nbsp;&nbsp; &nbsp;Interoperability Happens Ted Neward&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;155&nbsp;&nbsp; &nbsp;871230&nbsp;&nbsp; &nbsp;570&nbsp;&nbsp; &nbsp;42<br />
26&nbsp;&nbsp; &nbsp;Gray's Matter Justice Gray&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;89&nbsp;&nbsp; &nbsp;302785&nbsp;&nbsp; &nbsp;607&nbsp;&nbsp; &nbsp;38<br />
27&nbsp;&nbsp; &nbsp;Mike Cohn's Blog: Succeeding with Agile Mike Cohn&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;401141&nbsp;&nbsp; &nbsp;264&nbsp;&nbsp; &nbsp;116<br />
28&nbsp;&nbsp; &nbsp;Object Mentor Blog (various)&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;83&nbsp;&nbsp; &nbsp;281113&nbsp;&nbsp; &nbsp;248&nbsp;&nbsp; &nbsp;84<br />
29&nbsp;&nbsp; &nbsp;James Bach&#8217;s Blog James Bach&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;45&nbsp;&nbsp; &nbsp;657727&nbsp;&nbsp; &nbsp;503&nbsp;&nbsp; &nbsp;159<br />
30&nbsp;&nbsp; &nbsp;Managing Product Development Johanna Rothman&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;50&nbsp;&nbsp; &nbsp;710781&nbsp;&nbsp; &nbsp;1020&nbsp;&nbsp; &nbsp;22<br />
31&nbsp;&nbsp; &nbsp;Google Testing Blog (various)&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;151&nbsp;&nbsp; &nbsp;308629&nbsp;&nbsp; &nbsp;216&nbsp;&nbsp; &nbsp;45<br />
32&nbsp;&nbsp; &nbsp;Alistair Cockburn Alistair Cockburn&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;636969&nbsp;&nbsp; &nbsp;426&nbsp;&nbsp; &nbsp; <br />
33&nbsp;&nbsp; &nbsp;Tyner Blain Scott Sehlhorst&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;63&nbsp;&nbsp; &nbsp;873747&nbsp;&nbsp; &nbsp;594&nbsp;&nbsp; &nbsp;40<br />
34&nbsp;&nbsp; &nbsp;Artima Weblogs (various)&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;250&nbsp;&nbsp; &nbsp;41092&nbsp;&nbsp; &nbsp;97&nbsp;&nbsp; &nbsp;21<br />
35&nbsp;&nbsp; &nbsp;It's Just a Bunch of Stuff That Happens Eric Burke&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;401&nbsp;&nbsp; &nbsp;338795&nbsp;&nbsp; &nbsp;109&nbsp;&nbsp; &nbsp;51<br />
36&nbsp;&nbsp; &nbsp;{ |one, step, back| } Jim Weirich&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;92&nbsp;&nbsp; &nbsp;699777&nbsp;&nbsp; &nbsp;315&nbsp;&nbsp; &nbsp; <br />
37&nbsp;&nbsp; &nbsp;Dr. Dobb's CodeTalk (various)&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;249123&nbsp;&nbsp; &nbsp;732&nbsp;&nbsp; &nbsp;6<br />
38&nbsp;&nbsp; &nbsp;Petzold Book Blog Charles Petzold&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;23&nbsp;&nbsp; &nbsp;400444&nbsp;&nbsp; &nbsp;362&nbsp;&nbsp; &nbsp;67<br />
39&nbsp;&nbsp; &nbsp;{Codesqueeze} Max Pool&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;77&nbsp;&nbsp; &nbsp;432030&nbsp;&nbsp; &nbsp;172&nbsp;&nbsp; &nbsp;56<br />
40&nbsp;&nbsp; &nbsp;Signal vs. Noise (various)&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;72462&nbsp;&nbsp; &nbsp;211&nbsp;&nbsp; &nbsp;220<br />
41&nbsp;&nbsp; &nbsp;Curious Cat John Hunter&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;44&nbsp;&nbsp; &nbsp;96174&nbsp;&nbsp; &nbsp;1030&nbsp;&nbsp; &nbsp;4<br />
42&nbsp;&nbsp; &nbsp;Knowing.NET Larry O'Brien&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;48&nbsp;&nbsp; &nbsp;601544&nbsp;&nbsp; &nbsp;482&nbsp;&nbsp; &nbsp;12<br />
43&nbsp;&nbsp; &nbsp;Agile Management Blog David Anderson&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;26&nbsp;&nbsp; &nbsp;655893&nbsp;&nbsp; &nbsp;1200&nbsp;&nbsp; &nbsp;15<br />
44&nbsp;&nbsp; &nbsp;/"ndy Andy Hunt&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;28&nbsp;&nbsp; &nbsp;1717994&nbsp;&nbsp; &nbsp;769&nbsp;&nbsp; &nbsp;21<br />
45&nbsp;&nbsp; &nbsp;James Shore: Successful Software James Shore&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;71&nbsp;&nbsp; &nbsp;1331837&nbsp;&nbsp; &nbsp;221&nbsp;&nbsp; &nbsp;28<br />
46&nbsp;&nbsp; &nbsp;Object Technology Jeff Sutherland&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;85&nbsp;&nbsp; &nbsp;500221&nbsp;&nbsp; &nbsp;186&nbsp;&nbsp; &nbsp;6<br />
47&nbsp;&nbsp; &nbsp;Better Projects Craig Brown&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;38&nbsp;&nbsp; &nbsp;1080915&nbsp;&nbsp; &nbsp;251&nbsp;&nbsp; &nbsp;21<br />
48&nbsp;&nbsp; &nbsp;Evolving Web Jim Benson&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;42&nbsp;&nbsp; &nbsp;1681730&nbsp;&nbsp; &nbsp;708&nbsp;&nbsp; &nbsp;16<br />
49&nbsp;&nbsp; &nbsp;Meme Agora Neal Ford&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;63&nbsp;&nbsp; &nbsp;2160111&nbsp;&nbsp; &nbsp;247&nbsp;&nbsp; &nbsp;28<br />
50&nbsp;&nbsp; &nbsp;Agility@Scale Scott W. Ambler&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;70&nbsp;&nbsp; &nbsp;68<br />
51&nbsp;&nbsp; &nbsp;David Chelimsky David Chelimsky&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;838069&nbsp;&nbsp; &nbsp;103&nbsp;&nbsp; &nbsp;62<br />
52&nbsp;&nbsp; &nbsp;Pure Danger Tech Alex Miller&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;70&nbsp;&nbsp; &nbsp;596549&nbsp;&nbsp; &nbsp;163&nbsp;&nbsp; &nbsp;9<br />
53&nbsp;&nbsp; &nbsp;Elegant Code (various)&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;96&nbsp;&nbsp; &nbsp;497139&nbsp;&nbsp; &nbsp;72&nbsp;&nbsp; &nbsp;18<br />
54&nbsp;&nbsp; &nbsp;Exploring Solutions Spaces C. Keith Ray&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;13&nbsp;&nbsp; &nbsp;1392656&nbsp;&nbsp; &nbsp;329&nbsp;&nbsp; &nbsp; <br />
55&nbsp;&nbsp; &nbsp;The Braidy Tester Micahel&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;21&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;344&nbsp;&nbsp; &nbsp;9<br />
56&nbsp;&nbsp; &nbsp;Destraynor Des Traynor&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;16&nbsp;&nbsp; &nbsp;966603&nbsp;&nbsp; &nbsp;169&nbsp;&nbsp; &nbsp;58<br />
57&nbsp;&nbsp; &nbsp;Project Shrink Bas de Baar&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;40&nbsp;&nbsp; &nbsp;141635&nbsp;&nbsp; &nbsp;237&nbsp;&nbsp; &nbsp;18<br />
58&nbsp;&nbsp; &nbsp;Stephans Blog Stephan Schmidt&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;32&nbsp;&nbsp; &nbsp;659770&nbsp;&nbsp; &nbsp;56&nbsp;&nbsp; &nbsp;87<br />
59&nbsp;&nbsp; &nbsp;Agile Advice (various)&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;64&nbsp;&nbsp; &nbsp;899353&nbsp;&nbsp; &nbsp;339&nbsp;&nbsp; &nbsp;2<br />
60&nbsp;&nbsp; &nbsp;LeadingAnswers Mike Griffiths&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;38&nbsp;&nbsp; &nbsp;1254375&nbsp;&nbsp; &nbsp;456&nbsp;&nbsp; &nbsp;30<br />
61&nbsp;&nbsp; &nbsp;Wide Awake Developers Michael Nygard&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;292&nbsp;&nbsp; &nbsp;1072770&nbsp;&nbsp; &nbsp;149&nbsp;&nbsp; &nbsp;4<br />
62&nbsp;&nbsp; &nbsp;Bit-Player Brian Hayes&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;12&nbsp;&nbsp; &nbsp;3504554&nbsp;&nbsp; &nbsp;240&nbsp;&nbsp; &nbsp;65<br />
63&nbsp;&nbsp; &nbsp;Word Aligned Thomas Guest&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;57&nbsp;&nbsp; &nbsp;536114&nbsp;&nbsp; &nbsp;43&nbsp;&nbsp; &nbsp;21<br />
64&nbsp;&nbsp; &nbsp;Testing Hotlist Update Bret Pettichord&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;14&nbsp;&nbsp; &nbsp;1409810&nbsp;&nbsp; &nbsp;231&nbsp;&nbsp; &nbsp;29<br />
65&nbsp;&nbsp; &nbsp;NOOP.NL: Managing Software Development Jurgen Appelo&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;73&nbsp;&nbsp; &nbsp;692206&nbsp;&nbsp; &nbsp;181&nbsp;&nbsp; &nbsp;19<br />
66&nbsp;&nbsp; &nbsp;Caffeinated Coder Russell Ball&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;52&nbsp;&nbsp; &nbsp;1558998&nbsp;&nbsp; &nbsp;46&nbsp;&nbsp; &nbsp;86<br />
67&nbsp;&nbsp; &nbsp;GrokCode Jess&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;109&nbsp;&nbsp; &nbsp;524914&nbsp;&nbsp; &nbsp;46&nbsp;&nbsp; &nbsp;74<br />
68&nbsp;&nbsp; &nbsp;Lean Software Engineering Corey Ladas&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;42&nbsp;&nbsp; &nbsp;1112902&nbsp;&nbsp; &nbsp;322&nbsp;&nbsp; &nbsp;19<br />
69&nbsp;&nbsp; &nbsp;Exploration Through Example Brian Marick&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;31&nbsp;&nbsp; &nbsp;3491602&nbsp;&nbsp; &nbsp;224&nbsp;&nbsp; &nbsp;27<br />
70&nbsp;&nbsp; &nbsp;Herding Cats Glen Alleman&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;51&nbsp;&nbsp; &nbsp;1434425&nbsp;&nbsp; &nbsp;70&nbsp;&nbsp; &nbsp;23<br />
71&nbsp;&nbsp; &nbsp;Legends of the Sun Pig Martin Sutherland&nbsp;&nbsp; &nbsp;7&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;1453763&nbsp;&nbsp; &nbsp;399&nbsp;&nbsp; &nbsp;14<br />
72&nbsp;&nbsp; &nbsp;Agile Developer Venkat's Blog Venkat Subramaniam&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;34&nbsp;&nbsp; &nbsp;1152021&nbsp;&nbsp; &nbsp;187&nbsp;&nbsp; &nbsp;9<br />
73&nbsp;&nbsp; &nbsp;The Third Bit Esan&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;44&nbsp;&nbsp; &nbsp;1084414&nbsp;&nbsp; &nbsp;321&nbsp;&nbsp; &nbsp;1<br />
74&nbsp;&nbsp; &nbsp;Implementing Scrum Mike Vizdos&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;53&nbsp;&nbsp; &nbsp;946336&nbsp;&nbsp; &nbsp;206&nbsp;&nbsp; &nbsp;3<br />
75&nbsp;&nbsp; &nbsp;Collaborative Software Testing Jonathan Kohl&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;26&nbsp;&nbsp; &nbsp;3279595&nbsp;&nbsp; &nbsp;296&nbsp;&nbsp; &nbsp; <br />
76&nbsp;&nbsp; &nbsp;Test Obsessed Elisabeth Hendrickson&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;34&nbsp;&nbsp; &nbsp;2117127&nbsp;&nbsp; &nbsp;256&nbsp;&nbsp; &nbsp;41<br />
77&nbsp;&nbsp; &nbsp;10x Software Development Steve McConnell&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;0&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;533&nbsp;&nbsp; &nbsp;108<br />
78&nbsp;&nbsp; &nbsp;Joel Pobar's Weblog Joel Pobar&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;21&nbsp;&nbsp; &nbsp;6854408&nbsp;&nbsp; &nbsp;139&nbsp;&nbsp; &nbsp;94<br />
79&nbsp;&nbsp; &nbsp;Creative Chaos Matthew Heusser&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;28&nbsp;&nbsp; &nbsp;3038531&nbsp;&nbsp; &nbsp;294&nbsp;&nbsp; &nbsp;11<br />
80&nbsp;&nbsp; &nbsp;Jcooney.NET Joseph Cooney&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;33&nbsp;&nbsp; &nbsp;2194958&nbsp;&nbsp; &nbsp;161&nbsp;&nbsp; &nbsp;15<br />
81&nbsp;&nbsp; &nbsp;All About Agile Kelly Waters&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;31&nbsp;&nbsp; &nbsp;408534&nbsp;&nbsp; &nbsp;223&nbsp;&nbsp; &nbsp;10<br />
82&nbsp;&nbsp; &nbsp;Project Management 2.0 Andrew Filev&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;12&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;272&nbsp;&nbsp; &nbsp;5<br />
83&nbsp;&nbsp; &nbsp;Agile Commons (various)&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;686263&nbsp;&nbsp; &nbsp;148&nbsp;&nbsp; &nbsp;4<br />
84&nbsp;&nbsp; &nbsp;The Cutter Blog (various)&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;6&nbsp;&nbsp; &nbsp;778348&nbsp;&nbsp; &nbsp;304&nbsp;&nbsp; &nbsp;7<br />
85&nbsp;&nbsp; &nbsp;Chris Spagnuolo's GeoScrum Chris Spagnuolo&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;51&nbsp;&nbsp; &nbsp;2259995&nbsp;&nbsp; &nbsp;198&nbsp;&nbsp; &nbsp;4<br />
86&nbsp;&nbsp; &nbsp;Aligning Technology, Strategy, People &amp; Projects Eric Brown&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;44&nbsp;&nbsp; &nbsp;1245105&nbsp;&nbsp; &nbsp;206&nbsp;&nbsp; &nbsp;12<br />
87&nbsp;&nbsp; &nbsp;Agile Software Development (various)&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;62&nbsp;&nbsp; &nbsp;331003&nbsp;&nbsp; &nbsp;100&nbsp;&nbsp; &nbsp;7<br />
88&nbsp;&nbsp; &nbsp;Clarke Ching - More Chilli Please Clarke Ching&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;36&nbsp;&nbsp; &nbsp;2456889&nbsp;&nbsp; &nbsp;280&nbsp;&nbsp; &nbsp;3<br />
89&nbsp;&nbsp; &nbsp;Musings of a Software Development Manager Ed Gibbs&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;11&nbsp;&nbsp; &nbsp;1538525&nbsp;&nbsp; &nbsp;252&nbsp;&nbsp; &nbsp;29<br />
90&nbsp;&nbsp; &nbsp;Notes from a Tool User Mark Levison&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;23&nbsp;&nbsp; &nbsp;1383460&nbsp;&nbsp; &nbsp;134&nbsp;&nbsp; &nbsp;24<br />
91&nbsp;&nbsp; &nbsp;Silk and Spinach Kevin Rutherford&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;9&nbsp;&nbsp; &nbsp;1117088&nbsp;&nbsp; &nbsp;121&nbsp;&nbsp; &nbsp;14<br />
92&nbsp;&nbsp; &nbsp;Focused Performance Frank Patrick&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;7&nbsp;&nbsp; &nbsp;729258&nbsp;&nbsp; &nbsp;1140&nbsp;&nbsp; &nbsp;6<br />
93&nbsp;&nbsp; &nbsp;Hot Needle of Inquiry Ron Jeffries&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;11&nbsp;&nbsp; &nbsp;273831&nbsp;&nbsp; &nbsp;694&nbsp;&nbsp; &nbsp;0<br />
94&nbsp;&nbsp; &nbsp;Mistaeks I Hav Made Nat Pryce&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;18&nbsp;&nbsp; &nbsp;187328&nbsp;&nbsp; &nbsp;94&nbsp;&nbsp; &nbsp;0<br />
95&nbsp;&nbsp; &nbsp;Agile Thoughts Tobias Mayer&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;21&nbsp;&nbsp; &nbsp;1782189&nbsp;&nbsp; &nbsp;80&nbsp;&nbsp; &nbsp;101<br />
96&nbsp;&nbsp; &nbsp;Agile Chronicles (various)&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;2680922&nbsp;&nbsp; &nbsp;131&nbsp;&nbsp; &nbsp;9<br />
97&nbsp;&nbsp; &nbsp;Steve Rowe's Blog Steve Rowe&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;20&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;119&nbsp;&nbsp; &nbsp;20<br />
98&nbsp;&nbsp; &nbsp;Kevin Dente's Blog Kevin Dente&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;22&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;40&nbsp;&nbsp; &nbsp;92<br />
99&nbsp;&nbsp; &nbsp;Agile CMMI Blog Hillel Glazer&nbsp;&nbsp; &nbsp;5&nbsp;&nbsp; &nbsp;8&nbsp;&nbsp; &nbsp;3340384&nbsp;&nbsp; &nbsp;164&nbsp;&nbsp; &nbsp;12<br />
100&nbsp;&nbsp; &nbsp;Andrew Tokeley Andrew Tokeley&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp; &nbsp;28&nbsp;&nbsp; &nbsp;1348226&nbsp;&nbsp; &nbsp;64&nbsp;&nbsp; &nbsp;20<br />
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/290700.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-08-11 18:13 <a href="http://www.blogjava.net/ruoyoux/articles/290700.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/08/06 perl socket script </title><link>http://www.blogjava.net/ruoyoux/articles/290071.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Thu, 06 Aug 2009 04:11:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/290071.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/290071.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/290071.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/290071.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/290071.html</trackback:ping><description><![CDATA[Here is the script in it's<br />
entirety.<br />
It would be taylored to only execute one<br />
command not an open perl script. Better<br />
than having root .rhosts everywhere.<br />
I think where it does the:<br />
<br />
print F $Line;<br />
<br />
at the bottom is where I could put some<br />
kind of execute statement.<br />
Take the string and run it not print it<br />
to a file.<br />
<br />
<br />
<br />
socket.client.perl<br />
#!/usr/bin/perl<br />
#===============================================<br />
# Client -- using object interface<br />
# Support Windows and UNIX<br />
#===============================================<br />
use IO::Socket;<br />
my $sock = new IO::Socket::INET (<br />
PeerAddr =&gt; '128.166.11.13',<br />
PeerPort =&gt; '9999',<br />
Proto =&gt; 'tcp',<br />
);<br />
die "Could not create socket: $!"n" unless $sock;<br />
print $sock "Hi there!"n";<br />
$sock-&gt;send("Hi again!"n");<br />
<br />
close($sock);<br />
<br />
<br />
socket.server.perl<br />
#!/usr/bin/perl<br />
#===============================================<br />
# Server -- using object interface<br />
# Support Windows and UNIX<br />
#===============================================<br />
<br />
#use Proc::Daemon;<br />
use IO::Socket;<br />
#Proc::Daemon::Init();<br />
<br />
use POSIX qw(setsid);<br />
<br />
sub daemonize {<br />
die "Can't fork" unless defined (my $child = fork());<br />
exit 0 if $child;<br />
setsid();<br />
open(STDIN, "&lt;/dev/null");<br />
open(STDOUT, "&gt;/dev/null");<br />
open(STDERR, "&gt;&amp;STDOUT");<br />
chdir '/';<br />
umask(0);<br />
#$ENV{PATH} = '/bin:/sbin:/usr/bin:/usr/sbin';<br />
return $$;<br />
};<br />
<br />
&amp;daemonize;<br />
while() {<br />
my $new_sock = $sock-&gt;accept();<br />
<br />
####################################<br />
# Put a message to file. #<br />
####################################<br />
<br />
while(defined($Line = &lt;$new_sock&gt;)) {<br />
open (F,"+&gt;&gt;/lhome/root/testfile.txt");<br />
print F $Line;<br />
close F;<br />
};<br />
close($sock);<br />
}; #End of while cycle<br />
A. Clay Stephenson Expert in this area This member has accumulated 80000 or more points &nbsp;&nbsp; &nbsp;<br />
May 21, 2004 16:47:45 GMT&nbsp; 10 pts &nbsp;&nbsp; &nbsp;<br />
In that case, $Line has your input so you can use it to execute whatever you like.<br />
<br />
Typically, your client should send a formatted request string of some type. I like to use &lt;tabs&gt; to separate the fields and then your server responds each time it sees a new line of input.<br />
<br />
<br />
<br />
------------------------------------------------------------------------------------------------------<br />
<br />
<span>All I am saying in that any client/server architecture, you must establish some sort of protocol.<br />
<br />
Let's suppose that your server does 4 things:<br />
1) lists files in a dedicated directories<br />
2) removes 1 file<br />
3) add's a line to an existing file<br />
4) kill the server<br />
<br />
Your create client requests that adhere to this, for example, you formant your protocol like this<br />
request_code&lt;tab&gt;string1&lt;tab&gt;string2&lt;LF&gt;<br />
<br />
Now
every line sent to the server expects these 3 arguments -- although
some may simply be dummy args. Tabs are nice because unlike spaces or
colons or commas they are not typically part of strings. Typically the
request_code is something very easy to parse; e.g 1 - list; 2 - remove,
4 - kill,kill,kill<br />
<br />
If you wanrt to see some examples of this
along with a little explanation, go to www.sysadminmag.com and look
under the April '03 issue. I wrote an article that used Perl a Perl
client/server pair to implement multi-host semaphores. Their web page
also has a source code link where you will find the client and server
pieces.<br />
<br />
-----------------------------------------------------------------------------------------------<br />
<br />
</span>For now though. I just wanted something<br />
simple to get around the root .rhosts problem. I was thinking as a security measure<br />
of passing a code to the server.pl but don't<br />
know the perl syntax at this time.<br />
Could you show me the simple syntax for<br />
passing two args.<br />
<br />
e.g.<br />
<br />
From client.pl send:<br />
<br />
1234  shutdown.sh<br />
<br />
On server.pl check code then run command:<br />
<br />
1234 shutdown.sh<br />
<br />
<br />
On my client.perl I currently have:<br />
<br />
print $sock "shutdown.sh"<br />
<br />
On my server.perl I have:<br />
<br />
while(defined($Line = &lt;$new_sock&gt;)) {<br />
system($Line);<br />
close($sock);<br />
};  #End <br />
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/290071.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-08-06 12:11 <a href="http://www.blogjava.net/ruoyoux/articles/290071.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/08/06 use ssh to execute perl script remotely</title><link>http://www.blogjava.net/ruoyoux/articles/290070.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Thu, 06 Aug 2009 04:08:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/290070.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/290070.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/290070.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/290070.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/290070.html</trackback:ping><description><![CDATA[<pre>#!/opt/TLCLperl/bin/perl -w<br />
#!/usr/local/bin/perl -w<br />
<br />
#<br />
# use ssh to execute perl script remotely<br />
#<br />
<br />
# You can change PERL and REMOTE_CMD constants to reflect your real<br />
# environment...<br />
<br />
use constant PERL =&gt; 'perl'; # maybe "/usr/local/bin/perl"<br />
use constant REMOTE_CMD =&gt; 'ssh';<br />
use constant CAT_CMD =&gt; 'cat';<br />
<br />
use strict;<br />
use vars qw($VERSION);<br />
$VERSION = '1.00';<br />
<br />
use constant USAGE =&gt; &lt;&lt;EOU;<br />
<br />
Usage:<br />
<br />
$0 ""<br />
[-v]                                 ""<br />
[-r&lt;remote command flags&gt;]           ""<br />
[-R&lt;remote command&gt;]                 ""<br />
[-Q&lt;perl path&gt;]                      ""<br />
[&lt;usual perl flags&gt;]                 ""<br />
&lt;[&lt;remote user&gt;@]remote_host&gt;[,...]  ""<br />
[&lt;local_script.pl | -e 'perl code'&gt;] ""<br />
[&lt;script args&gt;]<br />
<br />
EOU<br />
<br />
# options for command line parsing<br />
my $verbose; # -v<br />
my @remote_opts; # opts for ssh/remote command<br />
my $remote_cmd; # ssh substitute<br />
my @perl_opts; # opts for remote perl<br />
my $perl_cmd; # remote perl path<br />
<br />
# extract options. This is very simple parsing of options and force<br />
# the args to be precisely ordered.<br />
while(defined $ARGV[0] and $ARGV[0]=~/^-/) {<br />
$_=shift;<br />
if    (/^-v/)     { $verbose=1 }<br />
elsif (/^-r(.*)/) { push @remote_opts,$1 }<br />
elsif (/^-R(.*)/) { $remote_cmd=$1 }<br />
elsif (/^-Q(.*)/) { $perl_cmd=$1 }<br />
else { push @perl_opts,"'$_'" }<br />
}<br />
<br />
# use the default REMOTE_CMD<br />
$remote_cmd||=REMOTE_CMD;<br />
<br />
# read remote machine name:<br />
my $machines=shift or die "error: remote machine not specified"n".USAGE;<br />
my @machines=split(',',$machines);<br />
<br />
# script name... when available:<br />
my $file=shift;<br />
<br />
# get the perl code to run remotely:<br />
my $code;<br />
if(defined $file and $file eq '-e') {<br />
# perl code is in cmd line after the -e switch.<br />
$code=shift or die "error: no perl code after '-e'"n".USAGE;<br />
}<br />
else {<br />
if (defined $file) {<br />
if($file=~/(.+):(.+)/) {<br />
# read perl code from remote file<br />
open(F,"$remote_cmd '$1' ".CAT_CMD." '$2'|")<br />
or die "error: unable to read remote file '$2' from '$1' ($!)"n";<br />
}<br />
else {<br />
# read perl code from file.<br />
open(F,"&lt; $file")<br />
or die "error: unable to open '$file' ($!)"n";<br />
}<br />
}<br />
else { *F=*STDIN } # read perl code from stdin<br />
{<br />
# slurp the file to $code<br />
local $/=undef;<br />
$code=&lt;F&gt;;<br />
}<br />
# gets perl path and flags for first line in src file if available:<br />
if ($code=~/"A"#!(.*)$/m) {<br />
my $line=$1;<br />
if ($line=~/"s*("S+)"s*(.*)/) {<br />
$perl_cmd||=$1;<br />
# anything in the line after the perl path will be considered to<br />
# be flags. I know this could be improved.<br />
push @perl_opts,$2 if defined $2;<br />
}<br />
}<br />
}<br />
<br />
# use the default PERL location if it is yet unknow<br />
$perl_cmd||=PERL;<br />
<br />
# convert code to hex string<br />
my $packed = unpack "h*",$code;<br />
<br />
# this is the remote program to decode and run the script:<br />
my $decoder = q{'BEGIN{eval"sub _R{".(pack"h*",shift)."}"}_R(@ARGV)'};<br />
# There was a simpler decoder but it didn't works with the -n flag so<br />
# I have changed it...<br />
# my $decoder = q{'eval pack"h*",shift'};<br />
<br />
# format script args with "'" between them:.<br />
my $args='';<br />
{<br />
local $"="' '";<br />
$args="'@ARGV'" if @ARGV;<br />
}<br />
<br />
foreach my $machine (@machines) {<br />
# complete ssh cmd. Remote command is escaped.<br />
my $cmd="$remote_cmd @remote_opts $machine ".<br />
quotemeta "$perl_cmd @perl_opts -e $decoder $packed $args";<br />
<br />
# print cmd if verbosity enabled<br />
print STDERR "remote cmd:"n$cmd"n"n" if $verbose;<br />
<br />
# run it and report problems<br />
system($cmd)<br />
and print STDERR "Unable to exec ($!)."nRemote command was:"n$cmd"n"n";<br />
}<br />
<br />
#################################################<br />
# documentation:<br />
<br />
<br />
=head1 NAME<br />
<br />
sperl - runs perl scripts in remote machines through ssh<br />
<br />
<br />
=head1 SCRIPT CATEGORIES<br />
<br />
Networking<br />
UNIX/System_administration<br />
Perl/Utilities<br />
<br />
<br />
=head1 README<br />
<br />
sperl is some kind of enhanced perl that lets you work in a network<br />
environment and run scripts and oneliners in remote machines without<br />
the need to <br />
<br />
<br />
=head1 USAGE<br />
<br />
$ sperl "<br />
[-v]                                                "<br />
[-r&lt;remote command flags&gt;]                          "<br />
[-R&lt;remote command&gt;]                                "<br />
[-Q&lt;perl path&gt;]                                     "<br />
[&lt;usual perl flags&gt;]                                "<br />
&lt;[&lt;remote user&gt;@]remote_host&gt;[,...]                 "<br />
[&lt;[&lt;[&lt;user&gt;@]machine&gt;:]script.pl | -e 'perl code'&gt;] "<br />
[&lt;script args&gt;]<br />
<br />
<br />
=head1 INSTALLATION<br />
<br />
To install sperl, copy it to some place in your path like<br />
/usr/local/bin/sperl and allow execution of it with C&lt;chmod 755<br />
/your/path/to/sperl&gt;.<br />
<br />
If you want, you can edit the script and change the PERL and<br />
REMOTE_CMD constants at the beginning to match your real environment.<br />
<br />
<br />
=head1 DESCRIPTION<br />
<br />
C&lt;sperl&gt; lets you run a locally stored perl script in a remote machine<br />
for which ssh (or equivalent) access is available.<br />
<br />
It doesn't need any special module installed in local or remote<br />
machines, just plain perl.<br />
<br />
If there isn't script name in the command line, neither C&lt;-e&gt; option,<br />
sperl will try to read the code form stdin as perl use to do.<br />
<br />
It's possible to take the script file from another remote machine<br />
with the syntax C&lt;machine:/path/to/script.pl&gt; or even<br />
C&lt;user@machine:/path/to/script.pl&gt;.<br />
<br />
It's also possible to include several remote host names separated by<br />
commas and the script will be run in all of them. For example C&lt;hippo,bugs,bill@www.microsoft.com&gt;<br />
<br />
<br />
=head1 OPTIONS<br />
<br />
C&lt;sperl&gt; accepts the same command line options as C&lt;perl&gt; does. The<br />
options are passed unchanged to the remote perl interpreter so some of<br />
them like C&lt;-S&gt; are nonsense.<br />
<br />
Additionally, it accepts some specific options:<br />
<br />
=over<br />
<br />
=item -rE&lt;lt&gt;remote command flagsE&lt;gt&gt;<br />
<br />
pass options to ssh. For instance C&lt;-r-v&gt;<br />
<br />
=item -RE&lt;lt&gt;remote commandE&lt;gt&gt;<br />
<br />
specify the command to use in place of ssh to connect to the remote<br />
machine. for instance C&lt;-Rrsh&gt;.<br />
<br />
=item -QE&lt;lt&gt;remote perl pathE&lt;gt&gt;<br />
<br />
specify the location of the perl interpreter in the remote<br />
machine. By default, sperl will try to look for the perl path in the<br />
script first line, if it uses the notation C&lt;#!/path/to/perl&gt;. As its<br />
last resource it expects perl to be in the PATH.<br />
<br />
=item -v<br />
<br />
dumps the remote command to stderr before running it. This is primary<br />
for debugging purposes.<br />
<br />
=back<br />
<br />
<br />
=head1 EXAMPLES<br />
<br />
[salvador@hippo:~]$ sperl admin@willy "<br />
&gt; -e 'print "hello from ".`hostname`'<br />
hello from willy<br />
<br />
# the -t option force ssh to allocate a new tty...<br />
[salvador@hippo:~]$ sperl -w -r-t willy -e 'print $count+1,""n"'<br />
Use of uninitialized value at (eval 1) line 1.<br />
1<br />
<br />
# you can even invoke the perl debugger remotely:<br />
[salvador@hippo:~]$ sperl -d -r-t willy -e 1<br />
<br />
Loading DB routines from perl5db.pl version 1.0401<br />
Emacs support available.<br />
<br />
Enter h or `h h' for help.<br />
<br />
main::(-e:1):   BEGIN{eval"sub _R{".(pack"h*",shift)."}"}_R(@ARGV)<br />
DB&lt;1&gt; p `hostname`<br />
p `hostname`<br />
willy<br />
<br />
DB&lt;2&gt; ...<br />
<br />
# running the same code in several machines:<br />
[salvador@hippo:~]$ sperl bugs,willy,hippo -e "<br />
&gt; 'chomp($h=`hostname`);print "hello from $h!!!"n"'<br />
hello from bugs!!!<br />
hello from willy!!!<br />
hello from hippo!!!<br />
<br />
<br />
<br />
=head1 CHANGES<br />
<br />
=over<br />
<br />
=item sperl 1.00     Thu Sep 23 1999<br />
<br />
First public release<br />
<br />
=back<br />
<br />
<br />
=head1 BUGS AND LIMITATIONS<br />
<br />
This is a beta release so expect errors in it.<br />
<br />
Lots of spelling errors in the docs... Help me!!!<br />
<br />
The order of the options in the command line is very inflexible.<br />
<br />
Switch parsing for the first line of the script is not very clever and<br />
it will produce unexpected results if something complex is there.<br />
<br />
Scripts with C&lt;__END__&gt; or C&lt;__DATA__&gt; sections will fail.<br />
<br />
I don't know if there is any possibility to make this to work in<br />
Microsoft's world.<br />
<br />
<br />
=head1 AUTHOR<br />
<br />
Salvador Fandi&#241;o Garc&#237;a &lt;salvador@cesat.es, fandino@usa.net&gt;<br />
<br />
<br />
=head1 SEE ALSO<br />
<br />
L&lt;perl(1)&gt;, L&lt;ssh(1)&gt; or L&lt;rsh(1)&gt;, L&lt;perlrun(1)&gt;.<br />
<br />
<br />
=cut <br />
</pre>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/290070.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-08-06 12:08 <a href="http://www.blogjava.net/ruoyoux/articles/290070.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/08/06 How to execute a perl script at remote server [My problem]</title><link>http://www.blogjava.net/ruoyoux/articles/290069.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Thu, 06 Aug 2009 04:06:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/290069.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/290069.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/290069.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/290069.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/290069.html</trackback:ping><description><![CDATA[Hi All,<br />
&nbsp; &nbsp;<br />
&nbsp;&nbsp;&nbsp; I have written a Perl script, which deals with the ftp ing<br />
(transferring) the file to remote server and executing a Perl script<br />
(AUT) at remote m/c.<br />
<br />
The script is as below and here I have 2 doubts, so please help me to<br />
resolve this.<br />
1) I am getting the message like "could not transfer the file to<br />
server" but it is ftp ing the flie to remote m/c, and I can see that<br />
file ( root1.txt ) there.<br />
<br />
2) And I want to run the perl script (AUT) at remote m/c depending<br />
on the data we sent, so could you please let me know how can I achieve<br />
this.<br />
<br />
Is it possible for me to do system("test.pl"),&nbsp; If I am at SFTP mode.<br />
Please see comment line in the code below.<br />
<br />
<br />
<br />
#!/usr/bin/perl -w<br />
<br />
use strict;<br />
use warnings;<br />
use Net::SFTP;<br />
<br />
my $server="A.BY.C.D";<br />
my $user="roserag";<br />
my $password="june@123";<br />
my %args = (user =&gt; "$user", password =&gt; "$password", ssh_args =&gt; []);<br />
$args{debug} = 1;<br />
$args{user} = "root";<br />
my $file="local.txt";<br />
my $rfile = "root1.txt";<br />
<br />
my $sftp=Net::SFTP-&gt;new($server, %args) or die "could not open<br />
connection to $server"n";<br />
$sftp-&gt;put($file,$rfile) or die " could not transfer the file to server<br />
"n";<br />
<br />
<br />
# system("test.pl");&nbsp;&nbsp;&nbsp; Is this command work out.<br />
<br />
exit;<br />
<br />
<br />
[gaurav@testbrix Examples]$ perl sftp3.pl<br />
testbrix.wipro.com: Reading configuration data /home/gaurav/.ssh/config<br />
testbrix.wipro.com: Reading configuration data /etc/ssh_config<br />
...................................<br />
...................................<br />
testbrix.wipro.com: sftp: In write loop, got 510 offset 0<br />
testbrix.wipro.com: sftp: Sent message T:10 I:2<br />
testbrix.wipro.com: sftp: Sent message T:4 I:3<br />
could not transfer the file to server<br />
<br />
But I can see the file the file at server.<br />
<br />
<br />
Regards,<br />
XXX<br />
<br />
<br />
Please do not print this email unless it is absolutely necessary. <br />
The information contained in this electronic message and any attachments to this message are intended for the exclusive use of the addressee(s) and may contain proprietary, confidential or privileged information. If you are not the intended recipient, you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately and destroy all copies of this message and any attachments. <br />
WARNING: Computer viruses can be transmitted via email. The recipient should check this email and any attachments for the presence of viruses. The company accepts no liability for any damage caused by any virus transmitted by this email. <br />
<br />
www.wipro.com<br />
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/290069.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-08-06 12:06 <a href="http://www.blogjava.net/ruoyoux/articles/290069.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/07/31 Create Glassfish Cluster in Windowns</title><link>http://www.blogjava.net/ruoyoux/articles/289240.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Fri, 31 Jul 2009 03:55:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/289240.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/289240.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/289240.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/289240.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/289240.html</trackback:ping><description><![CDATA[[mdrop@deployment1-1 newDeploy]$ cat config-new-environment.bat <br />
@echo off<br />
<br />
set DOMAIN=domain1<br />
set CLUSTER=server<br />
<br />
<br />
set MASTERIP=127.0.0.1<br />
set NODE1=agent1<br />
<br />
set INSTANCE1=ps1<br />
set NODE2=agent2<br />
set INSTANCE2=ps2<br />
<br />
if "%1" == "" goto :ERROR<br />
<br />
if "%2" == "" goto :ERROR<br />
<br />
call %1"bin"asadmin stop-domain domain1<br />
<br />
xcopy classes"*.* /s %1"domains"domain1"lib"classes<br />
copy mysql-connector-java-5.1.5-bin.jar %1"domains"domain1"lib"ext<br />
<br />
call %1"bin"asadmin start-domain domain1<br />
<br />
call %1"bin"asadmin set server.java-config.classpath-suffix=%1"domains"domain1"lib"ext"mysql-connector-java-5.1.5-bin.jar<br />
call %1"bin"asadmin set server.java-config.classpath-suffix=${com.sun.aas.instanceRoot}/lib/classes<br />
call %1"bin"asadmin set server.system-property.com_outblaze_config_cobrand="C:"config"<br />
<br />
call %1"bin"asadmin create-auth-realm --classname com.outblaze.glassfish.security.OBAppservRealm --property auth-type=obRealm:jaas-context=obRealm --target server obRealm<br />
<br />
echo obRealm {com.outblaze.glassfish.security.OBPasswordLoginModule required;}; &gt;&gt; %1"domains"domain1"config"login.conf<br />
<br />
<br />
<br />
call %1"bin"asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource --isolationlevel read-committed --isisolationguaranteed --property User=root:Password=123:URL=jdbc":mysql"://localhost/pointsystem_sd --target server mysqlPool<br />
<br />
call %1"bin"asadmin create-jdbc-resource --connectionpoolid mysqlPool --target server jndi/cobrandpsDS<br />
<br />
call %1"bin"asadmin delete-jdbc-connection-pool --cascade=true --target server mysqlPoolOffline<br />
<br />
call %1"bin"asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource --isolationlevel read-committed --isisolationguaranteed --property User=root:Password=123:URL=jdbc":mysql"://localhost/pointsystem_off --target server mysqlPoolOffline<br />
<br />
call %1"bin"asadmin create-jdbc-resource --connectionpoolid mysqlPoolOffline --target server jndi/cobrandpsDS_of<br />
<br />
call %1"bin"asadmin delete-jdbc-connection-pool --cascade=true --target server mysqlPoolLog<br />
<br />
call %1"bin"asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource --isolationlevel read-committed --isisolationguaranteed --property User=root:Password=123:URL=jdbc":mysql"://localhost/wslog_stats_db --target server mysqlPoolLog<br />
<br />
call %1"bin"asadmin create-jdbc-resource --connectionpoolid mysqlPoolLog --target server jndi/cobrandpsDS_log<br />
<br />
call %1"bin"asadmin delete-jdbc-connection-pool --cascade=true --target server itemmallsqlPool<br />
<br />
call %1"bin"asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource --isolationlevel read-committed --isisolationguaranteed --property User=root:Password=123:URL="jdbc":mysql"://localhost/obcart" --target server itemmallsqlPool<br />
<br />
call %1"bin"asadmin create-jdbc-resource --connectionpoolid itemmallsqlPool --target server jndi/itemmallDS<br />
<br />
call %1"bin"asadmin delete-jdbc-connection-pool --cascade=true --target server mysqlPoolpsClusterTimer<br />
call %1"bin"asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource --isolationlevel read-committed --isisolationguaranteed --property User=root:Password=123:URL="jdbc":mysql"://localhost/glassfishtimer" --target server mysqlPoolpsClusterTimer<br />
call %1"bin"asadmin create-jdbc-resource --connectionpoolid mysqlPoolpsClusterTimer --target server jndi/ps_cluster_timer<br />
call %1"bin"asadmin set --user admin --port 4848 server-config.ejb-container.ejb-timer-service.timer-datasource=jndi/ps_cluster_timer<br />
<br />
<br />
echo prepare for MQ<br />
echo =============================================================================<br />
call %1"bin"asadmin delete-jmsdest&nbsp; --desttype queue --target server ActiveMqQueue<br />
call %1"bin"asadmin delete-admin-object --target server jms/ActiveMqQueue<br />
call %1"bin"asadmin delete-connector-resource --target server jms/ActiveMQConnectionFactory<br />
call %1"bin"asadmin delete-connector-connection-pool --target server jms/ActiveMQpool<br />
call %1"bin"asadmin undeploy --target server activemq-rar-5.1.0<br />
echo finished prepare for MQ<br />
echo =============================================================================<br />
<br />
echo start config for MQ<br />
echo --------------------------------------------------------------------------------<br />
XCOPY activeMQ_config"bin"*.* %2"bin" /k /y /z<br />
XCOPY activeMQ_config"conf"*.* %2"conf /k /y /z<br />
XCOPY activeMQ_config"webapps"admin"*.* %2"webapps"admin" /k /y /z<br />
XCOPY activeMQ_config"webapps"admin"decorators"*.* %2"webapps"admin"decorators" /k /y /z<br />
XCOPY activeMQ_config"webapps"admin"WEB-INF"*.* %2"webapps"admin"WEB-INF" /k /y /z<br />
<br />
<br />
call %1"bin"asadmin deploy --user admin --host localhost --port 4848 --target server activemq-rar-5.1.0.rar<br />
echo finished deploying activemq-rar-5.1.0.rar<br />
<br />
call %1"bin"asadmin create-admin-object --raname activemq-rar-5.1.0 --restype javax.jms.Queue --property DestinationJndiName=ActiveMqQueue --target server jms/ActiveMqQueue<br />
echo finished create admin object jms/ActiveMqQueue<br />
<br />
call %1"bin"asadmin create-jmsdest --desttype queue --target server ActiveMqQueue<br />
echo finished create jmsdest ActiveMqQueue<br />
<br />
call %1"bin"asadmin create-connector-connection-pool --raname activemq-rar-5.1.0 --connectiondefinition javax.jms.ConnectionFactory --transactionsupport&nbsp; XATransaction --target server jms/ActiveMQpool<br />
echo finished create connector connection pool jms/ActiveMQpool<br />
<br />
call %1"bin"asadmin create-connector-resource --poolname jms/ActiveMQpool --target server jms/ActiveMQConnectionFactory<br />
echo finished create connector resource jms/ActiveMQConnectionFactory<br />
<br />
echo MQ Setup complete<br />
echo --------------------------------------------------------------------------------<br />
<br />
echo Shutting down Glassfish<br />
call %1"bin"asadmin stop-domain domain1<br />
<br />
echo Setup complete<br />
goto :END<br />
<br />
<br />
:ERROR<br />
echo Please set glassfish base path and activeMQ path.<br />
echo e.g. config-new-glassfish c:"glassfish c:"apache-activemq-5.1.0-bin<br />
<br />
:END
<img src ="http://www.blogjava.net/ruoyoux/aggbug/289240.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-07-31 11:55 <a href="http://www.blogjava.net/ruoyoux/articles/289240.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/07/31 Set Up Glassfish Cluster &amp; Config Sql Connection in Linux</title><link>http://www.blogjava.net/ruoyoux/articles/289239.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Fri, 31 Jul 2009 03:53:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/289239.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/289239.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/289239.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/289239.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/289239.html</trackback:ping><description><![CDATA[[mdrop@deployment1-1 newDeploy]$ cat setup_gf.sh <br />
#!/bin/bash<br />
<br />
# Do not edit below , please supply variable in command line<br />
ACTION=$1<br />
COBRAND=$2<br />
GLASS_FISH=$3<br />
DOMAIN=domain1<br />
MASTERIP=$4<br />
ACTIVEMQ=$5<br />
INSTANCE_NO=$6<br />
JDBC_USER=$7<br />
JDBC_PASSWORD=$8<br />
JDBC_HOST=$9<br />
<br />
<br />
<br />
CLUSTER=ps-$COBRAND-cluster<br />
NODE=ps-$COBRAND-node-$INSTANCE_NO<br />
INSTANCE=ps-$COBRAND-instance-$INSTANCE_NO<br />
<br />
<br />
function common () {<br />
<br />
<br />
#those two command should be executed in master and slave machine<br />
cp mysql-connector-java-5.1.5-bin.jar $GLASS_FISH/lib<br />
cp obrealm.jar&nbsp; $GLASS_FISH/lib<br />
cp -rf activeMQ_config/*&nbsp; $ACTIVEMQ/<br />
<br />
if [ $ACTION = "master" ]; then<br />
$GLASS_FISH/bin/asadmin stop-domain $DOMAIN<br />
$GLASS_FISH/bin/asadmin start-domain $DOMAIN<br />
fi<br />
<br />
#run those following lines to stop cluster and node in the master machine<br />
if [ $ACTION = "master" ]; then<br />
$GLASS_FISH/bin/asadmin stop-cluster --user admin --host&nbsp; $MASTERIP&nbsp; --port 4848 $CLUSTER<br />
fi<br />
$GLASS_FISH/bin/asadmin stop-node-agent $NODE<br />
<br />
#run those following lines to delete node, cluster and instance in the master machine<br />
$GLASS_FISH/bin/asadmin delete-node-agent&nbsp; $NODE<br />
if [ $ACTION = "master" ]; then<br />
$GLASS_FISH/bin/asadmin delete-cluster&nbsp; $CLUSTER<br />
fi<br />
$GLASS_FISH/bin/asadmin delete-instance&nbsp; $INSTANCE<br />
<br />
<br />
#run those following lines to create node, cluster and instance in the master machine<br />
$GLASS_FISH/bin/asadmin create-node-agent --host $MASTERIP --port 4848 $NODE<br />
if [ $ACTION = "master" ]; then<br />
$GLASS_FISH/bin/asadmin create-cluster --host $MASTERIP --port 4848 $CLUSTER<br />
fi<br />
$GLASS_FISH/bin/asadmin create-instance --host $MASTERIP --port 4848 --nodeagent $NODE --cluster $CLUSTER $INSTANCE<br />
<br />
<br />
<br />
#run those following lines to start node, cluster and instance in the master machine<br />
#bin/asadmin start-node-agent --syncinstances=true $NODE<br />
#bin/asadmin start-cluster --user admin --host $MASTERIP --port 4848 $CLUSTER<br />
#bin/asadmin start-instance --user admin --host $MASTERIP --port 4848 $INSTANCE<br />
<br />
}<br />
<br />
function master () {<br />
<br />
#cp -r classes/* $GLASS_FISH/domains/$DOMAIN/lib/classes/<br />
<br />
cp&nbsp; activemq-rar-5.1.0.rar&nbsp; $GLASS_FISH/<br />
<br />
#those two command should be executed in master and slave machine<br />
cp mysql-connector-java-5.1.5-bin.jar $GLASS_FISH/lib<br />
cp obrealm.jar&nbsp; $GLASS_FISH/lib<br />
<br />
$GLASS_FISH/bin/asadmin stop-domain $DOMAIN<br />
$GLASS_FISH/bin/asadmin start-domain $DOMAIN<br />
<br />
<br />
<br />
$GLASS_FISH/bin/asadmin set $CLUSTER.java-config.classpath-suffix='${com.sun.aas.installRoot}/lib/mysql-connector-java-5.1.5-bin.jar'<br />
$GLASS_FISH/bin/asadmin set $CLUSTER.java-config.classpath-suffix='${com.sun.aas.installRoot}/lib/obrealm.jar'<br />
mkdir -p /usr/local/site/webroot/template/pointsystem/<br />
$GLASS_FISH/bin/asadmin set $CLUSTER.system-property.com_outblaze_config_cobrand='/usr/local/site/webroot/template/pointsystem/'<br />
$GLASS_FISH/bin/asadmin create-auth-realm --classname com.outblaze.glassfish.security.OBAppservRealm --property auth-type=obRealm:jaas-context=obRealm --target $CLUSTER obRealm<br />
<br />
echo "obRealm {com.outblaze.glassfish.security.OBPasswordLoginModule required;};" &gt;&gt; $GLASS_FISH/domains/$DOMAIN/config/login.conf<br />
<br />
$GLASS_FISH/bin/asadmin&nbsp; set $CLUSTER.http-service.virtual-server.server.property.accessLoggingEnabled=true<br />
echo "finished setting the access log "<br />
<br />
$GLASS_FISH/bin/asadmin delete-jdbc-connection-pool --cascade=true --target $CLUSTER mysqlPool<br />
$GLASS_FISH/bin/asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource --isolationlevel read-committed --isisolationguaranteed --property User=$JDBC_USER:Password=$JDBC_PASSWORD:URL="jdbc":mysql"://$JDBC_HOST/pointsystem_sd" --target $CLUSTER mysqlPool<br />
$GLASS_FISH/bin/asadmin create-jdbc-resource --connectionpoolid mysqlPool --target $CLUSTER jndi/cobrandpsDS<br />
$GLASS_FISH/bin/asadmin delete-jdbc-connection-pool --cascade=true --target $CLUSTER mysqlPoolOffline<br />
$GLASS_FISH/bin/asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource --isolationlevel read-committed --isisolationguaranteed --property User=$JDBC_USER:Password=$JDBC_PASSWORD:URL="jdbc":mysql"://$JDBC_HOST/pointsystem_off" --target $CLUSTER mysqlPoolOffline<br />
$GLASS_FISH/bin/asadmin create-jdbc-resource --connectionpoolid mysqlPoolOffline --target $CLUSTER jndi/cobrandpsDS_of<br />
$GLASS_FISH/bin/asadmin delete-jdbc-connection-pool --cascade=true --target $CLUSTER mysqlPoolLog<br />
$GLASS_FISH/bin/asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource --isolationlevel read-committed --isisolationguaranteed --property User=$JDBC_USER:Password=$JDBC_PASSWORD:URL="jdbc":mysql"://$JDBC_HOST/wslog_stats_db" --target $CLUSTER mysqlPoolLog<br />
$GLASS_FISH/bin/asadmin create-jdbc-resource --connectionpoolid mysqlPoolLog --target $CLUSTER jndi/cobrandpsDS_log<br />
$GLASS_FISH/bin/asadmin delete-jdbc-connection-pool --cascade=true --target $CLUSTER itemmallsqlPool<br />
$GLASS_FISH/bin/asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource --isolationlevel read-committed --isisolationguaranteed --property User=$JDBC_USER:Password=$JDBC_PASSWORD:URL="jdbc":mysql"://$JDBC_HOST/obcart" --target $CLUSTER itemmallsqlPool<br />
$GLASS_FISH/bin/asadmin create-jdbc-resource --connectionpoolid itemmallsqlPool --target $CLUSTER jndi/itemmallDS<br />
<br />
$GLASS_FISH/bin/asadmin delete-jdbc-connection-pool --cascade=true --target $CLUSTER mysqlPoolpsClusterTimer<br />
$GLASS_FISH/bin/asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource --isolationlevel read-committed --isisolationguaranteed --property User=$JDBC_USER:Password=$JDBC_PASSWORD:URL="jdbc":mysql"://$JDBC_HOST/glassfishtimer" --target $CLUSTER mysqlPoolpsClusterTimer<br />
$GLASS_FISH/bin/asadmin create-jdbc-resource --connectionpoolid mysqlPoolpsClusterTimer --target $CLUSTER jndi/ps_cluster_timer<br />
<br />
$GLASS_FISH/bin/asadmin delete-jdbc-connection-pool --cascade=true --target $CLUSTER reportPool<br />
$GLASS_FISH/bin/asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource --isolationlevel read-committed --isisolationguaranteed --property User=$JDBC_USER:Password=$JDBC_PASSWORD:URL="jdbc":mysql"://$JDBC_HOST/pointsystem_sd" --target $CLUSTER reportPool<br />
$GLASS_FISH/bin/asadmin create-jdbc-resource --connectionpoolid reportPool --target $CLUSTER jndi/reportDS<br />
<br />
$GLASS_FISH/bin/asadmin set $CLUSTER-config.ejb-container.ejb-timer-service.timer-datasource=jndi/ps_cluster_timer<br />
<br />
#$GLASS_FISH/bin/asadmin create-jvm-options --target $CLUSTER -Dcom.sun.enterprise.web.connector.enableJK=8012<br />
#$GLASS_FISH/bin/asadmin create-jvm-options --target $CLUSTER -DjvmRoute=glassfish1<br />
#$GLASS_FISH/bin/asadmin create-jvm-options --target $CLUSTER -DjvmRoute=glassfish2<br />
#$GLASS_FISH/bin/asadmin set $CLUSTER.java-config.classpath-prefix='${com.sun.aas.installRoot}/lib/patch.jar'<br />
#$GLASS_FISH/bin/asadmin set $CLUSTER.java-config.system-classpath='${com.sun.aas.installRoot}/lib/tomcat-ajp.jar,${com.sun.aas.installRoot}/lib/commons-modeler.jar,${com.sun.aas.installRoot}/lib/commons-logging.jar'<br />
<br />
<br />
}<br />
<br />
function setupmq () {<br />
<br />
<br />
echo "Prepare for MQ"<br />
echo "============================================================================="<br />
$GLASS_FISH/bin/asadmin delete-jmsdest&nbsp; --desttype queue --target $CLUSTER ActiveMqQueue<br />
$GLASS_FISH/bin/asadmin delete-admin-object --target $CLUSTER jms/ActiveMqQueue<br />
$GLASS_FISH/bin/asadmin delete-connector-resource --target $CLUSTER jms/ActiveMQConnectionFactory<br />
$GLASS_FISH/bin/asadmin delete-connector-connection-pool --target $CLUSTER jms/ActiveMQpool<br />
$GLASS_FISH/bin/asadmin undeploy --target $CLUSTER activemq-rar-5.1.0<br />
echo "finished prepare for MQ"<br />
echo "============================================================================="<br />
<br />
<br />
echo "Start config for MQ"<br />
echo "--------------------------------------------------------------------------------"<br />
$GLASS_FISH/bin/asadmin deploy --target $CLUSTER activemq-rar-5.1.0.rar<br />
echo "finished deploying activemq-rar-5.1.0.rar"<br />
<br />
$GLASS_FISH/bin/asadmin create-admin-object --raname activemq-rar-5.1.0 --restype javax.jms.Queue --property DestinationJndiName=ActiveMqQueue --target $CLUSTER jms/ActiveMqQueue<br />
echo "finished create admin object jms/ActiveMqQueue"<br />
<br />
$GLASS_FISH/bin/asadmin create-jmsdest --desttype queue --target $CLUSTER ActiveMqQueue<br />
echo "finished create jmsdest ActiveMqQueue"<br />
<br />
$GLASS_FISH/bin/asadmin create-connector-connection-pool --raname activemq-rar-5.1.0 --connectiondefinition javax.jms.ConnectionFactory --transactionsupport&nbsp; XATransaction --target $CLUSTER jms/ActiveMQpool<br />
echo "finished create connector connection pool jms/ActiveMQpool"<br />
<br />
$GLASS_FISH/bin/asadmin create-connector-resource --poolname jms/ActiveMQpool --target $CLUSTER jms/ActiveMQConnectionFactory<br />
echo "finished create connector resource jms/ActiveMQConnectionFactory"<br />
<br />
echo "MQ Setup complete"<br />
echo "--------------------------------------------------------------------------------"<br />
<br />
<br />
}<br />
<br />
if [ $# != 9 ]; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo $"Usage: $prog {master|slave cobrand_name glassfish_path DAS_hostname ActiveMQ_path instance_no mysql_username mysql_password mysql_host}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit 1<br />
fi<br />
<br />
case "$1" in<br />
&nbsp; master)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; common<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; master<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setupmq<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; slave)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; common<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; *)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo $"Usage: $prog {master|slave cobrand_name glassfish_path DAS_hostname ActiveMQ_path instance_no mysql_username mysql_password mysql_host}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit 1<br />
esac<br />
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/289239.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-07-31 11:53 <a href="http://www.blogjava.net/ruoyoux/articles/289239.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/07/29 insert-mysql-statement</title><link>http://www.blogjava.net/ruoyoux/articles/288844.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Wed, 29 Jul 2009 02:13:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/288844.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/288844.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/288844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/288844.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/288844.html</trackback:ping><description><![CDATA[[mdrop@authbackup5 jojo]$ cat insert_sql_statement.sql<br />
<br />
#!/usr/bin/perl -w<br />
<br />
#<br />
# Created by: JoJo<br />
# Created Date: 28 July 2009<br />
# Desc: To create the sql statement for Sanriotown Digital<br />
#<br />
<br />
use DateTime;<br />
use DBI;<br />
<br />
<br />
#open log file for writing, append purpose<br />
open(MYLOGFILE, "&gt;&gt; mylog");<br />
<br />
<br />
######### Step 1: Create DB Connection&nbsp; ################################<br />
#definition of variables<br />
$db="UserDB";<br />
$host="localhost";<br />
$socket="/var/lib/auth5-1.us4/mysql1/mysql.sock";<br />
$user="root";<br />
$password="pwd";<br />
<br />
<br />
#connect to MySQL database<br />
my $dbh&nbsp;&nbsp; = DBI-&gt;connect ("DBI:mysql::mysql_socket=$socket;database=$db:host=$host",$user,$password)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or die "Can't connect to database: $DBI::errstr"n";<br />
<br />
<br />
<br />
######### Step 2: Get Active User ################################<br />
<br />
# Get date<br />
my $sdt = DateTime-&gt;now;<br />
# Get active user ( from userdb, usertype != 8)<br />
print MYLOGFILE "Get all active users from cobranddb.sanriotown_com_userdb tables at&nbsp; $sdt."n";<br />
#!`echo 'select username from cobranddb.sanriotown_com_userdb where usertype&nbsp; &amp;8 &lt;&gt; 8 '|mysql -uroot -ppwd --socket=/var/lib/auth5-1.us4/mysql/mysql.sock --skip-column-names &gt;&nbsp; activeuser.txt` || die print "Cannot connect to cobranddb database."n";<br />
# Get date<br />
my $edt = DateTime-&gt;now;<br />
print MYLOGFILE "Finish grep all active users from cobranddb.sanriotown_com_userdb tables at&nbsp; $edt."n";<br />
<br />
<br />
<br />
<br />
######### Step 3: Get Active UserID and Field Value, then Create Insert Statement File#############<br />
<br />
# Open active user file for reading<br />
open (USERFILE, 'activeuser.txt');<br />
# Get date<br />
my $s1dt = DateTime-&gt;now;<br />
# Get active userid and its field value for "country" filedname whose cobrand is "sanriotown.com"<br />
print MYLOGFILE "Get active userid and its field value for 'country' filedname whose cobrand is 'sanriotown.com' from UserDB.UserProfileTbl and UserDB.UserTbl tables at&nbsp; $s1dt."n";<br />
while (&lt;USERFILE&gt;) {<br />
&nbsp; chomp;<br />
&nbsp; #prepare the query<br />
&nbsp; my $sql = "select&nbsp; u.userid, p.fieldvalue from UserDB.UserProfileTbl p, UserDB.UserTbl u where u.cobrand='sanriotown.com' and u.username='$_' and u.userid=p.userid and p.fieldname='country' ";<br />
&nbsp; my $sth = $dbh-&gt;prepare( $sql);<br />
&nbsp; #execute the query<br />
&nbsp; $sth-&gt;execute( );<br />
<br />
&nbsp; ## Retrieve the results of a row of data and print<br />
&nbsp; my ( $userid,$fieldvalue);<br />
&nbsp; $sth-&gt;bind_columns ( undef,"$userid,"$fieldvalue );<br />
&nbsp; while ( $sth-&gt;fetch( ) )&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #print MYLOGFILE&nbsp; "Userid is $userid and the fieldvalue is $fieldvalue"n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; `echo "insert UserDB.UserProfileTbl values($userid,'orignal_country', '$fieldvalue');" &gt;&gt; insert_sql_statement.sql`;<br />
&nbsp; }<br />
<br />
&nbsp; $sth-&gt;finish( );<br />
}<br />
# Get date<br />
my $e1dt = DateTime-&gt;now;<br />
print MYLOGFILE "Finish grep active userid and its field value for 'country' filedname whose cobrand is 'sanriotown.com' from UserDB.UserProfileTbl and UserDB.UserTbl tables at&nbsp; $e1dt."n";<br />
<br />
<br />
######### Step 4: Close All File and DB Connection#############<br />
<br />
# Close all opened file <br />
close (USERFILE); <br />
close (MYLOGFILE); <br />
$dbh-&gt;disconnect( );<br />
exit;<br />
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/288844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-07-29 10:13 <a href="http://www.blogjava.net/ruoyoux/articles/288844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/07/21 squid script for supervise purpose</title><link>http://www.blogjava.net/ruoyoux/articles/287651.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Tue, 21 Jul 2009 06:45:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/287651.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/287651.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/287651.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/287651.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/287651.html</trackback:ping><description><![CDATA[<ol>
    <li value="5"> Create directory <strong>squid</strong> under <strong>/service/</strong> to let <strong>supervise</strong> start <strong>Squid</strong> automatically
    <ul>
        <li> Cmd: <em>mkdir -p /service/squid</em>
        </li>
    </ul>
    </li>
    <li> Create a <strong>run</strong> file in <strong>/service/squid</strong> with the following content
    <ul>
        <li> <strong>/service/squid/run</strong>
        <pre>#!/bin/sh<br />
        if (test `ps -e | grep -c squid` = 0)<br />
        then<br />
        {<br />
        echo "no squid is running, clean up pid file";<br />
        rm -f /usr/local/site/squid/logs/squid.pid<br />
        }<br />
        fi<br />
        exec /usr/local/site/squid/bin/squid -N<br />
        </pre>
        </li>
    </ul>
    </li>
    <li> Change the permission to <strong>755</strong>, so <strong>supervise</strong> can run it automatically <dl><dt> Cmd</dt><dd> <em>chmod 755 /service/squid/run</em>
    </dd></dl>
    <ul>
        <li> Note: You can verify if a service is started by <strong>supervise</strong> correctly by typing the following command.
        <ul>
            <li> Cmd: <em>svstat /service/*</em>
            </li>
        </ul>
        </li>
        <li> Note: <strong>Squid</strong> cannot start until you fill <strong>/usr/local/site/webroot/errordoc/squid/</strong> with corresponding content later.
        </li>
        <li> Note: If <strong>Squid</strong> appears to restart and fail
        in one second over and over again by itself, check the owner of the
        folder /usr/local/site/squid/var/cache/ is mdrop:mdrop. And don't
        forget to create the swap folder for Squid. (Squid -z option)
        </li>
    </ul>
    </li>
</ol>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/287651.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-07-21 14:45 <a href="http://www.blogjava.net/ruoyoux/articles/287651.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/07/17 mysql init script</title><link>http://www.blogjava.net/ruoyoux/articles/287087.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Fri, 17 Jul 2009 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/287087.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/287087.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/287087.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/287087.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/287087.html</trackback:ping><description><![CDATA[[mdrop@jojo1-1 init.d]$ cat mysqld.jojo1-1.us1.master.3306 <br />
#!/bin/bash<br />
#<br />
# mysqld&nbsp;&nbsp; &nbsp;This shell script takes care of starting and stopping<br />
#&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;the MySQL subsystem (mysqld).<br />
#<br />
# chkconfig: - 64 36<br />
# description:&nbsp;&nbsp; &nbsp;MySQL database server.<br />
# processname: mysqld<br />
# config: /etc/my.cnf.jojo1-1.us1.master.3306<br />
# pidfile: /var/run/mysqld-$MYSQLD_SUFFIX/mysqld.pid<br />
<br />
# Source function library.<br />
. /etc/rc.d/init.d/functions<br />
<br />
# Source networking configuration.<br />
. /etc/sysconfig/network<br />
<br />
MYSQLD_SUFFIX="jojo1-1.us1.master.3306"<br />
MYCNF="/etc/my.cnf.$MYSQLD_SUFFIX"<br />
<br />
prog="MySQL"<br />
<br />
# extract value of a MySQL option from config files<br />
# Usage: get_mysql_option SECTION VARNAME DEFAULT<br />
# result is returned in $result<br />
# We use my_print_defaults which prints all options from multiple files,<br />
# with the more specific ones later; hence take the last match.<br />
get_mysql_option(){<br />
&nbsp;&nbsp; &nbsp;#result=`/usr/bin/my_print_defaults "$1" | sed -n "s/^--$2=//p" | tail -n 1`<br />
&nbsp;&nbsp; &nbsp;#if [ -z "$result" ]; then<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; # not found, use default<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; #result="$3"<br />
&nbsp;&nbsp; &nbsp;#fi<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result="$3"<br />
}<br />
<br />
get_mysql_option mysqld datadir "/var/lib/mysql"<br />
datadir="$result"<br />
get_mysql_option mysqld socket "$datadir/mysql.sock"<br />
socketfile="$result"<br />
get_mysql_option mysqld_safe log-error "/var/log/mysqld-$MYSQLD_SUFFIX.log"<br />
errlogfile="$result"<br />
get_mysql_option mysqld_safe pid-file "/var/run/mysqld-$MYSQLD_SUFFIX/mysqld.pid"<br />
mypidfile="$result"<br />
<br />
<br />
start(){<br />
&nbsp;&nbsp; &nbsp;touch "$errlogfile"<br />
&nbsp;&nbsp; &nbsp;chown mysql:mysql "$errlogfile" <br />
&nbsp;&nbsp; &nbsp;chmod 0640 "$errlogfile"<br />
&nbsp;&nbsp; &nbsp;[ -x /sbin/restorecon ] &amp;&amp; /sbin/restorecon "$errlogfile"<br />
&nbsp;&nbsp; &nbsp;if [ ! -d "$datadir/mysql" ] ; then<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; action $"Initializing MySQL database: " /usr/bin/mysql_install_db<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; ret=$?<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; chown -R mysql:mysql "$datadir"<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; if [ $ret -ne 0 ] ; then<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return $ret<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp; &nbsp;fi<br />
&nbsp;&nbsp; &nbsp;chown mysql:mysql "$datadir"<br />
&nbsp;&nbsp; &nbsp;chmod 0755 "$datadir"<br />
&nbsp;&nbsp; &nbsp;# Pass all the options determined above, to ensure consistent behavior.<br />
&nbsp;&nbsp; &nbsp;# In many cases mysqld_safe would arrive at the same conclusions anyway<br />
&nbsp;&nbsp; &nbsp;# but we need to be sure.<br />
&nbsp;&nbsp; &nbsp;/usr/bin/mysqld_safe&nbsp; --defaults-file=$MYCNF&nbsp; --datadir="$datadir" --socket="$socketfile" "<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;--log-error="$errlogfile" --pid-file="$mypidfile" "<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&gt;/dev/null 2&gt;&amp;1 &amp;<br />
&nbsp;&nbsp; &nbsp;ret=$?<br />
&nbsp;&nbsp; &nbsp;# Spin for a maximum of N seconds waiting for the server to come up.<br />
&nbsp;&nbsp; &nbsp;# Rather than assuming we know a valid username, accept an "access<br />
&nbsp;&nbsp; &nbsp;# denied" response as meaning the server is functioning.<br />
&nbsp;&nbsp; &nbsp;if [ $ret -eq 0 ]; then<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; STARTTIMEOUT=30<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; while [ $STARTTIMEOUT -gt 0 ]; do<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;RESPONSE=`/usr/bin/mysqladmin -uUNKNOWN_MYSQL_USER ping 2&gt;&amp;1` &amp;&amp; break<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;echo "$RESPONSE" | grep -q "Access denied for user" &amp;&amp; break<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;sleep 1<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;let STARTTIMEOUT=${STARTTIMEOUT}-1<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; done<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; if [ $STARTTIMEOUT -eq 0 ]; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "Timeout error occurred trying to start MySQL Daemon."<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Starting $prog: " /bin/false<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret=1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Starting $prog: " /bin/true<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp; &nbsp;else<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; action $"Starting $prog: " /bin/false<br />
&nbsp;&nbsp; &nbsp;fi<br />
&nbsp;&nbsp; &nbsp;[ $ret -eq 0 ] &amp;&amp; touch /var/lock/subsys/mysqld.$MYSQLD_SUFFIX<br />
&nbsp;&nbsp; &nbsp;return $ret<br />
}<br />
<br />
stop(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MYSQLPID=`cat "$mypidfile"&nbsp; 2&gt;/dev/null `<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [ -n "$MYSQLPID" ]; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /bin/kill "$MYSQLPID" &gt;/dev/null 2&gt;&amp;1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret=$?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [ $ret -eq 0 ]; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STOPTIMEOUT=60<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while [ $STOPTIMEOUT -gt 0 ]; do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /bin/kill -0 "$MYSQLPID" &gt;/dev/null 2&gt;&amp;1 || break<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let STOPTIMEOUT=${STOPTIMEOUT}-1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [ $STOPTIMEOUT -eq 0 ]; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "Timeout error occurred trying to stop MySQL Daemon."<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret=1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Stopping $prog: " /bin/false<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rm -f /var/lock/subsys/mysqld.$MYSQLD_SUFFIX<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rm -f "$socketfile"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Stopping $prog: " /bin/true<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Stopping $prog: " /bin/false<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret=1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Stopping $prog: " /bin/false<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $ret<br />
}<br />
&nbsp;<br />
restart(){<br />
&nbsp;&nbsp;&nbsp; stop<br />
&nbsp;&nbsp;&nbsp; start<br />
}<br />
<br />
mystatus(){<br />
&nbsp;MYSQLPID=`cat "$mypidfile"&nbsp; 2&gt;/dev/null `<br />
<br />
&nbsp;if [ -n "$MYSQLPID"&nbsp; ]; <br />
&nbsp;then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "mysqld-$MYSQLD_SUFFIX is running"<br />
&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "mysqld-$MYSQLD_SUFFIX is not running"<br />
&nbsp;fi<br />
}<br />
<br />
condrestart(){<br />
&nbsp;&nbsp;&nbsp; [ -e /var/lock/subsys/mysqld.$MYSQLD_SUFFIX ] &amp;&amp; restart || :<br />
}<br />
<br />
# See how we were called.<br />
case "$1" in<br />
&nbsp; start)<br />
&nbsp;&nbsp;&nbsp; start<br />
&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; stop)<br />
&nbsp;&nbsp;&nbsp; stop<br />
&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; status)<br />
&nbsp;&nbsp;&nbsp; #status -p "$mypidfile"&nbsp; mysqld<br />
&nbsp;&nbsp;&nbsp; mystatus<br />
&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; restart)<br />
&nbsp;&nbsp;&nbsp; restart<br />
&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; condrestart)<br />
&nbsp;&nbsp;&nbsp; condrestart<br />
&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; *)<br />
&nbsp;&nbsp;&nbsp; echo $"Usage: $0 {start|stop|status|condrestart|restart}"<br />
&nbsp;&nbsp;&nbsp; exit 1<br />
esac<br />
<br />
exit $?<br />
<br />
<br />
***********************************************************<br />
[mdrop@jojo1-1 init.d]$ cat /etc/my.cnf.jojo1-1.us1.master.3306<br />
[mysqld]<br />
datadir=/var/lib/mysql<br />
socket=/var/lib/mysql/mysql.sock<br />
<br />
port=3306<br />
set-variable = thread_cache_size=950<br />
set-variable = table_cache=4200<br />
set-variable = key_buffer_size=400M<br />
set-variable = record_buffer=100000<br />
set-variable = max_connect_errors=9999999999<br />
set-variable = max_connections=1700<br />
set-variable = tmp_table_size=10M<br />
transaction-isolation = READ-UNCOMMITTED<br />
set-variable = wait_timeout=180<br />
set-variable = max_write_lock_count=120<br />
skip-name-resolve<br />
skip-locking<br />
skip-innodb<br />
set-variable = query_cache_type=1<br />
set-variable = query_cache_size=52428800<br />
log-slow-queries<br />
memlock<br />
<br />
set-variable = max_binlog_size=10M<br />
log-bin=/var/lib/mysql/jojo1-1-us1-log-bin<br />
log-bin-index=/var/lib/mysql/jojo1-1-us1-log-bin.index<br />
server-id=1<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
[mysql.server]<br />
user=mysql<br />
basedir=/var/lib<br />
<br />
[safe_mysqld]<br />
err-log=/var/lib/mysql/mysqld.log<br />
pid-file=/var/lib/mysql/mysqld.pid<br />
<br />
<br />
##################################################<br />
<br />
<br />
<br />
[mdrop@jojo1-1 init.d]$ cat mysqld.jojo1-2.us1.slave.3307 <br />
#!/bin/bash<br />
#<br />
# mysqld&nbsp;&nbsp;&nbsp; This shell script takes care of starting and stopping<br />
#&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; the MySQL subsystem (mysqld).<br />
#<br />
# chkconfig: - 64 36<br />
# description:&nbsp;&nbsp;&nbsp; MySQL database server.<br />
# processname: mysqld<br />
# config: /etc/my.cnf.jojo1-2.us1.slave.3307<br />
# pidfile: /var/run/mysqld.jojo1-2.slave/mysqld.pid<br />
<br />
# Source function library.<br />
. /etc/rc.d/init.d/functions<br />
<br />
# Source networking configuration.<br />
. /etc/sysconfig/network<br />
<br />
MYSQLD_SUFFIX="jojo1-2.us1.slave.3307"<br />
MYCNF="/etc/my.cnf.$MYSQLD_SUFFIX"<br />
<br />
prog="MySQL"<br />
<br />
# extract value of a MySQL option from config files<br />
# Usage: get_mysql_option SECTION VARNAME DEFAULT<br />
# result is returned in $result<br />
# We use my_print_defaults which prints all options from multiple files,<br />
# with the more specific ones later; hence take the last match.<br />
get_mysql_option(){<br />
&nbsp;&nbsp;&nbsp; #result=`/usr/bin/my_print_defaults "$1" | sed -n "s/^--$2=//p" | tail -n 1`<br />
&nbsp;&nbsp;&nbsp; #if [ -z "$result" ]; then<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # not found, use default<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #result="$3"<br />
&nbsp;&nbsp;&nbsp; #fi<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result="$3"<br />
}<br />
<br />
get_mysql_option mysqld datadir "/var/lib/mysql1"<br />
datadir="$result"<br />
get_mysql_option mysqld socket "$datadir/mysql.sock"<br />
socketfile="$result"<br />
get_mysql_option mysqld_safe log-error "/var/log/mysqld-$MYSQLD_SUFFIX.log"<br />
errlogfile="$result"<br />
get_mysql_option mysqld_safe pid-file "/var/run/mysqld-$MYSQLD_SUFFIX/mysqld.pid"<br />
mypidfile="$result"<br />
<br />
<br />
start(){<br />
&nbsp;&nbsp;&nbsp; touch "$errlogfile"<br />
&nbsp;&nbsp;&nbsp; chown mysql:mysql "$errlogfile" <br />
&nbsp;&nbsp;&nbsp; chmod 0640 "$errlogfile"<br />
&nbsp;&nbsp;&nbsp; [ -x /sbin/restorecon ] &amp;&amp; /sbin/restorecon "$errlogfile"<br />
&nbsp;&nbsp;&nbsp; if [ ! -d "$datadir/mysql" ] ; then<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; action $"Initializing MySQL database: " /usr/bin/mysql_install_db<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ret=$?<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; chown -R mysql:mysql "$datadir"<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if [ $ret -ne 0 ] ; then<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $ret<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp; chown mysql:mysql "$datadir"<br />
&nbsp;&nbsp;&nbsp; chmod 0755 "$datadir"<br />
&nbsp;&nbsp;&nbsp; # Pass all the options determined above, to ensure consistent behavior.<br />
&nbsp;&nbsp;&nbsp; # In many cases mysqld_safe would arrive at the same conclusions anyway<br />
&nbsp;&nbsp;&nbsp; # but we need to be sure.<br />
&nbsp;&nbsp;&nbsp; /usr/bin/mysqld_safe&nbsp; --defaults-file=$MYCNF&nbsp; --datadir="$datadir" --socket="$socketfile" "<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; --log-error="$errlogfile" --pid-file="$mypidfile" "<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &gt;/dev/null 2&gt;&amp;1 &amp;<br />
&nbsp;&nbsp;&nbsp; ret=$?<br />
&nbsp;&nbsp;&nbsp; # Spin for a maximum of N seconds waiting for the server to come up.<br />
&nbsp;&nbsp;&nbsp; # Rather than assuming we know a valid username, accept an "access<br />
&nbsp;&nbsp;&nbsp; # denied" response as meaning the server is functioning.<br />
&nbsp;&nbsp;&nbsp; if [ $ret -eq 0 ]; then<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; STARTTIMEOUT=30<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while [ $STARTTIMEOUT -gt 0 ]; do<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RESPONSE=`/usr/bin/mysqladmin -uUNKNOWN_MYSQL_USER ping 2&gt;&amp;1` &amp;&amp; break<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "$RESPONSE" | grep -q "Access denied for user" &amp;&amp; break<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sleep 1<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; let STARTTIMEOUT=${STARTTIMEOUT}-1<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; done<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if [ $STARTTIMEOUT -eq 0 ]; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "Timeout error occurred trying to start MySQL Daemon."<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Starting $prog: " /bin/false<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret=1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Starting $prog: " /bin/true<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; action $"Starting $prog: " /bin/false<br />
&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp; [ $ret -eq 0 ] &amp;&amp; touch /var/lock/subsys/mysqld.$MYSQLD_SUFFIX<br />
&nbsp;&nbsp;&nbsp; return $ret<br />
}<br />
<br />
stop(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MYSQLPID=`cat "$mypidfile"&nbsp; 2&gt;/dev/null `<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [ -n "$MYSQLPID" ]; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /bin/kill "$MYSQLPID" &gt;/dev/null 2&gt;&amp;1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret=$?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [ $ret -eq 0 ]; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STOPTIMEOUT=60<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while [ $STOPTIMEOUT -gt 0 ]; do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /bin/kill -0 "$MYSQLPID" &gt;/dev/null 2&gt;&amp;1 || break<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let STOPTIMEOUT=${STOPTIMEOUT}-1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [ $STOPTIMEOUT -eq 0 ]; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "Timeout error occurred trying to stop MySQL Daemon."<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret=1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Stopping $prog: " /bin/false<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rm -f /var/lock/subsys/mysqld.$MYSQLD_SUFFIX<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rm -f "$socketfile"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Stopping $prog: " /bin/true<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Stopping $prog: " /bin/false<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret=1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action $"Stopping $prog: " /bin/false<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $ret<br />
}<br />
&nbsp;<br />
restart(){<br />
&nbsp;&nbsp;&nbsp; stop<br />
&nbsp;&nbsp;&nbsp; start<br />
}<br />
<br />
mystatus(){<br />
&nbsp;MYSQLPID=`cat "$mypidfile"&nbsp; 2&gt;/dev/null `<br />
<br />
&nbsp;if [ -n "$MYSQLPID"&nbsp; ];<br />
&nbsp;then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "mysqld-$MYSQLD_SUFFIX is running"<br />
&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "mysqld-$MYSQLD_SUFFIX is not running"<br />
&nbsp;fi<br />
}<br />
<br />
<br />
<br />
condrestart(){<br />
&nbsp;&nbsp;&nbsp; [ -e /var/lock/subsys/mysqld.$MYSQLD_SUFFIX ] &amp;&amp; restart || :<br />
}<br />
<br />
# See how we were called.<br />
case "$1" in<br />
&nbsp; start)<br />
&nbsp;&nbsp;&nbsp; start<br />
&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; stop)<br />
&nbsp;&nbsp;&nbsp; stop<br />
&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; status)<br />
&nbsp;&nbsp;&nbsp; #status mysqld<br />
&nbsp;&nbsp;&nbsp; mystatus<br />
&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; restart)<br />
&nbsp;&nbsp;&nbsp; restart<br />
&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; condrestart)<br />
&nbsp;&nbsp;&nbsp; condrestart<br />
&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; *)<br />
&nbsp;&nbsp;&nbsp; echo $"Usage: $0 {start|stop|status|condrestart|restart}"<br />
&nbsp;&nbsp;&nbsp; exit 1<br />
esac<br />
<br />
exit $?<br />
<br />
**********************************************<br />
[mdrop@jojo1-1 init.d]$ cat /etc/my.cnf.jojo1-2.us1.slave.3307<br />
[mysqld]<br />
datadir=/var/lib/mysql1<br />
socket=/var/lib/mysql1/mysql.sock<br />
port=3307<br />
set-variable = thread_cache_size=950<br />
set-variable = table_cache=4200<br />
set-variable = key_buffer_size=400M<br />
set-variable = record_buffer=100000<br />
set-variable = max_connect_errors=9999999999<br />
set-variable = max_connections=950<br />
set-variable = tmp_table_size=10M<br />
transaction-isolation = READ-UNCOMMITTED<br />
set-variable = wait_timeout=500<br />
set-variable = max_write_lock_count=120<br />
skip-name-resolve<br />
skip-locking<br />
skip-innodb<br />
set-variable = query_cache_type=1<br />
set-variable = query_cache_size=52428800<br />
log-slow-queries<br />
memlock<br />
<br />
master-host=192.168.8.73<br />
master-user=repl<br />
master-password=repl12<br />
master-port=3307<br />
master-connect-retry=60<br />
server-id=6239<br />
set-variable = report-host=jojo1-1.us1.outblaze.com:3307<br />
<br />
[mysql.server]<br />
user=mysql<br />
<br />
[safe_mysqld]<br />
err-log=/var/lib/mysql1/mysqld.log<br />
pid-file=/var/lib/mysql1/mysqld.pid<br />
<br />
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/287087.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-07-17 10:02 <a href="http://www.blogjava.net/ruoyoux/articles/287087.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/07/14 Selenium 学习录</title><link>http://www.blogjava.net/ruoyoux/articles/286677.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Tue, 14 Jul 2009 05:58:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/286677.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/286677.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/286677.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/286677.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/286677.html</trackback:ping><description><![CDATA[<strong>Part One --- Selenium IDE</strong><br />
<br />
<br />
&nbsp;&nbsp;&nbsp; Selenium IDE 是<a href="javascript:;" onclick="javascript:tagshow(event, 'selenium');" target="_self"><u><strong>selenium</strong></u></a><a href="javascript:;" onclick="javascript:tagshow(event, '%B2%E2%CA%D4');" target="_self"><u><strong>测试</strong></u></a>工具中的其中一个,是一个基于FireFox的<a href="javascript:;" onclick="javascript:tagshow(event, 'Web%B2%E2%CA%D4');" target="_self"><u><strong>Web测试</strong></u></a>开发环境，可以录制、编辑和调试测试。Selenium IDE包含了Selenium Core，因此可以轻易地在浏览器中录制和回放测试。
<div>　　Selenium IDE不仅仅是一个测试录制工具，而是一个IDE，可以录制测试，也可以手工编辑测试，可设置断点进行调试，可把测试保存到HTML、<a href="javascript:;" onclick="javascript:tagshow(event, 'Ruby');" target="_self"><u><strong>Ruby</strong></u></a>、C#、<a href="javascript:;" onclick="javascript:tagshow(event, 'Java');" target="_self"><u><strong>Java</strong></u></a>等<a href="javascript:;" onclick="javascript:tagshow(event, '%C6%E4%CB%FB');" target="_self"><u><strong>其他</strong></u></a>脚本格式，然后使用Selenium RC来实现并运行更加灵活和强大的测试。</div>
<div>&nbsp;&nbsp;
Selenium
IDE是一个firfox插件,录制相当方便,而且效果不错,很多录制后不需要修改即可回放.编辑也相当简单,一行就是一个完整的命令.十分适合于编程基
础较薄的测试人员使用.但是由于所用的语言是selenese即是类html脚本语言而非程式语言,于组织脚本不够灵活,所形成的功能不如
selenium RC 强大,而且对脚本组织也不方便.更重要的是暂时只支持 firefox浏览器.所以一般情况下是以selenium IDE
来熟悉 selenium功具.然后利用IDE 来录制脚本作为selenium
core的脚本文件或更多的是用IDE录制而保存为drive脚本即是程式语言脚本如java 脚本.但无论如何 selenium
IDE是学习selenium的必修课,因为日后录制脚本需要它,即使用selenium
rc也可用它录制部分脚本并可方便用于调试.下面将简单介绍Selenium IDE的整个使用过程.</div>
<div>&nbsp;&nbsp; &nbsp;1&gt;
Selenium IDE 安装. 从其官方网站下载安装:http://selenium-ide.openqa.org/,跟普通frifox
插件安装没有什么两样(注意是firefox安装插件不是IE哦..).安装完成后,在浏览器"工具"菜单栏即可见Selenium IDE 工具.</div>
<div>&nbsp;&nbsp;
&nbsp;2&gt;Selenium
IDE录制脚本.安装完成后当然是开始录制脚本了.打开IDE工具后,类似一个小浏览器(此时默认是录制状态),在Base URL
中输入你要录制的网站网址如www.google.com.然后在Firefox 中打开google 网站,输入"Selenium
ide",再点击搜索.然后点击IDE工具的停止录制按钮停止录制.此时你会发现在"Table"中有了一些命令行,每一有三个部分组成.
&nbsp;　command:命令如单击click, Target:目标即是命令的对象如单击按钮(用xpath或是<a href="javascript:;" onclick="javascript:tagshow(event, '%C6%E4%CB%FC');" target="_self"><u><strong>其它</strong></u></a>定位方法表示),Value即是值如向输入框输入东西即在这里设置.而在"Sourse"中可看到类似html 的脚本,保存后就这样了,呵呵.</div>
<div>&nbsp;&nbsp;
&nbsp;3&gt; Selenium
IDE编辑脚本.你可以在Table中修改,点击相应命令行,所在行内部便会出现在下方,即可方便修改,如选择相应的command.当然你也可以在
Sourece中修改,但人必须对 Selenium命令很熟悉. 现在修改下刚才录制的脚本,将第二行命令的value 修改为Selenium.</div>
<div>&nbsp;&nbsp; &nbsp;4&gt;Selenium IDE脚本运行. 修改完后即可点击运行按钮运行.运行刚才修改过的脚本,你会发现其迅速打开google浏览器并输入"Selenium"并点击进行搜索.此时运行结束.</div>
<div>&nbsp;&nbsp; &nbsp;5&gt;Selenium IDE脚本保存.保存时可保存为html脚本或是其它程式语言脚本,初步<a href="javascript:;" onclick="javascript:tagshow(event, '%D1%A7%CF%B0');" target="_self"><u><strong>学习</strong></u></a>还是保存为html脚本吧.</div>
<div>&nbsp;&nbsp; &nbsp;6&gt;打开 seleniumIDE脚本并运行.这个就非常简单了....</div>
<div>&nbsp;&nbsp;
&nbsp;到此,Selenium IDE录制并修改运行整个过程完成了,你已经可以轻松方便使用selenium
IDE进行录制运行脚本了.但是要运用到测试中去尚需要时间熟悉,如都有什么命令啊,如何进行定位啊,如何用assert来验证验证点啊，这也是
selenium 测试主要学习的三点．如果这三占都搞明白了,熟悉了,恭喜你,你已经可以用selenium进行测试了．</div>
<div>&nbsp;&nbsp;
&nbsp;作为使用selenium IDE 工具并不复杂,而在于如何更熟悉它并用于测试中去.况且如前面提到只用Selenium IDE
进行测试局限性太高,所以建议借学习selenium IDE 了解并熟悉selenium工具,然后用其录制脚本并用 selenium
其它工具进行测试如selenium Core, selenium RC,selenium
Grid.于本人使用经验而言,建议使用selenium
RC.当然并不是说其它不好,其它有自己的优势或是功能也是RC不具备的.从学习与使用方面考虑是先学习 selenium IDE,
然后转向Selenium RC. 所以接下来将介绍Selenium RC.<br />
<br />
<br />
<br />
<br />
<br />
<strong>Part Two --- Selenium Introduction</strong> 1<br />
<br />
<div>
<p>其实几天前就看了一下Selenium，不过因为之前写别的东西，就拖到了今天。
Selenium包括三部分，Selenium core，Selenium IDE和Selenium RC。Selenium
core自然就是他的核心代码，Selenium
IDE是用JavaScript写成的Firefox插件，可以录制脚本，转换成其他语言，并且回放等。但是喵喵在这里主要想说的是Selenium
RC，即Selenium Remote Control，以及它和ant的集成使用。</p>
<p>Selenium Remote Control现在最新的是0.9.2，可以在<a href="http://www.openqa.org/selenium-rc/" title="http://www.openqa.org/selenium-rc/"><font color="#4389cf">http://www.openqa.org/selenium-rc/</font></a>下
载。Selenium Remote Control可以允许你使用编程语言（Java, .NET, Perl, Python, and
Ruby）实现自动化web应用UI的测试，它提供了一个Selenium
Server，它可以自动的start/stop/control所有支持的浏览器（Windows平台上为Internet Explorer
6.0 and 7.0, Firefox 1.5.0.8 and 2.0, Opera 8.5.4 and 9.0.2）。</p>
<p>Selenium Server必须跑在JRE1.5以上版本，可以通过java -version查看当前的JRE版本。</p>
<p>启动Selenium Server：java -jar selenium-server.jar</p>
<p>可以通过-interactive参数使之以interactive mode启动，当然，在此喵喵不采用这种方式，而是用java编写testcase来进行测试。</p>
<p>代码如下：</p>
<p>import com.thoughtworks.selenium.*;<br />
import junit.framework.*;<br />
public class GoogleTest extends TestCase {<br />
&nbsp;&nbsp;&nbsp; private Selenium browser;<br />
&nbsp;&nbsp;&nbsp; public void setUp() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; browser = new DefaultSelenium("localhost",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4444, "*firefox", <a href="http://www.google.com/"><font color="#4389cf">http://www.google.com</font></a>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; browser.start();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public void testGoogle() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; browser.open(<a href="http://www.google.com/webhp?hl=en"><font color="#4389cf">http://www.google.com/webhp?hl=en</font></a>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; browser.type("q", "hello world");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; browser.click("btnG");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; browser.waitForPageToLoad("5000");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertEquals("hello world - Google Search", browser.getTitle());<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public void tearDown() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; browser.stop();<br />
&nbsp;&nbsp;&nbsp; }<br />
} </p>
<p>启
动Selenium
Server以后，就可以运行上面的testcase了。相信大家也都看到了，这个testcase是继承了junit的testcase。所以下面要讲
的用ant进行自动化的编译和测试就和前面的ant学习笔记（一）中提到的&lt;junit&gt;task完全一样了。</p>
<p>ant脚本片段如下：</p>
<p>&lt;!--&nbsp; 编译selenium test文件 --&gt;<br />
&lt;target name="compileselenium"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;mkdir dir="${dist.selenium}"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;javac destdir="${dist.selenium}" deprecation="on"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;src path="${src.selenium}"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;classpath refid="classpath"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;classpath refid="proj.libs"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/javac&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&lt;/target&gt;<br />
&lt;!--&nbsp; 运行selenium&nbsp; --&gt;<br />
&lt;target name="selenium" depends="compileselenium"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;junit printsummary="yes" haltonfailure="yes"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;classpath&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;path refid="classpath"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pathelement location="${dist.selenium}"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/classpath&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;formatter type="plain"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;test name="GoogleTest" haltonfailure="no" outfile="result"/ &gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/junit&gt;<br />
&lt;/target&gt;</p>
</div>
<br />
<br />
<strong>Part Three -- Selenium学习笔记</strong><br />
<br />
最近准备用Selenium自动化录制测试脚本，稍微总结一下。<br />
Selenium的主页是<a href="http://seleniumhq.org/" target="_blank"><font color="#2970a6">http://seleniumhq.org</font></a><br />
Selenium包括很多组件，其中我现在用的是Selenium RC和Selenium IDE。Selenium IDE是Firefox的一个插件，我们可以使用它录制页面操作。<br />
Selenium
IDE安装完毕之后，可以从工具菜单中激活，然后我们就可以在firefox中访问需要测试的网页，进行各种页面操作，Selenium
IDE在这个过程中会记录我们的页面控件和动作。完成录制之后，Selenium IDE生成一个HTML文件保存脚本，比如<br />
<br />
<div>
<div>
<div><a href="http://www.itpub.net/viewthread.php?tid=1153458###" class="smalltxt" onclick="copycode($('code0'));">[Copy to clipboard]</a> <a href="http://www.itpub.net/viewthread.php?tid=1153458###" onclick="toggle_collapse('code0');">[ <span id="code0_symbol">-</span> ]</a></div>
CODE:</div>
<div id="code0">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;<br />
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;<br />
&lt;head profile="http://selenium-ide.openqa.org/profiles/test-case"&gt;<br />
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;<br />
&lt;link rel="selenium.base" href="http://www.baidu.com/" /&gt;<br />
&lt;title&gt;baidu&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;table cellpadding="1" cellspacing="1" border="1"&gt;<br />
&lt;thead&gt;<br />
&lt;tr&gt;&lt;td rowspan="1" colspan="3"&gt;baidu&lt;/td&gt;&lt;/tr&gt;<br />
&lt;/thead&gt;&lt;tbody&gt;<br />
&lt;tr&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;td&gt;open&lt;/td&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;td&gt;/&lt;/td&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;/td&gt;<br />
&lt;/tr&gt;<br />
&lt;tr&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;td&gt;type&lt;/td&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;td&gt;kw&lt;/td&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;td&gt;ckword&lt;/td&gt;<br />
&lt;/tr&gt;<br />
&lt;tr&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;td&gt;clickAndWait&lt;/td&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;td&gt;sb&lt;/td&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;/td&gt;<br />
&lt;/tr&gt;<br />
&lt;/tbody&gt;&lt;/table&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</div>
</div>
<br />
我们可以导出成Java文件，比如：<br />
<br />
<div>
<div>
<div><a href="http://www.itpub.net/viewthread.php?tid=1153458###" class="smalltxt" onclick="copycode($('code1'));">[Copy to clipboard]</a> <a href="http://www.itpub.net/viewthread.php?tid=1153458###" onclick="toggle_collapse('code1');">[ <span id="code1_symbol">-</span> ]</a></div>
CODE:</div>
<div id="code1">package com.example.tests;<br />
<br />
import com.thoughtworks.selenium.*;<br />
import java.util.regex.Pattern;<br />
<br />
public class NewTest extends SeleneseTestCase {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;public void setUp() throws Exception {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; setUp("http://www.baidu.com/", "*chrome");<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;public void testNew() throws Exception {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; selenium.open("/");<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; selenium.type("kw", "ckword");<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; selenium.click("sb");<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; selenium.waitForPageToLoad("30000");<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br />
}</div>
</div>
<br />
只要导入相应的selenium和Junit包就可运行。<br />
有一点需要注意的是在回放脚本时，应该添加setSpeed方法，参数是ms，因为Selenium
IDE虽然可以选择回放速度（慢——中——快），但实际上即使选择慢速，Selenium
IDE仍然运行的有些快，导致其在顺序执行用户操作时，可以发生没等到页面加载完毕就执行下一个命令的现象，导致下一个命令找不到响应的页面控件。除了
setSpeed之外，Selenium IDE还可以添加大量的命令。具体见Selenium IDE界面。<br />
另外一个关键是如何识别页面控件。自动化的核心是录制的控件识别方法可以复用，Selenium
IDE支持的识别格式包括ID、Name、XPath:attributes、DOM index和XPath :
position，而且允许正则表达式，所以非常灵活，根据我使用的情况来看，对于富客户端应用，控件ID通常都增加了一个随机数，不适合做识
别，Name还不错，但是如何这个控件Name带有版本信息，比如控件在不断升级，从1.3升到1.4，那么Name可以会失效，要小心。XPath:
position我用的最多，也觉得定位最准。但是Selenium
IDE有时抓不到某些操作，比如，可以某一个Logout链接，是由span来实现的，此时Selenium
IDE抓不到，此时可以XPath:attributes识别，这样写：//span[text()='Log out']，搞定。<br />
对于Selenium IDE，还有很多细节需要学习，比如正则表达式的应用，如何写出通用的识别方法，等等。我准备使用Selenium IDE录制脚本，然后导出成java文件，做一些修改之后用Selenium RC驱动。<br />
<br />
原文 <a href="http://www.ckword.com/blog/?p=36" target="_blank">http://www.ckword.com/blog/?p=36</a><br />
<br />
<p><font color="#000000" size="3"><strong>Part Four --- About Selenium</strong></font></p>
<p><strong>优势：</strong></p>
<p>1. 记录<a href="javascript:;" onclick="javascript:tagshow(event, '%B2%E2%CA%D4');" target="_self"><u><strong>测试</strong></u></a>过程中，所见 即是所得，selenium 的所有内部程序都是用Javascipt编写的。</p>
<p>[Javascrīpt: 由Netscape Communications 和Sun Micorsystems公司共同开发的一种描述<a href="javascript:;" onclick="javascript:tagshow(event, '%D3%EF%D1%D4');" target="_self"><u><strong>语言</strong></u></a>，与Java 的关系比较松散。Javascrīpt 能为Web页添加基本的联机应用程序和功能，但它不是一种真正的面向对象语言。</p>
<p>它的工作特点是，当client端发出一个JS的请求时，它不必从web server下载，而直接由浏览器做出响应。]</p>
<p>2. 支持多种操作系统，如windows, Mac, <a href="javascript:;" onclick="javascript:tagshow(event, 'Linux');" target="_self"><u><strong>Linux</strong></u></a>，也支持多种浏览器，如IE,Firefox, Mozilla.</p>
<p>若使用Selenium IDE进行web 自动记录<a href="javascript:;" onclick="javascript:tagshow(event, '%B2%E2%CA%D4%D3%C3%C0%FD');" target="_self"><u><strong>测试用例</strong></u></a>录制，只能是在Firefox （笔者还没试过Mozilla,嘿嘿）是先录制好<a href="javascript:;" onclick="javascript:tagshow(event, '%BD%C5%B1%BE');" target="_self"><u><strong>脚本</strong></u></a>，再在其它浏览器执行测试用例，进行测试。</p>
<p>3.
执行两种开发脚本，test runner,需要安装Selenium
Core,执行的文件为.HTML后缀名。另一种是driven(脚本语言编写)，支持多种语言：JAVA,.NET, Perl, Python,
Ruby.(在下用的是ruby, 没办法，谁叫它既简洁又明了呢！^ ^)</p>
<p><strong>劣势：</strong></p>
<p>较难处理逻辑关系强的业务测试。</p>
<p><font size="3"><strong>Selenium 实质：</strong></font></p>
<p>&nbsp; 通过HTTP协议，发送请求来完成测试用例的。</p>
<p><font size="3"><strong>Selenium <a href="javascript:;" onclick="javascript:tagshow(event, '%C3%FC%C1%EE');" target="_self"><u><strong>命令</strong></u></a>：</strong></font>只有两种</p>
<p>1. 操作(action)：用于模拟用户与web的交互。</p>
<p>2. 断言（assertion）:验证一个命令的预期结果。（类似于watir^ ^）</p>
<p><font size="3"><strong>Selenium 的组成：</strong></font></p>
<p><strong>Selenium IDE：</strong>firefox 的 plug-in。 是浏览器的工具，不能安装在IE上。</p>
<p><strong>Selenium Core:</strong>纯粹由Javascrīpt组成的，有assertion机制的test suit runnner.</p>
<p><strong>Selenium Remote Control:</strong></p>
<p>一个代理与控制端， 可代替Selenium core 和IDE 的client端。</p>
<p>下载地址：<a href="http://www.openqa.org/">http://www.openqa.org/</a></p>
<p><font size="3"><strong>一个使用Selenium IDE的测试例子脚本：</strong></font></p>
<p>class NewTest<br />
&nbsp; def test_foo<br />
&nbsp;&nbsp;&nbsp; open "/intl/zh-CN/"<br />
&nbsp;&nbsp;&nbsp; assertTitle "Google"<br />
&nbsp;&nbsp;&nbsp; type "q", "selenium"<br />
&nbsp;&nbsp;&nbsp; clickAndWait "btnG"<br />
&nbsp;&nbsp;&nbsp; assertTitle "selenium - Google 搜索"<br />
&nbsp;&nbsp;&nbsp; clickAndWait "link=高级搜索"<br />
&nbsp;&nbsp;&nbsp; assertTitle "Google 高级搜索"<br />
&nbsp;&nbsp;&nbsp; type "as_epq", "iccer"<br />
&nbsp;&nbsp;&nbsp; select "lr", "label=简体中文"<br />
&nbsp;&nbsp;&nbsp; clickAndWait "btnG"<br />
&nbsp;&nbsp;&nbsp; assertTitle "selenium "iccer" - Google 搜索"<br />
&nbsp;&nbsp;&nbsp; click "link=测试| 软件测试| 软件缺陷跟踪| 软件配置工具| 测试用例设计| Web测试 ..."<br />
&nbsp; end<br />
end</p>
<p>将脚本拷下，存为.HTML文档，再在firefox的selenium IDE工作中打开，执行就OK了。（执行不了就多试几次吧。^ ^）</p>
<p>迟点要添加用selenium core的例子。</p>
<p><br />
</p>
<h2><a id="ctl04_TitleUrl" href="http://www.cnblogs.com/hyddd/archive/2009/05/24/1488377.html">Part Five -- Selenium RC测试案例</a>
</h2>
<p><span style="font-size: medium;"><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 《<a href="http://www.cnblogs.com/hyddd/archive/2009/05/20/1473146.html">Selenium简介</a>》
中讲过，Selenium
RC支持多种语言编写测试案例，如：C#，Python。在工作中，我倾向于是用Python这类动态语言编写测试案例，因为这样的测试案例无需编
译:&gt;，试想如果你有1000个测试案例，每个都要编译，那会给编译服务器很大的压力，而且案例修改后，还得重新编译才能运行:&lt;。但在本系
列的文章中，我还是打算使用C#编写示范例子。</span></span></p>
<p><span style="font-size: medium;"><span style="font-family: 宋体;">Selenium RC下载：<a href="http://seleniumhq.org/download/" title="http://seleniumhq.org/download/">http://seleniumhq.org/download/</a></span></span></p>
<p><span style="font-size: medium;"><span style="font-family: 宋体;"><img src="http://pic002.cnblogs.com/img/hyddd/200905/2009052419031197.jpg" alt="" /></span></span></p>
<p><span style="font-size: medium;"><span style="font-family: 宋体;"><span style="font-size: large;"><strong>写Selenium RC的测试案例</strong></span></span></span></p>
<p><span style="font-size: medium;"><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 上一篇《<a href="http://www.cnblogs.com/hyddd/archive/2009/05/24/1487967.html">Selenium IDE的使用</a>》中，提到了Selenium IDE可以把录制的脚本转为其他语言的脚本，所以我继续用上一篇的脚本为例子，下面是把脚本语言转换为C#后的代码：</span></span></p>
<div><span style="font-size: medium;"><span style="font-family: 宋体;"><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);">&nbsp;System;<br />
</span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);">&nbsp;System.Text;<br />
</span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);">&nbsp;System.Text.RegularExpressions;<br />
</span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);">&nbsp;System.Threading;<br />
</span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);">&nbsp;NUnit.Framework;<br />
</span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);">&nbsp;Selenium;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">namespace</span><span style="color: rgb(0, 0, 0);">&nbsp;SeleniumTests<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;[TestFixture]<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span>&nbsp;<span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;NewTest<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">&nbsp;ISelenium&nbsp;selenium;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">&nbsp;StringBuilder&nbsp;verificationErrors;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[SetUp]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span>&nbsp;<span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;SetupTest()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span>&nbsp;<span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;DefaultSelenium(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">localhost</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(128, 0, 128);">4444</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">*chrome</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">http://change-this-to-the-site-you-are-testing/</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;verificationErrors&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span>&nbsp;<span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;StringBuilder();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[TearDown]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span>&nbsp;<span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;TeardownTest()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Stop();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);">&nbsp;(Exception)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;Ignore&nbsp;errors&nbsp;if&nbsp;unable&nbsp;to&nbsp;close&nbsp;the&nbsp;browser</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.AreEqual(</span><span style="color: rgb(128, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">,&nbsp;verificationErrors.ToString());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Test]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span>&nbsp;<span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;TheNewTest()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Open(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">/</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Type(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">kw</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">hyddd</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Click(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">sb</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.WaitForPageToLoad(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">30000</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.IsTrue(selenium.IsTextPresent(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">hyddd&nbsp;-&nbsp;博客园</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);">&nbsp;(AssertionException&nbsp;e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;verificationErrors.Append(e.Message);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Click(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">//table[@id='1']/tbody/tr/td/a/font</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></span></span></div>
<p><span style="font-size: medium;"><span style="font-family: 宋体;">在这里，转换后的脚本使用了NUnit测试框架，为了简化，我用VS的Test Project代替（当然你也可以用Console Application建立测试工程的），步骤如下：<br />
<strong>1.建立Test Project</strong><br />
</span></span></p>
<p><span style="font-size: medium;"><span style="font-family: 宋体;"><img src="http://pic002.cnblogs.com/img/hyddd/200905/2009052419043083.jpg" alt="" /></span></span></p>
<p><span style="font-size: medium;"><strong><span style="font-family: 宋体;">2.导入DLL引用</span></strong></span></p>
<p><span style="font-size: medium;"><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 把selenium-dotnet-client-driver-1.0-beta-2目录中的<span style="color: rgb(0, 0, 255);">ThoughtWorks.Selenium.Core.dll</span>，<span style="color: rgb(0, 0, 255);">ThoughtWorks.Selenium.IntegrationTests.dll</span>，<span style="color: rgb(0, 0, 255);">ThoughtWorks.Selenium.UnitTests.dll</span>加入项目：</span></span></p>
<p><span style="font-size: medium;"><span style="font-family: 宋体;"><img src="http://pic002.cnblogs.com/img/hyddd/200905/2009052419061081.jpg" alt="" /></span></span></p>
<p><strong><span style="font-size: medium;"><span style="font-family: 宋体;">3.把上面自动生成的代码再改一下</span></span></strong></p>
<div><span style="font-size: medium;"><span style="font-family: 宋体;"><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);">&nbsp;System;<br />
</span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);">&nbsp;System.Text;<br />
</span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);">&nbsp;System.Collections.Generic;<br />
</span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);">&nbsp;Microsoft.VisualStudio.TestTools.UnitTesting;<br />
</span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);">&nbsp;Selenium;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">namespace</span><span style="color: rgb(0, 0, 0);">&nbsp;SeleniumTest<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;[TestClass]<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span>&nbsp;<span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;UnitTest1<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[TestMethod]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span>&nbsp;<span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;Test()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">127.0.0.1为Selenium测试服务器位置。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">4444为Selenium测试服务器监听端口。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">*iexplore为启动浏览器类型，我把它改为了IE浏览器。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0); text-decoration: underline;">http://www.baidu.com为源地址</span><span style="color: rgb(0, 128, 0);">。</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ISelenium&nbsp;selenium&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span>&nbsp;<span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;DefaultSelenium(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">127.0.0.1</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(128, 0, 128);">4444</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">*iexplore</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">http://www.baidu.com</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Open(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">/</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Type(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">kw</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">hyddd</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Click(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">sb</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.WaitForPageToLoad(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">30000</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.IsTrue(selenium.IsTextPresent(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">hyddd&nbsp;-&nbsp;博客园</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Click(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">//table[@id='1']/tbody/tr/td/a/font</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
</span></span></span><span style="font-size: medium;"><span style="font-family: 宋体;"><span style="color: rgb(0, 0, 0);">selenium.Close();</span></span></span><br />
<span style="font-size: medium;"><span style="font-family: 宋体;"><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selenium.Stop();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></span></span></div>
<p><span style="font-size: medium;"><span style="font-family: 宋体;"><strong>4.启动Selenium测试服务器</strong><br />
&nbsp;&nbsp;&nbsp; 打开cmd进入selenium-server-1.0-beta-2目录，输入&#8220;java -jar selenium-server.jar&#8221;</span></span><span style="font-size: medium;"><span style="font-family: 宋体;">(需要先安装JRE)</span></span><span style="font-size: medium;"><span style="font-family: 宋体;">，启动Selenium测试服务器。<br />
<img src="http://pic002.cnblogs.com/img/hyddd/200905/2009052419082473.jpg" alt="" /></span></span></p>
<p><span style="font-size: medium;"><span style="font-family: 宋体;"><strong>5.运行测试案例</strong><br />
(1).运行测试案例：<br />
<img src="http://pic002.cnblogs.com/img/hyddd/200905/2009052419090425.jpg" alt="" /></span></span></p>
<p><span style="font-size: medium;"><span style="font-family: 宋体;">(2).测试结果：</span></span></p>
<p><span style="font-size: medium;"><span style="font-family: 宋体;"><img src="http://pic002.cnblogs.com/img/hyddd/200905/2009052419093965.jpg" alt="" /><br />
恩，案例Pass了，如果案例失败的话，Error Meesage会说明失败的原因。<br />
(注
意:和Firefox一样，IE下也有屏蔽弹出网页功能，修改设置方法：MenuBar-&gt;Tools-&gt;Popup
Blocker-&gt;Turn off Popup Blocker，或者在Popup Blocker Settings里面配置。)</span></span></p>
<p><br />
</p>
<strong>Part Six -- 配置 selenium rc for HTTPS 测试</strong><br />
<br />
1。选择工具<br />
selenium有好几种，首先需要确定的是哪种工具适合<br />
<br />
* selenium IDE: 是一个firefox的plug-in，这个基本上对任何<a href="http://hi.baidu.com/wsh0102/blog/item/%20:;" target="_self"><u><strong>测试</strong></u></a>都有用，主要是因为可以省下大量的手写测试的时间。根据我的经验，最新的版本(1.0 beta)在RHEL 5.0上不能用，所以我用的是0.87版本。<br />
在这里下载：http://selenium-ide.openqa.org/download.jsp不过它只能在firefox上用<br />
<br />
* selenium rc : 这个是用来遥控的。(rc = remote controller)如果你需要在一台电脑上控制<a href="http://hi.baidu.com/wsh0102/blog/item/%20:;" target="_self"><u><strong>其它</strong></u></a>几台电脑进行测试，我用的就是这个。不过我用它的主要原因是它支持比较多的脚本语言（perl，python。。。）写自动测试程序比较容易<br />
<br />
* selenium core : 只能支持Selenese语言（a simple scrīpting language. Selenese
has a number of strict limitations: it has no conditionals (no "if"
statements), and it has no loops (no "for" statements). This can make
writing complicated tests difficult or even
impossible.）如果需要知道比较具体的区别的话，还是看它们自己的文件：http://wiki.openqa.org/pages
/viewpage.action?pageId=7632<br />
<br />
2。配置<br />
配置有很多步骤和方面，首先需要了解的是selenium rc的<a href="http://hi.baidu.com/wsh0102/blog/item/%20:;" target="_self"><u><strong>工作</strong></u></a>流程<br />
<img title="点击图片可在新窗口打开" style="width: 400px; cursor: pointer;" src="http://selenium.openqa.org/selenium-rc.png" alt="" /><br />
图片看起来好像复杂，但是实际上我们可以将所有的部件放到一台机器上。我们需要了解的是它的工作流程。<br />
selenium包含三个部件：<br />
测试程序(testing scrīpt)<br />
selenium rc (selenium <a href="http://hi.baidu.com/wsh0102/blog/item/%20:;" target="_self"><u><strong>server</strong></u></a>)<br />
browser (firefox, in my case)<br />
他们之间的关系如下<br />
testing scrīpt &lt;=&gt;selenium server &lt;=&gt; browser<br />
(1)测试程序将HTTP/HTTPS请求发给selenium server<br />
(2)selenium server将请求转发(also called proxing)给browser，<br />
(3)browser 执行请求，得到执行结果，然后回复给selenium server<br />
(4)selenium server 将回复转发给测试程序*<br />
(5)测试程序检验测试结果，记录之，然后执行下一个测试<br />
这个过程中，selenium server和browser必须要在同一台机器上，但是测试程序可以随意。我的配置是三者都在同一台机器上。<br />
<br />
测试环境配置 (testing environment configuration)<br />
* perl  （我使用的是perl） <br />
用perl写selenium的测试程序需要首先安装必要的module:  <a href="http://hi.baidu.com/wsh0102/blog/item/%20:;" target="_self"><u><strong>Test</strong></u></a>::WWW::Selenium  <br />
我的安装方式如下： <br />
$&gt; yum install perl.CPAN.386 &nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  -- yum 是<a href="http://hi.baidu.com/wsh0102/blog/item/%20:;" target="_self"><u><strong>linux</strong></u></a>里面的程序包安装程序 <br />
$&gt; perl -MCPAN -e "install Test::WWW::Selenium"&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --安装Selenium会同时要求你同时安装一些其它的module，比如Test::Mock Test::MockObject
Test::More Test::Exception Test::Mock:LWP Test::Pod.
如果你的CPAN配置好了的话，这些安装都是自动的，安装过程中如果有提问，直接回车就好，一般不会有太多问题 （如果需要重新配置perl
CPAN，比如说我<br />
&nbsp;&nbsp;  $&gt; perl -MCPAN -e "<a href="http://hi.baidu.com/wsh0102/blog/item/%20:;" target="_self"><u><strong>shell</strong></u></a>"&nbsp;&nbsp;<br />
&nbsp;&nbsp;  CPAN&gt; o conf init<br />
<br />
* <a href="http://hi.baidu.com/wsh0102/blog/item/%20:;" target="_self"><u><strong>JAVA</strong></u></a><br />
Selenium server 是用Java写的，所以你需要有JAVA。我开始用的是<a href="http://hi.baidu.com/wsh0102/blog/item/%20:;" target="_self"><u><strong>IBM</strong></u></a> JAVA 1.5后来才发现不行，就转到了SUN的JRE1.6<br />
<br />
* Selenium Core : 在selenium rc 的网站上说需要 selenium core，但是我的经验是不必管它<br />
<br />
* Selenium Server:  <br />
** 下载： Selenium 1.0<a href="http://archiva.openqa.org/repository/releases/org/openqa/selenium/selenium-remote-control/1.0-beta-1/selenium-remote-control-1.0-beta-1-dist.zip">Major release</a> <br />
** unzip selenium-remote-control-1.0-beta-1-dist.zip <br />
** 到这里其实就可以了，但是让程序跑起来，这里需要一个额外的配置： 将firefox-bin放到系统路径里面去<br />
&nbsp;&nbsp;  $&gt; export PATH=$PATH:/usr/lib/firefox-1.5.0.9*<br />
<br />
* HTTPS <br />
前面的都很简单。如果你不需要测试HTTPS，那么前面的配置就足够了。但是要让selenium server用HTTPS，还需要将一个专门用于测试的cert放到firefox里面去。步骤如下： <br />
** open firefox <br />
** import certificates:  <br />
*** go to "Edit-&gt;Preference"<br />
&nbsp;&nbsp;  -&gt; open "Advanced" tab<br />
&nbsp;&nbsp;  -&gt; click "Security" (or "Encryption" )&nbsp;&nbsp;<br />
&nbsp;&nbsp;  -&gt; click "view certificates", a new window will open,  <br />
&nbsp;&nbsp;  -&gt; then select "Web Sites" tab <br />
&nbsp;&nbsp;  -&gt; then click "import"（图片如下）<br />
<br />
<br />
<br />
3。最后一步，就是怎么让程序跑起来。这里有三个问题需要注意：<br />
1&gt; selenium rc beta 1。0 的SSL cert已经过期了(4/18/2008)，所以我们需要将我们的系统时间改回到过期之前。<br />
$&gt; date 041800002007<br />
2&gt; 需要用让selenium server使用刚刚设定好的firefox profile<br />
3&gt; 需要设置一个特定的参数（trustAllCertificates），让所有的SSL请求能够顺利通达。［这条在selenium正式的网站上没有写出来，是通过看源程序找到的］<br />
<br />
<br />
我的命令如下：<br />
<br />
让selenium server跑起来：<br />
<span style="color: rgb(0, 1, 255);">java -jar ~/server/selenium-server.jar "</span><br style="color: rgb(0, 1, 255);" />
<span style="color: rgb(0, 1, 255);">&nbsp;&nbsp;&nbsp;&nbsp;  -log /tmp/selenium.log "</span><br style="color: rgb(0, 1, 255);" />
<span style="color: rgb(0, 1, 255);">&nbsp;&nbsp;&nbsp;&nbsp;  -trustAllSSLCertificates "</span><br style="color: rgb(0, 1, 255);" />
<span style="color: rgb(0, 1, 255);">&nbsp;&nbsp;&nbsp;&nbsp;  -multiWindow "</span><br style="color: rgb(0, 1, 255);" />
<span style="color: rgb(0, 1, 255);">&nbsp;&nbsp;&nbsp;&nbsp;  -firefoxProfileTemplate /opt/ipatest.profile<br />
<br />
</span>15:52:10.698 INFO - Writing debug logs to /tmp/selenium.log<br />
15:52:10.699 INFO - Java: Sun Microsystems Inc. 10.0-b19<br />
15:52:10.699 INFO - OS: Linux 2.6.18-8.el5 i386<br />
15:52:10.702 INFO - v1.0-beta-1 [2201], with Core v1.0-beta-1 [1994]<br />
15:52:10.758 INFO - Version Jetty/5.1.x<br />
15:52:10.760 INFO - Started HttpContext[/selenium-server/driver,/selenium-server/driver]<br />
15:52:10.762 INFO - Started HttpContext[/selenium-server,/selenium-server]<br />
15:52:10.763 INFO - Started HttpContext[/,/]<br />
15:52:10.772 INFO - Started SocketListener on 0.0.0.0:4444<br />
15:52:10.773 INFO - Started org.mortbay.jetty.Server@5ac072<br />
<br />
让测试程序跑起来：<br />
<span style="color: rgb(0, 1, 255);">perl test.pl</span><br />
<br />
我的test.pl 程序开头部分如下：<br />
----------------------------<br />
#!/usr/bin/perl<br />
<br />
use strict;<br />
use warnings;<br />
use Time::HiRes qw(sleep);<br />
use Test::WWW::Selenium;<br />
use Test::More "no_plan";<br />
use Test::Exception;<br />
<br />
my $sel = Test::WWW::Selenium-&gt;new( host =&gt; "localhost",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  port =&gt; 4444,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  browser =&gt; "*firefox",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  browser_url =&gt; "https://some.com");<br />
<br />
$sel-&gt;open_ok("/testpage");<br />
$sel-&gt;click_ok("link=Add User");<br />
$sel-&gt;wait_for_page_to_load_ok("30000");<br />
$sel-&gt;type_ok("form_title", "auto001");<br />
$sel-&gt;type_ok("form_givenname", "selenium");<br />
$sel-&gt;type_ok("form_sn", "001");<br />
$sel-&gt;type_ok("form_krbprincipalkey", "redhat123");<br />
$sel-&gt;type_ok("form_krbprincipalkey_confirm", "redhat123");<br />
$sel-&gt;click_ok("document.form.submit[1]");<br />
$sel-&gt;wait_for_page_to_load_ok("30000");<br />
$sel-&gt;is_text_present_ok("s001 added!");<br />
$sel-&gt;click_ok("link=Find Users");<br />
$sel-&gt;wait_for_page_to_load_ok("30000");<br />
$sel-&gt;type_ok("uid", "s101");<br />
$sel-&gt;click_ok("//input["@value='Find Users']");<br />
$sel-&gt;wait_for_page_to_load_ok("30000");<br />
$sel-&gt;type_ok("uid", "s001");<br />
<br />
---------------------------<br />
我其实没有写什么东西，上面的程序都是selenium IDE自动录的。<br />
<br />
<br />
<br />
<a href="http://www.51testing.com/batch.download.php?aid=9701" target="_blank"><img style="width: 400px;" src="http://www.51testing.com/attachments/2008/05/95943_200805010620451.png" alt="" border="0" /></a><br />
</div>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/286677.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-07-14 13:58 <a href="http://www.blogjava.net/ruoyoux/articles/286677.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/07/09 Sed Command Tutorial/Example</title><link>http://www.blogjava.net/ruoyoux/articles/286084.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Thu, 09 Jul 2009 06:45:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/286084.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/286084.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/286084.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/286084.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/286084.html</trackback:ping><description><![CDATA[<div>
<h3>SED Tutorial</h3>
<ul>
    <li>The sed utility is an "editor"
    </li>
    <li>It is also noninteractive. This means you have to insert
    commands to be executed on the data at the command line or in a
    script to be processed.
    </li>
    <li>sed accepts a series of commands and executes them on a file
    (or set of files).</li>
    <li>sed fittingly stands for stream editor.
    </li>
    <li>It can be used to change all occurrences of "SAD" to "SED" or
    "New York" to "Newport."
    </li>
    <li>The stream editor is ideally suited to performing repetitive
    edits that would take considerable time if done manually.
    </li>
</ul>
<p>
<br />
How sed Works
</p>
<p>
The sed utility works by sequentially reading a file, line by line,
into memory. It then performs all actions specified for the line
and places the line back in memory to dump to the terminal with the
requested changes made. After all actions have taken place to this
one line, it reads the next line of the file and repeats the
process until it is finished with the file. As mentioned, the
default output is to display the contents of each line on the
screen. Two important factors come into play here—first, the
output can be redirected to another file to save the changes;
second, the original file, by default, is left unchanged. The
default is for sed to read the entire file and make changes to each
line within it. It can, however, be restricted to specified lines
as needed.
</p>
<p>
The syntax for the utility is:
</p>
<pre>sed [options] '{command}' [filename]<br />
<br />
</pre>
<p>
In this tutorial we will walk through the most commonly used commands
and options and illustrate how they work and where they would be
appropriate for use.
</p>
<p>
The Substitute Command
</p>
<p>
One of the most common uses of the sed utility, and any similar
editor, is to substitute one value for another. To accomplish this,
the syntax for the command portion of the operation is:
</p>
<pre>'s/{old value}/{new value}/'<br />
<br />
</pre>
<p>
Thus, the following illustrates how "lion" can be changed to
"eagle" very simply:
</p>
<pre>$ echo The lion group will meet on Tuesday after school | sed <br />
<br />
's/lion/eagle/'<br />
<br />
The eagle group will meet on Tuesday after school<br />
<br />
$<br />
<br />
</pre>
<p>
Notice that it is not necessary to specify a filename if input is
being derived from the output of a preceding command—the same
as is true for awk, sort, and most other LinuxUNIX command-line
utility programs.
</p>
<p>
Multiple Changes
</p>
<p>
If multiple changes need to be made to the same file or line, there
are three methods by which this can be accomplished. The first is
to use the "-e" option, which informs the program that more than
one editing command is being used. For example:
</p>
<pre>$ echo The lion group will meet on Tuesday after school | sed -e '<br />
<br />
s/lion/eagle/' -e 's/after/before/'<br />
<br />
The eagle group will meet on Tuesday before school<br />
<br />
$<br />
<br />
</pre>
<p>
This is pretty much the long way of going about it, and the "-e"
option is not commonly used to any great extent. A more preferable
way is to separate command with semicolons:
</p>
<pre>$ echo The lion group will meet on Tuesday after school | sed '<br />
<br />
s/lion/eagle/; s/after/before/'<br />
<br />
The eagle group will meet on Tuesday before school <br />
<br />
$<br />
<br />
</pre>
<p>
Notice that the semicolon must be the next character following the
slash. If a space is between the two, the operation will not
successfully complete and an error message will be returned. These
two methods are well and good, but there is one more method that
many administrators prefer. The key thing to note is that
everything between the two apostrophes (' ') is interpreted as sed
commands. The shell program reading in the commands will not assume
you are finished entering until the second apostrophe is entered.
This means that the command can be entered on multiple
lines—with Linux changing the prompt from PS1 to a
continuation prompt (usually "&gt;")—until the second
apostrophe is entered. As soon as it is entered, and Enter pressed,
the processing will take place and the same results will be
generated, as the following illustrates:
</p>
<pre>$ echo The lion group will meet on Tuesday after school | sed '<br />
<br />
&gt; s/lion/eagle/<br />
<br />
&gt; s/after/before/'<br />
<br />
The eagle group will meet on Tuesday before school<br />
<br />
$<br />
<br />
</pre>
<p>
Global Changes
</p>
<p>
Let's begin with a deceptively simple edit. Suppose the message
that is to be changed contains more than one occurrence of the item
to be changed. By default, the result can be different than what
was expected, as the following illustrates:
</p>
<pre>$ echo The lion group will meet this Tuesday at the same time<br />
<br />
as the meeting last Tuesday | sed 's/Tuesday/Thursday/'<br />
<br />
The lion group will meet this Thursday at the same time<br />
<br />
as the meeting last Tuesday <br />
<br />
$<br />
<br />
</pre>
<p>
Instead of changing every occurrence of "Tuesday" for "Thursday,"
the sed editor moves on after finding a change and making it,
without reading the whole line. The majority of sed commands
function like the substitute one, meaning they all work for the
first occurrence of the chosen sequence in each line. In order for
every occurrence to be substituted, in the event that more than one
occurrence appears in the same line, you must specify for the
action to take place globally:
</p>
<pre>$ echo The lion group will meet this Tuesday at the same time<br />
<br />
as the meeting last Tuesday | sed 's/Tuesday/Thursday/g'<br />
<br />
The lion group will meet this Thursday at the same time<br />
<br />
as the meeting last Thursday<br />
<br />
$<br />
<br />
</pre>
<p>
Bear in mind that this need for globalization is true whether the
sequence you are looking for consists of only one character or a
phrase.
</p>
<p>
sed can also be used to change record field delimiters from one to
another. For example, the following will change all tabs to spaces:
</p>
<pre>sed 's/	/ /g' <br />
<br />
</pre>
<p>
where the entry between the first set of slashes is a tab, while
the entry between the second set is a space. As a general rule, sed
can be used to change any printable character to any other
printable character. If you want to change unprintable characters
to printable ones—for example, a bell to the word
"bell"—sed is not the right tool for the job (but tr would
be).
</p>
<p>
Sometimes, you don't want to change every occurrence that appears
in a file. At times, you only want to make a change if certain
conditions are met—for example, following a match of some
other data. To illustrate, consider the following text file:
</p>
<pre>$ cat sample_one<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
three   1<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
two     1<br />
<br />
three   1<br />
<br />
$<br />
<br />
</pre>
<p>
Suppose that it would be desirable for "1" to be substituted with
"2," but only after the word "two" and not throughout every line.
This can be accomplished by specifying that a match is to be found
before giving the substitute command:
</p>
<pre>$ sed '/two/ s/1/2/' sample_one<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
three   1<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
two     2<br />
<br />
three   1<br />
<br />
$<br />
<br />
</pre>
<p>
And now, to make it even more accurate:
</p>
<pre>$ sed '<br />
<br />
&gt; /two/ s/1/2/<br />
<br />
&gt; /three/ s/1/3/' sample_one<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
$<br />
<br />
</pre>
<p>
Bear in mind once again that the only thing changed is the display.
If you look at the original file, it is the same as it always was.
You must save the output to another file to create permanence. It
is worth repeating that the fact that changes are not made to the
original file is a true blessing in disguise—it lets you
experiment with the file without causing any real harm, until you
get the right commands working exactly the way you expect and want
them to.
</p>
<p>
The following saves the changed output to a new file:
</p>
<pre>$ sed '<br />
<br />
&gt; /two/ s/1/2/<br />
<br />
&gt; /three/ s/1/3/' sample_one &gt; sample_two<br />
<br />
</pre>
<p>
The output file has all the changes incorporated in it that would
normally appear on the screen. It can now be viewed with head, cat,
or any other similar utility.
</p>
<p>
Script Files
</p>
<p>
The sed tool allows you to create a script file containing commands
that are processed from the file, rather than at the command line,
and is referenced via the "-f" option. By creating a script file,
you have the ability to run the same operations over and over
again, and to specify far more detailed operations than what you
would want to try to tackle from the command line each time.
</p>
<p>
Consider the following script file:
</p>
<pre>$ cat sedlist<br />
<br />
/two/ s/1/2/<br />
<br />
/three/ s/1/3/<br />
<br />
$<br />
<br />
</pre>
<p>
It can now be used on the data file to obtain the same results we
saw earlier:
</p>
<pre>$ sed -f sedlist sample_one<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
$<br />
<br />
</pre>
<p>
Notice that apostrophes are not used inside the source file, or
from the command line when the "-f" option is invoked. Script
files, also known as source files, are invaluable for operations
that you intend to repeat more than once and for complicated
commands where there is a possibility that you may make an error at
the command line. It is far easier to edit the source file and
change one character than to retype a multiple-line entry at the
command line.
</p>
<p>
Restricting Lines
</p>
<p>
The default is for the editor to look at, and for editing to take
place on, every line that is input to the stream editor. This can
be changed by specifying restrictions preceding the command. For
example, to substitute "1" with "2" only in the fifth and sixth
lines of the sample file's output, the command would be:
</p>
<pre>$ sed '5,6 s/1/2/' sample_one<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
three   1<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
two     2<br />
<br />
three   1<br />
<br />
$<br />
<br />
</pre>
<p>
In this case, since the lines to changes were specifically
specified, the substitute command was not needed. Thus you have the
flexibility of choosing which lines to changes (essentially,
restricting the changes) based upon matching criteria that can be
either line numbers or a matched pattern.
</p>
<p>
Prohibiting the Display
</p>
<p>
The default is for sed to display on the screen (or to a file, if
so redirected) every line from the original file, whether it is
affected by an edit operation or not; the "-n" parameter overrides
this action. "-n" overrides all printing and displays no lines
whatsoever, whether they were changed by the edit or not. For
example:
</p>
<pre>$ sed -n -f sedlist sample_one<br />
<br />
$<br />
<br />
<br />
<br />
$ sed -n -f sedlist sample_one &gt; sample_two<br />
<br />
$ cat sample_two<br />
<br />
$<br />
<br />
</pre>
<p>
In the first example, nothing is displayed on the screen. In the
second example, nothing is changed, and thus nothing is written to
the new file—it ends up being empty. Doesn't this negate the
whole purpose of the edit? Why is this useful? It is useful only
because the "-n" option has the ability to be overridden by a print
command (-p). To illustrate, suppose the script file were modified
to now resemble the following:
</p>
<pre>$ cat sedlist<br />
<br />
/two/ s/1/2/p<br />
<br />
/three/ s/1/3/p<br />
<br />
$<br />
<br />
</pre>
<p>
Then this would be the result of running it:
</p>
<pre>$ sed -n -f sedlist sample_one<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
two     2<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
$<br />
<br />
</pre>
<p>
Lines that stay the same as they were are not displayed at all.
Only the lines affected by the edit are displayed.  In this manner,
it is possible to pull those lines only, make the changes, and
place them in a separate file:
</p>
<pre>$ sed -n -f sedlist sample_one &gt; sample_two<br />
<br />
$<br />
<br />
<br />
<br />
$ cat sample_two<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
two     2<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
$<br />
<br />
</pre>
<p>
Another method of utilizing this is to print only a set number of
lines. For example, to print only lines two through six while
making no other editing changes:
</p>
<pre>$ sed -n '2,6p' sample_one<br />
<br />
two     1<br />
<br />
three   1<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
two     1<br />
<br />
$<br />
<br />
</pre>
<p>
All other lines are ignored, and only lines two through six are
printed as output. This is something remarkable that you cannot do
easily with any other utility. head will print the top of a file,
and tail will print the bottom, but sed allows you to pull anything
you want to from anywhere.
</p>
<p>
Deleting Lines
</p>
<p>
Substituting one value for another is far from the only function
that can be performed with a stream editor. There are many more
possibilities, and the second-most-used function in my opinion is
delete. Delete works in the same manner as substitute, only it
removes the specified lines (if you want to remove a word and not a
line, don't think of deleting, but think of substituting it for
nothing—<tt>s/cat//</tt>).
</p>
<p>
The syntax for the command is:
</p>
<pre>'{what to find} d'<br />
<br />
</pre>
<p>
To remove all of the lines containing "two" from the sample_one
file:
</p>
<pre>$ sed '/two/ d' sample_one<br />
<br />
one     1<br />
<br />
three   1<br />
<br />
one     1<br />
<br />
three   1<br />
<br />
$<br />
<br />
</pre>
<p>
To remove the first three lines from the display, regardless of
what they are:
</p>
<pre>$ sed '1,3 d' sample_one<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
two     1<br />
<br />
three   1<br />
<br />
$<br />
<br />
</pre>
<p>
Only the remaining lines are shown, and the first three cease to
exist in the display. There are several things to keep in mind with
the stream editor as they relate to global expressions in general,
and as they apply to deletions in particular:
</p>
<li> The up carat (^) signifies the beginning of a line, thus
<pre>sed '/^two/ d' sample_one<br />
<br />
</pre>
<p>
would only delete the line if "two" were the first three
characters of the line.
</p>
</li>
<li> The dollar sign ($) represents the end of the file, or the end
of a line, thus
<pre>sed '/two$/ d' sample_one<br />
<br />
</pre>
<p>
would delete the line only if "two" were the last three characters
of the line.
</p>
<p>
The result of putting these two together:
</p>
<pre>sed '/^$/ d' {filename}<br />
<br />
</pre>
<p>
deletes all blank lines from a file. For example, the following
substitutes "1" for "2" as well as "1" for "3" and removes any
trailing lines in the file:
</p>
<pre>$ sed '/two/ s/1/2/; /three/ s/1/3/; /^$/ d' sample_one<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
three   1<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
two     2<br />
<br />
three   1<br />
<br />
$<br />
<br />
</pre>
<p>
A common use for this is to delete a header. The following command
will delete all lines in a file, from the first line through to the
first blank line:
</p>
<pre>sed '1,/^$/ d' {filename}<br />
<br />
</pre>
<p>
Appending and Inserting Text
</p>
<p>
Text can be appended to the end of a file by using sed with the "a"
option. This is done in the following manner:
</p>
<pre>$ sed '$a<br />
<br />
&gt; This is where we stop<br />
<br />
&gt; the test' sample_one<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
three   1<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
two     1<br />
<br />
three   1<br />
<br />
This is where we stop<br />
<br />
the test<br />
<br />
$<br />
<br />
</pre>
<p>
Within the command, the dollar sign ($) signifies that the text is
to be appended to the end of the file. The backslashes () are
necessary to signify that a carriage return is coming. If they are
left out, an error will result proclaiming that the command is
garbled; anywhere that a carriage return is to be entered, you must
use the backslash.
</p>
<p>
To append the lines into the fourth and fifth positions instead of
at the end, the command becomes:
</p>
<pre>$ sed '3a<br />
<br />
&gt; This is where we stop<br />
<br />
&gt; the test' sample_one<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
three   1<br />
<br />
This is where we stop<br />
<br />
the test<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
two     1<br />
<br />
three   1<br />
<br />
$<br />
<br />
</pre>
<p>
This appends the text after the third line. As with almost any
editor, you can choose to insert rather than append if you so
desire. The difference between the two is that append follows the
line specified, and insert starts with the line specified. When
using insert instead of append, just replace the "a" with an "i,"
as shown below:
</p>
<pre>$ sed '3i<br />
<br />
&gt; This is where we stop<br />
<br />
&gt; the test' sample_one<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
This is where we stop<br />
<br />
the test<br />
<br />
three   1<br />
<br />
one     1<br />
<br />
two     1<br />
<br />
two     1<br />
<br />
three   1<br />
<br />
$<br />
<br />
</pre>
<p>
The new text appears in the middle of the output, and processing
resumes normally after the specified operation is carried out.
</p>
<p>
Reading and Writing Files
</p>
<p>
The ability to redirect the output has already been illustrated,
but it needs to be pointed out that files can be read in and
written out to simultaneously during operation of the editing
commands. For example, to perform the substitution and write the
lines between one and three to a file called sample_three:
</p>
<pre>$ sed '<br />
<br />
&gt; /two/ s/1/2/<br />
<br />
&gt; /three/ s/1/3/<br />
<br />
&gt; 1,3 w sample_three' sample_one<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
$<br />
<br />
<br />
<br />
$ cat sample_three<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
$<br />
<br />
</pre>
<p>
Only the lines specified are written to the new file, thanks to the
"1,3" specification given to the w (write) command. Regardless of
those written, all lines are displayed in the default output.
</p>
<p>
The Change Command
</p>
<p>
In addition to substituting entries, it is possible to change the
lines from one value to another. The thing to keep in mind is that
substitute works on a character-for-character basis, whereas change
functions like delete in that it affects the entire line:
</p>
<pre>$ sed '/two/ c<br />
<br />
&gt; We are no longer using two' sample_one<br />
<br />
one     1<br />
<br />
We are no longer using two<br />
<br />
three   1<br />
<br />
one     1<br />
<br />
We are no longer using two<br />
<br />
We are no longer using two<br />
<br />
three   1<br />
<br />
$<br />
<br />
</pre>
<p>
Working much like substitute, the change command is greater in
scale—completely replacing the one entry for another,
regardless of character content, or context. At the risk of
overstating the obvious, when substitute was used, then only the
character "1" was replaced with "2," while when using change, the
entire original line was modified. In both situations, the match to
look for was simply the "two."
</p>
<p>
Change All but...
</p>
<p>
With most sed commands, the functions are spelled out as to what
changes are to take place. Using the exclamation mark, it is
possible to have the changes take place everywhere but those
specified—completely reversing the default operation.
</p>
<p>
For example, to delete all lines that contain the phrase "two," the
operation is:
</p>
<pre>$ sed '/two/ d' sample_one<br />
<br />
one     1<br />
<br />
three   1<br />
<br />
one     1<br />
<br />
three   1<br />
<br />
$<br />
<br />
</pre>
<p>
And to delete all lines except those that contain the phrase "two,"
the syntax becomes:
</p>
<pre>$ sed '/two/ !d' sample_one<br />
<br />
two     1<br />
<br />
two     1<br />
<br />
two     1<br />
<br />
$<br />
<br />
</pre>
<p>
If you have a file that contains a list of items and want to
perform an operation on each of the items in the file, then it is
important that you first do an intelligent scan of those entries
and think about what you are doing. To make matters easier, you can
do so by combining sed with any iteration routine (for, while,
until).
</p>
<p>
As an example, assume you have a text file named "animals" with the
following entries:
</p>
<p>
pig<br />
horse<br />
elephant<br />
cow<br />
dog<br />
cat
</p>
<p>
And you want to run the following routine:
</p>
<pre>#mcd.ksh<br />
<br />
for I in $*<br />
<br />
do<br />
<br />
echo Old McDonald had a $I<br />
<br />
echo E-I, E-I-O<br />
<br />
done<br />
<br />
</pre>
<p>
The result will be that each line is printed at the end of "Old
McDonald has a." While this is correct for the majority of the
entries, it is grammatically incorrect for the "elephant" entry, as
the result should be "an elephant" rather than "a elephant." Using
sed, you can scan the output from your shell file for such
grammatical errors and correct them on the fly, by first creating a
file of commands:
</p>
<pre>#sublist<br />
<br />
/ a a/ s/ a / an /<br />
<br />
/ a e/ s/ a / an /<br />
<br />
/a i/ s / a / an /<br />
<br />
/a o/ s/ a / an /<br />
<br />
/a u/ s/ a / an /<br />
<br />
</pre>
<p>
and then executing the process as follows:
</p>
<pre>$ sh mcd.ksh 'cat animals' | sed -f sublist  <br />
<br />
</pre>
<p>
Now, after the mcd script has been run, sed will scan the output
for anywhere that the single letter a (space, "a," space) is
followed by a vowel. If such exists, it will change the sequence to
space, "an," space. This corrects the problem before it ever prints
on the screen and ensures that editors everywhere sleep easier at
night. The result is:
</p>
<p>
Old McDonald had a pig<br />
E-I, E-I-O<br />
Old McDonald had a horse<br />
E-I, E-I-O<br />
Old McDonald had an elephant<br />
E-I, E-I-O<br />
Old McDonald had a cow<br />
E-I, E-I-O<br />
Old McDonald had a dog<br />
E-I, E-I-O<br />
Old McDonald had a cat<br />
E-I, E-I-O
</p>
<p>
Quitting Early
</p>
<p>
The default is for sed to read through an entire file and stop only
when the end is reached. You can stop processing early, however, by
using the quit command. Only one quit command can be specified, and
processing will continue until the condition calling the quit
command is satisfied.
</p>
<p>
For example, to perform substitution only on the first five lines
of a file and then quit:
</p>
<pre>$ sed '<br />
<br />
&gt; /two/ s/1/2/<br />
<br />
&gt; /three/ s/1/3/<br />
<br />
&gt; 5q' sample_one<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
$<br />
<br />
</pre>
<p>
The entry preceding the quit command can be a line number, as
shown, or a find/matching command like the following:
</p>
<pre>$ sed '<br />
<br />
&gt; /two/ s/1/2/<br />
<br />
&gt; /three/ s/1/3/<br />
<br />
&gt; /three/q' sample_one<br />
<br />
one     1<br />
<br />
two     2<br />
<br />
three   3<br />
<br />
$<br />
<br />
</pre>
<p>
You can also use the quit command to view lines beyond a standard
number and add functionality that exceeds those in head. For
example, the head command allows you to specify how many of the
first lines of a file you want to see—the default number is
ten, but any number can be used from one to ninety-nine. If you
want to see the first 110 lines of a file, you cannot do so with
head, but you can with sed:
</p>
<pre>sed 110q filename<br />
<br />
</pre>
<p>
Handling Problems
</p>
<p>
The main thing to keep in mind when dealing with sed is how it
works. It works by reading one line in, performing all the tasks it
knows to perform on that one line, and then moving on to the next
line. Each line is subjected to every editing command given.
</p>
<p>
This can be troublesome if the order of your operations is not
thoroughly thought out. For example, suppose you need to change all
"two" entries to "three" and all "three" to "four":
</p>
<pre>$ sed '<br />
<br />
&gt; /two/ s/two/three/<br />
<br />
&gt; /three/ s/three/four/' sample_one<br />
<br />
one     1<br />
<br />
four     1<br />
<br />
four   1<br />
<br />
one     1<br />
<br />
four     1<br />
<br />
four     1<br />
<br />
four   1<br />
<br />
$<br />
<br />
</pre>
<p>
The very first "two" read was changed to "three." It then meets the
criteria established for the next edit and becomes "four." The end
result is not what was wanted—there are now no entries but
"four" where there should be "three" and "four."
</p>
<p>
When performing such an operation, you must pay diligent attention
to the manner in which the operations are specified and arrange
them in an order in which one will not clobber another. For
example:
</p>
<pre>$ sed '<br />
<br />
&gt; /three/ s/three/four/<br />
<br />
&gt; /two/ s/two/three/' sample_one<br />
<br />
one     1<br />
<br />
three     1<br />
<br />
four   1<br />
<br />
one     1<br />
<br />
three     1<br />
<br />
three     1<br />
<br />
four   1<br />
<br />
$<br />
<br />
</pre>
<p>
This works perfectly, since the "three" value is changed prior to
"two" becoming "three."
</p>
<p>
Labels and Comments
</p>
<p>
Labels can be placed inside sed script files to make it easier to
explain what is transpiring, once the files begin to grow in size.
There are a variety of commands that relate to these labels, and
they include:
</p>
</li>
<li> : The colon signifies a label name. For example:
<pre>         :HERE<br />
<br />
</pre>
<p>
Labels beginning with the colon can be addressed by "b" and "t"
commands.
</p>
</li>
<li><tt>  b {label}</tt>  Works as a "goto" statement,
sending processing to the label preceded by a colon. For example,
<pre>    b HERE<br />
<br />
</pre>
<p>
sends processing to the line
</p>
<pre>    :HERE<br />
<br />
</pre>
<p>
If no label is specified following the b, processing goes to the
end of the script file.
</p>
</li>
<li><tt>  t {label}</tt>  Branches to the label only if
substitutions have been made since the last input line or execution
of a "t" command. As with "b," if a label name is not given,
processing moves to the end of the script file.</li>
<li><tt> #</tt>  The pound sign as the first character of a line
causes the entire line to be treated as a comment.  Comment lines
are different from labels and cannot be branched to with b or t
commands.</li>
</div>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/286084.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-07-09 14:45 <a href="http://www.blogjava.net/ruoyoux/articles/286084.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/07/03 memcached完全剖析</title><link>http://www.blogjava.net/ruoyoux/articles/285323.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Fri, 03 Jul 2009 04:20:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/285323.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/285323.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/285323.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/285323.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/285323.html</trackback:ping><description><![CDATA[<h1>1. memcached的基础</h1>
<br />
<p>翻译一篇技术评论社的文章，是讲memcached的连载。<a href="http://www.fcicq.net/wp/">fcicq</a>同学说这个东西很有用，希望大家喜欢。</p>
<p>发表日：2008/7/2 <br />
作者：长野雅广(Masahiro Nagano) <br />
原文链接：<a href="http://gihyo.jp/dev/feature/01/memcached/0001">http://gihyo.jp/dev/feature/01/memcached/0001</a></p>
<p>我是<a href="http://mixi.jp/">mixi株式会社</a>开发部系统运营组的长野。
日常负责程序的运营。从今天开始，将分几次针对最近在Web应用的可扩展性领域
的热门话题memcached，与我公司开发部研究开发组的前坂一起，
说明其内部结构和使用。</p>
<h2 id="content_2_0">memcached是什么？</h2>
<p><a href="http://www.danga.com/memcached/">memcached</a>
是以<a href="http://www.livejournal.com/">LiveJournal</a>
旗下<a href="http://www.danga.com/">Danga Interactive</a>
公司的<a href="http://www.bradfitz.com/">Brad Fitzpatric</a>
为首开发的一款软件。现在已成为
<a href="http://mixi.jp/">mixi</a>、
<a href="http://www.hatena.ne.jp/">hatena</a>、
<a href="http://www.facebook.com/">Facebook</a>、
<a href="http://www.vox.com/">Vox</a>、LiveJournal等众多服务中
提高Web应用扩展性的重要因素。</p>
<p>许多Web应用都将数据保存到RDBMS中，应用服务器从中读取数据并在浏览器中显示。
但随着数据量的增大、访问的集中，就会出现RDBMS的负担加重、数据库响应恶化、
网站显示延迟等重大影响。</p>
<p>这时就该memcached大显身手了。memcached是高性能的分布式内存缓存服务器。
一般的使用目的是，通过缓存数据库查询结果，减少数据库访问次数，以提高动态Web应用的速度、
提高可扩展性。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092816494460.png" alt="" /><br />
</div>
<p>图1 一般情况下memcached的用途</p>
<h2 id="content_2_1">memcached的特征</h2>
<p>memcached作为高速运行的分布式缓存服务器，具有以下的特点。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li>协议简单</li>
    <li>基于libevent的事件处理</li>
    <li>内置内存存储方式</li>
    <li>memcached不互相通信的分布式</li>
</ul>
<h3 id="content_2_2">协议简单</h3>
<p>memcached的服务器客户端通信并不使用复杂的XML等格式，
而使用简单的基于文本行的协议。因此，通过telnet
也能在memcached上保存数据、取得数据。下面是例子。</p>
<pre>$ telnet localhost 11211<br />
<br />
Trying 127.0.0.1...<br />
<br />
Connected to localhost.localdomain (127.0.0.1).<br />
<br />
Escape character is '^]'.<br />
<br />
set foo 0 0 3     （保存命令）<br />
<br />
bar               （数据）<br />
<br />
STORED            （结果）<br />
<br />
get foo           （取得命令）<br />
<br />
VALUE foo 0 3     （数据）<br />
<br />
bar               （数据）</pre>
<p>协议文档位于memcached的源代码内，也可以参考以下的URL。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt">http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt</a></li>
</ul>
<h3 id="content_2_3">基于libevent的事件处理</h3>
<p>libevent是个程序库，它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能
封装成统一的接口。即使对服务器的连接数增加，也能发挥O(1)的性能。
memcached使用这个libevent库，因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。
关于事件处理这里就不再详细介绍，可以参考Dan Kegel的The C10K Problem。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><strong>libevent</strong>: <a href="http://www.monkey.org/%7Eprovos/libevent/">http://www.monkey.org/~provos/libevent/</a></li>
    <li><strong>The C10K Problem</strong>: <a href="http://www.kegel.com/c10k.html">http://www.kegel.com/c10k.html</a></li>
</ul>
<h3 id="content_2_4">内置内存存储方式</h3>
<p>为了提高性能，memcached中保存的数据都存储在memcached内置的内存存储空间中。
由于数据仅存在于内存中，因此重启memcached、重启操作系统会导致全部数据消失。
另外，内容容量达到指定值之后，就基于LRU(Least Recently Used)算法自动删除不使用的缓存。
memcached本身是为缓存而设计的服务器，因此并没有过多考虑数据的永久性问题。
关于内存存储的详细信息，本连载的第二讲以后前坂会进行介绍，请届时参考。</p>
<h3 id="content_2_5">memcached不互相通信的分布式</h3>
<p>memcached尽管是&#8220;分布式&#8221;缓存服务器，但服务器端并没有分布式功能。
各个memcached不会互相通信以共享信息。那么，怎样进行分布式呢？
这完全取决于客户端的实现。本连载也将介绍memcached的分布式。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092816503963.png" alt="" /><br />
</div>
<p>图2 memcached的分布式</p>
<p>接下来简单介绍一下memcached的使用方法。</p>
<h2 id="content_2_6">安装memcached</h2>
<p>memcached的安装比较简单，这里稍加说明。</p>
<p>memcached支持许多平台。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li>Linux</li>
    <li>FreeBSD</li>
    <li>Solaris (memcached 1.2.5以上版本)</li>
    <li>Mac OS X</li>
</ul>
<p>另外也能安装在Windows上。这里使用Fedora Core 8进行说明。</p>
<h3 id="content_2_7">memcached的安装</h3>
<p>运行memcached需要本文开头介绍的libevent库。Fedora 8中有现成的rpm包，
通过yum命令安装即可。</p>
<pre>$ sudo yum install libevent libevent-devel</pre>
<p>memcached的源代码可以从memcached网站上下载。本文执笔时的最新版本为1.2.5。
Fedora 8虽然也包含了memcached的rpm，但版本比较老。因为源代码安装并不困难，
这里就不使用rpm了。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><strong>下载memcached</strong>：<a href="http://www.danga.com/memcached/download.bml">http://www.danga.com/memcached/download.bml</a></li>
</ul>
<p>memcached安装与一般应用程序相同，configure、make、make install就行了。</p>
<pre>$ wget http://www.danga.com/memcached/dist/memcached-1.2.5.tar.gz<br />
<br />
$ tar zxf memcached-1.2.5.tar.gz<br />
<br />
$ cd memcached-1.2.5<br />
<br />
$ ./configure<br />
<br />
$ make<br />
<br />
$ sudo make install</pre>
<p>默认情况下memcached安装到/usr/local/bin下。</p>
<h3 id="content_2_8">memcached的启动</h3>
<p>从终端输入以下命令，启动memcached。</p>
<pre>$ /usr/local/bin/memcached -p 11211 -m 64m -vv<br />
<br />
slab class   1: chunk size     88 perslab 11915<br />
<br />
slab class   2: chunk size    112 perslab  9362<br />
<br />
slab class   3: chunk size    144 perslab  7281<br />
<br />
中间省略<br />
<br />
slab class  38: chunk size 391224 perslab     2<br />
<br />
slab class  39: chunk size 489032 perslab     2<br />
<br />
&lt;23 server listening<br />
<br />
&lt;24 send buffer was 110592, now 268435456<br />
<br />
&lt;24 server listening (udp)<br />
<br />
&lt;24 server listening (udp)<br />
<br />
&lt;24 server listening (udp)<br />
<br />
&lt;24 server listening (udp)</pre>
<p>这里显示了调试信息。这样就在前台启动了memcached，监听TCP端口11211
最大内存使用量为64M。调试信息的内容大部分是关于存储的信息，
下次连载时具体说明。</p>
<p>作为daemon后台启动时，只需</p>
<pre>$ /usr/local/bin/memcached -p 11211 -m 64m -d</pre>
<p>这里使用的memcached启动选项的内容如下。</p>
<div>
<table border="0" cellspacing="1">
    <tbody>
        <tr>
            <td>选项</td>
            <td>说明</td>
        </tr>
        <tr>
            <td>-p</td>
            <td>使用的TCP端口。默认为11211</td>
        </tr>
        <tr>
            <td>-m</td>
            <td>最大内存大小。默认为64M</td>
        </tr>
        <tr>
            <td>-vv</td>
            <td>用very vrebose模式启动，调试信息和错误输出到控制台</td>
        </tr>
        <tr>
            <td>-d</td>
            <td>作为daemon在后台启动</td>
        </tr>
    </tbody>
</table>
</div>
<p>上面四个是常用的启动选项，其他还有很多，通过</p>
<pre>$ /usr/local/bin/memcached -h</pre>
<p>命令可以显示。许多选项可以改变memcached的各种行为，
推荐读一读。</p>
<h2 id="content_2_9">用客户端连接</h2>
<p>许多语言都实现了连接memcached的客户端，其中以Perl、PHP为主。
仅仅memcached网站上列出的语言就有</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li>Perl</li>
    <li>PHP</li>
    <li>Python</li>
    <li>Ruby</li>
    <li>C#</li>
    <li>C/C++</li>
    <li>Lua</li>
</ul>
<p>等等。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><strong>memcached客户端API</strong>：<a href="http://www.danga.com/memcached/apis.bml">http://www.danga.com/memcached/apis.bml</a></li>
</ul>
<p>这里介绍通过mixi正在使用的Perl库链接memcached的方法。</p>
<h2 id="content_2_10">使用Cache::Memcached</h2>
<p>Perl的memcached客户端有</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li>Cache::Memcached</li>
    <li>Cache::Memcached::Fast</li>
    <li>Cache::Memcached::libmemcached</li>
</ul>
<p>等几个CPAN模块。这里介绍的Cache::Memcached是memcached的作者Brad Fitzpatric的作品，
应该算是memcached的客户端中应用最为广泛的模块了。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><strong>Cache::Memcached - search.cpan.org</strong>: <a href="http://search.cpan.org/dist/Cache-Memcached/">http://search.cpan.org/dist/Cache-Memcached/</a></li>
</ul>
<h3 id="content_2_11">使用Cache::Memcached连接memcached</h3>
<p>下面的源代码为通过Cache::Memcached连接刚才启动的memcached的例子。</p>
<pre>#!/usr/bin/perl<br />
<br />
<br />
<br />
use strict;<br />
<br />
use warnings;<br />
<br />
use Cache::Memcached;<br />
<br />
<br />
<br />
my $key = "foo";<br />
<br />
my $value = "bar";<br />
<br />
my $expires = 3600; # 1 hour<br />
<br />
my $memcached = Cache::Memcached-&gt;new({<br />
<br />
servers =&gt; ["127.0.0.1:11211"],<br />
<br />
compress_threshold =&gt; 10_000<br />
<br />
});<br />
<br />
<br />
<br />
$memcached-&gt;add($key, $value, $expires);<br />
<br />
my $ret = $memcached-&gt;get($key);<br />
<br />
print "$ret"n";</pre>
<p>在这里，为Cache::Memcached指定了memcached服务器的IP地址和一个选项，以生成实例。
Cache::Memcached常用的选项如下所示。</p>
<div>
<table border="0" cellspacing="1">
    <tbody>
        <tr>
            <td>选项</td>
            <td>说明</td>
        </tr>
        <tr>
            <td>servers</td>
            <td>用数组指定memcached服务器和端口</td>
        </tr>
        <tr>
            <td>compress_threshold</td>
            <td>数据压缩时使用的值</td>
        </tr>
        <tr>
            <td>namespace</td>
            <td>指定添加到键的前缀</td>
        </tr>
    </tbody>
</table>
</div>
<p>另外，Cache::Memcached通过Storable模块可以将Perl的复杂数据序列化之后再保存，
因此散列、数组、对象等都可以直接保存到memcached中。</p>
<h3 id="content_2_12">保存数据</h3>
<p>向memcached保存数据的方法有</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li>add</li>
    <li>replace</li>
    <li>set</li>
</ul>
<p>它们的使用方法都相同：</p>
<pre>my $add = $memcached-&gt;add( '键', '值', '期限' );<br />
<br />
my $replace = $memcached-&gt;replace( '键', '值', '期限' );<br />
<br />
my $set = $memcached-&gt;set( '键', '值', '期限' );</pre>
<p>向memcached保存数据时可以指定期限(秒)。不指定期限时，memcached按照LRU算法保存数据。
这三个方法的区别如下：</p>
<div>
<table border="0" cellspacing="1">
    <tbody>
        <tr>
            <td>选项</td>
            <td>说明</td>
        </tr>
        <tr>
            <td>add</td>
            <td>仅当存储空间中不存在键相同的数据时才保存</td>
        </tr>
        <tr>
            <td>replace</td>
            <td>仅当存储空间中存在键相同的数据时才保存</td>
        </tr>
        <tr>
            <td>set</td>
            <td>与add和replace不同，无论何时都保存</td>
        </tr>
    </tbody>
</table>
</div>
<h3 id="content_2_13">获取数据</h3>
<p>获取数据可以使用get和get_multi方法。</p>
<pre>my $val = $memcached-&gt;get('键');<br />
<br />
my $val = $memcached-&gt;get_multi('键1', '键2', '键3', '键4', '键5');</pre>
<p>一次取得多条数据时使用get_multi。get_multi可以非同步地同时取得多个键值，
其速度要比循环调用get快数十倍。</p>
<h3 id="content_2_14">删除数据</h3>
<p>删除数据使用delete方法，不过它有个独特的功能。</p>
<pre>$memcached-&gt;delete('键', '阻塞时间(秒)');</pre>
<p>删除第一个参数指定的键的数据。第二个参数指定一个时间值，可以禁止使用同样的键保存新数据。
此功能可以用于防止缓存数据的不完整。但是要注意，<strong>set函数忽视该阻塞，照常保存数据</strong></p>
<h3 id="content_2_15">增一和减一操作</h3>
<p>可以将memcached上特定的键值作为计数器使用。</p>
<pre>my $ret = $memcached-&gt;incr('键');<br />
<br />
$memcached-&gt;add('键', 0) unless defined $ret;</pre>
<p>增一和减一是原子操作，但未设置初始值时，不会自动赋成0。因此，
应当进行错误检查，必要时加入初始化操作。而且，服务器端也不会对
超过2&lt;sup&gt;32&lt;/sup&gt;时的行为进行检查。</p>
<h2 id="content_2_16">总结</h2>
<p>这次简单介绍了memcached，以及它的安装方法、Perl客户端Cache::Memcached的用法。
只要知道，memcached的使用方法十分简单就足够了。</p>
<p>下次由前坂来说明memcached的内部结构。了解memcached的内部构造，
就能知道如何使用memcached才能使Web应用的速度更上一层楼。
欢迎继续阅读下一章。</p>
<p><br />
</p>
<h1>2.理解memcached的内存存储</h1>
<br />
<p>下面是《memcached全面剖析》的第二部分。</p>
<p>发表日：2008/7/9 <br />
作者：前坂徹(Toru Maesaka) <br />
原文链接：<a href="http://gihyo.jp/dev/feature/01/memcached/0002">http://gihyo.jp/dev/feature/01/memcached/0002</a></p>
<p>我是<a href="http://mixi.jp/">mixi株式会社</a>研究开发组的前坂徹。
<a href="http://tech.idv2.com/2008/07/10/memcached-001/">上次</a>的文章介绍了memcached是分布式的高速缓存服务器。
本次将介绍memcached的内部构造的实现方式，以及内存的管理方式。
另外，memcached的内部构造导致的弱点也将加以说明。</p>
<h2 id="content_2_0">Slab Allocation机制：整理内存以便重复使用</h2>
<p>最近的memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。
在该机制出现以前，内存的分配是通过对所有记录简单地进行malloc和free来进行的。
但是，这种方式会导致内存碎片，加重操作系统内存管理器的负担，最坏的情况下，
会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。</p>
<p>下面来看看Slab Allocator的原理。下面是memcached文档中的slab allocator的目标：</p>
<p>the primary goal of the slabs subsystem in memcached was to
eliminate memory fragmentation issues totally by using fixed-size
memory chunks coming from a few predetermined size classes.</p>
<p>也就是说，Slab Allocator的基本原理是按照预先规定的大小，将分配的内存分割成特定长度的块，
以完全解决内存碎片问题。</p>
<p>Slab Allocation的原理相当简单。 将分配的内存分割成各种尺寸的块（chunk），
并把尺寸相同的块分成组（chunk的集合）（图1）。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092816564538.png" alt="" /><br />
</div>
<p>图1 Slab Allocation的构造图</p>
<p>而且，slab allocator还有重复使用已分配的内存的目的。
也就是说，分配到的内存不会释放，而是重复利用。</p>
<h3 id="content_2_1">Slab Allocation的主要术语</h3>
<p><strong>Page</strong></p>
<p>分配给Slab的内存空间，默认是1MB。分配给Slab之后根据slab的大小切分成chunk。</p>
<p><strong>Chunk</strong></p>
<p>用于缓存记录的内存空间。</p>
<p><strong>Slab Class</strong></p>
<p>特定大小的chunk的组。</p>
<h2 id="content_2_2">在Slab中缓存记录的原理</h2>
<p>下面说明memcached如何针对客户端发送的数据选择slab并缓存到chunk中。</p>
<p>memcached根据收到的数据的大小，选择最适合数据大小的slab（图2）。
memcached中保存着slab内空闲chunk的列表，根据该列表选择chunk，
然后将数据缓存于其中。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092816571451.png" alt="" /><br />
</div>
<p>图2 选择存储记录的组的方法</p>
<p>实际上，Slab Allocator也是有利也有弊。下面介绍一下它的缺点。</p>
<h2 id="content_2_3">Slab Allocator的缺点</h2>
<p>Slab Allocator解决了当初的内存碎片问题，但新的机制也给memcached带来了新的问题。</p>
<p>这个问题就是，由于分配的是特定长度的内存，因此无法有效利用分配的内存。
例如，将100字节的数据缓存到128字节的chunk中，剩余的28字节就浪费了（图3）。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092816574192.png" alt="" /><br />
</div>
<p>图3 chunk空间的使用</p>
<p>对于该问题目前还没有完美的解决方案，但在文档中记载了比较有效的解决方案。</p>
<p>The most efficient way to reduce the waste is to use a list of size
classes that closely matches (if that's at all possible) common sizes
of objects that the clients of this particular installation of
memcached are likely to store.</p>
<p>就是说，如果预先知道客户端发送的数据的公用大小，或者仅缓存大小相同的数据的情况下，
只要使用适合数据大小的组的列表，就可以减少浪费。</p>
<p>但是很遗憾，现在还不能进行任何调优，只能期待以后的版本了。
但是，我们可以调节slab class的大小的差别。
接下来说明growth factor选项。</p>
<h2 id="content_2_4">使用Growth Factor进行调优</h2>
<p>memcached在启动时指定 Growth Factor因子（通过-f选项），
就可以在某种程度上控制slab之间的差异。默认值为1.25。
但是，在该选项出现之前，这个因子曾经固定为2，称为&#8220;powers of 2&#8221;策略。</p>
<p>让我们用以前的设置，以verbose模式启动memcached试试看：</p>
<pre>$ memcached -f 2 -vv</pre>
<p>下面是启动后的verbose输出：</p>
<pre>slab class   1: chunk size    128 perslab  8192<br />
<br />
slab class   2: chunk size    256 perslab  4096<br />
<br />
slab class   3: chunk size    512 perslab  2048<br />
<br />
slab class   4: chunk size   1024 perslab  1024<br />
<br />
slab class   5: chunk size   2048 perslab   512<br />
<br />
slab class   6: chunk size   4096 perslab   256<br />
<br />
slab class   7: chunk size   8192 perslab   128<br />
<br />
slab class   8: chunk size  16384 perslab    64<br />
<br />
slab class   9: chunk size  32768 perslab    32<br />
<br />
slab class  10: chunk size  65536 perslab    16<br />
<br />
slab class  11: chunk size 131072 perslab     8<br />
<br />
slab class  12: chunk size 262144 perslab     4<br />
<br />
slab class  13: chunk size 524288 perslab     2</pre>
<p>可见，从128字节的组开始，组的大小依次增大为原来的2倍。
这样设置的问题是，slab之间的差别比较大，有些情况下就相当浪费内存。
因此，为尽量减少内存浪费，两年前追加了growth factor这个选项。</p>
<p>来看看现在的默认设置（f=1.25）时的输出（篇幅所限，这里只写到第10组）：</p>
<pre>slab class   1: chunk size     88 perslab 11915<br />
<br />
slab class   2: chunk size    112 perslab  9362<br />
<br />
slab class   3: chunk size    144 perslab  7281<br />
<br />
slab class   4: chunk size    184 perslab  5698<br />
<br />
slab class   5: chunk size    232 perslab  4519<br />
<br />
slab class   6: chunk size    296 perslab  3542<br />
<br />
slab class   7: chunk size    376 perslab  2788<br />
<br />
slab class   8: chunk size    472 perslab  2221<br />
<br />
slab class   9: chunk size    592 perslab  1771<br />
<br />
slab class  10: chunk size    744 perslab  1409</pre>
<p>可见，组间差距比因子为2时小得多，更适合缓存几百字节的记录。
从上面的输出结果来看，可能会觉得有些计算误差，
这些误差是为了保持字节数的对齐而故意设置的。</p>
<p>将memcached引入产品，或是直接使用默认值进行部署时，
最好是重新计算一下数据的预期平均长度，调整growth factor，
以获得最恰当的设置。内存是珍贵的资源，浪费就太可惜了。</p>
<p>接下来介绍一下如何使用memcached的stats命令查看slabs的利用率等各种各样的信息。</p>
<h2 id="content_2_5">查看memcached的内部状态</h2>
<p>memcached有个名为stats的命令，使用它可以获得各种各样的信息。
执行命令的方法很多，用telnet最为简单：</p>
<pre>$ telnet 主机名 端口号</pre>
<p>连接到memcached之后，输入stats再按回车，即可获得包括资源利用率在内的各种信息。
此外，输入"stats slabs"或"stats items"还可以获得关于缓存记录的信息。
结束程序请输入quit。</p>
<p>这些命令的详细信息可以参考memcached软件包内的protocol.txt文档。</p>
<pre>$ telnet localhost 11211<br />
<br />
Trying ::1...<br />
<br />
Connected to localhost.<br />
<br />
Escape character is '^]'.<br />
<br />
stats<br />
<br />
STAT pid 481<br />
<br />
STAT uptime 16574<br />
<br />
STAT time 1213687612<br />
<br />
STAT version 1.2.5<br />
<br />
STAT pointer_size 32<br />
<br />
STAT rusage_user 0.102297<br />
<br />
STAT rusage_system 0.214317<br />
<br />
STAT curr_items 0<br />
<br />
STAT total_items 0<br />
<br />
STAT bytes 0<br />
<br />
STAT curr_connections 6<br />
<br />
STAT total_connections 8<br />
<br />
STAT connection_structures 7<br />
<br />
STAT cmd_get 0<br />
<br />
STAT cmd_set 0<br />
<br />
STAT get_hits 0<br />
<br />
STAT get_misses 0<br />
<br />
STAT evictions 0<br />
<br />
STAT bytes_read 20<br />
<br />
STAT bytes_written 465<br />
<br />
STAT limit_maxbytes 67108864<br />
<br />
STAT threads 4<br />
<br />
END<br />
<br />
quit</pre>
<p>另外，如果安装了libmemcached这个面向C/C++语言的客户端库，就会安装 memstat 这个命令。
使用方法很简单，可以用更少的步骤获得与telnet相同的信息，还能一次性从多台服务器获得信息。</p>
<pre>$ memstat --servers=server1,server2,server3,...</pre>
<p>libmemcached可以从下面的地址获得：</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://tangent.org/552/libmemcached.html">http://tangent.org/552/libmemcached.html</a></li>
</ul>
<h2 id="content_2_6">查看slabs的使用状况</h2>
<p>使用memcached的创造着Brad写的名为memcached-tool的Perl脚本，可以方便地获得slab的使用情况
（它将memcached的返回值整理成容易阅读的格式）。可以从下面的地址获得脚本：</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://code.sixapart.com/svn/memcached/trunk/server/scripts/memcached-tool">http://code.sixapart.com/svn/memcached/trunk/server/scripts/memcached-tool</a></li>
</ul>
<p>使用方法也极其简单：</p>
<pre>$ memcached-tool 主机名:端口 选项</pre>
<p>查看slabs使用状况时无需指定选项，因此用下面的命令即可：</p>
<pre>$ memcached-tool 主机名:端口</pre>
<p>获得的信息如下所示：</p>
<pre> #  Item_Size   Max_age  1MB_pages Count   Full?<br />
<br />
1     104 B  1394292 s    1215 12249628    yes<br />
<br />
2     136 B  1456795 s      52  400919     yes<br />
<br />
3     176 B  1339587 s      33  196567     yes<br />
<br />
4     224 B  1360926 s     109  510221     yes<br />
<br />
5     280 B  1570071 s      49  183452     yes<br />
<br />
6     352 B  1592051 s      77  229197     yes<br />
<br />
7     440 B  1517732 s      66  157183     yes<br />
<br />
8     552 B  1460821 s      62  117697     yes<br />
<br />
9     696 B  1521917 s     143  215308     yes<br />
<br />
10     872 B  1695035 s     205  246162     yes<br />
<br />
11     1.1 kB 1681650 s     233  221968     yes<br />
<br />
12     1.3 kB 1603363 s     241  183621     yes<br />
<br />
13     1.7 kB 1634218 s      94   57197     yes<br />
<br />
14     2.1 kB 1695038 s      75   36488     yes<br />
<br />
15     2.6 kB 1747075 s      65   25203     yes<br />
<br />
16     3.3 kB 1760661 s      78   24167     yes</pre>
<p>各列的含义为：</p>
<div>
<table border="0" cellspacing="1">
    <tbody>
        <tr>
            <td>列</td>
            <td>含义</td>
        </tr>
        <tr>
            <td>#</td>
            <td>slab class编号</td>
        </tr>
        <tr>
            <td>Item_Size</td>
            <td>Chunk大小</td>
        </tr>
        <tr>
            <td>Max_age</td>
            <td>LRU内最旧的记录的生存时间</td>
        </tr>
        <tr>
            <td>1MB_pages</td>
            <td>分配给Slab的页数</td>
        </tr>
        <tr>
            <td>Count</td>
            <td>Slab内的记录数</td>
        </tr>
        <tr>
            <td>Full?</td>
            <td>Slab内是否含有空闲chunk</td>
        </tr>
    </tbody>
</table>
</div>
<p>从这个脚本获得的信息对于调优非常方便，强烈推荐使用。</p>
<h2 id="content_2_7">内存存储的总结</h2>
<p>本次简单说明了memcached的缓存机制和调优方法。
希望读者能理解memcached的内存管理原理及其优缺点。</p>
<p>下次将继续说明LRU和Expire等原理，以及memcached的最新发展方向——
可扩充体系（pluggable architecher））。</p>
<p><br />
</p>
<h1>3.memcached的删除机制和发展方向</h1>
<br />
<p>下面是《memcached全面剖析》的第三部分。</p>
<p>发表日：2008/7/16 <br />
作者：前坂徹(Toru Maesaka) <br />
原文链接：<a href="http://gihyo.jp/dev/feature/01/memcached/0003">http://gihyo.jp/dev/feature/01/memcached/0003</a></p>
<p>memcached是缓存，所以数据不会永久保存在服务器上，这是向系统中引入memcached的前提。
本次介绍memcached的数据删除机制，以及memcached的最新发展方向——二进制协议（Binary Protocol）
和外部引擎支持。</p>
<h2 id="content_2_0">memcached在数据删除方面有效利用资源</h2>
<h3 id="content_2_1">数据不会真正从memcached中消失</h3>
<p><a href="http://tech.idv2.com/2008/07/11/memcached-002/">上次</a>介绍过，
memcached不会释放已分配的内存。记录超时后，客户端就无法再看见该记录（invisible，透明），
其存储空间即可重复使用。</p>
<h3 id="content_2_2">Lazy Expiration</h3>
<p>memcached内部不会监视记录是否过期，而是在get时查看记录的时间戳，检查记录是否过期。
这种技术被称为lazy（惰性）expiration。因此，memcached不会在过期监视上耗费CPU时间。</p>
<h2 id="content_2_3">LRU：从缓存中有效删除数据的原理</h2>
<p>memcached会优先使用已超时的记录的空间，但即使如此，也会发生追加新记录时空间不足的情况，
此时就要使用名为 Least Recently Used（LRU）机制来分配空间。
顾名思义，这是删除&#8220;最近最少使用&#8221;的记录的机制。
因此，当memcached的内存空间不足时（无法从<a href="http://tech.idv2.com/2008/07/11/memcached-002/">slab class</a>
获取到新的空间时），就从最近未被使用的记录中搜索，并将其空间分配给新的记录。
从缓存的实用角度来看，该模型十分理想。</p>
<p>不过，有些情况下LRU机制反倒会造成麻烦。memcached启动时通过&#8220;-M&#8221;参数可以禁止LRU，如下所示：</p>
<pre>$ memcached -M -m 1024</pre>
<p>启动时必须注意的是，小写的&#8220;-m&#8221;选项是用来指定最大内存大小的。不指定具体数值则使用默认值64MB。</p>
<p>指定&#8220;-M&#8221;参数启动后，内存用尽时memcached会返回错误。
话说回来，memcached毕竟不是存储器，而是缓存，所以推荐使用LRU。</p>
<h2 id="content_2_4">memcached的最新发展方向</h2>
<p>memcached的roadmap上有两个大的目标。一个是二进制协议的策划和实现，另一个是外部引擎的加载功能。</p>
<h3 id="content_2_5">关于二进制协议</h3>
<p>使用二进制协议的理由是它不需要文本协议的解析处理，使得原本高速的memcached的性能更上一层楼，
还能减少文本协议的漏洞。目前已大部分实现，开发用的代码库中已包含了该功能。
memcached的下载页面上有代码库的链接。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://danga.com/memcached/download.bml">http://danga.com/memcached/download.bml</a></li>
</ul>
<h3 id="content_2_6">二进制协议的格式</h3>
<p>协议的包为24字节的帧，其后面是键和无结构数据（Unstructured Data）。
实际的格式如下（引自协议文档）：</p>
<pre> Byte/     0       |       1       |       2       |       3       |   <br />
<br />
/              |               |               |               |   <br />
<br />
|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|<br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
0/ HEADER                                                        /   <br />
<br />
/                                                               /   <br />
<br />
/                                                               /   <br />
<br />
/                                                               /   <br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
24/ COMMAND-SPECIFIC EXTRAS (as needed)                           /   <br />
<br />
+/  (note length in th extras length header field)               /   <br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
m/ Key (as needed)                                               /   <br />
<br />
+/  (note length in key length header field)                     /   <br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
n/ Value (as needed)                                             /   <br />
<br />
+/  (note length is total body length header field, minus        /   <br />
<br />
+/   sum of the extras and key length body fields)               /   <br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
Total 24 bytes</pre>
<p>如上所示，包格式十分简单。需要注意的是，占据了16字节的头部(HEADER)分为
请求头（Request Header）和响应头（Response Header）两种。
头部中包含了表示包的有效性的Magic字节、命令种类、键长度、值长度等信息，格式如下：</p>
<pre>Request Header<br />
<br />
<br />
<br />
Byte/     0       |       1       |       2       |       3       |<br />
<br />
/              |               |               |               |<br />
<br />
|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|<br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
0| Magic         | Opcode        | Key length                    |<br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
4| Extras length | Data type     | Reserved                      |<br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
8| Total body length                                             |<br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
12| Opaque                                                        |<br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
16| CAS                                                           |<br />
<br />
|                                                               |<br />
<br />
+---------------+---------------+---------------+---------------+</pre>
<pre>Response Header<br />
<br />
<br />
<br />
Byte/     0       |       1       |       2       |       3       |<br />
<br />
/              |               |               |               |<br />
<br />
|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|<br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
0| Magic         | Opcode        | Key Length                    |<br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
4| Extras length | Data type     | Status                        |<br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
8| Total body length                                             |<br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
12| Opaque                                                        |<br />
<br />
+---------------+---------------+---------------+---------------+<br />
<br />
16| CAS                                                           |<br />
<br />
|                                                               |<br />
<br />
+---------------+---------------+---------------+---------------+</pre>
<p>如希望了解各个部分的详细内容，可以checkout出memcached的二进制协议的代码树，
参考其中的docs文件夹中的protocol_binary.txt文档。</p>
<h3 id="content_2_7">HEADER中引人注目的地方</h3>
<p>看到HEADER格式后我的感想是，键的上限太大了！现在的memcached规格中，键长度最大为250字节，
但二进制协议中键的大小用2字节表示。因此，理论上最大可使用65536字节（2&lt;sup&gt;16&lt;/sup&gt;）长的键。
尽管250字节以上的键并不会太常用，二进制协议发布之后就可以使用巨大的键了。</p>
<p>二进制协议从下一版本1.3系列开始支持。</p>
<h2 id="content_2_8">外部引擎支持</h2>
<p>我去年曾经试验性地将memcached的存储层改造成了可扩展的（pluggable）。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://alpha.mixi.co.jp/blog/?p=129">http://alpha.mixi.co.jp/blog/?p=129</a></li>
</ul>
<p>MySQL的Brian Aker看到这个改造之后，就将代码发到了memcached的邮件列表。
memcached的开发者也十分感兴趣，就放到了roadmap中。现在由我和
memcached的开发者Trond Norbye协同开发（规格设计、实现和测试）。
和国外协同开发时时差是个大问题，但抱着相同的愿景，
最后终于可以将可扩展架构的原型公布了。
代码库可以从<a href="http://danga.com/memcached/download.bml">memcached的下载页面</a>
上访问。</p>
<h3 id="content_2_9">外部引擎支持的必要性</h3>
<p>世界上有许多memcached的派生软件，其理由是希望永久保存数据、实现数据冗余等，
即使牺牲一些性能也在所不惜。我在开发memcached之前，在mixi的研发部也曾经
考虑过重新发明memcached。</p>
<p>外部引擎的加载机制能封装memcached的网络功能、事件处理等复杂的处理。
因此，现阶段通过强制手段或重新设计等方式使memcached和存储引擎合作的困难
就会烟消云散，尝试各种引擎就会变得轻而易举了。</p>
<h3 id="content_2_10">简单API设计的成功的关键</h3>
<p>该项目中我们最重视的是API设计。函数过多，会使引擎开发者感到麻烦；
过于复杂，实现引擎的门槛就会过高。因此，最初版本的接口函数只有13个。
具体内容限于篇幅，这里就省略了，仅说明一下引擎应当完成的操作：</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li>引擎信息（版本等）</li>
    <li>引擎初始化</li>
    <li>引擎关闭</li>
    <li>引擎的统计信息</li>
    <li>在容量方面，测试给定记录能否保存</li>
    <li>为item（记录）结构分配内存</li>
    <li>释放item（记录）的内存</li>
    <li>删除记录</li>
    <li>保存记录</li>
    <li>回收记录</li>
    <li>更新记录的时间戳</li>
    <li>数学运算处理</li>
    <li>数据的flush</li>
</ul>
<p>对详细规格有兴趣的读者，可以checkout engine项目的代码，阅读器中的engine.h。</p>
<h3 id="content_2_11">重新审视现在的体系</h3>
<p>memcached支持外部存储的难点是，网络和事件处理相关的代码（核心服务器）与
内存存储的代码紧密关联。这种现象也称为tightly coupled（紧密耦合）。
必须将内存存储的代码从核心服务器中独立出来，才能灵活地支持外部引擎。
因此，基于我们设计的API，memcached被重构成下面的样子：</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092817035014.png" alt="" /><br />
</div>
<p>重构之后，我们与1.2.5版、二进制协议支持版等进行了性能对比，证实了它不会造成性能影响。</p>
<p>在考虑如何支持外部引擎加载时，让memcached进行并行控制（concurrency control）的方案是最为容易的，
但是对于引擎而言，并行控制正是性能的真谛，因此我们采用了将多线程支持完全交给引擎的设计方案。</p>
<p>以后的改进，会使得memcached的应用范围更为广泛。</p>
<h2 id="content_2_12">总结</h2>
<p>本次介绍了memcached的超时原理、内部如何删除数据等，在此之上又介绍了二进制协议和
外部引擎支持等memcached的最新发展方向。这些功能要到1.3版才会支持，敬请期待！</p>
<p>这是我在本连载中的最后一篇。感谢大家阅读我的文章！</p>
<p>下次由长野来介绍memcached的应用知识和应用程序兼容性等内容。</p>
<p><br />
</p>
<p><br />
</p>
<h1>4. memcached的分布式算法</h1>
<br />
<p>发表日：2008/7/23 <br />
作者：长野雅广(Masahiro Nagano) <br />
原文链接：<a href="http://gihyo.jp/dev/feature/01/memcached/0004">http://gihyo.jp/dev/feature/01/memcached/0004</a></p>
<p>我是Mixi的长野。
<a href="http://tech.idv2.com/2008/07/11/memcached-002/">第2次</a>、
<a href="http://tech.idv2.com/2008/07/16/memcached-003/">第3次</a>
由前坂介绍了memcached的内部情况。本次不再介绍memcached的内部结构，
开始介绍memcached的分布式。</p>
<h2 id="content_2_0">memcached的分布式</h2>
<p>正如<a href="http://tech.idv2.com/2008/07/10/memcached-001/">第1次</a>中介绍的那样，
memcached虽然称为&#8220;分布式&#8221;缓存服务器，但服务器端并没有&#8220;分布式&#8221;功能。
服务器端仅包括
<a href="http://tech.idv2.com/2008/07/11/memcached-002/">第2次</a>、
<a href="http://tech.idv2.com/2008/07/16/memcached-003/">第3次</a>
前坂介绍的内存存储功能，其实现非常简单。
至于memcached的分布式，则是完全由客户端程序库实现的。
这种分布式是memcached的最大特点。</p>
<h3 id="content_2_1">memcached的分布式是什么意思？</h3>
<p>这里多次使用了&#8220;分布式&#8221;这个词，但并未做详细解释。
现在开始简单地介绍一下其原理，各个客户端的实现基本相同。</p>
<p>下面假设memcached服务器有node1～node3三台，
应用程序要保存键名为&#8220;tokyo&#8221;&#8220;kanagawa&#8221;&#8220;chiba&#8221;&#8220;saitama&#8221;&#8220;gunma&#8221;
的数据。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092817111437.png" alt="" /><br />
</div>
<p>图1 分布式简介：准备</p>
<p>首先向memcached中添加&#8220;tokyo&#8221;。将&#8220;tokyo&#8221;传给客户端程序库后，
客户端实现的算法就会根据&#8220;键&#8221;来决定保存数据的memcached服务器。
服务器选定后，即命令它保存&#8220;tokyo&#8221;及其值。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092817114280.png" alt="" /><br />
</div>
<p>图2 分布式简介：添加时</p>
<p>同样，&#8220;kanagawa&#8221;&#8220;chiba&#8221;&#8220;saitama&#8221;&#8220;gunma&#8221;都是先选择服务器再保存。</p>
<p>接下来获取保存的数据。获取时也要将要获取的键&#8220;tokyo&#8221;传递给函数库。
函数库通过与数据保存时相同的算法，根据&#8220;键&#8221;选择服务器。
使用的算法相同，就能选中与保存时相同的服务器，然后发送get命令。
只要数据没有因为某些原因被删除，就能获得保存的值。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092817121928.png" alt="" /><br />
</div>
<p>图3 分布式简介：获取时</p>
<p>这样，将不同的键保存到不同的服务器上，就实现了memcached的分布式。
memcached服务器增多后，键就会分散，即使一台memcached服务器发生故障
无法连接，也不会影响其他的缓存，系统依然能继续运行。</p>
<p>接下来介绍<a href="http://tech.idv2.com/2008/07/10/memcached-001/">第1次</a>
中提到的Perl客户端函数库Cache::Memcached实现的分布式方法。</p>
<h2 id="content_2_2">Cache::Memcached的分布式方法</h2>
<p>Perl的memcached客户端函数库Cache::Memcached是
memcached的作者Brad Fitzpatrick的作品，可以说是原装的函数库了。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://search.cpan.org/dist/Cache-Memcached/">Cache::Memcached - search.cpan.org</a></li>
</ul>
<p>该函数库实现了分布式功能，是memcached标准的分布式方法。</p>
<h3 id="content_2_3">根据余数计算分散</h3>
<p>Cache::Memcached的分布式方法简单来说，就是&#8220;根据服务器台数的余数进行分散&#8221;。
求得键的整数哈希值，再除以服务器台数，根据其余数来选择服务器。</p>
<p>下面将Cache::Memcached简化成以下的Perl脚本来进行说明。</p>
<pre>use strict;<br />
<br />
use warnings;<br />
<br />
use String::CRC32;<br />
<br />
<br />
<br />
my @nodes = ('node1','node2','node3');<br />
<br />
my @keys = ('tokyo', 'kanagawa', 'chiba', 'saitama', 'gunma');<br />
<br />
<br />
<br />
foreach my $key (@keys) {<br />
<br />
my $crc = crc32($key);             # CRC値<br />
<br />
my $mod = $crc % ( $#nodes + 1 );<br />
<br />
my $server = $nodes[ $mod ];       # 根据余数选择服务器<br />
<br />
printf "%s =&gt; %s"n", $key, $server;<br />
<br />
}</pre>
<p>Cache::Memcached在求哈希值时使用了CRC。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://search.cpan.org/dist/String-CRC32/">String::CRC32 - search.cpan.org</a></li>
</ul>
<p>首先求得字符串的CRC值，根据该值除以服务器节点数目得到的余数决定服务器。
上面的代码执行后输入以下结果：</p>
<pre>tokyo       =&gt; node2<br />
<br />
kanagawa =&gt; node3<br />
<br />
chiba       =&gt; node2<br />
<br />
saitama   =&gt; node1<br />
<br />
gunma     =&gt; node1</pre>
<p>根据该结果，&#8220;tokyo&#8221;分散到node2，&#8220;kanagawa&#8221;分散到node3等。
多说一句，当选择的服务器无法连接时，Cache::Memcached会将连接次数
添加到键之后，再次计算哈希值并尝试连接。这个动作称为rehash。
不希望rehash时可以在生成Cache::Memcached对象时指定&#8220;rehash =&gt; 0&#8221;选项。</p>
<h3 id="content_2_4">根据余数计算分散的缺点</h3>
<p>余数计算的方法简单，数据的分散性也相当优秀，但也有其缺点。
那就是当添加或移除服务器时，缓存重组的代价相当巨大。
添加服务器后，余数就会产生巨变，这样就无法获取与保存时相同的服务器，
从而影响缓存的命中率。用Perl写段代码来验证其代价。</p>
<pre>use strict;<br />
<br />
use warnings;<br />
<br />
use String::CRC32;<br />
<br />
<br />
<br />
my @nodes = @ARGV;<br />
<br />
my @keys = ('a'..'z');<br />
<br />
my %nodes;<br />
<br />
<br />
<br />
foreach my $key ( @keys ) {<br />
<br />
my $hash = crc32($key);<br />
<br />
my $mod = $hash % ( $#nodes + 1 );<br />
<br />
my $server = $nodes[ $mod ];<br />
<br />
push @{ $nodes{ $server } }, $key;<br />
<br />
}<br />
<br />
<br />
<br />
foreach my $node ( sort keys %nodes ) {<br />
<br />
printf "%s: %s"n", $node,  join ",", @{ $nodes{$node} };<br />
<br />
}</pre>
<p>这段Perl脚本演示了将&#8220;a&#8221;到&#8220;z&#8221;的键保存到memcached并访问的情况。
将其保存为mod.pl并执行。</p>
<p>首先，当服务器只有三台时：</p>
<pre>$ mod.pl node1 node2 nod3<br />
<br />
node1: a,c,d,e,h,j,n,u,w,x<br />
<br />
node2: g,i,k,l,p,r,s,y<br />
<br />
node3: b,f,m,o,q,t,v,z</pre>
<p>结果如上，node1保存a、c、d、e&#8230;&#8230;，node2保存g、i、k&#8230;&#8230;，
每台服务器都保存了8个到10个数据。</p>
<p>接下来增加一台memcached服务器。</p>
<pre>$ mod.pl node1 node2 node3 node4<br />
<br />
node1: d,f,m,o,t,v<br />
<br />
node2: b,i,k,p,r,y<br />
<br />
node3: e,g,l,n,u,w<br />
<br />
node4: a,c,h,j,q,s,x,z</pre>
<p>添加了node4。可见，只有d、i、k、p、r、y命中了。像这样，添加节点后
键分散到的服务器会发生巨大变化。26个键中只有六个在访问原来的服务器，
其他的全都移到了其他服务器。命中率降低到23%。在Web应用程序中使用memcached时，
在添加memcached服务器的瞬间缓存效率会大幅度下降，负载会集中到数据库服务器上，
有可能会发生无法提供正常服务的情况。</p>
<p>mixi的Web应用程序运用中也有这个问题，导致无法添加memcached服务器。
但由于使用了新的分布式方法，现在可以轻而易举地添加memcached服务器了。
这种分布式方法称为 Consistent Hashing。</p>
<h2 id="content_2_5">Consistent Hashing</h2>
<p>关于Consistent Hashing的思想，mixi株式会社的开发blog等许多地方都介绍过，
这里只简单地说明一下。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://alpha.mixi.co.jp/blog/?p=158">mixi Engineers' Blog - スマートな分散で快適キャッシュライフ </a></li>
    <li><a href="http://www.hyuki.com/yukiwiki/wiki.cgi?ConsistentHashing">ConsistentHashing - コンシステント ハッシュ法</a></li>
</ul>
<h3 id="content_2_6">Consistent Hashing的简单说明</h3>
<p>Consistent Hashing如下所示：首先求出memcached服务器（节点）的哈希值，
并将其配置到0～2<sup>32</sup>的圆（continuum）上。
然后用同样的方法求出存储数据的键的哈希值，并映射到圆上。
然后从数据映射到的位置开始顺时针查找，将数据保存到找到的第一个服务器上。
如果超过2<sup>32</sup>仍然找不到服务器，就会保存到第一台memcached服务器上。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092817125369.png" alt="" /><br />
</div>
<p>图4 Consistent Hashing：基本原理</p>
<p>从上图的状态中添加一台memcached服务器。余数分布式算法由于保存键的服务器会发生巨大变化
而影响缓存的命中率，但Consistent Hashing中，只有在continuum上增加服务器的地点逆时针方向的
第一台服务器上的键会受到影响。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092817131010.png" alt="" /><br />
</div>
<p>图5 Consistent Hashing：添加服务器</p>
<p>因此，Consistent Hashing最大限度地抑制了键的重新分布。
而且，有的Consistent Hashing的实现方法还采用了虚拟节点的思想。
使用一般的hash函数的话，服务器的映射地点的分布非常不均匀。
因此，使用虚拟节点的思想，为每个物理节点（服务器）
在continuum上分配100～200个点。这样就能抑制分布不均匀，
最大限度地减小服务器增减时的缓存重新分布。</p>
<p>通过下文中介绍的使用Consistent Hashing算法的memcached客户端函数库进行测试的结果是，
由服务器台数（n）和增加的服务器台数（m）计算增加服务器后的命中率计算公式如下：</p>
<p>(1 - n/(n+m)) * 100</p>
<h3 id="content_2_7">支持Consistent Hashing的函数库</h3>
<p>本连载中多次介绍的Cache::Memcached虽然不支持Consistent Hashing，
但已有几个客户端函数库支持了这种新的分布式算法。
第一个支持Consistent Hashing和虚拟节点的memcached客户端函数库是
名为libketama的PHP库，由last.fm开发。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://www.lastfm.jp/user/RJ/journal/2007/04/10/rz_libketama_-_a_consistent_hashing_algo_for_memcache_clients">libketama - a consistent hashing algo for memcache clients &#8211; RJ ブログ - Users at Last.fm </a></li>
</ul>
<p>至于Perl客户端，连载的<a href="http://tech.idv2.com/2008/07/11/memcached-001/">第1次</a>
中介绍过的Cache::Memcached::Fast和Cache::Memcached::libmemcached支持
Consistent Hashing。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://search.cpan.org/dist/Cache-Memcached-Fast/">Cache::Memcached::Fast - search.cpan.org </a></li>
    <li><a href="http://search.cpan.org/dist/Cache-Memcached-libmemcached/">Cache::Memcached::libmemcached - search.cpan.org </a></li>
</ul>
<p>两者的接口都与Cache::Memcached几乎相同，如果正在使用Cache::Memcached，
那么就可以方便地替换过来。Cache::Memcached::Fast重新实现了libketama，
使用Consistent Hashing创建对象时可以指定ketama_points选项。</p>
<pre>my $memcached = Cache::Memcached::Fast-&gt;new({<br />
<br />
servers =&gt; ["192.168.0.1:11211","192.168.0.2:11211"],<br />
<br />
ketama_points =&gt; 150<br />
<br />
});</pre>
<p>另外，Cache::Memcached::libmemcached 是一个使用了Brain Aker开发的C函数库libmemcached的Perl模块。
libmemcached本身支持几种分布式算法，也支持Consistent Hashing，
其Perl绑定也支持Consistent Hashing。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://tangent.org/552/libmemcached.html">Tangent Software: libmemcached </a></li>
</ul>
<h2 id="content_2_8">总结</h2>
<p>本次介绍了memcached的分布式算法，主要有memcached的分布式是由客户端函数库实现，
以及高效率地分散数据的Consistent Hashing算法。下次将介绍mixi在memcached应用方面的一些经验，
和相关的兼容应用程序。</p>
<p><br />
</p>
<h1>5. memcached的应用和兼容程序</h1>
<br />
<p>发表日：2008/7/30 <br />
作者：长野雅广(Masahiro Nagano) <br />
原文链接：<a href="http://gihyo.jp/dev/feature/01/memcached/0005">http://gihyo.jp/dev/feature/01/memcached/0005</a></p>
<p>我是Mixi的长野。memcached的连载终于要结束了。
到<a href="http://tech.idv2.com/2008/07/24/memcached-004/">上次</a>为止，
我们介绍了与memcached直接相关的话题，本次介绍一些mixi的案例和
实际应用上的话题，并介绍一些与memcached兼容的程序。
</p>
<h2 id="content_2_0">mixi案例研究</h2>
<p>mixi在提供服务的初期阶段就使用了memcached。
随着网站访问量的急剧增加，单纯为数据库添加slave已无法满足需要，因此引入了memcached。
此外，我们也从增加可扩展性的方面进行了验证，证明了memcached的速度和稳定性都能满足需要。
现在，memcached已成为mixi服务中非常重要的组成部分。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092817263955.png" alt="" /><br />
</div>
<p>图1 现在的系统组件</p>
<h3 id="content_2_1">服务器配置和数量</h3>
<p>mixi使用了许许多多服务器，如数据库服务器、应用服务器、图片服务器、
反向代理服务器等。单单memcached就有将近200台服务器在运行。
memcached服务器的典型配置如下：</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li>CPU：Intel Pentium 4 2.8GHz</li>
    <li>内存：4GB</li>
    <li>硬盘：146GB SCSI</li>
    <li>操作系统：Linux（x86_64）</li>
</ul>
<p>这些服务器以前曾用于数据库服务器等。随着CPU性能提升、内存价格下降，
我们积极地将数据库服务器、应用服务器等换成了性能更强大、内存更多的服务器。
这样，可以抑制mixi整体使用的服务器数量的急剧增加，降低管理成本。
由于memcached服务器几乎不占用CPU，就将换下来的服务器用作memcached服务器了。</p>
<h3 id="content_2_2">memcached进程</h3>
<p>每台memcached服务器仅启动一个memcached进程。分配给memcached的内存为3GB，
启动参数如下：</p>
<pre>/usr/bin/memcached -p 11211 -u nobody -m 3000 -c 30720</pre>
<p>由于使用了x86_64的操作系统，因此能分配2GB以上的内存。32位操作系统中，
每个进程最多只能使用2GB内存。也曾经考虑过启动多个分配2GB以下内存的进程，
但这样一台服务器上的TCP连接数就会成倍增加，管理上也变得复杂，
所以mixi就统一使用了64位操作系统。</p>
<p>另外，虽然服务器的内存为4GB，却仅分配了3GB，是因为内存分配量超过这个值，
就有可能导致内存交换(swap)。连载的<a href="http://tech.idv2.com/2008/07/11/memcached-002/">第2次</a>中
前坂讲解过了memcached的内存存储&#8220;slab allocator&#8221;，当时说过，memcached启动时
指定的内存分配量是memcached用于保存数据的量，没有包括&#8220;slab allocator&#8221;本身占用的内存、
以及为了保存数据而设置的管理空间。因此，memcached进程的实际内存分配量要比
指定的容量要大，这一点应当注意。</p>
<p>mixi保存在memcached中的数据大部分都比较小。这样，进程的大小要比
指定的容量大很多。因此，我们反复改变内存分配量进行验证，
确认了3GB的大小不会引发swap，这就是现在应用的数值。</p>
<h3 id="content_2_3">memcached使用方法和客户端</h3>
<p>现在，mixi的服务将200台左右的memcached服务器作为一个pool使用。
每台服务器的容量为3GB，那么全体就有了将近600GB的巨大的内存数据库。
客户端程序库使用了本连载中多次提到车的Cache::Memcached::Fast，
与服务器进行交互。当然，缓存的分布式算法使用的是
<a href="http://tech.idv2.com/2008/07/24/memcached-004/">第4次</a>介绍过的
Consistent Hashing算法。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://search.cpan.org/dist/Cache-Memcached-Fast/">Cache::Memcached::Fast - search.cpan.org</a></li>
</ul>
<p>应用层上memcached的使用方法由开发应用程序的工程师自行决定并实现。
但是，为了防止车轮再造、防止Cache::Memcached::Fast上的教训再次发生，
我们提供了Cache::Memcached::Fast的wrap模块并使用。</p>
<h4 id="content_2_4">通过Cache::Memcached::Fast维持连接</h4>
<p>Cache::Memcached的情况下，与memcached的连接（文件句柄）保存在Cache::Memcached包内的类变量中。
在mod_perl和FastCGI等环境下，包内的变量不会像CGI那样随时重新启动，
而是在进程中一直保持。其结果就是不会断开与memcached的连接，
减少了TCP连接建立时的开销，同时也能防止短时间内反复进行TCP连接、断开
而导致的TCP端口资源枯竭。</p>
<p>但是，Cache::Memcached::Fast没有这个功能，所以需要在模块之外
将Cache::Memcached::Fast对象保持在类变量中，以保证持久连接。</p>
<pre>package Gihyo::Memcached;<br />
<br />
<br />
<br />
use strict;<br />
<br />
use warnings;<br />
<br />
use Cache::Memcached::Fast;<br />
<br />
<br />
<br />
my @server_list = qw/192.168.1.1:11211 192.168.1.1:11211/;<br />
<br />
my $fast;  ## 用于保持对象<br />
<br />
<br />
<br />
sub new {<br />
<br />
my $self  = bless {}, shift;<br />
<br />
if ( !$fast ) {<br />
<br />
$fast = Cache::Memcached::Fast-&gt;new({ servers =&gt; "@server_list });<br />
<br />
}<br />
<br />
$self-&gt;{_fast} = $fast;<br />
<br />
return $self;<br />
<br />
}<br />
<br />
<br />
<br />
sub get {<br />
<br />
my $self = shift;<br />
<br />
$self-&gt;{_fast}-&gt;get(@_);<br />
<br />
}</pre>
<p>上面的例子中，Cache::Memcached::Fast对象保存到类变量$fast中。</p>
<h4 id="content_2_5">公共数据的处理和rehash</h4>
<p>诸如mixi的主页上的新闻这样的所有用户共享的缓存数据、设置信息等数据，
会占用许多页，访问次数也非常多。在这种条件下，访问很容易集中到某台memcached服务器上。
访问集中本身并不是问题，但是一旦访问集中的那台服务器发生故障导致memcached无法连接，
就会产生巨大的问题。</p>
<p>连载的<a href="http://tech.idv2.com/2008/07/24/memcached-004/">第4次</a>
中提到，Cache::Memcached拥有rehash功能，即在无法连接保存数据的服务器的情况下，
会再次计算hash值，连接其他的服务器。</p>
<p>但是，Cache::Memcached::Fast没有这个功能。不过，它能够在连接服务器失败时，
短时间内不再连接该服务器的功能。</p>
<pre>my $fast = Cache::Memcached::Fast-&gt;new({<br />
<br />
max_failures     =&gt; 3,<br />
<br />
failure_timeout  =&gt; 1<br />
<br />
});</pre>
<p>在failure_timeout秒内发生max_failures以上次连接失败，就不再连接该memcached服务器。
我们的设置是1秒钟3次以上。</p>
<p>此外，mixi还为所有用户共享的缓存数据的键名设置命名规则，
符合命名规则的数据会自动保存到多台memcached服务器中，
取得时从中仅选取一台服务器。创建该函数库后，就可以使memcached服务器故障
不再产生其他影响。</p>
<h2 id="content_2_6">memcached应用经验</h2>
<p>到此为止介绍了memcached内部构造和函数库，接下来介绍一些其他的应用经验。</p>
<h3 id="content_2_7">通过daemontools启动</h3>
<p>通常情况下memcached运行得相当稳定，但mixi现在使用的最新版1.2.5
曾经发生过几次memcached进程死掉的情况。架构上保证了即使有几台memcached故障
也不会影响服务，不过对于memcached进程死掉的服务器，只要重新启动memcached，
就可以正常运行，所以采用了监视memcached进程并自动启动的方法。
于是使用了daemontools。</p>
<p>daemontools是qmail的作者DJB开发的UNIX服务管理工具集，
其中名为supervise的程序可用于服务启动、停止的服务重启等。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://cr.yp.to/daemontools.html">daemontools</a></li>
</ul>
<p>这里不介绍daemontools的安装了。mixi使用了以下的run脚本来启动memcached。</p>
<pre>#!/bin/sh<br />
<br />
<br />
<br />
if [ -f /etc/sysconfig/memcached ];then<br />
<br />
. /etc/sysconfig/memcached<br />
<br />
fi<br />
<br />
<br />
<br />
exec 2&gt;&amp;1<br />
<br />
exec /usr/bin/memcached -p $PORT -u $USER  -m $CACHESIZE -c $MAXCONN $OPTIONS</pre>
<h3 id="content_2_8">监视</h3>
<p>mixi使用了名为&#8220;nagios&#8221;的开源监视软件来监视memcached。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://www.nagios.org/">Nagios: Home</a></li>
</ul>
<p>在nagios中可以简单地开发插件，可以详细地监视memcached的get、add等动作。
不过mixi仅通过stats命令来确认memcached的运行状态。</p>
<pre>define command {<br />
<br />
command_name                   check_memcached<br />
<br />
command_line                   $USER1$/check_tcp -H $HOSTADDRESS$ -p 11211 -t 5 -E -s 'stats"r"nquit"r"n' -e 'uptime' -M crit<br />
<br />
}</pre>
<p>此外，mixi将stats目录的结果通过rrdtool转化成图形，进行性能监视，
并将每天的内存使用量做成报表，通过邮件与开发者共享。</p>
<h3 id="content_2_9">memcached的性能</h3>
<p>连载中已介绍过，memcached的性能十分优秀。我们来看看mixi的实际案例。
这里介绍的图表是服务所使用的访问最为集中的memcached服务器。</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092817275633.png" alt="" /><br />
</div>
<p>图2 请求数</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092817281265.png" alt="" /><br />
</div>
<p>图3 流量</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092817282573.png" alt="" /><br />
</div>
<p>图4 TCP连接数</p>
<p>从上至下依次为请求数、流量和TCP连接数。请求数最大为15000qps，
流量达到400Mbps，这时的连接数已超过了10000个。
该服务器没有特别的硬件，就是开头介绍的普通的memcached服务器。
此时的CPU利用率为：</p>
<div style="text-align: left;"><img src="http://pic001.cnblogs.com/img/dudu/200809/2008092817284036.png" alt="" /><br />
</div>
<p>图5 CPU利用率</p>
<p>可见，仍然有idle的部分。因此，memcached的性能非常高，
可以作为Web应用程序开发者放心地保存临时数据或缓存数据的地方。</p>
<h2 id="content_2_10">兼容应用程序</h2>
<p>memcached的实现和协议都十分简单，因此有很多与memcached兼容的实现。
一些功能强大的扩展可以将memcached的内存数据写到磁盘上，实现数据的持久性和冗余。
连载<a href="http://tech.idv2.com/2008/07/16/memcached-003/">第3次</a>
介绍过，以后的memcached的存储层将变成可扩展的（pluggable），逐渐支持这些功能。</p>
<p>这里介绍几个与memcached兼容的应用程序。</p>
<dl style="padding-left: 16px; margin-left: 16px;"><dt>repcached</dt><dd>为memcached提供复制(replication)功能的patch。</dd><dt>Flared</dt><dd>存储到QDBM。同时实现了异步复制和fail over等功能。</dd><dt>memcachedb</dt><dd>存储到BerkleyDB。还实现了message queue。</dd><dt>Tokyo Tyrant</dt><dd>将数据存储到Tokyo Cabinet。不仅与memcached协议兼容，还能通过HTTP进行访问。</dd></dl>
<h3 id="content_2_11">Tokyo Tyrant案例</h3>
<p>mixi使用了上述兼容应用程序中的Tokyo Tyrant。Tokyo Tyrant是平林开发的
Tokyo Cabinet DBM的网络接口。它有自己的协议，但也拥有memcached兼容协议，
也可以通过HTTP进行数据交换。Tokyo Cabinet虽然是一种将数据写到磁盘的实现，但速度相当快。</p>
<p>mixi并没有将Tokyo Tyrant作为缓存服务器，而是将它作为保存键值对组合的DBMS来使用。
主要作为存储用户上次访问时间的数据库来使用。它与几乎所有的mixi服务都有关，
每次用户访问页面时都要更新数据，因此负荷相当高。MySQL的处理十分笨重，
单独使用memcached保存数据又有可能会丢失数据，所以引入了Tokyo Tyrant。
但无需重新开发客户端，只需原封不动地使用Cache::Memcached::Fast即可，
这也是优点之一。关于Tokyo Tyrant的详细信息，请参考本公司的开发blog。</p>
<ul style="padding-left: 16px; margin-left: 16px;">
    <li><a href="http://alpha.mixi.co.jp/blog/?p=166">mixi Engineers' Blog - Tokyo Tyrantによる耐高負荷DBの構築</a></li>
    <li><a href="http://alpha.mixi.co.jp/blog/?p=185">mixi Engineers' Blog - Tokyo (Cabinet|Tyrant)の新機能</a></li>
</ul>
<h2 id="content_2_12">总结</h2>
<p>到本次为止，&#8220;memcached全面剖析&#8221;系列就结束了。我们介绍了memcached的基础、内部结构、
分散算法和应用等内容。读完后如果您能对memcached产生兴趣，就是我们的荣幸。
关于mixi的系统、应用方面的信息，请参考本公司的<a href="http://alpha.mixi.co.jp/">开发blog</a>。
感谢您的阅读。</p>
<p><br />
</p>
<p><br />
</p>
<p><br />
</p>
<p><br />
</p>
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/285323.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-07-03 12:20 <a href="http://www.blogjava.net/ruoyoux/articles/285323.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/07/03 How to install NGINX</title><link>http://www.blogjava.net/ruoyoux/articles/285313.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Fri, 03 Jul 2009 03:28:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/285313.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/285313.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/285313.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/285313.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/285313.html</trackback:ping><description><![CDATA[<div entry-content="">
Nginx (pronounced Engine-X) is a russian open source httpd server originally written by <a href="http://sysoev.ru/en/">Igor Sysoev</a>
back in 2005. Nginx is a very light weight httpd server and reverse
proxy. It is estimated that approx. 3 per cent of all web servers run
nginx. In Russia the number is as high as 20 percent, including some of
their biggest web sites. Nginx is also used by Wordpress.com and 4chan.<br />
<br />
Why
use Nginx instead of Apache or Lighty? Nginx should be fast. I mean
FAST. Fast in a way of over 10000 concurrent requests / sec per server.
Now that's fast!<br />
<br />
I have wanted to screw 'round with Nginx for a while, so here goes nothing!<br />
<br />
<span style="font-weight: bold;">How to install Nginx on your Linux box</span><br />
<br />
Nginx can be downloaded from <a href="http://www.nginx.net/">www.nginx.net</a>. Simple web page displays the latest distribution packages and small introduction. Further instructions can be found from <a href="http://wiki.codemongers.com/">Nginx Wiki</a>.<br />
<br />
I
installed Nginx on my CentOs 5.1 running on VMWare &amp; Macbook.
Nginx's version was 0.6.32. The default installation is very
straightforward - <span style="font-style: italic;">configure, make &amp; make install</span>.
I had to install pcre packages to my box before installing httpd server
in order to enable rewrite module. I also used --prefix module to
install application where i wanted:<br />
<br />
<span style="font-style: italic;">[root@cluster1 nginx-0.6.32]# ./configure --prefix=/opt/nginx-0.6.32</span><br />
<span style="font-style: italic;">[root@cluster1 nginx-0.6.32]# make</span><br />
<span style="font-style: italic;">[root@cluster1 nginx-0.6.32]# make install</span><br />
<br />
After this Nginx is ready to serve static files!<br />
<br />
<br />
<span style="font-weight: bold;">How to configure Nginx</span><br />
<br />
When you move to your Nginx installation directory, here's what you see:<br />
<br />
drwxr-xr-x 2 root   root 4096 Oct  5 23:52 sbin<br />
drwxr-xr-x 2 root   root 4096 Oct  5 23:52 html<br />
drwxr-xr-x 2 root   root 4096 Oct  5 23:52 conf<br />
<br />
Sbin
directory has only nginx executable file which starts up httpd. Html
directory is same as htdocs directory in Apache - copy your files here
in order to serve 'em to the world! Conf-file has all configuration
files.<br />
<br />
When you start up your nginx (just go to sbin and type ./nginx in order to start your web server!) you get few more directories:<br />
<br />
drwx------ 2 nobody root 4096 Oct  5 23:52 proxy_temp<br />
drwxr-xr-x 2 root   root 4096 Oct  5 23:52 logs<br />
drwx------ 2 nobody root 4096 Oct  5 23:52 fastcgi_temp<br />
drwx------ 2 nobody root 4096 Oct  5 23:52 client_body_temp<br />
<br />
In the conf-directory you can see the following files:<br />
<br />
-rw-r--r-- 1 root root 3610 Oct  5 23:52 win-utf<br />
-rw-r--r-- 1 root root 2726 Oct  5 23:52 nginx.conf.default<br />
-rw-r--r-- 1 root root 2726 Oct  5 23:52 nginx.conf<br />
-rw-r--r-- 1 root root 2991 Oct  5 23:52 mime.types.default<br />
-rw-r--r-- 1 root root 2991 Oct  5 23:52 mime.types<br />
-rw-r--r-- 1 root root 2223 Oct  5 23:52 koi-win<br />
-rw-r--r-- 1 root root 2837 Oct  5 23:52 koi-utf<br />
-rw-r--r-- 1 root root  909 Oct  5 23:52 fastcgi_params.default<br />
-rw-r--r-- 1 root root  909 Oct  5 23:52 fastcgi_params<br />
<br />
The most important file of them all is of course nginx.conf. The default configuration looks like this after installation:<br />
<br />
<span style="font-style: italic;">#user  nobody;<br />
worker_processes  1;<br />
<br />
#error_log  logs/error.log;<br />
#error_log  logs/error.log  notice;<br />
#error_log  logs/error.log  info;<br />
<br />
#pid        logs/nginx.pid;<br />
</span><br />
<br />
events {<br />
worker_connections  1024;<br />
}<br />
<br />
<br />
These
are default configuration parameters to set user and logging
preferences. If you are your box to run many different applications it
is a good idea to change default user to something else, like "nginx"
or "www_user". <br />
<br />
Worker_connections parameter sets the maximum number of connections each worker can handle. This is quite good default value.<br />
<br />
The following part defines base settings for the http access:<br />
<br />
<span style="font-style: italic;">http {<br />
include       mime.types;<br />
default_type  application/octet-stream;<br />
</span><br />
<br />
You should not tamper round with mime types because you will likely end up with screwed up web server!<br />
<br />
If you want to, you can also change default log format in the following part.<br />
<br />
<span style="font-style: italic;">    #log_format  main  '$remote_addr - $remote_user [$time_local] $request '<br />
#                  '"$status" $body_bytes_sent "$http_referer" '<br />
#                  '"$http_user_agent" "$http_x_forwarded_for"';<br />
<br />
#access_log  logs/access.log  main;<br />
</span><br />
<br />
TCP
nopush setting means that HTTP response hearders are all sent in one
packet. Sendfile setting means that Nginx ignores the details of the
file it is sending and uses kernel sendfile support instead. Keepalive
setting defines how long server waits for users packets. This should be
changed only to few seconds on busy sites. Gzip compression saves
bandwith on site, depending what kind of packets server is sending.<br />
<br />
<span style="font-style: italic;">    sendfile        on;<br />
#tcp_nopush     on;<br />
<br />
#keepalive_timeout  0;<br />
keepalive_timeout  65;<br />
<br />
#gzip  on;<br />
<br />
</span>    <br />
<br />
The
following server part is just like server settings on Apache HTTPD and
if you have tampered 'round with Apache before this is quite
straightforward to you.<br />
<br />
<span style="font-style: italic;">server {<br />
listen       80;<br />
server_name  localhost;<br />
<br />
#charset koi8-r;<br />
<br />
#access_log  logs/host.access.log  main;<br />
<br />
location / {<br />
root   html;<br />
index  index.html index.htm;<br />
}<br />
<br />
#error_page  404              /404.html;<br />
<br />
# redirect server error pages to the static page /50x.html<br />
#<br />
error_page   500 502 503 504  /50x.html;<br />
location = /50x.html {<br />
root   html;<br />
}<br />
<br />
<br />
Example how to configure virtual host on Nginx:<br />
<br />
<span style="font-style: italic;">    # another virtual host using mix of IP-, name-, and port-based configuration<br />
#<br />
#server {<br />
#    listen       8000;<br />
#    listen       somename:8080;<br />
#    server_name  somename  alias  another.alias;<br />
<br />
#    location / {<br />
#        root   html;<br />
#        index  index.html index.htm;<br />
#    }<br />
#}<br />
<br />
<br />
</span><br />
<br />
These
were basic examples of Nginx and what one can do with it. I stripped
some configuration examples but here you can see the basics. Later
we're going to configure Nginx to use PHP and we're going thru how to
use mod_rewrite with Nginx.
</span></div>
<div post-footer-line-1=""><span><span blog-admin="" pid-2125882932=""><a href="http://www.blogger.com/post-edit.g?blogID=7195174666217314934&amp;postID=4063009524279360636" title="Edit Post"><br />
</a>
</span>
</span>
</div>
<div post-footer-line-2=""><a href="http://thelinuxguru.blogspot.com/search/label/nginx" rel="tag">./configure --prefix=/usr/local/site/nginx-0.6.37<br />
<br />
<br />
when error happen ,pls run the following command line.<br />
<br />
yum install pcre pcre-devel&nbsp; openssl openssl-devel md5 md5-devel&nbsp; sha1&nbsp; sha1-devel&nbsp; zlib&nbsp; zlib-devel<br />
<br />
and then execute:<br />
<br />
make &amp;&amp; make install<br />
<br />
<br />
Then update the config file for nginx.<br />
</a><br />
<br />
[root@TEST ~]# cd /usr/local/site/nginx/conf/<br />
<br />
<a href="http://thelinuxguru.blogspot.com/search/label/nginx" rel="tag"><br />
[root@TEST conf]# cat nginx.conf<br />
user&nbsp; mdrop;<br />
worker_processes&nbsp; 1;<br />
master_process on;<br />
daemon off;<br />
<br />
error_log&nbsp; logs/error.log;<br />
#error_log&nbsp; logs/error.log&nbsp; info;<br />
<br />
#pid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logs/nginx.pid;<br />
<br />
<br />
events {<br />
&nbsp;&nbsp;&nbsp; worker_connections&nbsp; 1024;<br />
}<br />
<br />
<br />
http {<br />
&nbsp;&nbsp;&nbsp; include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mime.types;<br />
&nbsp;&nbsp;&nbsp; default_type&nbsp; application/octet-stream;<br />
<br />
&nbsp;&nbsp;&nbsp; log_format&nbsp; main&nbsp; '$remote_addr - $remote_user [$time_local] $request '<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '"$status" $body_bytes_sent "$http_referer" '<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '"$http_user_agent" "$http_x_forwarded_for"';<br />
<br />
&nbsp;&nbsp;&nbsp; access_log&nbsp; logs/access.log&nbsp; main;<br />
<br />
&nbsp;&nbsp;&nbsp; sendfile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; on;<br />
&nbsp;&nbsp;&nbsp; tcp_nopush&nbsp;&nbsp;&nbsp;&nbsp; on;<br />
&nbsp;&nbsp;&nbsp; tcp_nodelay&nbsp;&nbsp;&nbsp;&nbsp; on;<br />
&nbsp;&nbsp;&nbsp; #keepalive_timeout&nbsp; 0;<br />
&nbsp;&nbsp;&nbsp; keepalive_timeout&nbsp; 65;<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gzip on;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gzip_types text/html text/css ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gzip_comp_level 3;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gzip_proxied any;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gzip_vary on;<br />
<br />
&nbsp;&nbsp;&nbsp; server {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; listen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 80;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server_name&nbsp; _*; <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #charset koi8-r;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #access_log&nbsp; logs/access.log&nbsp; ;<br />
<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location ~* ".(jpg|jpeg|gif|css|png|js|ico|html|inc|mp3|xml|swf)$ {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp; /usr/local/site/webroot/$host/;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index&nbsp; index.html index.htm index.php;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location / {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_pass&nbsp;&nbsp; http://127.0.0.1:8080;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_set_header&nbsp; Host&nbsp; $host;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_set_header&nbsp;&nbsp; X-Forwarded-For&nbsp; $proxy_add_x_forwarded_for;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_pass_header Server;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client_max_body_size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8m;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client_body_buffer_size&nbsp;&nbsp;&nbsp; 128k;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_connect_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 90;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_send_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 90;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_read_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 90;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_buffer_size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4k;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_buffers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 64 32k;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_busy_buffers_size&nbsp;&nbsp;&nbsp; 64k;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_temp_file_write_size 64k;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #error_page&nbsp; 404&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /404.html;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # redirect server error pages to the static page /50x.html<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; error_page&nbsp;&nbsp; 500 502 503 504&nbsp; /50x.html;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location = /50x.html {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp; html;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # deny access to .htaccess files, if Apache's document root<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # concurs with nginx's one<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location ~ /".ht {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deny&nbsp; all;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location ~ /".svn {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deny&nbsp; all;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location ~ /"sql {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deny&nbsp; all;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
<br />
&nbsp;&nbsp;&nbsp; # another virtual host using mix of IP-, name-, and port-based configuration<br />
&nbsp;&nbsp;&nbsp; #<br />
&nbsp;&nbsp;&nbsp; #server {<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; listen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8000;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; listen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; somename:8080;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; server_name&nbsp; somename&nbsp; alias&nbsp; another.alias;<br />
<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; location / {<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp; html;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index&nbsp; index.html index.htm;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; #}<br />
<br />
<br />
&nbsp;&nbsp;&nbsp; # HTTPS server<br />
&nbsp;&nbsp;&nbsp; #<br />
&nbsp;&nbsp;&nbsp; #server {<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; listen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 443;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; server_name&nbsp; localhost;<br />
<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; on;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_certificate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cert.pem;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_certificate_key&nbsp; cert.key;<br />
<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_session_timeout&nbsp; 5m;<br />
<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_protocols&nbsp; SSLv2 SSLv3 TLSv1;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_ciphers&nbsp; ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_prefer_server_ciphers&nbsp;&nbsp; on;<br />
<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; location / {<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp; html;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index&nbsp; index.html index.htm;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; #}<br />
<br />
}<br />
<br />
<br />
<br />
<br />
</a>
</div>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/285313.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-07-03 11:28 <a href="http://www.blogjava.net/ruoyoux/articles/285313.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/07/03 Private network</title><link>http://www.blogjava.net/ruoyoux/articles/285308.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Fri, 03 Jul 2009 03:20:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/285308.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/285308.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/285308.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/285308.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/285308.html</trackback:ping><description><![CDATA[<h3 id="siteSub">From Wikipedia, the free encyclopedia</h3>
<div id="jump-to-nav">Jump to: <a href="http://en.wikipedia.org/wiki/Private_network#column-one">navigation</a>, <a href="http://en.wikipedia.org/wiki/Private_network#searchInput">search</a></div>
<table style="padding: 0.5em 0pt 0.8em 1.4em; background: transparent none repeat scroll 0% 0%; clear: right; margin-bottom: 0.5em; float: right; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: auto;" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <table id="toc" class="toc" summary="Contents">
                <tbody>
                    <tr>
                        <td>
                        <div id="toctitle">
                        <h2>Contents</h2>
                        [<a href="javascript:toggleToc()" class="internal" id="togglelink">hide</a>]</div>
                        <ul>
                            <li><a href="http://en.wikipedia.org/wiki/Private_network#Link-local_addresses">1 Link-local addresses</a></li>
                            <li><a href="http://en.wikipedia.org/wiki/Private_network#Private_networks_and_IPv6">2 Private networks and IPv6</a></li>
                            <li><a href="http://en.wikipedia.org/wiki/Private_network#Private_use_of_other_reserved_addresses">3 Private use of other reserved addresses</a></li>
                            <li><a href="http://en.wikipedia.org/wiki/Private_network#RFC_References">4 RFC References</a></li>
                            <li><a href="http://en.wikipedia.org/wiki/Private_network#References">5 References</a></li>
                            <li><a href="http://en.wikipedia.org/wiki/Private_network#External_links">6 External links</a></li>
                        </ul>
                        </td>
                    </tr>
                </tbody>
            </table>
            <script type="text/javascript">
            //<![CDATA[
            if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); }
            //]]&gt;
            </script>
            </td>
        </tr>
    </tbody>
</table>
<p>In <a href="http://en.wikipedia.org/wiki/Internet" title="Internet">Internet</a> terminology, a <strong>private network</strong> is typically a network that uses private <a href="http://en.wikipedia.org/wiki/IP_address" title="IP address">IP address</a> space, following the standards set by <a href="http://tools.ietf.org/html/rfc1918" class="external" title="http://tools.ietf.org/html/rfc1918">RFC 1918</a> and <a href="http://tools.ietf.org/html/rfc4193" class="external" title="http://tools.ietf.org/html/rfc4193">RFC 4193</a>. These addresses are common in home and office <a href="http://en.wikipedia.org/wiki/Local_area_network" title="Local area network">local area networks</a>
(LANs), as using globally routable addresses is seen as impractical or
unnecessary. Private IP addresses were originally created due to the
shortage of publicly registered IP addresses created by the <a href="http://en.wikipedia.org/wiki/IPv4" title="IPv4">IPv4</a> standard, but are also a feature of the next generation <a href="http://en.wikipedia.org/wiki/Internet_Protocol" title="Internet Protocol">Internet Protocol</a>, <a href="http://en.wikipedia.org/wiki/IPv6" title="IPv6">IPv6</a>.</p>
<p>These addresses are private because they are not <em>globally assigned</em>,
meaning they aren't allocated to a specific organization--instead, any
organization needing private address space can use these addresses
without needing approval from a <a href="http://en.wikipedia.org/wiki/Regional_Internet_registry" title="Regional Internet registry">regional Internet registry</a> (RIR). Consequently, they are not routable on the public <a href="http://en.wikipedia.org/wiki/Internet" title="Internet">Internet</a>, meaning that if such a private network wishes to connect to the Internet, it must use either a <a href="http://en.wikipedia.org/wiki/Network_Address_Translation" title="Network Address Translation" class="mw-redirect">Network Address Translation</a> (NAT) gateway, or a <a href="http://en.wikipedia.org/wiki/Proxy_server" title="Proxy server">proxy server</a>.</p>
<p>The most common use of these addresses is in home networks, since most <a href="http://en.wikipedia.org/wiki/Internet_Service_Provider" title="Internet Service Provider" class="mw-redirect">Internet Service Providers</a>
(ISPs) only allocate a single IP address to each customer, but many
homes have more than one networking device (for example, several
computers, or a printer). In this situation, a NAT gateway is almost
always used to provide Internet connectivity. They are also commonly
used in corporate networks, which for security reasons, are not
connected directly to the internet, meaning globally routable addresses
are unnecessary. Often a proxy, <a href="http://en.wikipedia.org/wiki/SOCKS" title="SOCKS">SOCKS</a>
gateway, or similar is used to provide restricted internet access to
internal users. In both cases, private addresses are seen as adding
security to the internal network, since it's impossible for an Internet
host to connect directly to an internal system.</p>
<p>Because many internal networks use the same private IP addresses, a
common problem when trying to merge two such networks (e.g. during a
company merger or takeover) is that both organizations have allocated
the same IPs in their networks. In this case, either one network must
renumber, often a difficult and time-consuming task, or a NAT router
must be placed between the networks to translate one network's
addresses before they can reach the other side.</p>
<p>It is not uncommon for private address space to "leak" onto the
Internet in various ways. Poorly configured private networks often
attempt <a href="http://en.wikipedia.org/wiki/Reverse_DNS_lookup" title="Reverse DNS lookup">reverse DNS lookups</a> for these addresses, putting extra load on the Internet's <a href="http://en.wikipedia.org/wiki/Root_nameservers" title="Root nameservers" class="mw-redirect">root nameservers</a>. The <a href="http://en.wikipedia.org/wiki/AS112" title="AS112">AS112</a> project mitigates this load by providing special "blackhole" <a href="http://en.wikipedia.org/wiki/Anycast" title="Anycast">anycast</a>
nameservers for private addresses which only return "not found" answers
for these queries. Organizational edge routers are usually configured
to drop ingress IP traffic for these networks, which can occur either
by accident, or from malicious traffic using a spoofed source address.
Less commonly, ISP edge routers will drop such ingress traffic from
customers, which reduces the impact to the Internet of such
misconfigured or malicious hosts on the customer's network.</p>
<p>A common misconception is that these addresses are not routable. While not routable on the public Internet, they <em>are</em> routable within an organization or site.</p>
<p>The <a href="http://en.wikipedia.org/wiki/Internet_Engineering_Task_Force" title="Internet Engineering Task Force">Internet Engineering Task Force</a> (IETF) has directed <a href="http://en.wikipedia.org/wiki/Internet_Assigned_Numbers_Authority" title="Internet Assigned Numbers Authority">IANA</a> to reserve the following IPv4 address ranges for private networks, as published in <a href="http://tools.ietf.org/html/rfc1918" class="external" title="http://tools.ietf.org/html/rfc1918">RFC 1918</a>:</p>
<table>
    <tbody>
        <tr>
            <th>RFC1918 name</th>
            <th>IP address range</th>
            <th>number of addresses</th>
            <th><em><a href="http://en.wikipedia.org/wiki/Classful_network" title="Classful network">classful</a></em> description</th>
            <th>largest <a href="http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" title="Classless Inter-Domain Routing">CIDR</a> block (subnet mask)</th>
            <th>host id size</th>
        </tr>
        <tr>
            <td>24-bit block</td>
            <td>10.0.0.0 &#8211; 10.255.255.255</td>
            <td>16,777,216</td>
            <td>single class A</td>
            <td>10.0.0.0/8 (255.0.0.0)</td>
            <td>24 bits</td>
        </tr>
        <tr>
            <td>20-bit block</td>
            <td>172.16.0.0 &#8211; 172.31.255.255</td>
            <td>1,048,576</td>
            <td>16 contiguous class Bs</td>
            <td>172.16.0.0/12 (255.240.0.0)</td>
            <td>20 bits</td>
        </tr>
        <tr>
            <td>16-bit block</td>
            <td>192.168.0.0 &#8211; 192.168.255.255</td>
            <td>65,536</td>
            <td>256 contiguous class Cs</td>
            <td>192.168.0.0/16 (255.255.0.0)</td>
            <td>16 bits</td>
        </tr>
    </tbody>
</table>
<p>Note that <a href="http://en.wikipedia.org/wiki/Classful_addressing" title="Classful addressing" class="mw-redirect">classful addressing</a>
is obsolete and no longer used on the Internet. For example, while
10.0.0.0/8 would be a single class A network, it is not uncommon for
organisations to divide it into smaller /16 or /24 networks.</p>
<h2>[<a href="http://en.wikipedia.org/w/index.php?title=Private_network&amp;action=edit&amp;section=1" title="Edit section: Link-local addresses">edit</a>] Link-local addresses</h2>
<div noprint="" relarticle="" mainarticle="">Main article: <a href="http://en.wikipedia.org/wiki/Zero_configuration_networking" title="Zero configuration networking">Zero configuration networking</a></div>
<p>A second set of private networks is the <em>link-local address range</em> codified in <a href="http://tools.ietf.org/html/rfc3330" class="external" title="http://tools.ietf.org/html/rfc3330">RFC 3330</a> and <a href="http://tools.ietf.org/html/rfc3927" class="external" title="http://tools.ietf.org/html/rfc3927">RFC 3927</a>. The intention behind these RFCs is to provide an IP address (and by implication, network connectivity) without a <a href="http://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol" title="Dynamic Host Configuration Protocol">DHCP</a>
server being available and without having to configure a network
address manually. The network 169.254/16 has been reserved for this
purpose. Within this address range, the networks 169.254.0.0/24 and
169.254.255.0/24 have been set aside for future use.</p>
<p>If a host on an IEEE 802 (<a href="http://en.wikipedia.org/wiki/Ethernet" title="Ethernet">ethernet</a>) network cannot obtain a network address via DHCP, an address from 169.254.0.0 to 169.254.255.255 is assigned <a href="http://en.wikipedia.org/wiki/Pseudorandom" title="Pseudorandom" class="mw-redirect">pseudorandomly</a>. The standard prescribes that address collisions must be handled gracefully.</p>
<p>Link-local addresses have even more restrictive rules than the private network addresses defined in <a href="http://tools.ietf.org/html/rfc1918" class="external" title="http://tools.ietf.org/html/rfc1918">RFC 1918</a>: packets to or from link-local addresses must not be allowed to pass through a router at all (<a href="http://tools.ietf.org/html/rfc3927" class="external" title="http://tools.ietf.org/html/rfc3927">RFC 3927</a>, <a href="http://tools.ietf.org/html/rfc3927#section-7" class="external text" title="http://tools.ietf.org/html/rfc3927#section-7" rel="nofollow">section 7</a>).</p>
<h2>[<a href="http://en.wikipedia.org/w/index.php?title=Private_network&amp;action=edit&amp;section=2" title="Edit section: Private networks and IPv6">edit</a>] Private networks and IPv6</h2>
<p>The concept of private networks and special addresses for such networks has been carried over to the next generation of the <a href="http://en.wikipedia.org/wiki/Internet_Protocol" title="Internet Protocol">Internet Protocol</a>, <a href="http://en.wikipedia.org/wiki/IPv6" title="IPv6">IPv6</a>.</p>
<p>The address block <tt>fc00::/7</tt> has been reserved by IANA as described in <a href="http://tools.ietf.org/html/rfc4193" class="external" title="http://tools.ietf.org/html/rfc4193">RFC 4193</a>. These addresses are called <a href="http://en.wikipedia.org/wiki/Unique_Local_Address" title="Unique Local Address" class="mw-redirect">Unique Local Addresses</a> (ULA). They are defined as being <a href="http://en.wikipedia.org/wiki/Unicast" title="Unicast">unicast</a>
in character and contain a 40-bit random number in the routing prefix
to prevent collisions when two private networks are interconnected.
Despite being inherently <em>local</em> in usage, the IPv6 address scope of unique local addresses is global (cf. <a href="http://en.wikipedia.org/wiki/IPv6" title="IPv6">IPv6</a>, section "Address Scopes").</p>
<p>A former standard proposed the use of so-called "site-local"
addresses in the fec0::/10 range, but due to major concerns about
scalability and the poor definition of what constitutes a <em>site</em>, its use has been deprecated since September 2004 by <a href="http://tools.ietf.org/html/rfc3879" class="external" title="http://tools.ietf.org/html/rfc3879">RFC 3879</a>.</p>
<h2>[<a href="http://en.wikipedia.org/w/index.php?title=Private_network&amp;action=edit&amp;section=3" title="Edit section: Private use of other reserved addresses">edit</a>] Private use of other reserved addresses</h2>
<p>Several other address ranges, in addition to the official private
ranges, are reserved for other or future uses, including 1.0.0.0/8 and
2.0.0.0/8<sup id="cite_ref-0" class="reference"><a href="http://en.wikipedia.org/wiki/Private_network#cite_note-0">[1]</a></sup>.
Though discouraged, some enterprises have begun to use this address
space internally for interconnecting private networks to eliminate the
chance of address conflicts when using standards-based private ranges.<sup template-fact="" title="This claim needs references to reliable sources&nbsp;from February 2009" style="white-space: nowrap;">[<em><a href="http://en.wikipedia.org/wiki/Wikipedia:Citation_needed" title="Wikipedia:Citation needed">citation needed</a></em>]</sup></p>
<p>IANA has stated that it will, eventually, allocate these ranges to the <a href="http://en.wikipedia.org/wiki/Regional_Internet_Registry" title="Regional Internet Registry" class="mw-redirect">Regional Internet Registries</a> and thus significant addressing problem might be encountered in the future due to non-standard use of reserved blocks.</p>
<h2>[<a href="http://en.wikipedia.org/w/index.php?title=Private_network&amp;action=edit&amp;section=4" title="Edit section: RFC References">edit</a>] RFC References</h2>
<ul>
    <li><a href="http://tools.ietf.org/html/rfc1918" class="external" title="http://tools.ietf.org/html/rfc1918">RFC 1918</a> &#8211; <em>"Address Allocation for Private Internets"</em></li>
    <li><a href="http://tools.ietf.org/html/rfc2036" class="external" title="http://tools.ietf.org/html/rfc2036">RFC 2036</a> &#8211; ""Observations on the use of Components of the Class A Address Space within the Internet."</li>
    <li><a href="http://tools.ietf.org/html/rfc2050" class="external" title="http://tools.ietf.org/html/rfc2050">RFC 2050</a> &#8211; ""Internet Registry IP Allocation Guidelines""</li>
    <li><a href="http://tools.ietf.org/html/rfc2101" class="external" title="http://tools.ietf.org/html/rfc2101">RFC 2101</a> &#8211; ""IPv4 Address Behaviour Today.""</li>
    <li><a href="http://tools.ietf.org/html/rfc2663" class="external" title="http://tools.ietf.org/html/rfc2663">RFC 2663</a> &#8211; ""IP Network Address Translator (NAT) Terminology and Considerations."</li>
    <li><a href="http://tools.ietf.org/html/rfc3022" class="external" title="http://tools.ietf.org/html/rfc3022">RFC 3022</a> &#8211; ""Traditional IP Network Address Translator (Traditional NAT)""</li>
    <li><a href="http://tools.ietf.org/html/rfc3330" class="external" title="http://tools.ietf.org/html/rfc3330">RFC 3330</a> &#8211; ""Special-Use IPv4 Addresses. IANA. September 2002::</li>
    <li><a href="http://tools.ietf.org/html/rfc3879" class="external" title="http://tools.ietf.org/html/rfc3879">RFC 3879</a> &#8211; <em>"Deprecating Site Local Addresses"</em></li>
    <li><a href="http://tools.ietf.org/html/rfc3927" class="external" title="http://tools.ietf.org/html/rfc3927">RFC 3927</a> &#8211; <em>"Dynamic Configuration of IPv4 Link-Local Addresses"</em></li>
    <li><a href="http://tools.ietf.org/html/rfc4193" class="external" title="http://tools.ietf.org/html/rfc4193">RFC 4193</a> &#8211; <em>"Unique Local IPv6 Unicast Addresses"</em></li>
</ul>
<h2>[<a href="http://en.wikipedia.org/w/index.php?title=Private_network&amp;action=edit&amp;section=5" title="Edit section: References">edit</a>] References</h2>
<ol>
    <li id="cite_note-0"><strong><a href="http://en.wikipedia.org/wiki/Private_network#cite_ref-0">^</a></strong> <a href="http://www.iana.org/ipaddress/ip-addresses.htm" class="external text" title="http://www.iana.org/ipaddress/ip-addresses.htm" rel="nofollow">Internet Protocol v4 Address Space</a></li>
</ol>
<h2>[<a href="http://en.wikipedia.org/w/index.php?title=Private_network&amp;action=edit&amp;section=6" title="Edit section: External links">edit</a>] External links</h2>
<ul>
    <li><a href="http://www.goebel-consult.de/ipv6/createLULA" class="external text" title="http://www.goebel-consult.de/ipv6/createLULA" rel="nofollow">Generator for RFC 4193 Addresses</a> (source code available from same page)</li>
</ul>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/285308.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-07-03 11:20 <a href="http://www.blogjava.net/ruoyoux/articles/285308.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/16 Linux的时间设置与同步 (NTP)</title><link>http://www.blogjava.net/ruoyoux/articles/282655.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Tue, 16 Jun 2009 09:54:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/282655.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/282655.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/282655.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/282655.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/282655.html</trackback:ping><description><![CDATA[Network Time Protocol (NTP) 也是RHCE新增的考试要求. 学习的时候也顺便复习了一下如何设置Linux的时间,现在拿出来和大家分享<br />
设置NTP服务器不难但是NTP本身是一个很复杂的协议. 这里只是简要地介绍一下实践方法<br />
和上次一样,下面的实验都在RHEL5上运行<br />
<br />
<strong>1. 时间和时区</strong><br />
<br />
如果有人问你说现在几点? 你看了看表回答他说晚上8点了. 这样回答看上去没有什么问题,但是如果问你的这个人在欧洲的话那么你的回答就会让他很疑惑,因为他那里还太阳当空呢.<br />
<br />
这里就有产生了一个如何定义时间的问题.
因为在地球环绕太阳旋转的24个小时中,世界各地日出日落的时间是不一样的.所以我们才有划分时区(timezone)
的必要,也就是把全球划分成24个不同的时区. 所以我们可以把时间的定义理解为一个时间的值加上所在地的时区(注意这个所在地可以精确到城市)<br />
<br />
地理课上我们都学过格林威治时间(GMT), 它也就是0时区时间. 但是我们在计算机中经常看到的是UTC. 它是Coordinated
Universal Time的简写.
虽然可以认为UTC和GMT的值相等(误差相当之小),但是UTC已经被认定为是国际标准,所以我们都应该遵守标准只使用UTC<br />
<br />
那么假如现在中国当地的时间是晚上8点的话,我们可以有下面两种表示方式<br />
<br />
20:00 CST<br />
12:00 UTC<br />
<br />
这里的CST是Chinese Standard Time,也就是我们通常所说的北京时间了. 因为中国处在UTC+8时区,依次类推那么也就是12:00 UTC了.<br />
<br />
为什么要说这些呢(呵呵这里不是地理论坛吧...)? <br />
<br />
第一,不管通过任何渠道我们想要同步系统的时间,通常提供方只会给出UTC+0的时间值而不会提供时区(因为它不知道你在哪里).所以当我们设置系统时间的时候,设置好时区是首先要做的工作<br />
第二,很多国家都有夏令时(我记得小时候中国也实行过一次),那就是在一年当中的某一天时钟拨快一小时(比如从UTC+8一下变成UTC+9了),那么同理到时候还要再拨慢回来.如果我们设置了正确的时区,当需要改变时间的时候系统就会自动替我们调整<br />
<br />
现在我们就来看一下如何在Linux下设置时区,也就是time zone<br />
<br />
<br />
<strong>2. 如何设置Linux Time Zone</strong><br />
<br />
在Linux下glibc提供了我们事先编译好的许多timezone文件, 他们就放在/usr/share/zoneinfo这个目录下,这里基本涵盖了大部分的国家和城市<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 194px;">
<div dir="ltr" style="text-align: left;"># ls -F /usr/share/zoneinfo/<br />
<br />
Africa/      Chile/   Factory    Iceland      Mexico/   posix/      Universal<br />
<br />
America/     CST6CDT  GB         Indian/      Mideast/  posixrules  US/<br />
<br />
Antarctica/  Cuba     GB-Eire    Iran         MST       PRC         UTC<br />
<br />
Arctic/      EET      GMT        iso3166.tab  MST7MDT   PST8PDT     WET<br />
<br />
Asia/        Egypt    GMT0       Israel       Navajo    right/      W-SU<br />
<br />
Atlantic/    Eire     GMT-0      Jamaica      NZ        ROC         zone.tab<br />
<br />
Australia/   EST      GMT+0      Japan        NZ-CHAT   ROK         Zulu<br />
<br />
Brazil/      EST5EDT  Greenwich  Kwajalein    Pacific/  Singapore<br />
<br />
Canada/      Etc/     Hongkong   Libya        Poland    Turkey<br />
<br />
CET          Europe/  HST        MET          Portugal  UCT</div>
<br />
</pre>
</div>
在这里面我们就可以找到自己所在城市的time zone文件. 那么如果我们想查看对于每个time zone当前的时间我们可以用zdump命令<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 50px;">
<div dir="ltr" style="text-align: left;"># zdump Hongkong<br />
<br />
Hongkong  Fri Jul  6 06:13:57 2007 HKT</div>
<br />
</pre>
</div>
那么我们又怎么来告诉系统我们所在time zone是哪个呢? 方法有很多,这里举出两种<br />
<br />
第一个就是修改/etc/localtime这个文件,这个文件定义了我么所在的local time zone.<br />
我们可以在/usr/share/zoneinfo下找到我们的time zone文件然后拷贝去到/etc/localtimezone(或者做个symbolic link)<br />
<br />
假设我们现在的time zone是BST(也就是英国的夏令时间,UTC+1)<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 50px;">
<div dir="ltr" style="text-align: left;"># date<br />
<br />
Thu Jul  5 23:33:40 BST 2007</div>
<br />
</pre>
</div>
我们想把time zone换成上海所在的时区就可以这么做<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 66px;">
<div dir="ltr" style="text-align: left;"># ln -sf /usr/share/zoneinfo/posix/Asia/Shanghai /etc/localtime<br />
<br />
# date<br />
<br />
Fri Jul  6 06:35:52 CST 2007</div>
<br />
</pre>
</div>
这样时区就改过来了(注意时间也做了相应的调整)<br />
<br />
第二种方法也就设置TZ环境变量的值. 许多程序和命令都会用到这个变量的值. TZ的值可以有多种格式,最简单的设置方法就是使用tzselect命令<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 66px;">
<div dir="ltr" style="text-align: left;"># tzselect<br />
<br />
...<br />
<br />
TZ='America/Los_Angeles';export TZ</div>
<br />
</pre>
</div>
tzselect会让你选择所在的国家和城市(我省略了这些步骤),最后输出相应的TZ变量的值.那么如果你设置了TZ的值之后时区就又会发生变化<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 50px;">
<div dir="ltr" style="text-align: left;"># date<br />
<br />
Thu Jul  5 15:48:11 PDT 2007</div>
<br />
</pre>
</div>
通过这两个例子我们也可以发现TZ变量的值会override /etc/localtime.
也就是说当TZ变量没有定义的时候系统才使用/etc/localtime来确定time zone. 所以你想永久修改time
zone的话那么可以把TZ变量的设置写入/etc/profile里<br />
<br />
好了现在我们知道怎么设置时区了,下面我们就来看看如何设置Linux的时间吧<br />
<br />
<br />
<strong>3. Real Time Clock(RTC) and System Clock</strong><br />
<br />
说道设置时间这里还要明确另外一个概念就是在一台计算机上我们有两个时钟:一个称之为硬件时间时钟(RTC),还有一个称之为系统时钟(System Clock)<br />
<br />
硬件时钟是指嵌在主板上的特殊的电路, 它的存在就是平时我们关机之后还可以计算时间的原因<br />
系统时钟就是操作系统的kernel所用来计算时间的时钟. 它从1970年1月1日00:00:00 UTC时间到目前为止秒数总和的值 在Linux下系统时间在开机的时候会和硬件时间同步(synchronization),之后也就各自独立运行了<br />
<br />
那么既然两个时钟独自运行,那么时间久了必然就会产生误差了,下面我们来看一个例子<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 82px;">
<div dir="ltr" style="text-align: left;"># date<br />
<br />
Fri Jul  6 00:27:13 BST 2007<br />
<br />
# hwclock --show<br />
<br />
Fri 06 Jul 2007 12:27:17 AM BST  -0.968931 seconds</div>
<br />
</pre>
</div>
通过hwclock --show命令我们可以查看机器上的硬件时间(always in local time zone), 我们可以看到它和系统时间还是有一定的误差的, 那么我们就需要把他们同步<br />
<br />
如果我们想要把硬件时间设置成系统时间我们可以运行以下命令<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 34px;">
<div dir="ltr" style="text-align: left;"># hwclock --hctosys</div>
<br />
</pre>
</div>
反之,我们也可以把系统时间设置成硬件时间<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 34px;">
<div dir="ltr" style="text-align: left;"># hwclock --systohc</div>
<br />
</pre>
</div>
那么如果想设置硬件时间我们可以开机的时候在BIOS里设定.也可以用hwclock命令<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 34px;">
<div dir="ltr" style="text-align: left;"># hwclock --set --date="mm/dd/yy hh:mm:ss"</div>
<br />
</pre>
</div>
如果想要修改系统时间那么用date命令就最简单了<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 34px;">
<div dir="ltr" style="text-align: left;"># date -s "dd/mm/yyyy hh:mm:ss"</div>
<br />
</pre>
</div>
现在我们知道了如何设置系统和硬件的时间. 但问题是如果这两个时间都不准确了怎么办?
那么我们就需要在互联网上找到一个可以提供我们准确时间的服务器然后通过一种协议来同步我们的系统时间,那么这个协议就是NTP了.
注意接下去我们所要说的同步就都是指系统时间和网络服务器之间的同步了<br />
<br />
<strong><br />
4. 设置NTP Server前的准备</strong><br />
<br />
其实这个标题应该改为设置"NTP Relay Server"前的准备更加合适.
因为不论我们的计算机配置多好运行时间久了都会产生误差,所以不足以给互联网上的其他服务器做NTP Server.
真正能够精确地测算时间的还是原子钟. 但由于原子钟十分的昂贵,只有少部分组织拥有, 他们连接到计算机之后就成了一台真正的NTP Server.
而我们所要做的就是连接到这些服务器上同步我们系统的时间,然后把我们自己的服务器做成NTP Relay
Server再给互联网或者是局域网内的用户提供同步服务<br />
<br />
好了,前面讲了一大堆理论,现在我们来动手实践一下吧. 架设一个NTP Relay Server其实非常简单,我们先把需要的RPM包装上<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 34px;">
<div dir="ltr" style="text-align: left;"># rpm -ivh ntp-4.2.2p1-5.el5.rpm</div>
<br />
</pre>
</div>
那么第一步我们就要找到在互联网上给我们提供同步服务的NTP Server<br />
<br />
<a href="http://www.pool.ntp.org/" target="_blank">http://www.pool.ntp.org</a>是NTP的官方网站,在这上面我们可以找到离我们城市最近的NTP Server. NTP建议我们为了保障时间的准确性,最少找两个个NTP Server<br />
那么比如在英国的话就可以选择下面两个服务器<br />
<br />
0.uk.pool.ntp.org<br />
1.uk.pool.ntp.org<br />
<br />
它的一般格式都是number.country.pool.ntp.org<br />
<br />
第二步要做的就是在打开NTP服务器之前先和这些服务器做一个同步,使得我们机器的时间尽量接近标准时间. 这里我们可以用ntpdate命令<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 82px;">
<div dir="ltr" style="text-align: left;"># ntpdate 0.uk.pool.ntp.org<br />
<br />
6 Jul 01:21:49 ntpdate[4528]: step time server 213.222.193.35 offset -38908.575181 sec<br />
<br />
# ntpdate 0.pool.ntp.org<br />
<br />
6 Jul 01:21:56 ntpdate[4530]: adjust time server 213.222.193.35 offset -0.000065 sec</div>
<br />
</pre>
</div>
假如你的时间差的很离谱的话第一次会看到调整的幅度比较大,所以保险起见可以运行两次. 那么为什么在打开NTP服务之前先要手动运行同步呢? <br />
<br />
1. 因为根据NTP的设置,如果你的系统时间比正确时间要快的话那么NTP是不会帮你调整的,所以要么你把时间设置回去,要么先做一个手动同步<br />
2. 当你的时间设置和NTP服务器的时间相差很大的时候,NTP会花上较长一段时间进行调整.所以手动同步可以减少这段时间<br />
<br />
<br />
<strong>5. 配置和运行NTP Server</strong><br />
<br />
现在我们就来创建NTP的配置文件了, 它就是/etc/ntp.conf. 我们只需要加入上面的NTP Server和一个driftfile就可以了<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 82px;">
<div dir="ltr" style="text-align: left;"># vi /etc/ntp.conf<br />
<br />
server 0.uk.pool.ntp.org<br />
<br />
server 1.uk.pool.ntp.org<br />
<br />
driftfile /var/lib/ntp/ntp.drift</div>
<br />
</pre>
</div>
非常的简单. 接下来我们就启动NTP Server,并且设置其在开机后自动运行<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 50px;">
<div dir="ltr" style="text-align: left;"># /etc/init.d/ntpd/start<br />
<br />
# chkconfig --level 35 ntpd on</div>
<br />
</pre>
</div>
<br />
<strong>6. 查看NTP服务的运行状况</strong><br />
<br />
现在我们已经启动了NTP的服务,但是我们的系统时间到底和服务器同步了没有呢? 为此NTP提供了一个很好的查看工具: ntpq (NTP query)<br />
<br />
我建议大家在打开NTP服务器后就可以运行ntpq命令来监测服务器的运行.这里我们可以使用watch命令来查看一段时间内服务器各项数值的变化<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 130px;">
<div dir="ltr" style="text-align: left;"># watch ntpq -p<br />
<br />
Every 2.0s: ntpq -p                                  Sat Jul  7 00:41:45 2007<br />
<br />
<br />
<br />
remote           refid      st t when poll reach   delay   offset  jitter<br />
<br />
==============================================================================<br />
<br />
+193.60.199.75   193.62.22.98     2 u   52   64  377    8.578   10.203 289.032<br />
<br />
*mozart.musicbox 192.5.41.41      2 u   54   64  377   19.301  -60.218 292.411</div>
<br />
</pre>
</div>
现在我就来解释一下其中的含义<br />
<br />
remote: 它指的就是本地机器所连接的远程NTP服务器<br />
<br />
refid: 它指的是给远程服务器(e.g. 193.60.199.75)提供时间同步的服务器<br />
<br />
st: 远程服务器的级别. 由于NTP是层型结构,有顶端的服务器,多层的Relay Server再到客户端. 所以服务器从高到低级别可以设定为1-16. 为了减缓负荷和网络堵塞,原则上应该避免直接连接到级别为1的服务器的.<br />
<br />
t: 这个.....我也不知道啥意思^_^<br />
<br />
when: 我个人把它理解为一个计时器用来告诉我们还有多久本地机器就需要和远程服务器进行一次时间同步<br />
<br />
poll: 本地机和远程服务器多少时间进行一次同步(单位为秒). 在一开始运行NTP的时候这个poll值会比较小,那样和服务器同步的频率也就增加了,可以尽快调整到正确的时间范围.之后poll值会逐渐增大,同步的频率也就会相应减小<br />
<br />
reach: 这是一个八进制值,用来测试能否和服务器连接.每成功连接一次它的值就会增加<br />
<br />
delay: 从本地机发送同步要求到服务器的round trip time<br />
<br />
offset: 这是个最关键的值, 它告诉了我们本地机和服务器之间的时间差别. offset越接近于0,我们就和服务器的时间越接近<br />
<br />
jitter: 这是一个用来做统计的值. 它统计了在特定个连续的连接数里offset的分布情况. 简单地说这个数值的绝对值越小我们和服务器的时间就越精确<br />
<br />
那么大家细心的话就会发现两个问题: 第一我们连接的是0.uk.pool.ntp.org为什么和remote server不一样? 第二那个最前面的+和*都是什么意思呢?<br />
<br />
第一个问题不难理解,因为NTP提供给我们的是一个cluster server所以每次连接的得到的服务器都有可能是不一样.同样这也告诉我们了在指定NTP Server的时候应该使用hostname而不是IP<br />
<br />
第二个问题和第一个相关,既然有这么多的服务器就是为了在发生问题的时候其他的服务器还可以正常地给我们提供服务.那么如何知道这些服务器的状态呢? 这就是第一个记号会告诉我们的信息<br />
<br />
*<br />
它告诉我们远端的服务器已经被确认为我们的主NTP Server,我们系统的时间将由这台机器所提供<br />
<br />
+<br />
它将作为辅助的NTP Server和带有*号的服务器一起为我们提供同步服务. 当*号服务器不可用时它就可以接管<br />
<br />
-<br />
远程服务器被clustering algorithm认为是不合格的NTP Server<br />
<br />
x<br />
远程服务器不可用<br />
<br />
了解这些之后我们就可以实时监测我们系统的时间同步状况了<br />
<br />
<strong><br />
7. NTP安全设置</strong><br />
<br />
运行一个NTP Server不需要占用很多的系统资源,所以也不用专门配置独立的服务器,就可以给许多client提供时间同步服务, 但是一些基本的安全设置还是很有必要的<br />
那么这里一个很简单的思路就是第一我们只允许局域网内一部分的用户连接到我们的服务器. 第二个就是这些client不能修改我们服务器上的时间<br />
<br />
在/etc/ntp.conf文件中我们可以用restrict关键字来配置上面的要求<br />
<br />
首先我们对于默认的client拒绝所有的操作<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 34px;">
<div dir="ltr" style="text-align: left;">restrict default kod nomodify notrap nopeer noquery</div>
<br />
</pre>
</div>
然后允许本机地址一切的操作<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 34px;">
<div dir="ltr" style="text-align: left;">restrict 127.0.0.1</div>
<br />
</pre>
</div>
最后我们允许局域网内所有client连接到这台服务器同步时间.但是拒绝让他们修改服务器上的时间<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 34px;">
<div dir="ltr" style="text-align: left;">restrict 192.168.1.0 mask 255.255.255.0 nomodify</div>
<br />
</pre>
</div>
把这三条加入到/etc/ntp.conf中就完成了我们的简单配置. NTP还可以用key来做authenticaiton,这里就不详细介绍了<br />
<br />
<br />
<strong>8. NTP client的设置</strong><br />
<br />
做到这里我们已经有了一台自己的Relay
Server.如果我们想让局域网内的其他client都进行时间同步的话那么我们就都应该照样再搭建一台Relay
Server,然后把所有的client都指向这两台服务器(注意不要把所有的client都指向Internet上的服务器).
只要在client的ntp.conf加上这你自己的服务器就可以了<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 50px;">
<div dir="ltr" style="text-align: left;">server ntp1.leonard.com<br />
<br />
server ntp2.leonard.com</div>
<br />
</pre>
</div>
<strong><br />
9. 一些补充和拾遗</strong><br />
<br />
1. 配置文件中的driftfile是什么?<br />
我们每一个system clock的频率都有小小的误差,这个就是为什么机器运行一段时间后会不精确.
NTP会自动来监测我们时钟的误差值并予以调整.但问题是这是一个冗长的过程,所以它会把记录下来的误差先写入driftfile.这样即使你重新开机以
后之前的计算结果也就不会丢失了<br />
<br />
2. 如何同步硬件时钟?<br />
NTP一般只会同步system clock. 但是如果我们也要同步RTC的话那么只需要把下面的选项打开就可以了<br />
<br />
<div style="margin: 5px 20px 20px 0px;">
<div style="margin-bottom: 2px;">代码:</div>
<pre style="border: 1px solid #c6c6c6; margin: 0px; padding: 4px; overflow: auto; width: 640px; height: 50px;">
<div dir="ltr" style="text-align: left;"># vi /etc/sysconfig/ntpd<br />
<br />
SYNC_HWCLOCK=yes</div>
<br />
</pre>
</div>
<strong>10. 参考资料</strong><br />
<br />
1. <a href="http://www.freebsd.org/cgi/man.cgi?query=ntp.conf&amp;sektion=5" target="_blank">http://www.freebsd.org/cgi/man.cgi?q...conf&amp;sektion=5</a> <br />
不知为什么Redhat没有ntp.conf的man page.费了好大劲才从FreeBSD上找到了.<br />
<br />
2. <a href="http://www.eecis.udel.edu/%7Emills/ntp/html/index.html" target="_blank">http://www.eecis.udel.edu/~mills/ntp/html/index.html</a><br />
官方的NTP文档<br />
<br />
3. <a href="http://tldp.org/HOWTO/TimePrecision-HOWTO/index.html" target="_blank">http://tldp.org/HOWTO/TimePrecision-HOWTO/index.html</a><br />
The Linux Documentation Project上的NTP HOWTO<br />
<br />
4. <a href="http://www.pool.ntp.org/" target="_blank">www.pool.ntp.org/</a><br />
全球NTP服务器提供站<br />
<br />
<strong>11. 说明</strong><br />
<br />
顺便说一下, 大家也许会注意到标准时间的英文是Coordinated Universal Time, 为什么缩写会是UTC呢？<br />
<br />
在Wiki上给出的定论是英国人把它叫做Coordinated Universal Time。但是法语中它叫temps universel coordonn&#233;, 缩写也就是TUC.两个国家争执不休，最后妥协起见就把它叫做UTC了<br />
<br />
其实我看了挺有感触的。英语虽然是通用语言，但是问题在于现在很多核心技术全都掌握在老美手中，所以每有一个新名次都是会以英文来定义, 我觉得过多的英语依赖也是阻碍Linux在中国普及的一个因素. 要是中国能在新的领域有所突破的话也绝对可以起上自己的名字<br />
<br />
呵呵，乱说一通。只是想到有一天要是老外问我们北京时间英语怎么说的时候不知道会有多骄傲啊<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/282655.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-16 17:54 <a href="http://www.blogjava.net/ruoyoux/articles/282655.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/16 linux 下修改时间 时区</title><link>http://www.blogjava.net/ruoyoux/articles/282654.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Tue, 16 Jun 2009 09:52:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/282654.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/282654.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/282654.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/282654.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/282654.html</trackback:ping><description><![CDATA[前几天邮件系统发到用户机器的邮件总是时间不对....
<br />
<br />
后来想到了新加的一台email服务器,可能系统时间不对...好,系统时间改了...发现还是不对...<img src="http://romyli.javaeye.com/images/smiles/icon_sad.gif"  alt="" />
<br />
<br />
后来仔细观察发现,不是到哪位同仁装系统的时候,把系统时区搞成了美国西部时区...闷了!
<br />
<br />
<strong>修改系统时间</strong>
<br />
<br />
date
<br />
显示当前时间 Fri Aug&nbsp; 3 14:15:16 CST 2007
<br />
<br />
date -s
<br />
按字符串方式修改时间
<br />
可以只修改日期,不修改时间,输入: date -s 2007-08-03
<br />
只修改时间,输入:date -s 14:15:00
<br />
同时修改日期时间,注意要加双引号,日期与时间之间有一空格,输入:date -s "2007-08-03 14:15:00"
<br />
<br />
修改完后,记得输入:clock -w
<br />
<br />
把系统时间写入CMOS
<br />
<br />
<strong>修改系统时区</strong>
<br />
<br />
1. 查看当前时区
<br />
<br />
# vi /etc/sysconfig/clock
<br />
<br />
2. 修改设置时区
<br />
<br />
&nbsp; 方法(1)
<br />
&nbsp; # tzselect
<br />
&nbsp; 方法(2 仅限于RedHat Linux 和 CentOS)
<br />
&nbsp; # timeconfig
<br />
<br />
3. 复制相应的时区文件，替换系统默认时区
<br />
<br />
&nbsp; # cp /usr/share/zoneinfo/$主时区/$次时区 /etc/localtime
<br />
&nbsp; 对于中国服务器则执行：
<br />
&nbsp; # cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
<br />
<br />
4. 将当前时间写入BIOS永久生效（避免重启后失效）
<br />
<br />
&nbsp; # hwclock
<img src ="http://www.blogjava.net/ruoyoux/aggbug/282654.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-16 17:52 <a href="http://www.blogjava.net/ruoyoux/articles/282654.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/16 开机时自动启动APACHE的SCRIPT</title><link>http://www.blogjava.net/ruoyoux/articles/282520.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Tue, 16 Jun 2009 01:31:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/282520.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/282520.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/282520.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/282520.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/282520.html</trackback:ping><description><![CDATA[#!/bin/bash<br />
#<br />
# httpd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Startup script for the Apache HTTP Server<br />
#<br />
# chkconfig: 345 85 15<br />
# description: Apache is a World Wide Web server.&nbsp; It is used to serve "<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HTML files and CGI.<br />
# processname: httpd<br />
# config: /usr/local/site/apache/conf/httpd.conf<br />
# config: /etc/sysconfig/httpd<br />
# pidfile: /usr/local/site/apache/logs/httpd.pid<br />
<br />
# Source function library.<br />
. /etc/rc.d/init.d/functions<br />
<br />
if [ -f /etc/sysconfig/httpd ]; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; . /etc/sysconfig/httpd<br />
fi<br />
<br />
# Start httpd in the C locale by default.<br />
HTTPD_LANG=${HTTPD_LANG-"C"}<br />
<br />
# This will prevent initlog from swallowing up a pass-phrase prompt if<br />
# mod_ssl needs a pass-phrase from the user.<br />
INITLOG_ARGS=""<br />
<br />
# Set HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server<br />
# with the thread-based "worker" MPM; BE WARNED that some modules may not<br />
# work correctly with a thread-based MPM; notably PHP will refuse to start.<br />
<br />
# Path to the apachectl script, server binary, and short-form for messages.<br />
apachectl=/usr/sbin/apachectl<br />
httpd=${HTTPD-/usr/local/site/apache/bin/httpd}<br />
prog=httpd<br />
pidfile=${PIDFILE-/usr/local/site/apache/logs/httpd.pid}<br />
lockfile=${LOCKFILE-/var/lock/subsys/httpd}<br />
RETVAL=0<br />
<br />
# check for 1.3 configuration<br />
check13 () {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CONFFILE=/usr/local/site/apache/conf/httpd.conf<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GONE="(ServerType|BindAddress|Port|AddModule|ClearModuleList|"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GONE="${GONE}AgentLog|RefererLog|RefererIgnore|FancyIndexing|"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GONE="${GONE}AccessConfig|ResourceConfig)"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if LANG=C grep -Eiq "^[[:space:]]*($GONE)" $CONFFILE; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo 1&gt;&amp;2 " Apache 1.3 configuration directives found"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo 1&gt;&amp;2 " please read /usr/share/doc/httpd-2.2.3/migration.html"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; failure "Apache 1.3 config directives test"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />
}<br />
<br />
# The semantics of these two functions differ from the way apachectl does<br />
# things -- attempting to start while running is a failure, and shutdown<br />
# when not running is also a failure.&nbsp; So we just do it the way init scripts<br />
# are expected to behave here.<br />
start() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -n $"Starting $prog: "<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; check13 || exit 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LANG=$HTTPD_LANG daemon $httpd $OPTIONS<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL=$?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ $RETVAL = 0 ] &amp;&amp; touch ${lockfile}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $RETVAL<br />
}<br />
<br />
# When stopping httpd a delay of &gt;10 second is required before SIGKILLing the<br />
# httpd parent; this gives enough time for the httpd parent to SIGKILL any<br />
# errant children.<br />
stop() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -n $"Stopping $prog: "<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; killproc -d 10 $httpd<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL=$?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ $RETVAL = 0 ] &amp;&amp; rm -f ${lockfile} ${pidfile}<br />
}<br />
reload() {<br />
&nbsp;&nbsp;&nbsp; echo -n $"Reloading $prog: "<br />
&nbsp;&nbsp;&nbsp; if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t &gt;&amp;/dev/null; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL=$?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo $"not reloading due to configuration syntax error"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; failure $"not reloading $httpd due to configuration syntax error"<br />
&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; killproc $httpd -HUP<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL=$?<br />
&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp; echo<br />
}<br />
<br />
# See how we were called.<br />
case "$1" in<br />
&nbsp; start)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; start<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; stop)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stop<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; status)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status $httpd<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL=$?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; restart)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stop<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; start<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; condrestart)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [ -f ${pidfile} ] ; then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stop<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; start<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; reload)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reload<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; graceful|help|configtest|fullstatus)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $apachectl $@<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL=$?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; *)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo $"Usage: $prog {start|stop|restart|condrestart|reload|status|fullstatus|graceful|help|configtest}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit 1<br />
esac<br />
<br />
exit $RETVAL<br />
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/282520.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-16 09:31 <a href="http://www.blogjava.net/ruoyoux/articles/282520.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/11 Sun GlassFish Enterprise Server 2.1 Reference Manual</title><link>http://www.blogjava.net/ruoyoux/articles/281525.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Thu, 11 Jun 2009 09:39:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/281525.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/281525.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/281525.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/281525.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/281525.html</trackback:ping><description><![CDATA[<h2>start-node-agent(1)</h2>
<p align="center">
<a href="http://docs.sun.com/app/docs/doc/820-4332/start-node-agent-1?a=view#NAME">Name</a>
| <a href="http://docs.sun.com/app/docs/doc/820-4332/start-node-agent-1?a=view#Synopsis">Synopsis</a>
| <a href="http://docs.sun.com/app/docs/doc/820-4332/start-node-agent-1?a=view#Description">Description</a>
| <a href="http://docs.sun.com/app/docs/doc/820-4332/start-node-agent-1?a=view#Options">Options</a>
| <a href="http://docs.sun.com/app/docs/doc/820-4332/start-node-agent-1?a=view#Operands">Operands</a>
| <a href="http://docs.sun.com/app/docs/doc/820-4332/start-node-agent-1?a=view#Examples">Examples</a>
| <a href="http://docs.sun.com/app/docs/doc/820-4332/start-node-agent-1?a=view#Exit%20Status">Exit Status</a>
| <a href="http://docs.sun.com/app/docs/doc/820-4332/start-node-agent-1?a=view#See%20Also">See Also</a>
</p>
<h4>Name</h4>
<ul>start-node-agent&#8211; starts a node agent</ul>
    <h4>Synopsis</h4>
    <ul>
        <pre><kbd>start-node-agent</kbd> [<kbd><strong>--user</strong></kbd> <var>user</var>]<br />
        <br />
        [<kbd><strong>--passwordfile</strong></kbd> <var>passwordfile</var>] [<kbd><strong>--secure={true|false}</strong></kbd>] <br />
        <br />
        [<kbd><strong> --terse={true|false} </strong></kbd>] [<kbd><strong> --echo={true|false} </strong></kbd>]<br />
        <br />
        [<kbd><strong> --interactive={true|false} </strong></kbd>] [<kbd><strong> --verbose={true|false} </strong></kbd>] <br />
        <br />
        [<kbd><strong> --agentdir </strong></kbd> <var>nodeagent_path</var>] [<kbd><strong>--startinstances={true|false}</strong></kbd>] <br />
        <br />
        [<kbd><strong> --syncinstances={true|false} </strong></kbd>] [<var>nodeagent_name</var>]</pre>
    </ul>
    <h4>Description</h4>
    <ul><hr />
        <strong>Note &#8211; </strong>
        <p>This command is available only in domains that are configured
        to support clusters, such as domains that are created with the cluster profile.</p>
        <hr />
        <p>Use the <kbd>start-node-agent</kbd> command start a node agent.
        The command will return control to the user before instances are actually
        started. The <kbd>list-instances</kbd> command can be executed to
        see if they have actually started. This command may take a while to execute
        since the node agent may need to create and start a number of server instances.</p>
        <p>This command is supported in local mode only.</p>
    </ul>
    <h4>Options</h4>
    <ul><dl><dt>
        <kbd><strong>-u</strong></kbd> <kbd><strong>--user</strong></kbd>
        </dt><dd>
        <p>The authorized domain administration server administrative
        username.</p>
        </dd><dt>
        <kbd><strong>--passwordfile</strong></kbd>
        </dt><dd>
        <p>The <kbd><strong>--passwordfile</strong></kbd> option
        specifies the name of a file containing the password entries in a specific
        format. The entry for the password must have the <tt>AS_ADMIN_</tt> prefix
        followed by the password name in uppercase letters.</p>
        <p>For example, to specify the domain administration server password, use
        an entry with the following format: <kbd>AS_ADMIN_PASSWORD</kbd>=<var>password</var>, where <var>password</var> is the actual
        administrator password. Other passwords that can be specified include <tt>AS_ADMIN_MAPPEDPASSWORD</tt>, <tt>AS_ADMIN_USERPASSWORD</tt>, and <tt>AS_ADMIN_ALIASPASSWORD</tt>.</p>
        <p>All remote commands must specify the administration password to authenticate
        to the domain administration server, either through <kbd><strong>--passwordfile</strong></kbd> or <kbd>asadmin login</kbd>, or interactively on the command
        prompt. The <kbd>asadmin login</kbd> command can be used only to specify
        the administration password. For other passwords, that must be specified for remote
        commands, use the <kbd><strong>--passwordfile</strong></kbd> or enter
        them at the command prompt. </p>
        <p>If you have authenticated to a domain using the <kbd>asadmin login</kbd> command,
        then you need not specify the administration password through the <kbd><strong>--passwordfile</strong></kbd> option on subsequent operations to
        this particular domain. However, this is applicable only to <kbd>AS_ADMIN_PASSWORD</kbd> option. You will still need to provide the other passwords, for
        example, <tt>AS_ADMIN_USERPASSWORD</tt>, as and when required by
        individual commands, such as <kbd>update-file-user</kbd>.</p>
        <p>For security reasons, passwords specified as an environment variable
        will not be read by <kbd>asadmin</kbd>. </p>
        <p>The default value for <tt>AS_ADMIN_MASTERPASSWORD</tt> is <tt>changeit</tt>.</p>
        </dd><dt>
        <kbd><strong>-s</strong></kbd> <kbd><strong>--secure</strong></kbd>
        </dt><dd>
        <p>If set to true, uses SSL/TLS to communicate with the domain
        administration server. Default is true.</p>
        </dd><dt>
        <kbd><strong>-t</strong></kbd> <kbd><strong>--terse</strong></kbd>
        </dt><dd>
        <p>Indicates that any output data must be very concise, typically
        avoiding human-friendly sentences and favoring well-formatted data for consumption
        by a script. Default is false.</p>
        </dd><dt>
        <kbd><strong>-e</strong></kbd> <kbd><strong>--echo</strong></kbd>
        </dt><dd>
        <p>Setting to true will echo the command line statement on the
        standard output. Default is false.</p>
        </dd><dt>
        <kbd><strong>-I</strong></kbd> <kbd><strong>--interactive</strong></kbd>
        </dt><dd>
        <p>If set to true (default), only the required password options
        are prompted.</p>
        </dd><dt>
        <kbd><strong>-h</strong></kbd> <kbd><strong>--help</strong></kbd>
        </dt><dd>
        <p>Displays the help text for the command.</p>
        </dd><dt>
        <kbd><strong>--verbose</strong></kbd>
        </dt><dd>
        <p>By default this flag is set to false. If set to true, a console
        window is opened for the node agent and for every server instance a node agent
        manages. On Windows, press Ctrl-Break in the console to print a thread dump.
        On UNIX, press CTRL-Backslash in the console to print a thread dump. The node
        agent thread dump goes to its console. The server instance thread dump goes
        to the instance log file.</p>
        </dd><dt>
        <kbd><strong>--agentdir</strong></kbd>
        </dt><dd>
        <p>Like a Domain Administration Server (DAS), each node agent
        resides in a top level directory named <var>agentdir</var>/<var>nodeagent_name</var>. If specified, the path must be accessible in
        the filesystem. If not specified, defaults to the <var>install_dir</var><tt>/nodeagents</tt> directory. </p>
        </dd><dt>
        <kbd><strong>--startinstances</strong></kbd>
        </dt><dd>
        <p>If set to true, all server instances that are not currently
        running are started. If set to false, instances are not started. If the option
        is omitted, it defaults to the value of the node agent's <kbd>start-servers-in-startup</kbd> attribute, located in the <kbd>domain.xml</kbd> file.</p>
        </dd><dt>
        <kbd><strong>--syncinstances</strong></kbd>
        </dt><dd>
        <p>If set to true, forcibly synchronizes the cache repositories
        of <strong>all</strong> server instances with the central repository of
        the DAS. The synchronization occurs when the node agent is started. Default
        is false.</p>
        </dd></dl></ul>
        <h4>Operands</h4>
        <ul><dl><dt>
            <var>nodeagent_name</var>
            </dt><dd>
            <p>The name of the node agent to be started.</p>
            </dd></dl></ul>
            <h4>Examples</h4>
            <ul><hr />
                <h5>Example&nbsp;1  Using the start-node-agent command</h5>
                <br />
                <table border="1" cellpadding="1" width="100%">
                    <tbody>
                        <tr>
                            <td nowrap="1">
                            <br />
                            <pre>asadmin&gt; <strong><kbd>start-node-agent --user admin <br />
                            <br />
                            --passwordfile passwordfile nodeagent1</kbd></strong><br />
                            <br />
                            Nodeagent1 started.</pre>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <p>The node agent <tt>nodeagent1</tt> is started in the default <kbd><var>install_dir</var>/nodeagents</kbd> directory. </p>
                <hr />
            </ul>
            <h4>Exit Status</h4>
            <ul><dl><dt>0</dt><dd>
                <p>command executed successfully</p>
                </dd><dt>1</dt><dd>
                <p>error in executing the command</p>
                </dd></dl></ul>
                <h4>See Also</h4>
                <ul>
                    <p>
                    <a href="http://docs.sun.com/app/docs/doc/820-4332/stop-node-agent-1?a=view">stop-node-agent(1)</a>, <a href="http://docs.sun.com/app/docs/doc/820-4332/delete-node-agent-1?a=view">delete-node-agent(1)</a>, <a href="http://docs.sun.com/app/docs/doc/820-4332/list-node-agents-1?a=view">list-node-agents(1)</a>, <a href="http://docs.sun.com/app/docs/doc/820-4332/create-node-agent-1?a=view">create-node-agent(1)</a>
                    </p>
                </ul>
                Java EE 5&nbsp;&nbsp;Last Revised 13 Jul 2007
<img src ="http://www.blogjava.net/ruoyoux/aggbug/281525.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-11 17:39 <a href="http://www.blogjava.net/ruoyoux/articles/281525.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/11 backup database every day [Script]</title><link>http://www.blogjava.net/ruoyoux/articles/281466.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Thu, 11 Jun 2009 06:17:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/281466.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/281466.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/281466.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/281466.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/281466.html</trackback:ping><description><![CDATA[#!/usr/bin/perl -w<br />
<br />
#<br />
# Created by: JOJO<br />
# Created Date: 10 June 2009<br />
# Desc: To backup ps corresponding databases for Point System<br />
#<br />
<br />
use strict;<br />
use DateTime;<br />
<br />
<br />
main();<br />
<br />
sub main {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get date<br />
&nbsp;&nbsp; &nbsp;my $dt = DateTime-&gt;now; <br />
&nbsp;&nbsp; &nbsp;my $year&nbsp;&nbsp; = $dt-&gt;year;<br />
&nbsp; &nbsp;&nbsp; &nbsp;my $month&nbsp; = sprintf "%02d", $dt-&gt;month;<br />
&nbsp;&nbsp; &nbsp;my $day = sprintf "%02d", $dt-&gt;day;<br />
&nbsp;&nbsp; &nbsp;my $ts = $dt-&gt;epoch();<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; `mkdir /home/mdrop/PSBackupDB` if (! -d "/home/mdrop/PSBackupDB" );<br />
&nbsp;&nbsp;&nbsp;&nbsp; `mkdir /home/mdrop/PSBackupDBLog` if (! -d "/home/mdrop/PSBackupDBLog" );<br />
&nbsp;&nbsp;&nbsp;&nbsp; `mkdir /home/mdrop/PSBackupDB/$year$month` if (! -d "/home/mdrop/PSBackupDB/$year$month" );<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $dbpath = "/home/mdrop/PSBackupDB";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $logpath = "/home/mdrop/PSBackupDBLog";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $backlog = "$logpath/backup.log";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $user = "root";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $pwd = "password";<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #open log file for writing, append purpose<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; open(MYLOGFILE, "&gt;&gt;$backlog"); <br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Export ps db to dump file<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print MYLOGFILE "mysqldump -u$user -p$pwd&nbsp; pointsystem_sd at $dt"n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`mysqldump -u$user -p$pwd&nbsp; pointsystem_sd &gt; $dbpath/pointsystem_sd.sql-$year$month$day` || die print "Cannot export pointsystem_sd database."n" &gt;&gt; $backlog;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print MYLOGFILE "mysqldump -u$user -p$pwd&nbsp; pointsystem_off at $dt"n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`mysqldump -u$user -p$pwd&nbsp; pointsystem_off &gt; $dbpath/pointsystem_off.sql-$year$month$day` || die print "Cannot export pointsystem_off database."n" &gt;&gt; $backlog;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print MYLOGFILE "mysqldump -u$user -p$pwd&nbsp; pointsys_log_db at $dt"n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`mysqldump -u$user -p$pwd&nbsp; pointsys_log_db &gt; $dbpath/pointsys_log_db.sql-$year$month$day` || die print "Cannot export pointsys_log_db database."n" &gt;&gt; $backlog;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print MYLOGFILE "mysqldump -u$user -p$pwd&nbsp; glassfishtimer at $dt"n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`mysqldump -u$user -p$pwd&nbsp; glassfishtimer &gt; $dbpath/glassfishtimer.sql-$year$month$day` || die print "Cannot export glassfishtimer database."n" &gt;&gt; $backlog;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print MYLOGFILE "mysqldump -u$user -p$pwd&nbsp; obcart at $dt"n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`mysqldump -u$user -p$pwd&nbsp; obcart &gt; $dbpath/obcart.sql-$year$month$day` || die print "Cannot export obcart database."n" &gt;&gt; $backlog;<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #gzip ps db backup file<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`cd $dbpath; gzip pointsystem_sd.sql-$year$month$day` || die print "Cannot gzip pointsystem_sd.sql-$year$month$day file."n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`cd $dbpath; gzip pointsystem_off.sql-$year$month$day` || die print "Cannot gzip pointsystem_off.sql-$year$month$day file."n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`cd $dbpath; gzip pointsys_log_db.sql-$year$month$day` || die print "Cannot gzip pointsys_log_db.sql-$year$month$day file."n" ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`cd $dbpath; gzip glassfishtimer.sql-$year$month$day`&nbsp; || die print "Cannot gzip glassfishtimer.sql-$year$month$day file."n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`cd $dbpath; gzip obcart.sql-$year$month$day`|| die print "Cannot gzip obcart.sql-$year$month$day database."n";<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #move ps db backup sql file to archive folder<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`mv&nbsp; $dbpath/pointsystem_sd.sql-$year$month$day.gz $dbpath/$year$month` || die print "Cannot move pointsystem_sd.sql-$year$month$day.gz file."n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`mv&nbsp; $dbpath/pointsystem_off.sql-$year$month$day.gz $dbpath/$year$month` || die print "Cannot move pointsystem_off.sql-$year$month$day.gz file."n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`mv&nbsp; $dbpath/pointsys_log_db.sql-$year$month$day.gz $dbpath/$year$month` || die print "Cannot move pointsys_log_db.sql-$year$month$day.gz file."n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`mv&nbsp; $dbpath/glassfishtimer.sql-$year$month$day.gz $dbpath/$year$month`&nbsp; || die print "Cannot move glassfishtimer.sql-$year$month$day.gz file."n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !`mv&nbsp; $dbpath/obcart.sql-$year$month$day.gz $dbpath/$year$month`|| die print "Cannot move glassfishtimer.sql-$year$month$day.gz file."n";<br />
<br />
}<br />
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/281466.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-11 14:17 <a href="http://www.blogjava.net/ruoyoux/articles/281466.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/11 NginX + Apache </title><link>http://www.blogjava.net/ruoyoux/articles/281404.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Thu, 11 Jun 2009 03:48:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/281404.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/281404.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/281404.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/281404.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/281404.html</trackback:ping><description><![CDATA[cat httpd-vhosts.conf<br />
--------------------------------------------------------------------------------------------<br />
#<br />
# Virtual Hosts<br />
#<br />
# If you want to maintain multiple domains/hostnames on your<br />
# machine you can setup VirtualHost containers for them. Most configurations<br />
# use only name-based virtual hosts so the server doesn't need to worry about<br />
# IP addresses. This is indicated by the asterisks in the directives below.<br />
#<br />
# Please see the documentation at<br />
# &lt;URL:http://httpd.apache.org/docs/2.2/vhosts/&gt;<br />
# for further details before you try to setup virtual hosts.<br />
#<br />
# You may use the command line option '-S' to verify your virtual host<br />
# configuration.<br />
<br />
#<br />
# Use name-based virtual hosting.<br />
#<br />
NameVirtualHost *:8080<br />
<br />
#<br />
# VirtualHost example:<br />
# Almost any Apache directive may go into a VirtualHost container.<br />
# The first VirtualHost section is used for all requests that do not<br />
# match a ServerName or ServerAlias in any &lt;VirtualHost&gt; block.<br />
#<br />
<br />
&lt;VirtualHost *:8080&gt;<br />
DocumentRoot /usr/local/site/webroot/mydomain1.com<br />
ServerName mydomain1.com<br />
ErrorLog "/var/log/apache_log/mydomain1.com-error_log"<br />
CustomLog "|/usr/local/site/apache/bin/rotatelogs /var/log/apache_log/apache_accesslog/mydomain1.com-access_log.%Y%m%d 86400 -360" common<br />
&lt;Directory "/usr/local/site/webroot/mydomain1.com"&gt;<br />
Options -Indexes FollowSymLinks<br />
AllowOverride None<br />
Options ExecCGI<br />
#Options None<br />
Order allow,deny<br />
Allow from all<br />
<br />
#AuthType basic<br />
#AuthName "private area"<br />
#AuthBasicProvider file<br />
#AuthUserFile /usr/local/site/webroot/mydomain1.com/.htpasswd<br />
#Require valid-user<br />
#Options Indexes FollowSymLinks<br />
#AllowOverride All<br />
#Order deny,allow<br />
ErrorDocument 404&nbsp; '/?c=interact.image&amp;f=show'<br />
&lt;/Directory&gt;<br />
RedirectMatch 404 /".svn(/|$)<br />
<br />
&lt;/VirtualHost&gt;<br />
<br />
<br />
&lt;VirtualHost *:8080&gt;<br />
DocumentRoot /usr/local/site/webroot/mydomain2.com<br />
ServerName mydomain2.com<br />
ErrorLog "/var/log/apache_log/hkogop-error_log"<br />
CustomLog "|/usr/local/site/apache/bin/rotatelogs /var/log/apache_log/apache_accesslog/mydomain2.com-access_log.%Y%m%d 86400 -360" common<br />
&lt;Directory "/usr/local/site/webroot/mydomain2.com"&gt;<br />
Options -Indexes FollowSymLinks<br />
AllowOverride None<br />
Order allow,deny<br />
Allow from all<br />
<br />
#AuthType basic<br />
#AuthName "private area"<br />
#AuthBasicProvider file<br />
#AuthUserFile /usr/local/site/webroot/mydomain1.com/.htpasswd<br />
#Require valid-user<br />
#Options -Indexes FollowSymLinks<br />
#AllowOverride All<br />
#Order deny,allow<br />
ErrorDocument 404&nbsp; '/?c=interact.image&amp;f=show'<br />
&lt;/Directory&gt;<br />
RedirectMatch 404 /".svn(/|$)<br />
<br />
&lt;/VirtualHost&gt;<br />
<br />
<br />
&lt;VirtualHost *:8080&gt;<br />
DocumentRoot /usr/local/site/webroot/mydomain3.com<br />
ServerName mydomain3.com<br />
ErrorLog "/var/log/apache_log/stage-hkogop-error_log"<br />
CustomLog "|/usr/local/site/apache/bin/rotatelogs /var/log/apache_log/apache_accesslog/mydomain3.com-access_log.%Y%m%d 86400 -360" common<br />
&lt;Directory "/usr/local/site/webroot/mydomain3.com"&gt;<br />
Options -Indexes FollowSymLinks<br />
AllowOverride All<br />
Order allow,deny<br />
Allow from all<br />
<br />
#AuthType basic<br />
#AuthName "private area"<br />
#AuthBasicProvider file<br />
#AuthUserFile /usr/local/site/webroot/mydomain3.com/.htpasswd<br />
#Require valid-user<br />
#Options -Indexes FollowSymLinks<br />
#AllowOverride All<br />
#Order deny,allow<br />
&lt;/Directory&gt;<br />
RedirectMatch 404 /".svn(/|$)<br />
<br />
&lt;/VirtualHost&gt;<br />
<br />
<br />
<br />
&lt;VirtualHost *:8080&gt;<br />
DocumentRoot /usr/local/site/webroot/mydomain4.com<br />
ServerName mydomain4.com<br />
ErrorLog "/var/log/apache_log/mydomain4.com-error_log"<br />
CustomLog "|/usr/local/site/apache/bin/rotatelogs /var/log/apache_log/apache_accesslog/mydomain4.com-access_log.%Y%m%d 86400 -360" common<br />
<br />
&lt;Directory "/usr/local/site/webroot/mydomain4.com"&gt;<br />
Options -Indexes FollowSymLinks<br />
AllowOverride None<br />
Order allow,deny<br />
Allow from all<br />
<br />
#AuthType basic<br />
#AuthName "private area"<br />
#AuthBasicProvider file<br />
#AuthUserFile /usr/local/site/webroot/mydomain4.com/.htpasswd<br />
#Require valid-user<br />
#Options -Indexes FollowSymLinks<br />
#AllowOverride All<br />
#Order deny,allow<br />
<br />
&lt;/Directory&gt;<br />
&lt;Location /zcart/index.php&gt;<br />
&nbsp;Order Deny,Allow<br />
&nbsp;Deny from All<br />
&nbsp;Satisfy All<br />
&lt;/Location&gt;<br />
<br />
RedirectMatch 404 /".svn(/|$)<br />
&lt;/VirtualHost&gt;<br />
<br />
cat nginx.conf<br />
--------------------------------------------------------------------------------------------<br />
user&nbsp; mdrop;<br />
worker_processes&nbsp; 1;<br />
master_process on;<br />
daemon off;<br />
<br />
error_log&nbsp; logs/error.log;<br />
#error_log&nbsp; logs/error.log&nbsp; info;<br />
<br />
#pid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logs/nginx.pid;<br />
<br />
<br />
events {<br />
&nbsp;&nbsp;&nbsp; worker_connections&nbsp; 1024;<br />
}<br />
<br />
<br />
http {<br />
&nbsp;&nbsp;&nbsp; include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mime.types;<br />
&nbsp;&nbsp;&nbsp; default_type&nbsp; application/octet-stream;<br />
<br />
&nbsp;&nbsp;&nbsp; log_format&nbsp; main&nbsp; '$remote_addr - $remote_user [$time_local] $request '<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '"$status" $body_bytes_sent "$http_referer" '<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '"$http_user_agent" "$http_x_forwarded_for"';<br />
<br />
&nbsp;&nbsp;&nbsp; access_log&nbsp; logs/access.log&nbsp; main;<br />
<br />
&nbsp;&nbsp;&nbsp; sendfile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; on;<br />
&nbsp;&nbsp;&nbsp; tcp_nopush&nbsp;&nbsp;&nbsp;&nbsp; on;<br />
&nbsp;&nbsp;&nbsp; tcp_nodelay&nbsp;&nbsp;&nbsp;&nbsp; on;<br />
&nbsp;&nbsp;&nbsp; #keepalive_timeout&nbsp; 0;<br />
&nbsp;&nbsp;&nbsp; keepalive_timeout&nbsp; 65;<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gzip on;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gzip_types text/html text/css ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gzip_comp_level 3;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gzip_proxied any;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gzip_vary on;<br />
<br />
&nbsp;&nbsp;&nbsp; server {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; listen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 80;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server_name&nbsp; _*; <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #charset koi8-r;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #access_log&nbsp; logs/access.log&nbsp; ;<br />
<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location ~* ".(jpg|jpeg|gif|css|png|js|ico|html|inc|mp3|xml|swf)$ {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp; /usr/local/site/webroot/$host/;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index&nbsp; index.html index.htm index.php;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location / {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy_pass&nbsp;&nbsp; http://127.0.0.1:8080;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; proxy_set_header&nbsp; Host&nbsp; $host;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; proxy_set_header&nbsp;&nbsp; X-Forwarded-For&nbsp; $proxy_add_x_forwarded_for;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; proxy_pass_header Server;<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; client_max_body_size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8m;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; client_body_buffer_size&nbsp;&nbsp;&nbsp; 128k;<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; proxy_connect_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 90;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; proxy_send_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 90;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; proxy_read_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 90;<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; proxy_buffer_size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4k;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; proxy_buffers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 64 32k;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; proxy_busy_buffers_size&nbsp;&nbsp;&nbsp; 64k;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; proxy_temp_file_write_size 64k;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #error_page&nbsp; 404&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /404.html;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # redirect server error pages to the static page /50x.html<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; error_page&nbsp;&nbsp; 500 502 503 504&nbsp; /50x.html;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location = /50x.html {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp; html;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # deny access to .htaccess files, if Apache's document root<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # concurs with nginx's one<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location ~ /".ht {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deny&nbsp; all;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location ~ /".svn {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deny&nbsp; all;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location ~ /"sql {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deny&nbsp; all;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
<br />
&nbsp;&nbsp;&nbsp; # another virtual host using mix of IP-, name-, and port-based configuration<br />
&nbsp;&nbsp;&nbsp; #<br />
&nbsp;&nbsp;&nbsp; #server {<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; listen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8000;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; listen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; somename:8080;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; server_name&nbsp; somename&nbsp; alias&nbsp; another.alias;<br />
<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; location / {<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp; html;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index&nbsp; index.html index.htm;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; #}<br />
<br />
<br />
&nbsp;&nbsp;&nbsp; # HTTPS server<br />
&nbsp;&nbsp;&nbsp; #<br />
&nbsp;&nbsp;&nbsp; #server {<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; listen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 443;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; server_name&nbsp; localhost;<br />
<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; on;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_certificate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cert.pem;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_certificate_key&nbsp; cert.key;<br />
<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_session_timeout&nbsp; 5m;<br />
<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_protocols&nbsp; SSLv2 SSLv3 TLSv1;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_ciphers&nbsp; ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; ssl_prefer_server_ciphers&nbsp;&nbsp; on;<br />
<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; location / {<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp; html;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index&nbsp; index.html index.htm;<br />
&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; #}<br />
<br />
}<br />
<br />
<br />
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/281404.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-11 11:48 <a href="http://www.blogjava.net/ruoyoux/articles/281404.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/10 How GlassFish DAS communicates with Node Agents and Instances</title><link>http://www.blogjava.net/ruoyoux/articles/281159.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Wed, 10 Jun 2009 07:12:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/281159.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/281159.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/281159.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/281159.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/281159.html</trackback:ping><description><![CDATA[<p><strong>Question</strong>: Explain the communication details between Domain
Admin Server, node-agents and server instances in Sun's Application
Server 8.x and 9.x (<a href="https://glassfish.dev.java.net/">GlassFish</a> V2).</p>
<p><strong>Terminology</strong>:</p>
<p><font size="2"><strong>DAS</strong>: Domain Admin Server (One per domain) -- The process that controls the management of the entire domain.<br />
</font></p>
<p><font size="2"><strong>NA</strong>: Node Agent -- Generally, one per box or Solaris container -- The process that controls the life cycle of server instances.<br />
</font></p>
<p><font size="2"><strong>SI</strong>: Server Instance --&nbsp; The real Java EE instances that run user applications in an enterprise.</font><br />
</p>
<p><strong>Answer</strong>:</p>
<p><strong>1. Background</strong>:
The domain.xml controls the configuration. At every node-agent, there
are also a few configuration files that are consulted by every NA. See <a href="http://docs.sun.com/app/docs/doc/819-3679/abdkv?a=view">NA section at docs.sun.com</a> for details. Following are the points in time when the communication (for administration/management purpose) happens:</p>
<ul>
    <li><strong>DAS communicates with each NA</strong>: Only when DAS needs to know NA's running status.</li>
    <li><strong>DAS communicates with each SI</strong>: When DAS needs to know SI's running status and when it needs to cascade the SI MBeans into the DAS's MBenServer.<br />
    </li>
    <li><strong>NA communicates with DAS</strong>:
    During initial rendezvous (which may happen during creation of NA),
    synchronization of the NA itself and synchronization of each SI that NA
    is responsible for.</li>
    <li><strong>SI communicates with the DAS</strong>: Never, explicitly.</li>
</ul>
<p>Thus,
the communication is mainly driven by DAS. When the domain is created,
the administration is configured to use an authentication realm named <em>admin-realm</em>.
This realm points to what's called a FileRealm which is nothing but the
implementation of a security realm implementation that uses <em>admin-keyfile</em>. If you see the domain's configuration, you'll find this file in config folder of that domain. </p>
<p>The
communication happens over two channels. One is the HTTP channel and
the other is RMI channel. For this purpose, there is a
SynchronizationServlet and a System JMX Connector (standard in JDK 5)
that is provided. Every DAS and SI, including the NA start a JMX RMI
ConnectorServer that can be optionally configured to use transport
layer security.</p>
<p>Every NA communicates with DAS multiple times,
but the key points are of initial hand-shake and synchronization. The
initial hand-shake is when NA makes DAS aware of its own existence and
DAS correspondingly responds if it has the correct credentials. When
the DAS is configured to have secure access (this is the default in
enterprise profile domain), both the HTTP and JMX/RMI channels use
Transport Layer Security with SSL/v3.&nbsp; Note that during the initial
hand-shake, the DAS knows about NA's existence alone. DAS does not
release the contents of the domain's repository during this phase. This
happens over HTTP channel since creation of node-agent takes the DAS's <strong>admin-port </strong>(default: 4848) as an option.<br />
</p>
<p>After an NA is created, the most natural step is to <em>start</em> that NA. This is done by executing the <strong>asadmin start-node-agent</strong>
command. Since this is the first-time startup of the NA, NA syncs up
with the DAS. Note that startup of NA requires the correct credentials
(admin user name and admin password) to be supplied. The DAS compares
them against its own admin-keyfile and the communication succeeds only
when this succeeds. The NA startup also requires the master password to
be provided on the command line because in order to start, the NA has
to be able to unlock the security store (e.g. keystore.jks) that it
synced from the DAS. Note that master password is never put on the
wire! It has to be provided at the time of both DAS startup and every
NA startup. For advanced use cases, there is an unattended boot
scenario that is handled by using the option <strong>--savemasterpassword</strong> which should be used with care.</p>
<p>The
reason NA needs the master password is also to pass it on to the SI's
it starts (as part of start-instance or start-cluster) so that these
instances are able to unlock the security store to get the primary keys
and certificates.&nbsp;</p>
<p>The NA always communicates with the DAS over
JMX/RMI channel. Thus NA opens an RMI connection to the DAS where DAS
is listening for RMI/JMX Connections. This is where the RMI Registry in
DAS (default port <strong>8686</strong>) comes into picture.<br />
</p>
<p>When the domain is created, it uses the self-signed certificate aliased <strong>s1as</strong>
which is used for internal communication. This certificate is created
anew every time a domain is created. The master password of a domain is
what locks the server's keystore. In enterprise profile domain, NSS is
used to manage the secure store, whereas in cluster profile domain, JKS
manages the secure store. The semantics of the master password are
unchanged in both the cases.</p>
<p>The Server Instances are synced with the DAS as part of either:</p>
<ol>
    <li>start-instance, or</li>
    <li>start-cluster, or</li>
    <li>start-node-agent --syncinstances procedure.</li>
</ol>
<p>For
this synchronization, they use the HTTP layer and communicate with the
SynchronizationServlet that's listening for sync requests. This servlet
is (of course) running in the DAS. </p>
<p>The server instances get the
admin credentials from the node-agent process in a secure manner (using
stdin). This also evident when you try to use the <strong>startserv</strong> script that's located in instance's <em>bin</em> folder.</p>
<p>The
process of DAS communicating with the NA and SI's is identical in that
it communicates with them over RMI/JMX in the other direction.<br />
</p>
<p><strong>2. Transport Layer Security</strong>:</p>
<p>This
is achieved when we enable the security-enabled flag on the
admin-listener and jmx-connector named system on the DAS and server
instances. Note that&nbsp; admin-listener (HTTP/S) is started only in the
DAS. There is no admin-listener in server instances.</p>
<p>It's of
course possible to use another CA-signed certificate for this purpose.
It needs additional configuration after importing those certs in the
store.<br />
</p>
<p><strong>3. Authentication and Credentials</strong>:</p>
<p>Please see: <a href="http://wiki.glassfish.java.net/attach/GlassFishAdministrationPages/admincreds.html">http://wiki.glassfish.java.net/attach/GlassFishAdministrationPages/admincreds.html</a><br />
</p>
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/281159.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-10 15:12 <a href="http://www.blogjava.net/ruoyoux/articles/281159.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/10 Running Glassfish as a service on CentOS</title><link>http://www.blogjava.net/ruoyoux/articles/281155.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Wed, 10 Jun 2009 06:39:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/281155.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/281155.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/281155.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/281155.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/281155.html</trackback:ping><description><![CDATA[<p>Here is how you run glassfish as a service on CentOS:</p>
<ol>
    <li> Create a user <em>glassfish (</em>you can call it anything you want) under which Glassfish will run.
    <div>
    <div>
    <pre style="font-family: monospace;"><span style="color: #666666; font-style: italic;">#useradd glassfish</span></pre>
    </div>
    </div>
    </li>
    <li> <a href="https://glassfish.dev.java.net/downloads/v2.1-b60e.html">Install glassfish</a> in /home/glassfish.</li>
    <li>Create the startup script <em>/etc/init.d/glassifsh</em> for glassfish.
    <div>
    <table>
        <tbody>
            <tr>
                <td>
                <pre style="font-family: monospace;"><span style="color: #666666; font-style: italic;">                #!/bin/bash</span><br />
                <span style="color: #666666; font-style: italic;">#</span><br />
                <span style="color: #666666; font-style: italic;"># glassfish:          Startup script for Glassfish Application Server.</span><br />
                <span style="color: #666666; font-style: italic;">#</span><br />
                <span style="color: #666666; font-style: italic;"># chkconfig: 3 80 05</span><br />
                <span style="color: #666666; font-style: italic;"># description:      Startup script for domain1 of Glassfish Application Server.</span><br />
                <span style="color: #007800;"><br />
                GLASSFISH_HOME</span>=<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>glassfish<span style="color: #000000; font-weight: bold;">/</span>glassfish;<br />
                <span style="color: #7a0874; font-weight: bold;">export</span> GLASSFISH_HOME<br />
                <span style="color: #007800;">GLASSFISH_OWNER</span>=glassfish;<br />
                <span style="color: #7a0874; font-weight: bold;">export</span> GLASSFISH_OWNER<br />
                <br />
                start<span style="color: #7a0874; font-weight: bold;">(</span><span style="color: #7a0874; font-weight: bold;">)</span> <span style="color: #7a0874; font-weight: bold;">{</span><br />
                <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">"Starting Glassfish: "</span><br />
                <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">"Starting Glassfish at <span style="color: #780078;">`date`</span>"</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$GLASSFISH_HOME</span><span style="color: #000000; font-weight: bold;">/</span>domains<span style="color: #000000; font-weight: bold;">/</span>domain1<span style="color: #000000; font-weight: bold;">/</span>logs<span style="color: #000000; font-weight: bold;">/</span>startup.log<br />
                <span style="color: #c20cb9; font-weight: bold;">su</span> <span style="color: #007800;">$GLASSFISH_OWNER</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">"<span style="color: #007800;">$GLASSFISH_HOME</span>/bin/asadmin start-domain domain1"</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$GLASSFISH_HOME</span><span style="color: #000000; font-weight: bold;">/</span>domains<span style="color: #000000; font-weight: bold;">/</span>domain1<span style="color: #000000; font-weight: bold;">/</span>logs<span style="color: #000000; font-weight: bold;">/</span>startup.log<br />
                <br />
                <span style="color: #c20cb9; font-weight: bold;">sleep</span> <span style="color: #000000;">2</span><br />
                <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">"done"</span><br />
                <span style="color: #7a0874; font-weight: bold;">}</span><br />
                <br />
                stop<span style="color: #7a0874; font-weight: bold;">(</span><span style="color: #7a0874; font-weight: bold;">)</span> <span style="color: #7a0874; font-weight: bold;">{</span><br />
                <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">"Stopping Glassfish: "</span><br />
                <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">"Stopping Glassfish at <span style="color: #780078;">`date`</span>"</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$GLASSFISH_HOME</span><span style="color: #000000; font-weight: bold;">/</span>domains<span style="color: #000000; font-weight: bold;">/</span>domain1<span style="color: #000000; font-weight: bold;">/</span>logs<span style="color: #000000; font-weight: bold;">/</span>startup.log<br />
                <span style="color: #c20cb9; font-weight: bold;">su</span> <span style="color: #007800;">$GLASSFISH_OWNER</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">"<span style="color: #007800;">$GLASSFISH_HOME</span>/bin/asadmin stop-domain domain1"</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$GLASSFISH_HOME</span><span style="color: #000000; font-weight: bold;">/</span>domains<span style="color: #000000; font-weight: bold;">/</span>domain1<span style="color: #000000; font-weight: bold;">/</span>logs<span style="color: #000000; font-weight: bold;">/</span>startup.log<br />
                <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">"done"</span><br />
                <span style="color: #7a0874; font-weight: bold;">}</span><br />
                <br />
                <span style="color: #666666; font-style: italic;"># See how we were called.</span><br />
                <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">"$1"</span> <span style="color: #000000; font-weight: bold;">in</span><br />
                start<span style="color: #7a0874; font-weight: bold;">)</span><br />
                <br />
                start<br />
                <span style="color: #000000; font-weight: bold;">  ;;</span><br />
                <br />
                stop<span style="color: #7a0874; font-weight: bold;">)</span><br />
                stop<br />
                <span style="color: #000000; font-weight: bold;">;;</span><br />
                <br />
                restart<span style="color: #7a0874; font-weight: bold;">)</span><br />
                stop<br />
                start<br />
                <span style="color: #000000; font-weight: bold;"> ;;</span><br />
                <br />
                <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">)</span><br />
                <span style="color: #7a0874; font-weight: bold;">echo</span> $<span style="color: #ff0000;">"Usage: glassfish {start|stop|restart}"</span><br />
                <span style="color: #7a0874; font-weight: bold;">exit</span><br />
                <span style="color: #000000; font-weight: bold;">esac</span></pre>
                </td>
            </tr>
        </tbody>
    </table>
    </div>
    </li>
    <li>Install the service
    <div>
    <div>
    <pre style="font-family: monospace;"><span style="color: #666666; font-style: italic;">#chmod +x /etc/init.d/glassfish</span><br />
    <span style="color: #666666; font-style: italic;">#chkconfig -add glassfish</span><br />
    <span style="color: #666666; font-style: italic;">#chkconfig --level 3 glassfish on</span></pre>
    </div>
    </div>
    </li>
    <li>Start glassfish.
    <div>
    <div>
    <pre style="font-family: monospace;"><span style="color: #666666; font-style: italic;">#/etc/init.d/glassfish start</span></pre>
    </div>
    </div>
    </li>
</ol>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/281155.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-10 14:39 <a href="http://www.blogjava.net/ruoyoux/articles/281155.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/10  Autostarting Glassfish on CentOS</title><link>http://www.blogjava.net/ruoyoux/articles/281154.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Wed, 10 Jun 2009 06:38:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/281154.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/281154.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/281154.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/281154.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/281154.html</trackback:ping><description><![CDATA[<div>
<p>I&#8217;ve been working with <a href="https://glassfish.dev.java.net/" target="_blank">Glassfish</a>
recently, from the system administration point of view.&nbsp; First task,
after getting a good build with Maven (doing it with basic rpm methods
netted me a massive dependency list, including things like Firefox!),
was to write an init script so that Glassfish can be integrated into
the CentOS boot sequence.</p>
<p>Because we might have multiple domains set up inside of Glassfish, I
opted for a setup similar to the Tomcat5 init script - check the
basename of $0, and use that to determine which domain to boot up.&nbsp; The
fiddling in start() gets around the fact that Glassfish doesn&#8217;t seem to
write a PID file out where we need one.</p>
<p>So, just in case anyone else needs to do this:</p>
<div>
<div>
<pre><span style="color: #808080; font-style: italic;">#!/bin/bash</span><br />
<span style="color: #808080; font-style: italic;"># chkconfig: 2345 85 15</span><br />
<span style="color: #808080; font-style: italic;"># description: GlassFish is a Java Application Server.</span><br />
<span style="color: #808080; font-style: italic;"># processname: glassfish</span><br />
<span style="color: #808080; font-style: italic;"># pidfile: /var/run/glassfish.pid</span><br />
<br />
<span style="color: #808080; font-style: italic;"># source function library</span><br />
. <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>functions<br />
<br />
<span style="color: #007800;">RETVAL=</span><span style="color: #000000;">0</span><br />
<br />
<span style="color: #007800;">GLASSFISH_BIN=</span><span style="color: #ff0000;">"/var/lib/glassfish/bin"</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Basename works with symbolic links.</span><br />
<span style="color: #007800;">NAME=</span><span style="color: #ff0000;">"$(basename $0)"</span><br />
<span style="color: #7a0874; font-weight: bold;">unset</span> ISBOOT<br />
<br />
<span style="color: #808080; font-style: italic;"># Trim off the Sxx/Kxx prefix</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">[</span> <span style="color: #ff0000;">"${NAME:0:1}"</span> = <span style="color: #ff0000;">"S"</span> -o <span style="color: #ff0000;">"${NAME:0:1}"</span> = <span style="color: #ff0000;">"K"</span> <span style="color: #7a0874; font-weight: bold;">]</span>; <span style="color: #000000; font-weight: bold;">then</span><br />
<span style="color: #007800;">NAME=</span><span style="color: #ff0000;">"${NAME:3}"</span><br />
<span style="color: #007800;">ISBOOT=</span><span style="color: #ff0000;">"1"</span><br />
<span style="color: #000000; font-weight: bold;">fi</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Trim off the glassfish- prefix</span><br />
<span style="color: #007800;">NAME=</span>$<span style="color: #7a0874; font-weight: bold;">{</span>NAME:<span style="color: #000000;">10</span><span style="color: #7a0874; font-weight: bold;">}</span><br />
<br />
<span style="color: #808080; font-style: italic;"># /etc/init.d/glassfish should never be called directly.</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">[</span> -z <span style="color: #007800;">$NAME</span> <span style="color: #7a0874; font-weight: bold;">]</span>; <span style="color: #000000; font-weight: bold;">then</span><br />
<span style="color: #7a0874; font-weight: bold;">echo</span> -n $<span style="color: #ff0000;">"Cannot start Glassfish without specifying a domain."</span><br />
failure<br />
<span style="color: #7a0874; font-weight: bold;">echo</span><br />
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span><br />
<span style="color: #000000; font-weight: bold;">fi</span><br />
<br />
start<span style="color: #7a0874; font-weight: bold;">(</span><span style="color: #7a0874; font-weight: bold;">)</span> <span style="color: #7a0874; font-weight: bold;">{</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">echo</span> -n $<span style="color: #ff0000;">"Starting Glassfish V2 domain $NAME: "</span><br />
daemon --user glassfish --pidfile <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>glassfish-<span style="color: #007800;">$NAME</span>.pid <span style="color: #ff0000;">"$GLASSFISH_BIN/asadmin start-domain $NAME &amp;gt;/dev/null 2&amp;gt;&amp;amp;1"</span><br />
<span style="color: #007800;">RETVAL=</span><span style="color: #007800;">$?</span><br />
<br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">[</span> <span style="color: #007800;">$RETVAL</span> -eq <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">]</span>; <span style="color: #000000; font-weight: bold;">then</span><br />
<span style="color: #007800;">PID=</span>`<span style="color: #c20cb9; font-weight: bold;">ps</span> U glassfish <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #007800;">$NAME</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{ print $1}'</span>`<br />
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$PID</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt; <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>glassfish-<span style="color: #007800;">$NAME</span>.pid<br />
<span style="color: #c20cb9; font-weight: bold;">touch</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>lock<span style="color: #000000; font-weight: bold;">/</span>subsys<span style="color: #000000; font-weight: bold;">/</span>glassfish-<span style="color: #007800;">$NAME</span><br />
<span style="color: #000000; font-weight: bold;">fi</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">echo</span><br />
<span style="color: #7a0874; font-weight: bold;">}</span><br />
<br />
<br />
stop<span style="color: #7a0874; font-weight: bold;">(</span><span style="color: #7a0874; font-weight: bold;">)</span> <span style="color: #7a0874; font-weight: bold;">{</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">echo</span> -n $<span style="color: #ff0000;">"Shutting down Glassfish V2 domain $NAME: "</span><br />
<br />
<span style="color: #007800;">$GLASSFISH_BIN</span><span style="color: #000000; font-weight: bold;">/</span>asadmin stop-domain <span style="color: #007800;">$NAME</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">1</span><br />
<br />
<span style="color: #007800;">RETVAL=</span><span style="color: #007800;">$?</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">[</span> <span style="color: #007800;">$RETVAL</span> -eq <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">]</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #c20cb9; font-weight: bold;">rm</span> -f <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>lock<span style="color: #000000; font-weight: bold;">/</span>subsys<span style="color: #000000; font-weight: bold;">/</span>glassfish-<span style="color: #007800;">$NAME</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #c20cb9; font-weight: bold;">rm</span> -f <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>glassfish-<span style="color: #007800;">$NAME</span>  <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; success <span style="color: #000000; font-weight: bold;">||</span> failure<br />
<br />
<span style="color: #7a0874; font-weight: bold;">echo</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">}</span><br />
<br />
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">"$1"</span> <span style="color: #000000; font-weight: bold;">in</span><br />
<br />
start<span style="color: #7a0874; font-weight: bold;">)</span><br />
<br />
start<br />
<br />
<span style="color: #000000; font-weight: bold;">;;</span><br />
<br />
stop<span style="color: #7a0874; font-weight: bold;">)</span><br />
<br />
stop<br />
<span style="color: #000000; font-weight: bold;">;;</span><br />
<br />
restart<span style="color: #000000; font-weight: bold;">|</span>reload<span style="color: #7a0874; font-weight: bold;">)</span><br />
<br />
stop<br />
<br />
start<br />
<br />
<span style="color: #000000; font-weight: bold;">;;</span><br />
<br />
condrestart<span style="color: #7a0874; font-weight: bold;">)</span><br />
<br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">[</span> -f <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>lock<span style="color: #000000; font-weight: bold;">/</span>subsys<span style="color: #000000; font-weight: bold;">/</span>glassfish-<span style="color: #007800;">$NAME</span> <span style="color: #7a0874; font-weight: bold;">]</span>; <span style="color: #000000; font-weight: bold;">then</span><br />
<br />
stop<br />
<br />
start<br />
<span style="color: #000000; font-weight: bold;">fi</span><br />
<span style="color: #000000; font-weight: bold;">;;</span><br />
<br />
status<span style="color: #7a0874; font-weight: bold;">)</span><br />
status glassfish-<span style="color: #007800;">$NAME</span><br />
<br />
<span style="color: #007800;">RETVAL=</span><span style="color: #007800;">$?</span><br />
<span style="color: #000000; font-weight: bold;">;;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">)</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">echo</span> $<span style="color: #ff0000;">"Usage: $0 {start|stop|restart|condrestart|status}"</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span><br />
<br />
<span style="color: #000000; font-weight: bold;">esac</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #007800;">$RETVAL</span></pre>
</div>
</div>
<p>The alternative is to define a /etc/sysconfig/glassfish file, and
insert a variable with the list of domains to boot, in sequence.&nbsp; This
is a little harder to manage automatically in <a href="http://reductivelabs.com/projects/puppet/" target="_blank">Puppet</a>,
but might be a better solution if precise boot sequences are required
(this method will boot in sequence based on the S numbers in the base
script, and then the alphabetical ordering of the names).</p>
</div>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/281154.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-10 14:38 <a href="http://www.blogjava.net/ruoyoux/articles/281154.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/10 Linux Glassfish startup service</title><link>http://www.blogjava.net/ruoyoux/articles/281153.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Wed, 10 Jun 2009 06:37:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/281153.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/281153.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/281153.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/281153.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/281153.html</trackback:ping><description><![CDATA[1. Add the script glassfish below to /etc/init.d<br />
Name of file = glassfish- e.g., glassfish-domain1<br />
-chmod a+x /etc/init.d/glassfish-<br />
<br />
2. To support service, the script must fulfill the below criteria:<br />
-3 functions: start, stop, restart<br />
-chkconfig level<br />
3. debug script # bash -x glassfish- <br />
4. to have glassfish start during boot (and stop during halt)<br />
<br />
run level: 2345<br />
start priority:64<br />
stop priority:36<br />
<br />
ln -s /etc/init.d/glassfish- /etc/rc0.d/K36glassfish-<br />
ln -s /etc/init.d/glassfish- /etc/rc1.d/K36glassfish-<br />
ln -s /etc/init.d/glassfish- /etc/rc2.d/S64glassfish-<br />
ln -s /etc/init.d/glassfish- /etc/rc3.d/S64glassfish-<br />
ln -s /etc/init.d/glassfish- /etc/rc4.d/S64glassfish-<br />
ln -s /etc/init.d/glassfish- /etc/rc5.d/S64glassfish-<br />
ln -s /etc/init.d/glassfish- /etc/rc6.d/K36glassfish-<br />
<br />
5. reboot<br />
<br />
Linux command to chkconfig service start on boot<br />
#: ntsysv<br />
<br />
ps U <br />
service glassfish- status<br />
service glassfish- start<br />
<br />
************glassfish****************************<br />
<br />
#!/bin/bash<br />
# chkconfig: 2345 64 36<br />
# description: GlassFish is a Java Application Server.<br />
# processname: glassfish<br />
# pidfile: /var/run/glassfish.pid<br />
<br />
# filename glassfish-<br />
<br />
# source function library<br />
. /etc/init.d/functions<br />
<br />
RETVAL=0<br />
GLASSFISH_BIN="/opt/glassfish/bin"<br />
PASSWORDPATH="/opt/glassfish/domains/dsss/config/startup-password"<br />
GFUSER="atworld"<br />
<br />
# Basename works with symbolic links.<br />
NAME="$(basename $0)"<br />
unset ISBOOT<br />
# Trim off the Sxx/Kxx prefix<br />
if [ "${NAME:0:1}" = "S" -o "${NAME:0:1}" = "K" ]; then<br />
NAME="${NAME:3}"<br />
ISBOOT="1"<br />
fi<br />
# Trim off the glassfish- prefix<br />
NAME=${NAME:10}<br />
<br />
# /etc/init.d/glassfish should never be called directly.<br />
if [ -z $NAME ]; then<br />
echo -n $"Cannot start Glassfish without specifying a domain."<br />
failure<br />
echo<br />
exit 1<br />
fi<br />
<br />
start() {<br />
echo -n $"Starting Glassfish V2 domain $NAME: "<br />
daemon --user $GFUSER --pidfile /var/run/glassfish-$NAME.pid
"$GLASSFISH_BIN/asadmin start-domain --passwordfile $PASSWORDPATH $NAME"<br />
RETVAL=$?<br />
if [ $RETVAL -eq 0 ]; then<br />
PID=`ps U $GFUSER | grep $NAME | awk '{ print $1}'`<br />
echo $PID &gt; /var/run/glassfish-$NAME.pid<br />
touch /var/lock/subsys/glassfish-$NAME<br />
fi<br />
echo<br />
}<br />
stop() {<br />
echo -n $"Shutting down Glassfish V2 domain $NAME: "<br />
$GLASSFISH_BIN/asadmin stop-domain $NAME<br />
RETVAL=$?<br />
[ $RETVAL -eq 0 ]<br />
rm -f /var/lock/subsys/glassfish-$NAME<br />
rm -f /var/run/glassfish-$NAME success || failure<br />
echo<br />
}<br />
<br />
case "$1" in<br />
start)<br />
start<br />
;;<br />
stop)<br />
stop<br />
;;<br />
restart|reload)<br />
stop<br />
start<br />
;;<br />
condrestart)<br />
if [ -f /var/lock/subsys/glassfish-$NAME ]; then<br />
stop<br />
start<br />
fi<br />
;;<br />
status)<br />
status glassfish-$NAME<br />
RETVAL=$?<br />
;;<br />
*)<br />
echo $"Usage: $0 {start|stop|restart|condrestart|status}"<br />
exit 1<br />
esac<br />
<br />
exit $RETVAL<br />
<br />
****************************************************<br />
<br />
References:<br />
http://www.thelinuxblog.com/adding-a-service-on-fedora/<br />
http://computingwithjasper.blogspot.com/2008/01/installing-glassfish-2-on-ubuntu-710.html<br />
http://www.cyberciti.biz/faq/rhel5-update-rcd-command/<br />
http://www.linux.com/feature/46892<br />
http://www.linuxjournal.com/article/4445<br />
http://www.comptechdoc.org/os/linux/startupman/linux_surcsysinit.html<br />
http://www.vias.org/linux-knowhow/fwpx_appendix_a_03.html<br />
http://www.cricalix.net/archives/2008/07/22/autostarting-glassfish-on-centos/<br />
http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch07_:_The_Linux_Boot_Process<br />
http://www.zimbra.com/forums/installation/10553-solved-sudo-sorry-you-must-have-tty-run-sudo.html<br />
http://www.linuxmanpages.com/man5/sudoers.5.php#lbAM<br />
http://www.yolinux.com/TUTORIALS/LinuxTutorialInitProcess.html
<img src ="http://www.blogjava.net/ruoyoux/aggbug/281153.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-10 14:37 <a href="http://www.blogjava.net/ruoyoux/articles/281153.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/09 How to disable directory browsing using .htaccess - Apache Web Server</title><link>http://www.blogjava.net/ruoyoux/articles/280804.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Tue, 09 Jun 2009 02:49:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/280804.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/280804.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/280804.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/280804.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/280804.html</trackback:ping><description><![CDATA[Apache web server allow directory browsing by default. It&#8217;s always good to <span style="border-bottom: 1px solid rgb(0, 0, 255); text-decoration: underline; color: rgb(0, 0, 255); font-size: 12px; font-weight: 400; font-style: normal; font-family: 'Lucida Grande',Verdana,Arial,Sans-Serif;" class="IL_LINK_STYLE">disable directory browsing in security aspect. To <input name="IL_MARKER" type="hidden" />disable directory browsing in apache web server you need to edit the httpd.conf or .htaccess</span>
<h3>Disable directory browsing using .htaccess:-</h3>
<ul>
    <li>Open your .htacces file</li>
    <li>Look for <strong>Options Indexes</strong></li>
    <li>If <strong>Options Indexes</strong> exists modify it to <strong>Options -Indexes</strong> or else add <strong>Options -Indexes</strong> as a new line</li>
    <li>The directory browsing feature should be <input name="IL_MARKER" type="hidden" />disable by now</li>
</ul>
<h3>Disable directory browsing using httpd.conf:-</h3>
<ul>
    <li>Open your httpd.conf, normally it&#8217;s located at /usr/local/apache/conf or /etc/httpd.conf</li>
    <li>Go to your own <span style="border-bottom: 1px solid rgb(0, 0, 255); text-decoration: underline; color: rgb(0, 0, 255); font-size: 12px; font-weight: 400; font-style: normal; font-family: 'Lucida Grande',Verdana,Arial,Sans-Serif;" class="IL_LINK_STYLE">Virtual Host settings and look for &#8220;</span><strong>Options Indexes</strong>&#8221; </li>
    <li>Change the <strong>Indexes</strong> to <strong>-Indexes</strong> if Option Indexes exists or else add the <strong>Options -Indexes</strong> line</li>
    <li>Restart your apache web server.</li>
    <li>The directory browsing feature should be <input name="IL_MARKER" type="hidden" />disable by now</li>
</ul>
<h3>Disable directory browsing in CPanel Share Hosting enviroment:-</h3>
<ul>
    <li>Login to your CPanel</li>
    <li>Click on <strong>Index Manager</strong></li>
    <li>Directory will be <span style="border-bottom: 1px solid rgb(0, 0, 255); text-decoration: underline; color: rgb(0, 0, 255); font-size: 12px; font-weight: 400; font-style: normal; font-family: 'Lucida Grande',Verdana,Arial,Sans-Serif;" class="IL_LINK_STYLE">list down. Click on the directory name which you want to <input name="IL_MARKER" type="hidden" />disable the directory browsing</span></li>
    <li>Select <strong>No Index</strong> and click Save</li>
    <li>The directory browsing feature should be <input name="IL_MARKER" type="hidden" />disable by now</li>
</ul>
<p>Once you <input name="IL_MARKER" type="hidden" />disable directory browsing, visitor will not able to browse your directory by accessing the directory directly (if there is no index.<span style="border-bottom: 1px solid rgb(0, 0, 255); text-decoration: underline; color: rgb(0, 0, 255); font-size: 12px; font-weight: 400; font-style: normal; font-family: 'Lucida Grande',Verdana,Arial,Sans-Serif;" class="IL_LINK_STYLE">html file). This will protect your files from exposing to the public.</span></p>
<p><br />
</p>
<p><br />
</p>
<p>http://ubuntuforums.org/archive/index.php/t-234876.html</p>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/280804.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-09 10:49 <a href="http://www.blogjava.net/ruoyoux/articles/280804.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/06 linux服务器配置之Sendmail配置</title><link>http://www.blogjava.net/ruoyoux/articles/280353.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Sat, 06 Jun 2009 11:22:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/280353.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/280353.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/280353.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/280353.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/280353.html</trackback:ping><description><![CDATA[<strong>今天我们来配置一下简单的sendmail服务。。。呵呵、、、真的简单的配置。。。<br />
<br />
rpm&nbsp;-q&nbsp;sendmail<br />
<br />
还需安装这三个包<br />
&nbsp;sendmail-cf-8.12.8-4.i386<br />
<br />
&nbsp;sendmail-devel-8.12.8-4.i<br />
<br />
&nbsp;sendmail-doc-8.12.8-4.i38<br />
<br />
安装好后，我开始配置文件，，，，，<br />
<br />
修改/etc/mail/local-hosts-name文件<br />
[root@localhost&nbsp;named]#&nbsp;cat&nbsp;/etc/mail/local-host-names&nbsp;<br />
#&nbsp;local-host-names&nbsp;-&nbsp;include&nbsp;all&nbsp;aliases&nbsp;for&nbsp;your&nbsp;machine&nbsp;here.&nbsp;<br />
xuwini.com&nbsp;<br />
<br />
<br />
更改/etc/mail/sendmail.mc文件，修改下列地方：&nbsp;<br />
DaemonPortsOptions=Port=smtp,Addr=127.0.0.1,&nbsp;Name=MTA&nbsp;更改为：&nbsp;<br />
DaemonPortsOptions=Port=smtp,Addr=yourip或者0.0.0.0,&nbsp;Name=MTA&nbsp;<br />
然后m4&nbsp;/etc/mail/sendmail.mc&nbsp;&gt;&nbsp;/etc/mail/sendmail.cf&nbsp;<br />
<br />
<br />
修改&nbsp;/etc/rc.d/rc.local<br />
加入一行&nbsp;/usr/sbin/saslauthd&nbsp;-a&nbsp;shadow<br />
<br />
<br />
用户管理&nbsp;<br />
认证的配置：修改/etc/mail/sendmail.mc中的字段，取消&#8220;TRUST_AUTH_MECH&#8221;一行和下一行&#8220;define&#8221;处的注释。然后m4&nbsp;/etc/&nbsp;mail/sendmail.mc&gt;/etc/mail/sendmail.cf。&nbsp;<br />
[root@localhost&nbsp;named]#&nbsp;chkconfig&nbsp;--list&nbsp;saslauthd&nbsp;开启认证&nbsp;<br />
saslauthd&nbsp;0:off&nbsp;1:off&nbsp;2:off&nbsp;3:off&nbsp;4:off&nbsp;5:off&nbsp;6:off&nbsp;<br />
[root@localhost&nbsp;named]#&nbsp;chkconfig&nbsp;--level&nbsp;35&nbsp;saslauthd&nbsp;on&nbsp;<br />
<br />
<br />
建立用户帐号&nbsp;<br />
[root@localhost&nbsp;named]#&nbsp;groupadd&nbsp;mailuser&nbsp;<br />
[root@localhost&nbsp;named]#&nbsp;adduser&nbsp;-g&nbsp;mailuser&nbsp;-s&nbsp;/bin/bash&nbsp;xuwin&nbsp;<br />
[root@localhost&nbsp;named]#&nbsp;adduser&nbsp;-g&nbsp;mailuser&nbsp;-s&nbsp;/sbin/nologin&nbsp;xxx&nbsp;<br />
[root@localhost&nbsp;named]#&nbsp;passwd&nbsp;xuwin&nbsp;<br />
[root@localhost&nbsp;named]#&nbsp;passwd&nbsp;xxx&nbsp;密码都是123&nbsp;<br />
<br />
<br />
<br />
【修改/etc/aliases文件实现邮件转发和邮件列表：&nbsp;<br />
admin:&nbsp;xxx&nbsp;为邮件用户xxx设置别名admin&nbsp;<br />
testgroup:&nbsp;xuwin,xxx&nbsp;实现群发&nbsp;发给testgroup的邮件发给xuwin&nbsp;和&nbsp;xxx&nbsp;以上2个可以分别测试&nbsp;<br />
#newaliases&nbsp;】&nbsp;&nbsp;-------对于我们简单的邮件体系没什么大的用处，个人觉得<br />
<br />
<br />
<br />
访问控制设置&nbsp;<br />
更改/etc/mail/accesss文件，增加：&nbsp;<br />
[root@localhost&nbsp;named]#&nbsp;cat&nbsp;/etc/mail/access&nbsp;<br />
#&nbsp;Check&nbsp;the&nbsp;/usr/share/doc/sendmail/README.cf&nbsp;file&nbsp;for&nbsp;a&nbsp;description&nbsp;<br />
#&nbsp;of&nbsp;the&nbsp;format&nbsp;of&nbsp;this&nbsp;file.&nbsp;(search&nbsp;for&nbsp;access_db&nbsp;in&nbsp;that&nbsp;file)&nbsp;<br />
#&nbsp;The&nbsp;/usr/share/doc/sendmail/README.cf&nbsp;is&nbsp;part&nbsp;of&nbsp;the&nbsp;sendmail-doc&nbsp;<br />
#&nbsp;package.&nbsp;<br />
#&nbsp;<br />
#&nbsp;by&nbsp;default&nbsp;we&nbsp;allow&nbsp;relaying&nbsp;from&nbsp;localhost...&nbsp;<br />
localhost.localdomain&nbsp;RELAY&nbsp;<br />
localhost&nbsp;RELAY&nbsp;<br />
127.0.0.1&nbsp;RELAY&nbsp;<br />
xuwin.com&nbsp;RELAY&nbsp;<br />
完成后makemap&nbsp;hash&nbsp;/etc/mail/access.db&nbsp;&lt;&nbsp;/etc/mail/access进行数据库更新。<br />
<br />
<br />
#service&nbsp;sendmail&nbsp;restart&nbsp;<br />
<br />
已经成功进入。。。。<br />
我们试着来写一份简单的信。。。<br />
那么我在服务器上收信看看。。。。晕倒。。把密码打出啦。。。<br />
[root@localhost&nbsp;root]#&nbsp;telnet&nbsp;localhost&nbsp;25<br />
Trying&nbsp;127.0.0.1...<br />
Connected&nbsp;to&nbsp;localhost.<br />
Escape&nbsp;character&nbsp;is&nbsp;'^]'.<br />
220&nbsp;localhost.localdomain&nbsp;ESMTP&nbsp;Sendmail&nbsp;8.12.8/8.12.8;&nbsp;Sun,&nbsp;10&nbsp;Aug&nbsp;2008&nbsp;20:47:0<br />
6&nbsp;+0800<br />
mail&nbsp;from:&nbsp;root@xuwin.com<br />
250&nbsp;2.1.0&nbsp;root@xuwin.com...&nbsp;Sender&nbsp;ok<br />
rcpt&nbsp;to:&nbsp;xuwin@xuwin.com<br />
250&nbsp;2.1.5&nbsp;xuwin@xuwin.com...&nbsp;Recipient&nbsp;ok<br />
data<br />
354&nbsp;Enter&nbsp;mail,&nbsp;end&nbsp;with&nbsp;"."&nbsp;on&nbsp;a&nbsp;line&nbsp;by&nbsp;itself<br />
test<br />
hi.baidu.com/proxuwin<br />
xuwin.com<br />
.<br />
250&nbsp;2.0.0&nbsp;m7ACl6B7004271&nbsp;Message&nbsp;accepted&nbsp;for&nbsp;delivery<br />
quit<br />
221&nbsp;2.0.0&nbsp;localhost.localdomain&nbsp;closing&nbsp;connection<br />
Connection&nbsp;closed&nbsp;by&nbsp;foreign&nbsp;host.<br />
检查日志[root@localhost&nbsp;root]#&nbsp;tail&nbsp;/var/log/maillog<br />
<br />
你如果想在客户机上收发邮件，那么还需跟着我做。。呵呵。。。上面算是成功了，我们看看接下来会不会成功。。。。期待。。<br />
<br />
检测imap是否安装rpm&nbsp;-q&nbsp;imap<br />
安装rpm&nbsp;-ivh&nbsp;imap-*.rpm<br />
<br />
[root@localhost&nbsp;root]#&nbsp;chkconfig&nbsp;imap&nbsp;on<br />
[root@localhost&nbsp;root]#&nbsp;service&nbsp;xinetd&nbsp;restart<br />
停止&nbsp;xinetd：&nbsp;&nbsp;确定&nbsp;&nbsp;]<br />
启动&nbsp;xinetd：&nbsp;&nbsp;确定&nbsp;&nbsp;]<br />
[root@localhost&nbsp;root]#&nbsp;grep&nbsp;imap&nbsp;/etc/services<br />
imap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;143/tcp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imap2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Interim&nbsp;Mail&nbsp;Access&nbsp;Proto&nbsp;v2<br />
imap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;143/udp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imap2<br />
imap3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;220/tcp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Interactive&nbsp;Mail&nbsp;Access<br />
imap3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;220/udp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Protocol&nbsp;v3<br />
imaps&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;993/tcp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;IMAP&nbsp;over&nbsp;SSL<br />
imaps&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;993/udp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;IMAP&nbsp;over&nbsp;SSL<br />
<br />
有错误。。。那么就仔细检查一下，我们刚刚的配置<br />
看了一下，我把网络服务重启了一下。。不知道行不行。。。呵呵<br />
我们继续。。。。我估计是imap没配置好，因为可以发送的。。。。<br />
你们看。。。没出错。。完全是可行的。。。。这个就是我们刚刚发的。。。。<br />
。。。。功夫不负有心人&nbsp;啊。。找到原因了。。。呵呵。。&nbsp;/sbin/chkconfig&nbsp;imap&nbsp;on。。。。。。是imap没启动。。。晕倒。。。<br />
<br />
收到信了把。。。。<br />
<br />
当然我们不可能在一台服务器上那么瞎搞，一般都是两台两个域进行邮件交互。。。方法跟这个是一样的。。大家可以试试。。。呵呵。。。。<br />
<br />
教程到此，不好意思，浪费大家那么多的时间在找错误上。。。。</strong>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/280353.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-06 19:22 <a href="http://www.blogjava.net/ruoyoux/articles/280353.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/06 Sender in mail -s command</title><link>http://www.blogjava.net/ruoyoux/articles/280318.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Sat, 06 Jun 2009 01:53:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/280318.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/280318.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/280318.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/280318.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/280318.html</trackback:ping><description><![CDATA[Paul Howarth wrote:<br />
&gt; On Thu, 2005-07-21 at 10:03 +0200, Andreas Wahlert wrote:<br />
&gt;<br />
&gt;&gt;Paul Howarth wrote:<br />
&gt;&gt;<br />
&gt;&gt;&gt;On Thu, 2005-07-21 at 09:35 +0200, Andreas Wahlert wrote:<br />
&gt;&gt;&gt;<br />
&gt;&gt;&gt;<br />
&gt;&gt;&gt;&gt;i have script which sends e-mail to me. How can i specify a complete<br />
&gt;&gt;&gt;&gt;sender address like "boom@work.de"?? i see in my mailclient only senders<br />
&gt;&gt;&gt;&gt;such "nagios@localhost.localdomain". On my host ist FC3 installed "out<br />
&gt;&gt;&gt;&gt;of the box"<br />
&gt;&gt;&gt;<br />
&gt;&gt;&gt;<br />
&gt;&gt;&gt;Do you want *all* mail originating from scripts on this machine to have<br />
&gt;&gt;&gt;a "work.de" address, or just mail originating from nagios?<br />
&gt;&gt;&gt;<br />
&gt;&gt;&gt;Does this mail need to be sent over the Internet? If so, you will need a<br />
&gt;&gt;&gt;valid envelope sender domain instead of localhost.localdomain. What type<br />
&gt;&gt;&gt;of Internet connection do you have (dialup, always-on, static/dynamic?).<br />
&gt;&gt;&gt;<br />
&gt;&gt;&gt;The configuration is best done in sendmail, which will then work for all<br />
&gt;&gt;&gt;programs, not just "mail".<br />
&gt;&gt;&gt;<br />
&gt;&gt;&gt;Paul.<br />
&gt;&gt;<br />
&gt;&gt;<br />
&gt;&gt;It's only a host for Monitoring. There runs "Fujitsu ServerView" and<br />
&gt;&gt;"nagios" That means "work.de" is enough for all. The script send only<br />
&gt;&gt;notifications mail to my internal mailserver.<br />
&gt;&gt;<br />
&gt;&gt;<br />
&gt;&gt;Where can i do this configuration in sendmail??<br />
&gt;<br />
&gt;<br />
&gt; # yum install sendmail-cf<br />
&gt;<br />
&gt; Edit /etc/mail/sendmail.mc and change:<br />
&gt;<br />
&gt; dnl MASQUERADE_AS(`mydomain.com')dnl<br />
&gt;<br />
&gt; to:<br />
&gt;<br />
&gt; MASQUERADE_AS(`work.de')dnl<br />
&gt;<br />
&gt; If you want to be able to rewrite "nagios" as "boom", you should also<br />
&gt; add:<br />
&gt;<br />
&gt; FEATURE(`genericstable',`hash -T&lt;TMPF&gt; /etc/mail/genericstable')dnl<br />
&gt;<br />
&gt; just below the existing line:<br />
&gt;<br />
&gt; FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable.db')dnl<br />
&gt;<br />
&gt; Then create a file /etc/mail/genericstable containing the line:<br />
&gt;<br />
&gt; nagios boom@work.de<br />
&gt;<br />
&gt; Then run "make -C /etc/mail; service sendmail reload"<br />
&gt;<br />
&gt; I think that should do what you want.<br />
&gt;<br />
&gt; Paul.<br />
<br />
<br />
wow,<br />
<br />
<br />
<br />
now it works.<br />
<br />
sendmail is really tricky. i have found a nice howto to switch to<br />
postfix. I guess it's better for me, to have a postfix on this machine.<br />
There i'm understanding what i'm doing :-))<br />
<br />
<br />
<br />
<img src ="http://www.blogjava.net/ruoyoux/aggbug/280318.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-06 09:53 <a href="http://www.blogjava.net/ruoyoux/articles/280318.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/06/03 screen处理后台任务 </title><link>http://www.blogjava.net/ruoyoux/articles/279817.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Wed, 03 Jun 2009 07:15:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/279817.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/279817.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/279817.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/279817.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/279817.html</trackback:ping><description><![CDATA[<p>大家在起后台服务，或者长时间执行某个脚本的时候。</p>
<p>是不是感觉，交互性很差，</p>
<p>有时，想把结果直接在终端上输出，又怕不小心关闭了终端导致进程退出？ （有些sshd服务还会设置连接超时，自动退出终端）</p>
<p>现在用 <span style="color: rgb(0, 0, 255);"><strong>screen</strong>
</span>
这个指令可以很好的解决跑后台服务的尴尬。</p>
<p>命令其实超简单的：</p>
<p>直接在终端上输入 screen , 这个时候，服务器端会启一个新的终端，但这个终端，与之前的普通终端不一样，它不隶属于 sshd 进程组，这样，当本地终端关闭后，服务器终端不会被 kill。</p>
<p>当然，优点还不止这么些，在服务器终端里执行任务时，你甚至可以随时地切换到本地终端做些其他事情，然后，要回去时，再恢复到刚才已经打开的服务器终端里，如果刚才的任务没有结束，还可以继续执行任务。</p>
<p>操作步骤：</p>
<p>首先，进入 <strong><span style="color: rgb(0, 0, 255);">screen </span>
</strong>
-S sessionname终端。(sessionname是为了分辨你的session)</p>
<p>然后按 <strong><span style="color: rgb(0, 0, 255);">ctrl + a</span>
</strong>
，再按 <span style="color: rgb(0, 0, 255);"><strong>d</strong>
</span>
键暂时退出终端。</p>
<p>当要返回时， 先查看刚才的终端进程ID， <strong><span style="color: rgb(0, 0, 255);">screen -list</span>
</strong>
</p>
<p>或直接</p>
<p>&nbsp;<strong><span style="color: rgb(0, 0, 255);">screen -r xx</span>
</strong>
(刚才的sessionname)就可以了 </p>
<p>当然，当你开了很多个session后，打算关闭几个session，可以进入到session后，<strong><span style="color: rgb(0, 0, 255);">exit</span>
</strong>
一下就可以了.</p>
<p>总的来说， screen是可以完全替代 nohup 的，并且本身提供了较复杂的功能，但是我认为，刚才那些简单的功能足以应付日常运作。 </p>
<p>如果对该指令感兴趣的朋友，推荐一篇文章：</p>
<p><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-screen/" target="_blank">http://www.ibm.com/developerworks/cn/linux/l-cn-screen/</a></p>
<p><br />
</p>
<p><br />
</p>
<p>补充：<br />
</p>
<p>A: secureCRT链接linux服务器时，网络断线了，但是服务器上的tty还没退出，我想重新连接到原来那个tty，可以做到么？<br />
<br />
B: 可以啊，你可以安装一个Screen，就可以享受他给你带来的方便了。<br />
<br />
A：如何创建一个虚拟shell环境？<br />
<br />
B：screen -S MyScr （其中&#8220;MyScr&#8221;是你为这个虚拟shell环境起的名字，可以自定义）<br />
输入回车之后，你就可以在这个虚拟的shell环境中工作了，你工作的内容都会被一直保留下来。试试吧，在里面敲几个命令，运行几个程序，和平常没有两样吧。<br />
<br />
A: 如何退出工作环境呢？<br />
<br />
B：如果想要退出要怎么办呢？只要按下Ctrl+A，然后按d，就可以退出刚刚建立的虚拟shell环境了（名字是MyScr）<br />
若干时间后，你又想继续刚才的工作了，只要再敲：<br />
screen -r MyScr<br />
就可以看到刚刚的界面了。怎么样，还是很简单适用的吧，呵呵。<br />
<br />
A: 可以不给他起名么？<br />
<br />
B：当然，你不给这个虚拟shell环境命名也是没问题的，如果只有一个虚拟环境的话，也可以这样用<br />
screen（回车）<br />
工作&#8230;&#8230;退出&#8230;&#8230;<br />
screen -r<br />
继续工作<br />
系统还会默认用PID号码表识screen虚拟的shell环境。<br />
例如，我直接用screen命令建立了一个虚拟环境，退出之后，我想查看虚拟环境的情况：<br />
<br />
A：如何察看当前有哪些Screen工作环境呢？<br />
<br />
B：screen -list<br />
输出应该是类似下面的：<br />
There is a screen on:<br />
25202.pts-1.firewallX (Detached)<br />
1 Socket in /tmp/screens/S-root.<br />
其中：<br />
&#8220;25202&#8221;是这个虚拟环境的PID。不信的话，可以ps查看一下，呵呵~<br />
&#8220;pts-1&#8221;是说你的ssh客户端登录的系统端口号是pts-1<br />
&#8220;firewallX&#8221;是我这台主机的名字<br />
如果你建立了很多虚拟环境，又没有为他们命名的话，就只能用PID来识别他们了。（记住这个PID号码太烦了吧，还是名字好！）<br />
例如，我现在有两个screen建立的虚拟环境，我输入：<br />
screen -list<br />
输出为：<br />
There are screens on:<br />
25202.pts-1.firewallX (Detached)<br />
25403.pts-1.firewallX (Detached)<br />
2 Sockets in /tmp/screens/S-root.<br />
那么，我如果想进入第二个虚拟环境的话，我可以用什么命令呢？答案如下：<br />
screen -r 25403<br />
<br />
A：如何创建新的screen呢？<br />
<br />
B：如果我登录进去之后，用ctrl-a c：再创建一个新的虚拟Shell环境，那么这个环境就是在PID为25403的虚拟环境里面的子虚拟环境。<br />
<br />
A：如何彻底退出一个screen工作环境呢？<br />
<br />
B：Ctrl-D<br />
<br />
A：如何在进入工作环境的时候就自动的运行screen呢？<br />
B：可以在~/.bash_profiler里最下面一行添加一句screen<br />
<br />
注意事项：关闭secureCRT之前，请先使用 Ctrl-D 退出screen
</p>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/279817.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-06-03 15:15 <a href="http://www.blogjava.net/ruoyoux/articles/279817.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/05/28 如何让你的监控系统发警报信息</title><link>http://www.blogjava.net/ruoyoux/articles/278350.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Thu, 28 May 2009 14:01:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/278350.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/278350.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/278350.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/278350.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/278350.html</trackback:ping><description><![CDATA[nagios中文：http://nagios-cn.sourceforge.net/ <br />
nagiso官方网站：http://www.nagios.org/ <br />
<br />
Ununtu下Nagios信息发送方式： <br />
1.mail <br />
如果要接收Nagios的EMail警报，需要安装(Postfix)包 <br />
<br />
sudo apt-get install mailx <br />
<br />
需要编辑Nagios里的EMail通知送出命令，它位于/usr/local/nagios/etc/commands.cfg文件中，将里面的'/bin/mail'全部替换为'/usr/bin/mail'。一旦设置好需要重启动Nagios以使配置生效。 <br />
<br />
sudo /etc/init.d/nagios restart <br />
<br />
2.MSN <br />
&nbsp; 用php来发送MSN信息。 <br />
&nbsp; wget http://downloads.fanatic.net.nz/dev/php/sendMsg.zip <br />
&nbsp; unzip sendMsg.zip <br />
&nbsp; mv sendMsg /path/to/web/dir/msn <br />
&nbsp; 可以先打开 http://server/msn/index.php 测试一下能否发送。如果没有问题，可以写一个脚本来执行 MSN 信息发送命令： <br />
&nbsp; /usr/local/nagios/libexec/msn_send.sh： <br />
&nbsp; #!/bin/sh <br />
&nbsp; wget -O - -q --post-data="sender=nagios@live.cn&amp;password=password&amp;&nbsp; <br />
&nbsp; recipient=$1&amp;message=$2" http://server/msn/index.php &gt; /dev/null <br />
<br />
&nbsp; chmod +x /usr/local/nagios/libexec/msn_send.sh <br />
<br />
/usr/local/nagios/etc/objects/commands.cfg： <br />
<br />
define command{ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; command_name&nbsp;&nbsp;&nbsp; notify-host-by-msn <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; command_line&nbsp;&nbsp;&nbsp; /usr/local/nagios/libexec/msn_send.sh $CONTACTEMAIL$ "`/usr/bin/printf "%b" "***** Monitor *****\n\nNotification Type: $NOTIFICATIONTYPE$\nHost: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n"`" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
<br />
define command{ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; command_name&nbsp;&nbsp;&nbsp; notify-service-by-msn <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; command_line&nbsp;&nbsp;&nbsp; /usr/local/nagios/libexec/msn_send.sh $CONTACTEMAIL$ "`/usr/bin/printf "%b" "***** Monitor *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$"`" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
<br />
/usr/local/nagios/etcobjects/contacts.cfg ： <br />
<br />
define contact{ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; contact_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nagios <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alias&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Nagios Msn <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; use&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; generic-contact <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service_notification_period&nbsp;&nbsp;&nbsp;&nbsp; 24x7 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; host_notification_period&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 24x7 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service_notification_options&nbsp;&nbsp;&nbsp; w,u,c,r <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; host_notification_options&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d,u,r <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service_notification_commands&nbsp;&nbsp; notify-service-by-msn <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; host_notification_commands&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; notify-host-by-msn <br />
} <br />
<br />
参考于：http://blog.bluedata.org/nagios-notification-type/ <br />
3.飞信通知 <br />
<br />
飞信官方网站：http://www.it-adv.net/ <br />
&nbsp; 下载：fetion20080910048-linux.tar.gz 和 library32.rar（版本不断更新） <br />
&nbsp; tar xvfz fetion_linux_20080402.tar.gz <br />
&nbsp; cd install <br />
&nbsp; sudo cp fetion /usr/bin <br />
&nbsp; fetion -h <br />
如果出现如下错误： <br />
&nbsp; error while loading shared libraries: libACE.so.5.4.7: cannot open shared object <span class="hilite4">file</span>: <span class="hilite2">No</span> <span class="hilite3">such</span> <span class="hilite4">file</span> or directory <br />
&nbsp; 说明缺少运行的库文件。 <br />
解决方法： <br />
&nbsp;&nbsp; a.sudo apt-get install libACE.so.5.4.7 libACE_SSL.so.5.4.7 <br />
&nbsp;&nbsp;&nbsp;&nbsp; （可能你的ubuntu已经不提供安装这两个库文件，采用下面的方案） <br />
&nbsp;&nbsp; b.unrar e library32.rar <br />
&nbsp;&nbsp;&nbsp;&nbsp; cd library32 <br />
&nbsp;&nbsp;&nbsp;&nbsp; sudo cp *.* /lib/ <br />
&nbsp;&nbsp;&nbsp;&nbsp; sudo cp *.* /usr/lib/ <br />
&nbsp; 重新执行 fetion -h.应该能看到所要的结果。 <br />
&nbsp; 如果你有飞信号，可以执行一下。 <br />
&nbsp; fetion&nbsp; -u 飞信号 -p pwd 来登录。 <br />
/usr/local/nagios/etc/objects/commands.cfg： <br />
# 'notify-service-by-fetion' command definition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
define command{ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; command_name notify-service-by-fetion <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; command_line /usr/bin/feiton -u 13888888888&nbsp; -p 123456&nbsp;&nbsp; -t $CONTACTPAGER$ -m "$HOSTNAME$ $SERVICEDESC$ is $SERVICESTATE$ on $TIME$ result is $SERVICEOUTPUT$" $CONTACTPAGER$ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
/usr/local/nagios/etcobjects/contacts.cfg ： <br />
define contact{ <br />
contact_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fetion <br />
alias&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nagios admin <br />
host_notification_period&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 24x7 <br />
service_notification_period&nbsp;&nbsp;&nbsp;&nbsp; 24x7 <br />
host_notification_options&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d,r, <br />
service_notification_options&nbsp;&nbsp;&nbsp; c,w,r <br />
service_notification_commands&nbsp;&nbsp; notify-service-by-email,notify-service-by-fetion <br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service_notification_commands&nbsp;&nbsp; notify-service-by-email&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
host_notification_commands&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; notify-host-by-email <br />
pager&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 158010775111 <br />
} <br />
<br />
<br />
最后将定义的contact添加到contactgroup中： <br />
define contactgroup{ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; contactgroup_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; admins <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alias&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Nagios Administrators <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; members&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nagiosadmin,nagios，fetion <br />
} <br />
当你定义一个主机的时候： <br />
/usr/local/nagios/etc/objects/templates: <br />
# Linux host definition template - This is NOT a real host, just a template!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<br />
define host{ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; linux-server&nbsp;&nbsp;&nbsp; ; The name of this host template <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; use&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; generic-host&nbsp;&nbsp;&nbsp; ; This template inherits other values from the generic-host template <br />
check_period&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 24x7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; By default, Linux hosts are checked round the clock <br />
check_interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Actively check the host every 5 minutes <br />
retry_interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Schedule host check retries at 1 minute intervals <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; max_check_attempts&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Check each Linux host 10 times (max) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; check_command&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; check-host-alive ; Default command to check Linux hosts <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; notification_period&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; workhours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Linux admins hate to be woken up, so we only notify during the day <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Note that the notification_period variable is being overridden from <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; the value that is inherited from the generic-host template! <br />
notification_interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Resend notifications every 2 hours <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; notification_options&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d,u,r&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Only send notifications for specific host states <br />
contact_groups&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; admins&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;使用的联系组为admins <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; register&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE! <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
<br />
&nbsp; 此处参考：http://yang2001.blog.51cto.com/25307/73164
<img src ="http://www.blogjava.net/ruoyoux/aggbug/278350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-05-28 22:01 <a href="http://www.blogjava.net/ruoyoux/articles/278350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日一记 2009/05/28 解决Nagios不发报警Mail的ISSUE</title><link>http://www.blogjava.net/ruoyoux/articles/278348.html</link><dc:creator>Blog of JoJo</dc:creator><author>Blog of JoJo</author><pubDate>Thu, 28 May 2009 13:50:00 GMT</pubDate><guid>http://www.blogjava.net/ruoyoux/articles/278348.html</guid><wfw:comment>http://www.blogjava.net/ruoyoux/comments/278348.html</wfw:comment><comments>http://www.blogjava.net/ruoyoux/articles/278348.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ruoyoux/comments/commentRss/278348.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ruoyoux/services/trackbacks/278348.html</trackback:ping><description><![CDATA[nagios自己也有日志记录呢！赶快打开看一眼，发现里面有不少Warning，抽一个出来，其内容如下：
<p>　　[1217166816] HOST NOTIFICATION: sery;mail-server;DOWN;host-notify-by-email;CRITICAL - Plugin timed out after 10 seconds<br />
[1217166816] Warning: Attempting to execute the command "/usr/bin/printf "%b" "***** Nagios 2.9 *****\n\nNotification Type: PROBLEM\nHost: mail-server\nState: DOWN\nAddress: 211.155.115.66\nInfo: CRITICAL - Plugin timed out after 10 seconds\n\nDate/Time: Sun Jul 27 13:53:36 UTC 2008\n" | /bin/mail -s "Host DOWN alert for mail-server!" <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#101;&#114;&#121;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;">ABC@163.com</a>" resulted in a return code of 127.&nbsp; Make sure the script or binary you are trying to execute actually exists...</p>
<br />
<br />
原因：邮件路径不对
<p>　　其他的行也更这个类似；最有用的信息我用红色标记，其大意是不能执行上面的2进制或可执行文件。在这个条目中，只有2个执行文件—printf及mail。我把它按原样单独拿出来执行，操作过程如下：</p>
<p>　　（1）/usr/bin/printf&nbsp; &#8220;"%b" "***** Nagios 2.9 *****\n&#8221;&nbsp; 输出 ***** Nagios 2.9 *****，这是正常的结果。</p>
<p>　　（2）/bin/mail -s "Host DOWN alert for mail-server!" <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#101;&#114;&#121;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;">sery@163.com</a> 输出su: /bin/mail: No such file or directory，没找到路径或目录。前面还手动发了邮件的，明明有mail这个客户端程序呀！可能这个路径不对，是<a class="channel_keylink" href="http://linux.chinaitlab.com/" target="_blank">linux</a>的mail路径。查一下freebsd的mail路径，执行find / -name 得到mail在freebsd的路径为/usr/bin/mail 。</p>
<p>　　到这里，我们知道了为啥不能发邮件的根本原因，接下来，我把nagios的配置文件commands.cfg的host-notify-by-email、service-notify-by-email的&#8221;/bin/mail&#8221;替换为&#8220;/usr/bin/mail&#8221;。其完整形式为：</p>
<p>　　# 'host-notify-by-email' command definition<br />
define command{<br />
command_name&nbsp;&nbsp;&nbsp; host-notify-by-email<br />
command_line&nbsp;&nbsp;&nbsp; /usr/bin/printf "%b" "***** Nagios 2.9 *****\n\nNotification Type: $NOTIFICATIONTYPE$\nHost: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n" | /usr/bin/mail -s "Host $HOSTSTATE$ alert for $HOSTNAME$!" $CONTACTEMAIL$<br />
}<br />
# 'notify-by-email' command definition<br />
define command{<br />
command_name&nbsp;&nbsp;&nbsp; service-notify-by-email<br />
command_line&nbsp;&nbsp;&nbsp; /usr/bin/printf "%b" "***** Nagios 2.9 *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$" | /usr/bin/mail -s "** $NOTIFICATIONTYPE$ alert - $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTACTEMAIL$<br />
}</p>
<p>　　修改完配置文件commands.cfg后重启 Nagios，再查看nagios日志，不再有&#8220;Make sure the script or binary you are trying to execute actually exists...&#8221;报错，并且有发送报警邮件的记录了：</p>
<p>　　[root@nagios /usr/local/nagios/var]# tail -f nagios.log<br />
[1217170467] SERVICE ALERT: mail-server;check_tcp 995;CRITICAL;SOFT;1;CRITICAL - Socket timeout after 10 seconds<br />
[1217170534] Auto-save of retention data completed successfully.<br />
[1217170577] HOST ALERT: mail-server;DOWN;SOFT;1;CRITICAL - Plugin timed out after 10 seconds<br />
[1217170587] HOST ALERT: mail-server;DOWN;SOFT;2;CRITICAL - Plugin timed out after 10 seconds<br />
[1217170597] HOST ALERT: mail-server;DOWN;SOFT;3;CRITICAL - Plugin timed out after 10 seconds<br />
[1217170607] HOST ALERT: mail-server;DOWN;SOFT;4;CRITICAL - Plugin timed out after 10 seconds<br />
[1217170607] HOST ALERT: mail-server;UP;SOFT;5;PING OK - Packet loss = 0%, RTA = 111.63 ms<br />
[1217170607] SERVICE ALERT: mail-server;check_tcp 995;CRITICAL;SOFT;2;CRITICAL - Socket timeout after 10 seconds<br />
[1217170687] SERVICE ALERT: mail-server;check_tcp 995;OK;SOFT;3;TCP OK - 3.137 second response time on port 995<br />
[1217171057] SERVICE NOTIFICATION: sery;fav-0;check_tcp 443;CRITICAL;service-notify-by-email;CRITICAL - Socket timeout after 10 seconds</p>
<p>　　收邮件，迫不及待，哈哈，我的163邮箱收到久违的报警信息了。再回去瞧一眼邮件日志/var/log/malllog,也记录了这个发送情况。</p>
<p>　　经验总结：通过日志记录，对于我们排查故障确实有着不可估量的好处。在实际的工作中，我们应该随时检查系统日志以及应用程序相关的日志，从记录项中寻找蛛丝马迹，从而得出解决问题的方法。</p>
<img src ="http://www.blogjava.net/ruoyoux/aggbug/278348.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ruoyoux/" target="_blank">Blog of JoJo</a> 2009-05-28 21:50 <a href="http://www.blogjava.net/ruoyoux/articles/278348.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>