<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>程式設計 遇上 小提琴 &#187; Unix-Like</title>
	<atom:link href="http://blog.ez2learn.com/category/unix-like/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ez2learn.com</link>
	<description>Victor&#039;s個人部落格，關於程式設計與小提琴</description>
	<lastBuildDate>Tue, 07 Feb 2012 03:26:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Zero-downtime service migration</title>
		<link>http://blog.ez2learn.com/2011/02/04/zero-downtime-service-migration/</link>
		<comments>http://blog.ez2learn.com/2011/02/04/zero-downtime-service-migration/#comments</comments>
		<pubDate>Fri, 04 Feb 2011 09:12:20 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[分享]]></category>
		<category><![CDATA[English Articles]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Unix-Like]]></category>
		<category><![CDATA[0-down-time]]></category>
		<category><![CDATA[hot code swap]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=1225</guid>
		<description><![CDATA[When I am running my website, now.in, I did encounter a trouble.  That is, when there is a bug in the production server, then I need to restart them.  Sounds fine, right? Just to restart a server.  Yes, for most &#8230; <a href="http://blog.ez2learn.com/2011/02/04/zero-downtime-service-migration/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>When I am running my website, now.in, I did encounter a trouble.  That is, when there is a bug in the production server, then I need to restart them.  Sounds fine, right? Just to restart a server.  Yes, for most of web HTTP servers, they are stateless,  it is fine to restart them whenever you want, but not true for now.in, they are audio streaming servers.  Here s a server stats diagram shows the problem:</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/02/server_diagram.png"><img class="alignnone size-medium wp-image-1217" title="server_diagram" src="http://blog.ez2learn.com/wp-content/uploads/2011/02/server_diagram-300x196.png" alt="" width="300" height="196" /></a></p>
<p>You can see there are some gaps in the plot, that&#8217;s caused by server restarting.  Of course, for users, that would definitely be bad experience.  Thus, I&#8217;m thinking how to solve this problem recently.  Before we go into the design, let&#8217;s look the reasons for restarting server first.</p>
<ul>
<li>To deploy new version of program</li>
<li>To fix bugs</li>
<li>The process is using to much memory</li>
<li>To reload environment, ulimit -n for example (the limit count of file descriptor under unix-like environment)</li>
<li>To migrate from host A to host B</li>
</ul>
<p>For simply employe new version of program, we can use reload function of Python to reload modules.  But there is some problems, reload function only rerun the module, those created instances are still there, it might work if the change is minor.  On the other hand,  reloading can&#8217;t solve memory usage problem, process environment change problem.  And here comes the final reason, to migrate service from host A to B.  Indeed, it is difficult not to make any down time for such migration, and there is little chance to do such migration, therefore, we&#8217;ll only focus on migration in same host.</p>
<h2>The idea</h2>
<p>The biggest challenge is, how to migrate those working connections?  My idea is simple, create a new process, and transfer those connection to the new process, and shut the old one down.  Following diagrams show my method.</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/02/mig_011.png"><img class="alignnone size-medium wp-image-1226" title="mig_01" src="http://blog.ez2learn.com/wp-content/uploads/2011/02/mig_011-226x300.png" alt="" width="226" height="300" /></a></p>
<p>The Master is a process which is charge for managing migration and receiving command from other process.  And the process A is for running service.</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/02/mig_02.png"><img class="alignnone size-medium wp-image-1220" title="mig_02" src="http://blog.ez2learn.com/wp-content/uploads/2011/02/mig_02-300x263.png" alt="" width="300" height="263" /></a></p>
<p>Before we perform the migration, the Manager startup process B, and wait it says it&#8217;s readly.</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/02/mig_03.png"><img class="alignnone size-medium wp-image-1221" title="mig_03" src="http://blog.ez2learn.com/wp-content/uploads/2011/02/mig_03-300x263.png" alt="" width="300" height="263" /></a></p>
<p>When process B said "Hey! I&#8217;m ready", then manager tell process A to send the connection state descriptor to process B.  Process B receive the state, and take over the service.</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/02/mig_04.png"><img class="alignnone size-medium wp-image-1222" title="mig_04" src="http://blog.ez2learn.com/wp-content/uploads/2011/02/mig_04-243x300.png" alt="" width="243" height="300" /></a></p>
<p>Finally, process B took over the service, then master tells process A "You are fired." and the process A rolls itself out.</p>
<p>That&#8217;s it, the service was migrated, and there is no down time.</p>
<h2>The problem &#8211; socket transfer</h2>
<p>The idea sounds good, right? But still, we have some technical problem to solve.  It is "How to transfer socket (file descriptor) from one process to another?".  To solve this problem, I have some study, and eventually I know two methods to achieve the goal.</p>
<h3>Child process</h3>
<p>For most of unix-like OS, child processes inherit file descriptors from their parent.  Of course we can use this feature to migrate our service, but however, it got its limitation.  You can only transfer file descriptors to child process.</p>
<h3>Sendmsg</h3>
<p>Another way to achieve same goal is, to use sendmsg through a unix domain socket to send the file descriptors.  With sendmsg, you can transfer file descriptors to almost any processes you like, that&#8217;s much flexible.</p>
<h2>A simple implementation</h2>
<p>To simplify the example, we only implement process A and process B here, it is quite enough for two process to complete the migration.  Before we go into the details, there is another problem to solve, which is sendmsg is not a standard function in Python.  Fortunately, there is a third party library named sendmsg provides this function.  To install sendmsg, it is easy, just type</p>
<p>easy_install sendmsg</p>
<p>And here you are.  Okay, following are the two programs.</p>
<p>a.py</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">socket</span>
<span style="color: #ff7700;font-weight:bold;">import</span> sendmsg
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">struct</span>
&nbsp;
s = <span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">AF_INET</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">SOCK_STREAM</span><span style="color: black;">&#41;</span>
s.<span style="color: black;">bind</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>, <span style="color: #ff4500;">5566</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
s.<span style="color: black;">listen</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
conn, addr = s.<span style="color: black;">accept</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
conn.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Hello, process %d is serving<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #66cc66;">%</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">getpid</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Accept inet connection'</span>, conn
&nbsp;
us = <span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">AF_UNIX</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">SOCK_STREAM</span><span style="color: black;">&#41;</span>
us.<span style="color: black;">bind</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mig.sock'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
us.<span style="color: black;">listen</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
uconn, addr = us.<span style="color: black;">accept</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Accept unix connection'</span>, uconn
&nbsp;
payload = <span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'i'</span>, conn.<span style="color: black;">fileno</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
sendmsg.<span style="color: black;">sendmsg</span><span style="color: black;">&#40;</span>
    uconn.<span style="color: black;">fileno</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">''</span>, <span style="color: #ff4500;">0</span>, <span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">SOL_SOCKET</span>, sendmsg.<span style="color: black;">SCM_RIGHTS</span>, payload<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Sent socket'</span>, conn.<span style="color: black;">fileno</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Done.'</span></pre></div></div>

<p>b.py</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">socket</span>
<span style="color: #ff7700;font-weight:bold;">import</span> sendmsg
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">struct</span>
&nbsp;
us = <span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">AF_UNIX</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">SOCK_STREAM</span><span style="color: black;">&#41;</span>
us.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mig.sock'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Make unix connection'</span>, us
&nbsp;
result = sendmsg.<span style="color: black;">recvmsg</span><span style="color: black;">&#40;</span>us.<span style="color: black;">fileno</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
identifier, flags, <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>level, <span style="color: #008000;">type</span>, data<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span> = result
<span style="color: #ff7700;font-weight:bold;">print</span> identifier, flags, <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>level, <span style="color: #008000;">type</span>, data<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
fd = <span style="color: #dc143c;">struct</span>.<span style="color: black;">unpack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'i'</span>, data<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Get fd'</span>, fd
&nbsp;
conn = <span style="color: #dc143c;">socket</span>.<span style="color: black;">fromfd</span><span style="color: black;">&#40;</span>fd, <span style="color: #dc143c;">socket</span>.<span style="color: black;">AF_INET</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">SOCK_STREAM</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">os</span>.<span style="color: black;">close</span><span style="color: black;">&#40;</span>fd<span style="color: black;">&#41;</span>
conn.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Hello, process %d is serving<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #66cc66;">%</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">getpid</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>The flow is simple, the a.py accept an inet socket and open an unix domain socket, wait b.py to take over the service.  And here we runs b.py, it connects to a.py, receives the fd of socket and takes over providing service.</p>
<h2>The result</h2>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/02/螢幕快照-2011-02-04-下午4.07.07.png"><img class="alignnone size-full wp-image-1223" title="螢幕快照 2011-02-04 下午4.07.07" src="http://blog.ez2learn.com/wp-content/uploads/2011/02/螢幕快照-2011-02-04-下午4.07.07.png" alt="" width="656" height="440" /></a></p>
<p>As the result shows, there is not down time between the service migration.</p>
<p>It is very useful to employ this technique in server programs.  You can even migrate service from Python server to a C/C++ server, or vice versa.  Also, to keep the memory usage low, you can also migrate the service to same program periodically.  I will try to employ this technique in my servers to achieve zero down time migration.  If you are interesting in this technique, have a try, it is fun and useful :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2011/02/04/zero-downtime-service-migration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VirtualBox下跑FreeBSD的網路問題和安裝Python模組心得</title>
		<link>http://blog.ez2learn.com/2008/10/06/network-problem-of-freebsd-under-virtualbox/</link>
		<comments>http://blog.ez2learn.com/2008/10/06/network-problem-of-freebsd-under-virtualbox/#comments</comments>
		<pubDate>Mon, 06 Oct 2008 03:33:57 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[問題]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Unix-Like]]></category>
		<category><![CDATA[虛擬機器]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[lxml]]></category>
		<category><![CDATA[twisted]]></category>
		<category><![CDATA[VirtualBox]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=124</guid>
		<description><![CDATA[昨天在VirtualBox上裝了FreeBSD，但是卻遇到無法上網的問題 #ping google.com ping: cannot resolve google.com: No address associated with name 看起來是網路沒有設定好，連DNS都找不到的樣子，於是在網路上找了一找，終於找到了解決方法 ifconfig pcn0 down ifcontig pcn0 media 10baseT/UTP ifconfig pcn0 up dhclient pcn0 解決了之後終於成功地在上面執行了我在Windows下寫的程式，一開始我連什麼指令用來抓檔案都不知道，我只知道curl這樣的指令，但它好像沒有這樣的指令，後來知到有fetch可以用，就裝好了easy_install之後就很方便，接著裝了Twisted，和lxml，而lxml並不是直接用easy_install就可以用，還得先安裝並編譯libxml2和libxslt，但其實也很簡單，先fetch下來，解開壓縮，然後執行 ./configure make install 編譯要花一小段時間，但沒想到這麼順利，沒有什麼編譯錯誤跑出來，完成後再用easy_install安裝lxml就可以了 寫一個小程式來測試 然後執行 Wow! 成功了!]]></description>
			<content:encoded><![CDATA[<p>昨天在VirtualBox上裝了FreeBSD，但是卻遇到無法上網的問題</p>
<blockquote><p>#ping google.com</p>
<p>ping: cannot resolve google.com: No address associated with name</p></blockquote>
<p>看起來是網路沒有設定好，連DNS都找不到的樣子，於是在網路上找了一找，終於找到了<a href="http://forums.virtualbox.org/viewtopic.php?t=2563">解決方法</a></p>
<blockquote><p>ifconfig pcn0 down<br />
ifcontig pcn0 media 10baseT/UTP<br />
ifconfig pcn0 up<br />
dhclient pcn0</p></blockquote>
<p>解決了之後終於成功地在上面執行了我在Windows下寫的程式，一開始我連什麼指令用來抓檔案都不知道，我只知道curl這樣的指令，但它好像沒有這樣的指令，後來知到有fetch可以用，就裝好了easy_install之後就很方便，接著裝了Twisted，和lxml，而lxml並不是直接用easy_install就可以用，還得先安裝並編譯libxml2和libxslt，但其實也很簡單，先fetch下來，解開壓縮，然後執行</p>
<blockquote><p>./configure<br />
make install</p></blockquote>
<p>編譯要花一小段時間，但沒想到這麼順利，沒有什麼編譯錯誤跑出來，完成後再用easy_install安裝lxml就可以了</p>
<p>寫一個小程式來測試</p>
<div id="attachment_132" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.ez2learn.com/wp-content/uploads/2008/10/2008-10-06_113534.png"><img class="size-medium wp-image-132" title="FreeBSD下的Twisted測試用程式" src="http://blog.ez2learn.com/wp-content/uploads/2008/10/2008-10-06_113534-300x195.png" alt="FreeBSD下的Twisted測試用程式" width="300" height="195" /></a><p class="wp-caption-text">FreeBSD下的Twisted測試用程式</p></div>
<p>然後執行</p>
<div id="attachment_133" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.ez2learn.com/wp-content/uploads/2008/10/2008-10-06_113629.png"><img class="size-medium wp-image-133" title="FreeBSD下的Twisted執行結果" src="http://blog.ez2learn.com/wp-content/uploads/2008/10/2008-10-06_113629-300x195.png" alt="FreeBSD下的Twisted執行結過" width="300" height="195" /></a><p class="wp-caption-text">FreeBSD下的Twisted執行結果</p></div>
<p>Wow! 成功了!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2008/10/06/network-problem-of-freebsd-under-virtualbox/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>這個網站的主機商 : WebFaction</title>
		<link>http://blog.ez2learn.com/2008/09/28/hosting-of-this-site/</link>
		<comments>http://blog.ez2learn.com/2008/09/28/hosting-of-this-site/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 15:28:41 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[網站]]></category>
		<category><![CDATA[設計]]></category>
		<category><![CDATA[Unix-Like]]></category>
		<category><![CDATA[主機商]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[Plone]]></category>
		<category><![CDATA[Rail on Ruby]]></category>
		<category><![CDATA[TurboGears]]></category>
		<category><![CDATA[WebFaction]]></category>
		<category><![CDATA[架站]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=20</guid>
		<description><![CDATA[主機商WebFaction 今天我要介紹我的網站所使用的主機商 : WebFaction 為什麼選擇這家主機商 我會選擇這家主機商的最主要原因，是因為他們有提供TurboGears、Django、Plone等各種我需要的Python網頁開發框架，或程式的虛擬主機服務，市面上最常見的主流虛擬主機服務都是以PHP為主，因此較難找到我需要能夠執行TurboGears和Plone的主機商，在經過找尋了一陣子，最後終於找到了這家主機商，其中也搜尋了不少在TurboGears的Google group的討論和評價，他們對於此主機商的評價都相當高，他們說這主機商盡力想讓他們的客戶高興，於是我就決使用這家主機商，用線上刷卡訂購了虛擬主機的服務，幾個小時內，網站就啟用了，相當地有效率 出色的控制面版 因為是較非主流的應用，所以不會看到常見的cPanel等虛擬主機的控制面版，而是他們自行研發的控制面版，他們在網站上有提供許多控制面版的示範影片，其中包括如何用來建置TurboGears的網站，或是Plone之類的程式，有興趣可以參考看看 面版控制示範影片 相信看完就可以大約了解，這控制面版相當地好用，操作很簡單，加上有示範影片可以看，帳戶開通沒多久我立刻成功地建立了一個Plone的站台 不可思議的優秀客服支援 如同我所見到的評價，他們的客服真的是盡力讓他們客戶高興的客服，因為有六十天無條件退款的保證，所以我決定當一個澳客，帳戶一開通我就毫不客氣地盡量使用客服，他們都很友善的回答，技術上的問題，他們都答得出來，他們建置了一個專門的知識庫 WebFaction 的客服 這網頁是開放的，即使你沒有帳號，你一樣可以在裡面找到很多有用的問題的解決方法，我發了幾個問題，他們都找到在裡面的解決方案然後跟我說明要如何解決，當一個發問不爬文的澳客感覺還真不錯 :P 以下是一封我題出問題和客服的對話，就可以明白他們的客服都相當友善，而且都有相當程度的專業知識 victorlin Hi, I configure Plone mail setting by following this article: https://help.webfaction.com/index.php?_m=knowledgebase&#038;_a=viewarticle&#038;kbarticleid=82 But I always got a " Error Please correct the &#8230; <a href="http://blog.ez2learn.com/2008/09/28/hosting-of-this-site/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>主機商WebFaction</h2>
<p>今天我要介紹我的網站所使用的主機商 : <a href="http://www.webfaction.com/?affiliate=victorlin">WebFaction</a></p>
<p><span id="more-20"></span></p>
<h3>為什麼選擇這家主機商</h3>
<p>我會選擇這家主機商的最主要原因，是因為他們有提供TurboGears、Django、Plone等各種我需要的Python網頁開發框架，或程式的虛擬主機服務，市面上最常見的主流虛擬主機服務都是以PHP為主，因此較難找到我需要能夠執行TurboGears和Plone的主機商，在經過找尋了一陣子，最後終於找到了這家主機商，其中也搜尋了不少在TurboGears的Google group的討論和評價，他們對於此主機商的評價都相當高，他們說這主機商盡力想讓他們的客戶高興，於是我就決使用這家主機商，用線上刷卡訂購了虛擬主機的服務，幾個小時內，網站就啟用了，相當地有效率</p>
<h3>出色的控制面版</h3>
<p>因為是較非主流的應用，所以不會看到常見的cPanel等虛擬主機的控制面版，而是他們自行研發的控制面版，他們在網站上有提供許多控制面版的示範影片，其中包括如何用來建置TurboGears的網站，或是Plone之類的程式，有興趣可以參考看看</p>
<p><a href="http://www.webfaction.com/demos/control-panel?affiliate=victorlin">面版控制示範影片</a></p>
<p>相信看完就可以大約了解，這控制面版相當地好用，操作很簡單，加上有示範影片可以看，帳戶開通沒多久我立刻成功地建立了一個Plone的站台</p>
<h3>不可思議的優秀客服支援</h3>
<p>如同我所見到的評價，他們的客服真的是盡力讓他們客戶高興的客服，因為有六十天無條件退款的保證，所以我決定當一個澳客，帳戶一開通我就毫不客氣地盡量使用客服，他們都很友善的回答，技術上的問題，他們都答得出來，他們建置了一個專門的知識庫</p>
<p><a href="https://help.webfaction.com/?affiliate=victorlin">WebFaction 的客服</a></p>
<p>這網頁是開放的，即使你沒有帳號，你一樣可以在裡面找到很多有用的問題的解決方法，我發了幾個問題，他們都找到在裡面的解決方案然後跟我說明要如何解決，當一個發問不爬文的澳客感覺還真不錯  :P</p>
<p>以下是一封我題出問題和客服的對話，就可以明白他們的客服都相當友善，而且都有相當程度的專業知識</p>
<p><strong><span class="ticketpostname">victorlin</span></strong></p>
<blockquote><p><span class="mediumtext">Hi, I configure Plone mail setting by following this article:</span></p>
<p>https://help.webfaction.com/index.php?_m=knowledgebase&#038;_a=viewarticle&#038;kbarticleid=82</p>
<p>But I always got a " Error Please correct the indicated errors. " error when sending a mail from plone. What am I doing wrong?</p>
<p>This is the configuration I set.</p>
<p>SMTP : *******<br />
SMTP port : 25<br />
ESMTP username : ********<br />
ESMTP password : (the password I set)<br />
From name : Site Administrator<br />
From e-mail : *********</p>
<p>Thanks.</p></blockquote>
<p><strong><span class="ticketpostname">Sime Ramov</span></strong></p>
<blockquote><p><span class="mediumtext">Hi,</span></p>
<p>&gt; But I always got a " Error Please correct the indicated errors. "<br />
&gt; error when sending a mail from plone. What am I doing wrong?</p>
<p>Does anything gets indicated? With red color or something? Could you<br />
post a screenshot?</p>
<p>&gt; This is the configuration I set.<br />
&gt;<br />
&gt; [...]</p>
<p>By the looks of it, the configuration looks fine.</p>
<p>Hope this helps and thanks for using WebFaction!</p>
<p>Best regards,<br />
&#8211; Sime</p></blockquote>
<p><strong><span class="ticketpostname">victorlin</span></strong></p>
<blockquote><p><span class="mediumtext">That bar says "Error Please correct the indicated errors.", but I don&#8217;t see any thing in errors of plone site setup. I have no idea where to see the error.</span></p>
<p>Thanks.</p></blockquote>
<p><strong><span class="ticketpostname">Sean Fulmer</span></strong></p>
<blockquote><p><span class="mediumtext">Hi Victor,</span></p>
<p>&gt; That bar says "Error Please correct the indicated errors.", but I don&#8217;t see<br />
&gt; any thing in errors of plone site setup. I have no idea where to see the<br />
&gt; error.</p>
<p>I&#8217;ve just sent myself an email from your site<br />
(http://ez2learn.com/99969801/sendto_form) and encountered no errors. I<br />
received the email a few seconds after I submitted the form.</p>
<p>It looks like this is working fine, but if you are still having trouble,<br />
please let us know the exact steps we can take to reproduce the error.</p>
<p>Thanks,</p>
<p>Sean Fulmer<br />
WebFaction Support</p></blockquote>
<p><strong><span class="ticketpostname">victorlin</span></strong></p>
<blockquote><p><span class="mediumtext">Oh, I send a article to my email without error, too. But I encounter that problem that I just mentioned before, when I use contact of my Plone site</span></p>
<p>http://www.ez2learn.com/contact-info</p>
<p>Once I send a mail by contact page, here comes the problem.</p></blockquote>
<p><strong><span class="ticketpostname">Sean Fulmer</span></strong></p>
<blockquote><p><span class="mediumtext">&gt; Oh, I send a article to my email without error, too. But I encounter that problem that I just mentioned before, when I use contact of my Plone site<br />
&gt;<br />
&gt; http://www.ez2learn.com/contact-info<br />
&gt;<br />
&gt; Once I send a mail by contact page, here comes the problem.</span></p>
<p>I just sent a test message from http://www.ez2learn.com/contact-info and did not encounter an error.</p>
<p>I&#8217;ve just noticed that your email address did not include your mailbox as a target, so I added your &#8216;victorlin&#8217; mailbox as a target for the address: https://panel.webfaction.com/email/read/24069</p>
<p>Can you tell if if that solved the problem for you?</p>
<p>Regards,</p>
<p>Sean Fulmer<br />
WebFaction Support</p></blockquote>
<p><strong><span class="ticketpostname">victorlin</span></strong></p>
<blockquote><p><span class="mediumtext">Nope. I still encounter that problem.</span></p>
<p>Wow! That&#8217;s so strange!<br />
It doesn&#8217;t make sense. I have never send a mail successfully by that contact page, how do you do that? What language do you use to browser my contact page?</p>
<p>By the way, I love your nice service and fantastic supporting! Nice job! :P</p></blockquote>
<p><strong><span class="ticketpostname">Sean Fulmer</span></strong></p>
<blockquote><p><span class="mediumtext">Hi Victor,</span></p>
<p>&gt; Nope. I still encounter that problem.<br />
&gt;<br />
&gt; Wow! That&#8217;s so strange!<br />
&gt; It doesn&#8217;t make sense. I have never send a mail successfully by that contact<br />
&gt; page, how do you do that? What language do you use to browser my contact<br />
&gt; page?</p>
<p>My browser is set to use English, but your site appears in Chinese for me.</p>
<p>Can you tell me the email &#8216;from&#8217; address that your Plone user account is<br />
using? I&#8217;ll try another test message from that address.</p>
<p>Also, if you could switch the site over to English, I might be better able to<br />
troubleshoot this.</p>
<p>&gt; By the way, I love your nice service and fantastic supporting! Nice job! :P</p>
<p>Thanks :)</p>
<p>Regards,</p>
<p>Sean Fulmer<br />
WebFaction Support</p></blockquote>
<p><strong><span class="ticketpostname">victorlin</span></strong></p>
<blockquote><p><span class="mediumtext">Oops! How stupid am I XD<br />
I login as my account, and that account did&#8217;t setup e-mail. That should be why I can&#8217;t send mail from contact page, but you can. Now I setup my e-mail, and everything works fine.</span></p>
<p>Thanks your help! :P</p></blockquote>
<p><strong><span class="ticketpostname">Sean Fulmer</span></strong></p>
<blockquote><p><span class="mediumtext">Hi Victor,</span></p>
<p>&gt; Oops! How stupid am I XD<br />
&gt; I login as my account, and that account did&#8217;t setup e-mail. That should be<br />
&gt; why I can&#8217;t send mail from contact page, but you can. Now I setup my e-mail,<br />
&gt; and everything works fine.</p>
<p>Aha! That would explain it :)</p>
<p>&gt; Thanks your help! :P</p>
<p>You&#8217;re very welcome!  Thanks for using WebFaction :)</p>
<p>Regards,</p>
<p>Sean Fulmer<br />
WebFaction Support</p></blockquote>
<p>結果到最後發現是自己在耍笨，但是整個過程中客服還是盡力的想幫我解決問題</p>
<h3>我原本所擔心的</h3>
<p>其實我原本最擔心的問題是，虛擬主機會不會有太多限制讓我沒辦法使用某些東西，例如某些Python的模組，可是我發現他們有提供SSH的連線，可以遠端登入到自己的帳號下指令，這讓使用上沒有太大的限制，如下圖所示的，使用遠端登入帳號來下指令</p>
<div id="attachment_28" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.ez2learn.com/wp-content/uploads/2008/09/2008-09-28_233501.png"><img class="size-medium wp-image-28" title="遠端登入WebFaction帳號" src="http://blog.ez2learn.com/wp-content/uploads/2008/09/2008-09-28_233501-300x188.png" alt="遠端登入WebFaction帳號" width="300" height="188" /></a><p class="wp-caption-text">遠端登入WebFaction帳號</p></div>
<h3>結論</h3>
<p>結論就是，這家主機商真的很不錯，值得推薦:P</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2008/09/28/hosting-of-this-site/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

