Posts for: #Web

web backend service in golang

先前後端開發 web service 大多是以小型的 web framework echo 來做基礎開發

https://github.com/labstack/echo

到了後來,因為他新版 v2 api 的介面修改,包了另一個 http engine fasthttp 的模組,雖然多了一層的彈性

多了一個選擇,但是在 golang 1.7 版以後,標準的函式庫已經包含了 context ,所有 framework 要解決的問題

幾乎都可以用標準函式庫,就全可以解決了,也可以真正體會 composition 組件式的架構方式,第三方的函式也更容易整併

請務必試試看,用 golang 標準的函式庫,加上一些第三方的函式,組建 web service

更新待續

最近流行小而美

此篇算是感恩文 (我知道感恩節過很久了)

Bottle

Bottle

現在時代不同,講求的是敏捷開發,一個人,當多個用,產生多個 thread 在不同專案,共用同一個大腦,開發人員進步的很快,工具也相當的進步,對函式庫的了解熟悉後,進行拆解

依照專案類型的不同,合併成最佳的組合,感覺,現在寫軟體,花一大堆的時間,看別人的函式庫,或是原始碼,要越高的彈性,及效能,就必須由越底層來切入

想想懶惰真是進步的原動力,這些工具,都是為了解決新問題與挑戰,想想身處在這個時代還蠻幸福的,有這麼多的東西可以玩

真不敢想,再過 10 年以後,軟體開發的進步,不知道可以到達什麼樣的境界,現在不管是 WEB 或是 Mobile 的應用都有長足的進步,想想10 年前的手機,在看看現在手裡的 iPhone 或是 Andriod 手機的運算能力,不可同日而語

自己比較熟的 Web 應用開發

CSS 工具有 SAAS 不過我喜歡 LESS

microjs 的一大堆 javascript 工具,還是自己來包 javascript 的工具
ender.js,還是用 coffee script 當成 Ruby 和 Python 合體來快速開發,我自己是只能算是 javascript 的幼幼班學生,所以只能用些基礎的

常用的 Web Framework,順便附一下,benchmark ,我知道,這一點都不科學,也不切實際,算是一個紀錄
硬體,都是同一台機器 Intel(R) Celeron(R) CPU E3400 @ 2.60GHz (真可憐用 Celeron), JVM 有暖身了
Node v0.6.1 (我知道他不是 framework,只是可以解決一樣的問題)


# Hello World benchmark
# all python framework under nginx 1.1.8 uwsgi 0.9.9.3, python2.6.7
# playframework under production mode java -version Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
# node -version v0.6.1
# ab -c 100 -n 1000 TO_TEST_URL

# bottle 0.11.dev
uwsgi –socket 127.0.0.1:3030 –module terry –processes 4
# ~1550 Requests/second


# flask 0.8
uwsgi –socket 127.0.0.1:3030 –module fsk –callable app –processes 4
# OR
uwsgi –socket 127.0.0.1:3030 –module fsk:app –processes 4
# ~1100 Requests/second

# django 1.3.1
# return HttpResponse(“Hello World”)
uwsgi –socket 127.0.0.1:3030 –pp .. –env DJANGO_SETTINGS_MODULE=hello.settings -w “django.core.handlers.wsgi:WSGIHandler()” –processes 4
# ~910 Requests/second


# playframework 1.2.4
# renderText(“Hello World”)
# ~1700 Requests/second


# node 0.6.1
#var http = require(‘http’);
#http.createServer(function (req, res) {
# res.writeHead(200, {‘Content-Type’: ’text/plain’});
# res.end(‘Hello World’);
#}).listen(1337, “127.0.0.1”);
#console.log(‘Server running at http://127.0.0.1:1337/’);
#
# ~2500 Requests/second
#


連結(順序無關喜好,不同的地方,不同的規劃,自己看著辦,Hello World 只是起點,大家的終點不一樣)

Bottle
Flask
Django
PlayFramework
Node.js

PS: 最重要是,由衷的感謝這麼多 Open Source 的前輩,可以這樣無私的和大家分享,不求回報,讓想法可以自由的世界的每一個角落激盪出更多的火花,讓我也可以撿拾前輩的一點點牙慧,增加一點點自己的力量,讓日子過得更美好,由衷的感恩

Tornado Gunicorn uWSGI 大亂鬥

最近因為有個屬於幫忙性質的案子,這一個專案的主角,有一些堅持,所以也算讓我可以多用一些東西 XD

在這一專案,我是屬於打工的角色,所以一般,主角決定了什麼,打工的做就對了,原本原型,是 Django 搭 MySQL 的專案,要改成 TornadoMongoDB , 但是,好歹多年前,也看過

Nicholas Piël 的 WSGI Server 大亂鬥 http://nichol.as/benchmark-of-python-web-servers

知道其實 Tornado 也沒有多佔便宜,但是口說無憑,當然秉持科學的精神(當然這樣也沒什麼科學),利用一下,小寶寶午休時間,中年老爸,趕快來作一下, benchmark 來驗證一下,就不 post 詳細的數據啦,我只是給自己驗證的結果,所有的軟體,都是安裝最新穩定版,用 pip install 的方式,在 debian 上面測試,官方的文件是說 nginx 只要是大於等於 0.7.63 版,都有將 uWSGI 包含進去,所以不需要重新編譯安裝 nginx , 想用新一點的人要自己再編譯 nginx ,測試用的工具是 Apache 的工具 ab -c 500 -n 2000

uWSGI 效能第一 (100%),穩定,但是,設定的選項很多,對 Linux 沒有概念的,可能比較不會發揮,適合 Linux 熟的

Tornado 效能第二 (93%),回應時間,落差比較大,適合,喜歡自己打造東西的人

Gunicorn 效能第三 (84%),穩定,設定非常的簡單,回應時間穩定


百分比,只是,回應速度,在加權一點回應時間,測試的程式,就只是基本的 Hello World or Ping Pong 的方式,以上三個,都足以應付 production 的需求環境


測試條件

uWSGI 基本上都是參考 Nicholas Piël 方式,不過有些系統的對應參數,必須先用 sysctl 調好,也要懂 -l 的數字一定要大於等於你的 concurrency 數,都是透過 nginx

sysctl -w net.ipv4.tcp_keepalive_time=300
sysctl -w net.core.somaxconn=250000
sysctl -w net.ipv4.tcp_max_syn_backlog=2500
sysctl -w net.core.netdev_max_backlog=2500


uwsgi –gid www-data –uid www-data -z 30 -l 500 -L -M -s 127.0.0.1:3031 -p 4 –env DJANGO_SETTINGS_MODULE=bench.settings -w “django.core.handlers.wsgi:WSGIHandler()” # django app

uwsgi –gid www-data –uid www-data -z 30 -l 500 -L -M -s 127.0.0.1:3031 -p 4 -pythonpath pwd -w myapp # 單純 wsgi app


Tornado 參考 Nicholas Piël 直接打,還有就是用 https://github.com/bdarnell/django-tornado-demo 的 testsite 測試


Gunicorn 直接用 gunicorn_django –worker=2 ,其實這樣對他有一點不公平,也應該直接接 wsgi app 才對,不過,他的設定最簡單,可以直接上,這就是他的好處


PS1: 專案的架構,一般都是見仁見智,很難有一定的評斷,但是連正式上線,都還沒有上線,就將原型完全換掉,也是一種神人級的豪賭,一種情形是,這些東西神人都可以自己生出來,所以不在乎原型,一種是,神人不喜歡,別人寫得東西,喜歡自己來,一般決定一個專案的架構的時候,第一點,一定是,時間,人力,還有成員的熟悉度,絕不是,盲目的追求效能,或是熱門的話提,要跨入 nosql 之前,先看看自己作過幾個大型的 SQL 專案,能發揮到什麼程度,可以先由一些小型的專案,驗證熟悉

PS2: 這個原型,是我看過非常乾淨的 Django project 不管是自身的架構或是重用別人的部份,都算是非常的漂亮 ( 原作者還呼隴我說寫的很丑很髒 )


PS3: 其實用 Django 外,Python 不像 Ruby 那樣,選擇不多,相反地,我的媽壓,還真不好選, http://wiki.python.org/moin/WebFrameworks ,不同專案有不同需求,找自己愛用的吧,玩得開心最重要,喜歡套件 AP 多,可以直接上,就 Django ,喜歡自己打造,選擇有一大票

Django with PayPal



要接付對大家最方便的應該還是 PayPal,畢竟,他運行的時間比較久

基本的方式, Web Form 或是 API 的方式,可以直接用 djangosnippets 的程式範例

http://djangosnippets.org/tags/paypal/

在加上 http://uswaretech.com/blog/2008/11/using-paypal-with-django/

這樣,很快就可以用啦

Web Form (PayNow),基本上,基本的元素

這是由文件的範例



但是我會再加上(加到 web form 裡)

input type=“hidden” name=“rm” value=“2”
input type=“hidden” name=“return” value=“http://somewhere after payment”
input type=“hidden” name=“cancel_return” value=“http://user cancel”>
input type=“hidden” name=“notify_url” value=“http://url to handle Paypal callback”



API

就直接照上面國外部落格作者寫得的就可以了

PhotonVPS TEST

2010-07-16 09:00 bought
2010-07-16 22:10 開通

開始測試

Disk read

www:/tmp# hdparm -tT /dev/sda1

/dev/sda1:
Timing cached reads: 9942 MB in 1.99 seconds = 4995.05 MB/sec
Timing buffered disk reads: 574 MB in 3.01 seconds = 190.87 MB/sec



Network

www:/tmp# wget http://cachefly.cachefly.net/100mb.test
–2010-07-16 15:34:38– http://cachefly.cachefly.net/100mb.test
Resolving cachefly.cachefly.net… 205.234.175.175
Connecting to cachefly.cachefly.net|205.234.175.175|:80… connected.
HTTP request sent, awaiting response… 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: 100mb.test'<br /><br />100%[===========================================================================================================================>] 104,857,600 10.8M/s in 9.3s<br /><br />2010-07-16 15:34:47 (10.8 MB/s) - 100mb.test’ saved [104857600/104857600]


www:/tmp# wget http://ftp.tw.debian.org/debian-cd/5.0.5/amd64/iso-dvd/debian-505-amd64-DVD-1.iso
–2010-07-16 15:28:30– http://ftp.tw.debian.org/debian-cd/5.0.5/amd64/iso-dvd/debian-505-amd64-DVD-1.iso
Resolving ftp.tw.debian.org… 140.112.8.139
Connecting to ftp.tw.debian.org|140.112.8.139|:80… connected.
HTTP request sent, awaiting response… 200 OK
Length: 4692975616 (4.4G) [application/x-iso9660-image]
Saving to: `debian-505-amd64-DVD-1.iso’

4% [====> ] 213,035,198 1.41M/s eta 55m 2s

tracerout from my home desktop (hinet) to my PhotonVPS host ip


terry@debian:$ traceroute 173.224.209.230
traceroute to 173.224.209.230 (173.224.209.230), 30 hops max, 60 byte packets
1 192.168.1.1 (192.168.1.1) 0.733 ms 0.978 ms 2.219 ms
2 h254.s98.ts.hinet.net (168.95.98.254) 15.678 ms 16.318 ms 17.691 ms
3 TPE4-3301.hinet.net (168.95.100.194) 17.343 ms 17.712 ms 17.797 ms
4 TPE4-3202.hinet.net (220.128.5.174) 18.059 ms tp-e4-t64-1.router.hinet.net (220.128.5.22) 18.962 ms 18.977 ms
5 TPDT-3011.hinet.net (220.128.1.110) 20.465 ms TPDT-3012.hinet.net (220.128.2.110) 19.320 ms TPDT-3011.hinet.net (220.128.3.22) 20.590 ms
6 r4003-s2.tp.hinet.net (220.128.4.253) 20.605 ms 13.820 ms 220-128-7-185.HINET-IP.hinet.net (220.128.7.185) 13.698 ms
7 220-128-7-213.HINET-IP.hinet.net (220.128.7.213) 17.782 ms 18.024 ms r4001-s2.tp.hinet.net (220.128.3.78) 18.190 ms
8 r01-pa.us.hinet.net (211.72.108.225) 156.362 ms r01-pa.us.hinet.net (211.72.108.201) 159.590 ms 160.744 ms
9 r11-la.us.hinet.net (202.39.83.229) 152.592 ms 152.346 ms 171.680 ms
10 unknown.xeex.net (216.151.129.113) 154.102 ms 154.006 ms 172.863 ms
11 xeex.cr1.sjc1.psychz.net (216.151.129.30) 174.068 ms 175.926 ms 175.922 ms
12 unassigned.psychz.net (173.224.209.230) 168.095 ms 148.604 ms 168.852 ms


unixbench 5.1.2

========================================================================
BYTE UNIX Benchmarks (Version 5.1.2)

System: www.xxx.com: GNU/Linux
OS: GNU/Linux – 2.6.18-164.11.1.el5xen – #1 SMP Wed Jan 20 08:06:04 EST 2010
Machine: x86_64 (unknown)
Language: en_US.utf8 (charmap=“UTF-8”, collate=“UTF-8”)
CPU 0: Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (5674.8 bogomips)
Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
CPU 1: Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (5674.8 bogomips)
Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
CPU 2: Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (5674.8 bogomips)
Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
CPU 3: Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (5674.8 bogomips)
Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
CPU 4: Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (5674.8 bogomips)
Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
CPU 5: Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (5674.8 bogomips)
Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
CPU 6: Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (5674.8 bogomips)
Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
CPU 7: Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (5674.8 bogomips)
Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
15:36:37 up 1:30, 3 users, load average: 0.01, 0.03, 0.00; runlevel 3

————————————————————————
Benchmark Run: Fri Jul 16 2010 15:36:38 - 16:04:53
8 CPUs in system; running 1 parallel copy of tests

Dhrystone 2 using register variables 16353920.9 lps (10.0 s, 7 samples)
Double-Precision Whetstone 2657.2 MWIPS (10.0 s, 7 samples)
Execl Throughput 1151.6 lps (30.0 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 221910.1 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 59516.0 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 660809.0 KBps (30.0 s, 2 samples)
Pipe Throughput 337014.0 lps (10.0 s, 7 samples)
Pipe-based Context Switching 75988.5 lps (10.0 s, 7 samples)
Process Creation 3247.1 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 3297.7 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 1219.1 lpm (60.0 s, 2 samples)
System Call Overhead 381956.6 lps (10.0 s, 7 samples)

System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 16353920.9 1401.4
Double-Precision Whetstone 55.0 2657.2 483.1
Execl Throughput 43.0 1151.6 267.8
File Copy 1024 bufsize 2000 maxblocks 3960.0 221910.1 560.4
File Copy 256 bufsize 500 maxblocks 1655.0 59516.0 359.6
File Copy 4096 bufsize 8000 maxblocks 5800.0 660809.0 1139.3
Pipe Throughput 12440.0 337014.0 270.9
Pipe-based Context Switching 4000.0 75988.5 190.0
Process Creation 126.0 3247.1 257.7
Shell Scripts (1 concurrent) 42.4 3297.7 777.8
Shell Scripts (8 concurrent) 6.0 1219.1 2031.9
System Call Overhead 15000.0 381956.6 254.6
========
System Benchmarks Index Score 496.1
————————————————————————
Benchmark Run: Fri Jul 16 2010 16:04:53 - 16:33:40
8 CPUs in system; running 8 parallel copies of tests

Dhrystone 2 using register variables 96059277.7 lps (10.1 s, 7 samples)
Double-Precision Whetstone 19860.3 MWIPS (9.8 s, 7 samples)
Execl Throughput 7234.4 lps (30.0 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 140202.9 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 37087.2 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 495818.2 KBps (30.0 s, 2 samples)
Pipe Throughput 2074287.5 lps (10.1 s, 7 samples)
Pipe-based Context Switching 547893.3 lps (10.1 s, 7 samples)
Process Creation 17365.7 lps (30.1 s, 2 samples)
Shell Scripts (1 concurrent) 13264.6 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 2103.4 lpm (60.1 s, 2 samples)
System Call Overhead 2104375.0 lps (10.1 s, 7 samples)

System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 96059277.7 8231.3
Double-Precision Whetstone 55.0 19860.3 3611.0
Execl Throughput 43.0 7234.4 1682.4
File Copy 1024 bufsize 2000 maxblocks 3960.0 140202.9 354.0
File Copy 256 bufsize 500 maxblocks 1655.0 37087.2 224.1
File Copy 4096 bufsize 8000 maxblocks 5800.0 495818.2 854.9
Pipe Throughput 12440.0 2074287.5 1667.4
Pipe-based Context Switching 4000.0 547893.3 1369.7
Process Creation 126.0 17365.7 1378.2
Shell Scripts (1 concurrent) 42.4 13264.6 3128.4
Shell Scripts (8 concurrent) 6.0 2103.4 3505.6
System Call Overhead 15000.0 2104375.0 1402.9
========
System Benchmarks Index Score 1529.8





www:/redis-2.0.0-rc2# ./redis-benchmark




====== PING ======
10000 requests completed in 0.57 seconds
50 parallel clients
3 bytes payload
keep alive: 1

27.80% <= 2 milliseconds
98.20% <= 3 milliseconds
99.50% <= 4 milliseconds
99.86% <= 5 milliseconds
100.00% <= 6 milliseconds
17574.69 requests per second

====== PING (multi bulk) ======
10001 requests completed in 0.43 seconds
50 parallel clients
3 bytes payload
keep alive: 1

0.03% <= 0 milliseconds
32.41% <= 1 milliseconds
56.89% <= 2 milliseconds
98.53% <= 3 milliseconds
99.97% <= 4 milliseconds
100.00% <= 5 milliseconds
23150.46 requests per second

====== SET ======
10021 requests completed in 0.28 seconds
50 parallel clients
3 bytes payload
keep alive: 1

0.58% <= 0 milliseconds
69.34% <= 1 milliseconds
95.58% <= 2 milliseconds
99.98% <= 3 milliseconds
100.00% <= 4 milliseconds
36307.97 requests per second
====== GET ======
10015 requests completed in 0.26 seconds
50 parallel clients
3 bytes payload
keep alive: 1

0.97% <= 0 milliseconds
76.25% <= 1 milliseconds
96.81% <= 2 milliseconds
100.00% <= 3 milliseconds
38968.87 requests per second