锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
2 from gevent import socket
3 import Tkinter as tk
4
5 class SockLoop(object):
6 def __init__(self, callback):
7 self.callback = callback
8
9 def __call__(self, sock, client):
10 while 1:
11 mes = sock.recv(256)
12 ret = self.callback(client, mes)
13 if ret is not None:
14 sock.send(ret)
15
16 def socket_server(port, callback):
17 ssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
18 ssock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
19 ssock.bind(('', port))
20 ssock.listen(5)
21
22 while 1:
23 sock, client = ssock.accept()
24 gevent.spawn(callback, sock, client)
25
26 class App(object):
27 def __init__(self, root):
28 self.greenlet = None
29 self.root = root
30 self._build_window(root)
31 self.root.after(100, self._connect)
32
33 def add_text(self, text):
34 cleaned_string = text.replace('\r', '')
35 self.text.insert(tk.END, cleaned_string)
36
37 def quit(self):
38 self.root.quit()
39
40 def _build_window(self, root):
41 self.frame = tk.Frame(root)
42 self.text = tk.Text(self.frame)
43 self.quit_button = tk.Button(self.frame, text="Quit", command=self.quit)
44 self.text.pack()
45 self.quit_button.pack()
46 self.frame.pack()
47
48 def _connect(self):
49 self.greenlet = gevent.spawn(
50 socket_server,
51 8080,
52 SockLoop(lambda cl, txt: self.add_text("%s: %s" % (cl, txt))))
53 self.gevent_loop_step()
54
55 def gevent_loop_step(self):
56 gevent.sleep()
57 self.root.after_idle(self.gevent_loop_step)
58
59
60 if __name__ == '__main__':
61 root = tk.Tk()
62 app = App(root)
63 root.mainloop()
]]>
鑰冭檻鍒板甫瀹藉埄鐢紝鎺ユ敹鑰呭緱鍒扮殑娑堟伅灝嗕笉鍖呭惈浜岃繘鍒舵暟鎹紝渚嬪: 闊抽錛屽浘鍍忕瓑絳夈?榪欒姹傛帴鏀惰呭騫沖彴鍙戣搗涓嬈¤幏鍙栨秷鎭寘鍐呮寚瀹氱殑闊抽鍜屽浘鍍忔暟鎹殑璇鋒眰銆?br />縐誨姩绔悜騫沖彴璇鋒眰浜岃繘鍒舵暟鎹殑鎯呭喌榪樺寘鍚?銆愮綰挎枃浠朵紶閫併戝満鏅?銆?
浜岃繘鍒舵暟鎹線寰鏄寚閭d簺鏁版嵁閲忔瘮杈冨ぇ鐨勫璞★紝榪欎簺瀵硅薄鍦ㄧЩ鍔ㄤ袱绔氦鎹㈡椂錛屼氦浜掗氶亾灝嗕笉鍗犵敤涓庢帴鍏ユ湇鍔″櫒鐨勮繛鎺ラ氶亾錛岃屾槸閫氳繃nginx浼犻佸埌騫沖彴鍐呴儴錛?鍚屾牱鎺ユ敹鑰呰幏鍙栦簩榪涘埗鏁版嵁涔熸槸閫氳繃nginx鑾峰彇銆傝繖縐嶈姹傛槸HTTP鐨勩?br />榪欓噷鏁寸悊鐨勬槸濡備綍鍦ㄥ鉤鍙伴儴緗?銆愯礋杞藉潎琛$殑闆嗙兢鐨勫垎甯冨紡鐨勬枃浠舵湇鍔°?br />
nginx : http鏈嶅姟錛屾彁渚涘弽鍚戜唬鐞嗗拰璐熻澆鍧囪 鏈嶅姟錛堥泦緹ゅ彲鐢―NS鎴栬冭檻LVS鏂規(guī)錛?br />mongodb+gridfs : 鐢ㄤ簬鏂囦歡鏈嶅姟鎻愪緵錛屽叾鍐呯疆gridfs鎻愪緵浜?jiǎn)鍒嗗竷寮忓Q屾搗閲忓瓨鍌ㄧ殑鏂規(guī)
gevent+webpy : nginx鐩存帴璇誨彇gridfs鏄笉鍚堥傜殑錛岄厤緗簡(jiǎn)cgi鎵嶈兘瀹屾垚鐗瑰畾鍔熻兘錛岃繖閲屼嬌鐢╳ebpy錛屾瘮django鏇磋交鏇村ソ鐢ㄣ?br /> webpy鐨勪綔鐢ㄦ槸鎺ユ敹鍒頒笂浼犲拰涓嬩紶鏂囦歡鐨勮姹傦紝璇誨啓gridfs鏂囦歡鍐呭緇欑Щ鍔ㄧ銆?br /> gevent鏄珮鏁堢殑閫氫俊妗嗘灦錛岃櫧鐒跺崟綰跨▼宸ヤ綔錛屼絾鎬ц兘闈炲父鐨勫ソ錛?br /> 鐢ㄥソgevent鍏抽敭鍦ㄤ笌澶栭儴鐨刬o蹇呴』鍏ㄩ儴閮芥槸寮傛鐨勶紝渚嬪錛?鏁版嵁搴擄紝鏂囦歡紓佺洏璁塊棶絳夌瓑銆?br /> mongodb瀵筭event宸茬粡鏀寔錛実event瀵箇ebpy錛宒jango錛宲sycopg2鏀寔涔熺浉褰撶殑濂斤紝鎵浠ヨ鎻愪緵webservice鏈嶅姟閭e氨鑰冭檻鐢╣event+webpy鎴杁jango鎶婏紝鎬ц兘鏄潬鏉犵殑錛屾瘮 apache+mod_wsgi瑕佸ソ寰堝 錛岃屼笖gevent鏄繘紼嬪唴鐨勪笉鍚岀殑HTTP REQUEST鍙互鏄叡浜暟鎹殑錛岃繖涓鐐歸潪甯歌鎯?apache+mod_wsgi鐨凴EQUEST鍙槸闅旂鐨勫摝錛侀櫎闈炴?zhèn)ㄩ氳繃redis鐨凱UB/SUB瀹炵幇涓や釜REQUEST鐨勯氫俊)
鍏蟲敞鐨勯棶棰橈細(xì)
錛?涓嬩紶澶ф枃浠舵椂鐨勫鐞?br />銆銆銆濡傛灉鐩存帴鐢╪ginx褰撶劧娌℃湁榪欎釜闂銆錛屼絾鐢╳ebpy璇誨彇鏂囦歡榪斿洖HttpResponse鏃墮棶棰樻潵浜?jiǎn)锛屾諱笉鑷充簬璇誨彇鏁翠釜鏂囦歡錛岀劧鍚庡啀return銆?br /> 榪欑鏂瑰紡鍦╬hp鏈塮lush鏂規(guī)硶錛宲ython鍙兘鐢▂ield鏉ュ仛
2.涓婁紶澶ф枃浠舵椂鐨勫鐞?br /> 褰撴帴鏀跺埌http鐨勬枃浠禤OST璇鋒眰鏃訛紝鏂囦歡宸茬粡鍏ㄩ儴緙撳瓨鍒皐eb鏈嶅姟鍣紝濡傛灉鍚屾椂鍑犲崈涓枃浠朵笂浼犲湪榪涜錛屾湇鍔″櫒灝變細(xì)琚尋鐖嗭紝榪欎篃鏄緢澶氱綉绔欎笉鍏佽澶ф枃浠朵笂浼犵殑緙樻晠鍚с傚叧浜庤繖涓棶棰橈紝鎴戞兂灝遍渶瑕佷慨鏀逛竴涓媤ebpy鍏充簬鏂囦歡涓婁紶鐨勫鐞嗕唬鐮佷簡(jiǎn)錛屽皢鎺ユ敹鍒扮殑鏂囦歡鏁版嵁浠ユ祦鐨勫艦寮忓啓鍏ュ埌gridfs閲屽幓浣滀負(fù)涓存椂鏂囦歡琚紦瀛橈紝絳夊畬鍏ㄦ帴鏀舵枃浠舵椂錛屾墠閫氱煡鍒癶andler浠g爜錛岃繖鏍峰繀瀹氶珮鏁堝緢澶?鏂扮殑闂鍙堟潵浜?jiǎn)锛屼細(xì)涓嶄細(xì)鎶奼ridfs鎼炵垎鎺? 澶勭悊鏃惰冭檻寤舵椂緙撳瓨鎻愪氦gridfs鎶?銆?br />
class download:
def GET(self):
file_name = 'file_name'
file_path = os.path.join('file_path', file_name)
f = None
try:
f = open(file_path, "rb")
webpy.header('Content-Type','application/octet-stream')
webpy.header('Content-disposition', 'attachment; filename=%s.dat' % file_name)
while True:
c = f.read(BUF_SIZE)
if c:
yield c
else:
break
except Exception, e:
print e
yield 'Error'
finally:
if f:
f.close()
links:
銆
]]>
嫻嬭瘯gevent妯″紡銆佷覆琛屾煡璇€佸綰跨▼鏌ヨ
鏁版嵁濡備笅錛?nbsp;
嫻嬭瘯浠g爜:
2 import gevent.queue
3
4 import psycopg2
5 import psycopg2.extensions
6
7 import psycogreen.gevent
8
9 psycogreen.gevent.patch_psycopg()
10
11 sys.path.insert(0,'../')
12
13 import easymq
14
15 '''
16 鍦ㄥ悓涓綰跨▼涓紝鍚屼竴涓繛鎺onn涓婁袱嬈″垱寤虹殑cur灝嗕細(xì)鏄竴鏍鋒淮錛屽洜涓烘槸寮傛wait_read()緙樻晠
17 鎵浠ヨ涔堟瘡嬈″垱寤烘暟鎹簱榪炴帴錛岃涔堜嬌鐢╠bpool
18 '''
19
20
21 def readThread():
22 conn = psycopg2.connect(database='postgres',user='postgres',password='111111')
23
24 # cur = conn.cursor(cursor_factory=psycopg2.extensions.DictCursor)
25 cur = conn.cursor(cursor_factory=psycopg2.extensions.cursor)
26
27 # cur.execute("select pg_sleep(%s)", (2,))
28 for n in range(10):
29 cur.execute("select CURRENT_DATE")
30 # print cur.fetchone()
31 # print 'read end..'
32 conn = None
33
34
35 def gevent_test():
36 jobs=[]
37 for n in range(100):
38 jobs.append(gevent.spawn(readThread))
39 gevent.joinall(jobs)
40
41 def normal_test():
42 for n in range(100):
43 readThread()
44
45 def multithread_test():
46 threads=[]
47 for n in range(100):
48 thread = threading.Thread(target=readThread)
49 threads.append(thread)
50 thread.start()
51 for thread in threads:
52 thread.join()
53
54 start = time.time()
55 normal_test()
56 end = time.time()
57 print 'normal_test cost time:',end-start
58
59 start = time.time()
60 gevent_test()
61 end = time.time()
62 print 'gevent_test cost time:',end-start
63
64 # start = time.time()
65 # multithread_test()
66 # end = time.time()
67 # print 'multithread_test cost time:',end-start
68
]]>
浣滀負(fù)縐誨姩搴旂敤騫沖彴錛屾搗閲忓茍鍙戝拰楂樻晥浼犺緭鏄瑕佽冭檻瑕佺偣銆?br />甯?jìng)闈笂鍏呭肩潃閮藉樊涓嶅鐨勮В鍐蟲妧鏈柟妗堬紝鏃犻潪閭d簺
webserver+db
ngnix+webserver+mq+logic-server
ngnix+gevent-wsgi+db
webapi宸茬粡琚珮涓懼埌涓嶅彲瓚呰秺鐨勫湴姝?br />
鑰屾垜錛屼笉璧板甯歌礬錛屾垜寰楀彟杈熸嵎寰?br />-http鐨勬晥鐜囨牴鏈棤娉曡窡socket鐨勯暱榪炴帴濯茬編
-鏈嶅姟鍣ㄦ槸闇瑕佸弽鍚戞帹閫佹秷鎭埌縐誨姩璁懼鐨?br />-鎿嶄綔鎺ュ彛鏄畝鍗曠殑鏄撴墿灞曠殑錛屽睆钄芥帀閫氫俊緇嗚妭
-鏀寔htm5鐨剋ebsocket錛屾敮鎸乯ava錛屾敮鎸乸ython錛屾敮鎸乸ython瀹㈡埛绔皟鐢?br />
閭f垜鐨勬柟妗堟槸tce涓哄熀紜鐨凴PC妗嗘灦騫沖彴錛屾姏寮冮偅浜泋mls錛宩son錛岃寮鍙戣呬粠鏃犲敖鐨勭綉緇滅紪瑙g爜宸ヤ綔涓劚紱誨嚭鏉ワ紝涓嶇敤鑰冭檻澶氱閫氫俊妯″紡錛屽悓姝ュ拰寮傛銆?br />font-gate : 鍓嶇鎺ュ叆鏈嶅姟鍣?br />easymq : 騫沖彴鏈嶅姟鎬葷嚎娑堟伅闃熷垪
logic-service 錛?涓嶅悓鐨勯昏緫鏈嶅姟鍣?br />
璁炬兂錛屽湪android鎵嬫満涓妀ava浠g爜璋冪敤鍑芥暟 whats_yourname(), 榪欎釜鍑芥暟騫朵笉鍦ㄦ湰鍦幫紝鑰屾槸瀛樺湪榪滅騫沖彴鍐呴儴鐨勪竴涓湇鍔″櫒涓?璋冪敤騫惰鎵ц榪斿洖'scott'鍒版墜鏈虹粓绔紝榪欐槸澶氫箞浠や漢蹇箰鐨勪簨鎯咃紝鐢ㄦ埛涓嶇敤鍏沖績(jī)娑堟伅濡備綍琚垪闆嗭紝濡備綍琚垎媧撅紝榪欎竴鍒囬兘鏄忔槑鐨勩?br />鍚屾牱錛屾湇鍔″櫒涓誨姩鎺ㄩ佸晢鍝佹墦鎶樹俊鎭埌鎵嬫満涓婏紝鏈嶅姟鍣ㄤ粎浠呴渶瑕佽皟鐢ㄦ墜鏈烘帴鏀跺嚱鏁幫紝騫跺~鍐欒浼犺緭鐨勫弬鏁板嵆鍙?br />鍏跺疄錛岃繖浜涘氨鏄疪PC鐨勫疄鐜幫紝榪欐牱鐨勪笢涓滃埌澶勯兘鏄?DCOM錛孋ORBA錛孖CE錛屽彧鏄垜鍋氬緱鏇村姞鐏墊椿
鎬繪槸鎯沖仛浜涗護(hù)浜鴻交鏉懼茍蹇箰鐨勪簨鎯咃紒
]]>
榪欑瘒鍗氭枃璁茬殑闈炲父娓呮錛屽緩璁涓涓?nbsp;
gevent鐨勭壒鐐瑰涓嬶細(xì)
1. 鍗曠嚎紼嬫墽琛岋紝鎵鏈夊崗紼嬮兘鍦ㄥ悓涓榪涚▼涓妯℃嫙鍜岃皟搴﹀垎媧?br /> 2. 鍙互鍒涘緩鎴愬崈涓婁竾鐨?鍗忕▼錛岃屼笉浼?xì)鍙椾恢M綍鎬ц兘褰卞搷
3. 鐢變簬spawn鐨勫崗紼嬩笉鏄痮s鍒嗛厤鍜岀鐞嗭紝鎵浠ヤ笉浼?xì)鏈夐澶栫殑绾拷E嬭祫婧愬垎閰嶏紝cpu涔熶笉鐢ㄥ湪榪欎簺綰跨▼涔嬮棿璋冨害鍒囨崲
4. 鍗曠嚎紼嬫墽琛岋紝鏃犻渶鑰冭檻璧勬簮浜掓枼
5. 鍗忕▼涔嬮棿鍒囨崲鏄氳繃gevent鐨刬o闃誨瀹屾垚錛屼緥濡?gevent.sleep(0), queue.get/put,event,socket....
姣忚皟鐢ㄤ竴嬈event 鐨刟pi錛実event灝辮兘鑾峰緱涓嬈chedule鐨勬満浼?榪欏緢綾諱技鎿嶄綔緋葷粺鐨勭敤鎴瘋皟鐢ㄤ腑鏂紝鐢辯敤鎴鋒佸垏鎹㈠埌鍐呮牳鎬?
浠ヤ笂鐗圭偣淇濊瘉gevent鐨勬ц兘闈炲父鍑鴻壊錛屼絾褰撴垜浠殑server鐢ㄥ埌絎笁鏂硅蔣浠跺寘鐨勬椂鍊欓偅瑕侀潪甯稿皬蹇?jī)浜?jiǎn)錛岀壒鍒槸榪欎簺鍖呭唴閮ㄦ秹鍙?qiáng)浜?jiǎn)io鎿嶄綔銆?br />濡傛灉絎笁鏂硅蔣浠跺寘鏄函python鐨勯偅寰堢畝鍗曪紝鍙渶瑕乬event.monkey_patch(xxx)灝眔kay錛?浣嗗鏋滃寘鏄墿灞昪lib,閭h褰撳績(jī)浜?jiǎn)锛宮onkey_patch
騫朵笉鑳藉皢鍏剁浉鍏砳o鎿嶄綔鎵撲笂琛ヤ竵錛屼負(fù)浜?jiǎn)鋴社敤杩欎簺绗笁鏂硅蒋錃g鍖咃紝瑕佹眰榪欎簺杞歡鍖呭繀欏繪敮鎸?鍗忕▼寮傛 鎺ュ彛(璋冪敤鍏跺悓姝o鎺ュ彛錛屽皢闃誨浣廹event鐨勬墽琛岀嚎紼嬶紝閭event灝卞畬铔嬩簡(jiǎn))銆?br />gevent鐨刾atch瀵筽sycopg2鏃犳晥錛屽洜涓簆sycopg2鐨勯氫俊閮ㄥ垎鏄痗鎺ュ彛鐨勫嚱鏁板簱錛岃繕濂絧sycopg2鍐呴儴鏀寔鍗忕▼錛岄渶瑕佷嬌鐢?鍒?nbsp;psycogreen 榪欎釜涓滀笢
涔嬪悗鐨勫湪gevent鐨勭嚎紼嬩腑鎵цsql騫剁瓑寰呮暟鎹繑鍥炴椂錛実event绔嬮┈灝嗘墽琛屽垏鎹㈠埌鍙﹀鐨勭嚎紼?br />
gvent欏圭洰涓細(xì)鐢ㄥ埌鍚勭璇稿鐨勭涓夋柟搴擄紝蹇呴』瑕佹眰榪欎簺搴撶殑io鎺ュ彛涓嶈兘鏄樆濉炵殑錛屼篃灝辨槸鑳芥敮鎸佸埌gevent寮傛妯″紡
搴旂敤閫昏緫浠g爜鍦ㄨ鎵ц鏃?鏃犵郴緇焌pi鍛煎彨)錛屽崟綰跨▼姣斿綰跨▼鎵ц閫熷害鏇村揩銆傚驚鐜墽琛屼竴孌佃綆椾簩嬈″嚱鏁頒唬鐮侊紝鐢變簬鏈熼棿娌℃湁緋葷粺api璋冪敤錛宱s涓嶈兘榪涜鍐呮牳tasklet鍒囨崲錛屾墍浠ュ鑷碿pu鐨勫嘲鍊煎彲浠ユ攢鍗囧埌90%錛岀洿鍒扮‖浠躲佹椂閽熺瓑涓柇浜х敓錛屽己琛屽垏鎹㈠埌鍏朵粬綰跨▼銆?澶氭牳蹇?jī)cpu琛ㄧ幇涓哄崟涓牳濮嬬粓寮傚父鐨勫繖紕岋紝鍏朵粬鍑犱釜姣旇緝絀洪棽銆?nbsp;
]]>
鎵鏈夐槦鍒楃被鍨嬮兘鏄畨鍏ㄧ殑(synchronized queue) ,鏁版嵁鎺ㄥ叆鍜屾彁鍙栨棤闇璁塊棶淇濇姢
LifoQueue - 鍚庤繘鍏堝嚭闃熷垪錛屽悓鏁版嵁鍫嗘爤緇撴瀯
JoinableQueue - 澧炲姞join錛屾墍鏈夋暟鎹彁鍙栧畬姣昷oin瑙i櫎闃誨
PriorityQueue - 浼樺厛綰ч槦鍒楋紝鎻愬彇鏍規(guī)嵁緗叆鏃剁殑浼樺厛綰у埆
Queue - 瓚呯被娑堟伅闃熷垪錛屾彁渚涘悓姝ユ暟鎹疆鍏ュ拰鎻愬彇鍔熻兘錛屽叾浠栭槦鍒楀潎浠嶲ueue媧劇敓
]]>
2 def __init__(self):
3 self.mtx = threading.Condition()
4 self.d = None
5
6 def waitObject(self,timeout):
7 d = None
8 self.mtx.acquire()
9 if self.d == None:
10 if timeout:
11 self.mtx.wait(timeout)
12 else:
13 self.mtx.wait()
14 d = self.d
15 self.d = None
16 self.mtx.release()
17 return d
18
19 def notify(self,d):
20 self.mtx.acquire()
21 self.d = d
22 self.mtx.notify()
23 self.mtx.release()
]]>