公共債務法草案爭議

本圖( public_debt.png )部份內容含有 玉山銀行 製作內容,非全屬 hoamon 所創作
這幾天,吵的比較正經的事,應該就是郝市長怨嘆陳院長推動新版公債法草案,大幅限縮臺北市的舉債空間,約略少了 2250 億的舉債額度。郝市長為此上告馬總統,並轉述總統親口回應『免煩惱』,以藉此倒打陳院長一耙。
但其實誰跟誰吵架,誰去找爸爸,爸爸又得要罵誰? 這些事並不是我在乎的。我在乎的是地方政府舉債問題。
本圖( public_debt.png )部份內容含有 玉山銀行 製作內容,非全屬 hoamon 所創作
這幾天,吵的比較正經的事,應該就是郝市長怨嘆陳院長推動新版公債法草案,大幅限縮臺北市的舉債空間,約略少了 2250 億的舉債額度。郝市長為此上告馬總統,並轉述總統親口回應『免煩惱』,以藉此倒打陳院長一耙。
但其實誰跟誰吵架,誰去找爸爸,爸爸又得要罵誰? 這些事並不是我在乎的。我在乎的是地方政府舉債問題。
我的 Netbeans 預設字型 Monospaced 一直有中英文不對齊的問題,但其實曾經在不知版本的 Ubuntu 上解決過,因為沒有作紀錄,所以升級後,就又出現這種問題,後來參考其他文章,本想代換成 MONACO 字型,但這個”通狼蚵樂”的字型,在我的 Netbeans 上,就是會出現方塊字。搞不定呀! 只得放棄。
本文是探討貧富差距的第一篇,主文在 貧富差距 。
吉尼係數是用來分析國家的貧富差距現象有多嚴重的一個指數,但我個人對它抱持懷疑態度,因為它只計算了收入分佈情形,卻沒有考慮擁有者識別度,這什麼意思? 我用一個例子說明:
某社會總共有 10 個人,其中有一人的收入佔總比 91 % ,而剩下 9 個人的收入各佔總比例 1 %,這個社會吉尼係數很大(有多大,請自己算,我懶得算),但如果在自由不管制的條件下,該社會中擁有 91 %收入的人,每年輪流換人坐, 10 年過去,平均每個人都有一年時間擁有 91 % 的收入。試問,這個社會的貧富差距很大嗎?
解決貧富差距問題,不見得一定要大家收入差不多,也可以是透過大風吹的方法讓大家輪流坐。
本圖( wealth_gap.png )部份內容含有 中央印製廠 製作內容,非全屬 hoamon 所創作
目前臺灣新聞大概不脫幾個主題: 『政府無能』、『貧富差距』、『青年高失業』、『軍公教退休人員該死』。也有陪襯一些:『誰喜歡誰』、『誰生小孩』、『誰離婚』的花邊,不過我向來對這些無益世界的主題沒什麼興趣。而前面四個主題,從我小時候就時常聽說,並沒有完全斷過。
接下來我將談談『貧富差距」、『青年高失業』及『軍公教退休人員該死』的問題。
本文是第一個主題,要談的是『貧富差距』。
一開始,我的疑問是這樣子的,大家都說:『臺灣政府無能,讓貧富差距愈來愈大。』,但我看很多國家也都發生貧富差距愈來愈大的現象,那這些國家首長、文官也都無能嗎? 可是他們有些人是從哈佛、芝大、牛津…這些名校畢業的,為什麼國家治理能力會這麼糟糕?
下圖為綠標憑證在瀏覽器的顯示情形:
本圖( greenbar.png )部份內容引自 https://www.startssl.com/ ,並非全屬 hoamon 創作
StartSSL.com 有提供我們這些已作過 Personal Identity Validation 的人 ( 詳見 Ho600’s SSL Certification ) 去幫別人購買 2 年效期憑證的 方案 ,如果有需要我可以協助購買。收費分五個等級,並有三個但書:
本圖( ho600_ssl.png )部份內容引自 https://www.ho600.com/ ,並非全屬 hoamon 創作
雖然 StartSSL.com 有免費一年的憑證( Class 1 )可以申請,但如果是商業運作的網站,它們是會拒絕你的申請,所以我的 Ho600.com 就被拒絕申請免費的 Class 1 憑證。不過,沒關係,人家開公司總要賺錢的嘛~ 況且他們的憑證服務真的很方便,也很便宜,所以我沒什麼好抱怨,甚至我很欣賞它們,因為它們提供的服務是以加解密技術為基礎向上發展的,或許之後我還會跟它們買硬體憑證以研發電子公文系統,或是幫它們代銷 SSL 憑證。那這樣本文就算廣告文,事實上也是,請詳見本文末 。
這次跟它們申請的是 *.Ho600.com 2 年效期 wild card 憑證( Class 2 ),適用於所有第一層 Ho600.com 的子網域,而且我打算把這張憑證用在 GAE 系統中。過去沒有設定自己的憑證時,要在 https://www.Ho600.com/ 與使用者端作加密通道( https ),只能使用 GAE 的預設網址 https://www-Ho600.appspot.com/ 。這當然會造成使用者的困惑,明明是跟 http://www.Ho600.com/ 作連線,怎麼網頁點著點著就變成 https://www-Ho600.appspot.com/ ,擔心是不是被”釣到”了。
本圖( sphinx.png )非屬 hoamon 創作,引用自 http://sphinx-doc.org/
改變的好叫『祖上積德』,改變的差叫『政府無能』。困難的是人們往往不知道是什麼時候變及變什麼,但如果只會講:『Yes, We Can Change』,而不知道要變什麼、怎麼變,那就只是喊喊口號而已。
格主因為人生進入另一個階段,所以把 個人網站 從 Python 生成的動態網頁系統改成 Sphinx 生成的靜態網頁系統。在試用一段時間之後,也打算把其他個人相關的網站及部落格一併轉成 Sphinx-based 的架構。使用同一種工具當然可降低維護成本。但為什麼是挑 Sphinx 呢?
子良問:『君不信因果,何得有富貴貧賤?』
縝答道:『人生如樹花同發,隨風而散,或拂簾幌,墜茵席之上; 或關籬牆,落糞溷之中。墜茵席者,殿下是也;落糞溷者,下官是也。貴賤雖復殊途,因果竟在何處?』
譯如下:
因綠際會讓我有機會去研究 Amazon Web Service 。那是個與 GAE 功能相同,但操作模式不盡相同的雲端服務。
GAE 像是個套裝雲端平台,有些東西它已幫你決定好,要就用,不用就拉倒,當然可以寫 ticket 去建議他們,但不一定會立案。犧性自由的收獲就是得到『自動擴展性』,當你的網站流量大時, GAE 自動開分身,也因為你寫的程式一開始就受 GAE 平台的限制,而這些限制的目的主要就是為了提升擴展性,所以一開始在 GAE 上寫網站很痛苦,但後期維護很輕鬆。
AWS 就像是個高級積木組,你想怎麼兜就怎麼組,在自己架站環境中跑的網站,不用改任何一行程式碼就能移至 AWS 上。但等到你的網站流量大,使用者多時,就得再利用 AWS 提供的系統維護工具來自行維護了。缺點當然是你得多請一組系統管理員,但相較於自己搞機房、架站,利用 AWS 平台可以讓系統管理員工作簡單多了。
對我而言,兩種開發平台各有好處,這我當然兩者都學,唯其資源分配乃先 GAE ,後 AWS 。
AWS 的主力產品就是 Elastic Compute Cloud (EC2) ,一個 EC2 可以想像它就是你的一台電腦,只是放在 Amazon 機房裡。
我們可以開一台 EC2 出來後,在裡面安裝 ubuntu, nginx, django, postgresql 等軟體,讓它跑網頁伺服器。或是裝了 postfix 就能變郵件伺服器,或是裝了 vlc 變影音串流伺服器。簡單講,只要有安裝相對應的軟體, EC2 也能變火箭。
但是 EC2 的硬碟不多,近 10 G 而已,如果你想放很多資料,那就需要 Simple Storage Service(S3) 。而且為了擴展性,你也得用 S3 ,用了 S3 ,當網站熱門到得多開幾台 EC2 出來時,它們才有共同儲存的地方。
當網站只用一台 EC2 時,可以把 MySQL/PostgreSQL/Oracle 資料庫裝在同一個 EC2 裡,但當有多個 EC2 時,怎麼辦? AWS 有給獨立的資料庫伺服器,除了關聯式資料庫( RDS )外,也有 NoSQL ( DynamoDB )的。把資料庫託給 RDS/DynamoDB 管理,也省得自己作備援、備份、調校等管理工作,而且以 Oracle DB 來看,可以不用購買授權改以每小時租用計費,這相當方便。易言之,在 AWS 上花錢就能換得輕鬆。
整個 AWS 架構是在一個虛擬化的機房內,每開啟一個 EC2 實體,它會得到一個虛擬 IP ,我們可以透過 boto (Python base)去管理它,也可以直接在 AWS Management Console 頁面管理。
目前 AWS 在美國維吉尼亞、奧勒岡、北加州、愛爾蘭、日本、新加坡、巴西聖保羅都有機房。你想把機器開在那裡,自己決定就行了。
如果要讓 EC2 有公共 IP ,可以到 Elastic IPs 去索取一個實體 IP ,但記得在索取後就要把它綁定到 EC2 實體去,如果要了公共 IP ,但沒有拿去用,是會被 AWS 索取 0.01/hours 的罰款,我就被罰了 0.71 元美金,因為我關了 EC2 實體後,並沒有再去退 IP ,結果那個 IP 就被我佔了 71 個小時。
其他 AWS 產品還有 CloudWatch, CloudFront, CloudCache, SQS, SES, SNS, SWF...,實在很多,請自行到 官網 了解。
目前 AWS 有 免費試用方案 ,方案為註冊後一年之內使用,而每個月的免費額度如下:
AWS Free Usage Tier (Per Month):
我已把未送到 bitbucket.org 的專案及 zotero webdav 丟上 AWS 了。
自己家裡的機器正式結束「網站」的工作,專職作「寫程式機」了。
2012 三月全世界的網頁伺服器市佔率圖 from http://netcraft.com/ 。本圖( wpid-overallc.png )非屬 hoamon 創作。
上圖可以看出歷久彌新的 Apache 持續雄距首位,有超過 15 年的時間,沒”器”可挑戰它的地位。直至 Nginx 的出現,或許它現在只有 10% ,但從各方評價看來,它絕對是 Apache 有史以來最強大的對手。短短 5 年,它已經爬上第 3 名的位子,從趨勢線上看來,要超越 IIS 也是有很大的機會。
而 Nginx 為什麼短短幾年竄起,絕不是因為『用的人多』。如果是這種原因的話, palm 、 Windows OS 、 x86 CPU 、 PlayStation 到現在會活得好好地,因為它們都曾有超越 50% 的市佔率。
Nginx 被選擇的原因有幾點:
簡單講,除了效能,還是效能。而我要的功能, Nginx 都有提供,唯一算得上缺點的,就是因為 Apache 活得比較久,安全性已被磨得比較好了。所以對於我們愛研究的研究生來說,還有什麼理由不切換過去呢? 大概只有「懶」是個原因吧!
目前我們使用 Apache + Django 的方式多是利用 mod_python 的技術。然而這種作法是比較不安全的,把很多事都包給 Apache 去作,那不管是我們程式設計有錯,或是它用的元件有錯,只要出錯那就是管理員等級的錯。不過這個「錯」也不算是 Apache 的錯,是「用 mod_python 」的錯,如果用的是「 mod_fastcgi 」,那安全層級就能拉高了。
所以說來,這次的「升級」是把「 mod_python 」丟掉,改用「 mod_fastcgi 」。那麼我心裡想想,都要換成 Django 自己跑 fcgi mode 了,為什麼不乾脆連前端網頁伺服器也換一下呢! 因為重點已換成 Django 的 fcgi server , Apache 的重點性大減,前端網頁伺服器的功能只剩下靜態檔案輸出、虛擬站台切換、 https 處理等,那我何必跑一個 Huge Apache 呢? Nginx 就是我的新選擇。
安裝很簡單,如果是在 Ubuntu 中,請打:
$ sudo apt-get install nginx
如果是在 Windows 中,請到官網下載 nginx.zip 檔,解開了,就是一個可執行的 nginx 程式。
而我用的方法是下載源始碼自己編譯:
$ wget some_file_link.tgz
$ tar -zxf some_file_link.tgz
$ cd nginx
$ sudo apt-get install libpcre3-dev libssl-dev # 這些是編譯時,須用到的函式庫程式碼
$ sudo apt-get install libxml2-dev libxslt-dev # 這些是編譯時,須用到的函式庫程式碼
$ sudo apt-get install libgd2-xpm-dev libgeoip-dev # 這些是編譯時,須用到的函式庫程式碼
$ ./configure --prefix=/usr/local/nginx --with-debug --with-http_dav_module \
--with-http_addition_module --with-http_geoip_module --with-http_gzip_static_module \
--with-http_image_filter_module --with-http_realip_module --with-http_stub_status_module \
--with-http_ssl_module --with-http_sub_module --with-http_xslt_module \
--with-ipv6 --with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl --with-mail \
--with-mail_ssl_module
$ make
$ sudo make install
這樣 Nginx 就安裝完成了。
接下來,我們作 Django 程式的設定,讓它可以跑在 fcgi mode 上,方法很簡單,原本我們在本機開發時,都是用:
$ python2.7 manage.py runserver 127.0.0.1:8080
讓它跑在 http://127.0.0.1:8080/ 上,現在則改用:
$ cd /home/somewhere
$ su - someuser -c "python2.7 manage.py runfcgi host=localhost port=3033 daemonize=true method=threaded workdir=/home/somewhere pidfile=/home/somewhere/fcgi.pid"
這樣 django 會在 127.0.0.1:3033 中,幫我們開一個 someuser 帳號權限的 fcgi server ,daemonize=true 則表示指令打完後,它就背景處理了,想要把這個 fcgi server 殺掉,就去看看/home/somewhere/fcgi.pid 的內容,裡面的編號就是系統行程編號, kill 那個編號就能關 fcgi server 了。 同時殺掉 fcgi server ,再馬上啟動它的指令可參考如下:
$ su - someuser -c "kill `cat /home/somewhere/fcgi.pid` && python2.7 manage.py runfcgi host=localhost port=3033 daemonize=true method=threaded workdir=/home/somewhere pidfile=/home/somewhere/fcgi.pid"
請注意在這個階段,你用瀏覽器去看 http://127.0.0.1:3033/ 是沒反應的,因為它現在跑的是 FastCGI 協定,不是 http 協定。瀏覽器無法跟 Django FastCGI 溝通。
接下來,我們再到 nginx.conf 去設定。Nginx 與 FastCGI Server 互動原理如下:
先由 Nginx 與瀏覽器互動,得到 GET, POST 等變數後,整理成 fastcgi 協定的變數,然後用 Socket 或 Port 方式傳遞給 FastCGI Server ,接下來就是 FastCGI 去驅動程式去處理,完成後拋回。
以下是 nginx.conf 的設定範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | user www-data; # 子行程用的是 www-data 帳號 worker_processes 4; # 常駐 4 個子行程 pid /var/run/nginx.pid; # 紀錄母行程的編號 http { server_tokens off; # 網頁上不顯示伺服器版本編號 sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 30; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; gzip_disable "msie6"; server { listen 80; server_name www.whatever-you-want.com.tw; root /var/www; index index.html; access_log /var/log/nginx/TW-access.log; error_log /var/log/nginx/TW-error.log; } server { listen 443; server_name www.whatever-you-want.com; keepalive_timeout 60; ssl on; ssl_certificate /etc/ssl/hoamon.info/hoamon.info.crt; ssl_certificate_key /etc/ssl/hoamon.info/hoamon.info.key; location "/" { fastcgi_pass_header Authorization; fastcgi_intercept_errors off; fastcgi_pass 127.0.0.1:3033; fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; } location "/media" { autoindex on; root /home/somewhere/media; } access_log /var/log/nginx/whatever-you-want.access_log; error_log /var/log/nginx/whatever-you-want.error_log; } } |
上面有兩個虛擬站台,一個是給 www.whatever-you-want.com.tw ,一個是給 www.whatever-you-want.com 。www.whatever-you-want.com.tw 只是單純的靜態網站,預設首頁是 http://www.whatever-you-want.com.tw/index.html ,而它的硬碟位置在 /var/www/index.html 。
而使用者若是瀏覽 https://www.whatever-you-want.com/media 的連結,則 Nginx 會給它 /home/somewhere/media 資料夾內的所有檔案。除了 /media/.* 外,其他的連結都會用 3033 port 送到 Django FastCGI Server 處理。
而使用 https 的方法,只須要設定 3 個變數值: ssl , ssl_certificate , ssl_certificate_key 即可。設定完成後,用指令開啟 Nginx :
$ /usr/local/nginx/sbin/nginx
重新載入:
$ /usr/local/nginx/sbin/nginx -s reload
關閉:
$ /usr/local/nginx/sbin/nginx -s stop
這樣 Nginx 伺服器就建立完成了。
在新架構下,可以由系統管理員獨立控管 Nginx 網頁伺服器的開啟、關閉,而讓程式設計師,自行作 FastCGI Server 的管理,程設師自己作程式更新、套用,避免給予過多的權限。畢竟這兩者的知識領域是有別的,少有人兩邊都作得很好。
如果我們一台機器有多個 django-base 的虛擬站台,那麼一個 django-base project 就要花一個 port ,這對於系統管理員及程式設計師而言,容易有搞亂的可能性,畢竟 “網址” <=> “port” <=> “django-base project” 的過程當中,是文字對應數字,再對應文字,難以記在人的腦中(也可能是我的記性比不上平均值吧!)。
所以我建議使用 Unix Socket 方式作對應。程式設計師把 socket 開在程式庫的 root 資料夾中,並取名為 django.socket 。再將 django.socket 權限設為 770 ,然後系統管理員把這個 django.socket 擁有群組設為 www-data 。
程式專案在 /home/someproject/ ,設定範例如下:
$ cd /home/someproject && /usr/bin/python2.7 manage.py runfcgi socket=`pwd`/django.socket method=threaded workdir=`pwd` pidfile=`pwd`/pid daemonize=true
上面程式設計師跑起一個 django-base 專案,並將 socket 開在 /home/someproject/django.socket 。
然後系統管理員作權限設定(也可以用 visudo 指給程式設計師作權限設定):
$ sudo chgrp www-data /home/someproject/django.socket
$ sudo chmod 770 /home/someproject/django.socket
系統管理員再把 nginx.conf 原本的 fastcgi_pass 127.0.0.1:3033 設定改如下:
fastcgi_pass unix:/home/someproject/django.socket;
改成這樣的設定方式,對程式設計師來說,永遠是把 socket 開在同一個專案資料夾中,並命名為 django.socket ,而系統管理員也知道一定是專案資料夾下的 django.socket 。少了數字 port 的對應記憶,減少錯誤的機率。