摘要:在十二贊的深度應(yīng)用我們是十二贊,一個(gè)致力于幫助電商賣(mài)家進(jìn)入小程序的小團(tuán)隊(duì),我們的主頁(yè)是。我們的整個(gè)業(yè)務(wù)構(gòu)建于阿里云之上,有臺(tái)每一對(duì)都有獨(dú)立的外網(wǎng)同時(shí)也在同一個(gè)內(nèi)網(wǎng)之中。,我們把所有的文件都挪到阿里云的服務(wù)上。當(dāng)然,也是可執(zhí)行文件發(fā)布的。
Golang 在十二贊的深度應(yīng)用
我們是“十二贊”,一個(gè)致力于幫助電商賣(mài)家進(jìn)入小程序的小團(tuán)隊(duì),我們的主頁(yè)是http://www.12zan.cn/。在實(shí)際運(yùn)行中,我們使用了大量由golang寫(xiě)就的小工具,幾乎每一個(gè)工具代碼量都超短,一般在200行左右就完成了一個(gè)獨(dú)立的功能,同時(shí)擔(dān)當(dāng)了相當(dāng)重要的角色;像代理服務(wù)器,代碼量一共500行多一點(diǎn)點(diǎn),卻是我們的核心支柱,壓測(cè)時(shí)QPS也直追nginx,表現(xiàn)優(yōu)異。
基于Docker的基礎(chǔ)結(jié)構(gòu)
做為基礎(chǔ)架構(gòu),我介紹一下我們的機(jī)器架構(gòu)。
我們的整個(gè)業(yè)務(wù)構(gòu)建于阿里云之上,有5臺(tái)server,每一對(duì)都有獨(dú)立的外網(wǎng)IP,同時(shí)也在同一個(gè)內(nèi)網(wǎng)之中。在每一臺(tái)機(jī)器上都跑了一個(gè)我們自己用golang寫(xiě)的守護(hù)進(jìn)程,這個(gè)進(jìn)程負(fù)責(zé)監(jiān)聽(tīng)一些業(yè)務(wù)重啟、新增域名等類(lèi)似的指令并執(zhí)行(這些指令最后都傳遞給了docker)。同時(shí),每臺(tái)機(jī)器上都有一個(gè)consul進(jìn)程,這些consul都join到了一起。另外,我們每一臺(tái)機(jī)器上,都用docker跑了一個(gè)nginx來(lái)做80端口的服務(wù),同時(shí)跑了一個(gè)用golang自己寫(xiě)的HTTP代理。nginx做做日志啊基礎(chǔ)的功能之后就把請(qǐng)求丟給這個(gè)http代理 ,HTTP代理會(huì)到consul里去查應(yīng)該將請(qǐng)求轉(zhuǎn)發(fā)到哪個(gè)IP的哪個(gè)端口上。
400行Golang代碼寫(xiě)的HTTP Proxy
在架構(gòu)選型的第一天,我們就決定,我們會(huì)服務(wù)化,會(huì)大量使用http 接口來(lái)提供服務(wù),并使用自己的http proxy來(lái)分發(fā)請(qǐng)求、添加自有的一些業(yè)務(wù)邏輯比如API的權(quán)限驗(yàn)證等邏輯。我們限定,所有業(yè)務(wù),域名都是*.app.12zan.net,比如我們要上一個(gè)聊天服務(wù),請(qǐng)求的接口就會(huì)是chat.app.12zan.net,哪天再上個(gè)評(píng)論服務(wù),請(qǐng)求的接口就是comment.app.12zan.net。
確定域名后我第一件事情,就是拿golang自己寫(xiě)了一個(gè)非常簡(jiǎn)單的基于consul的http proxy server;感謝Golang這完善的HTTP庫(kù),我們只用了幾百行代碼就完成了所有功能。每當(dāng)有http請(qǐng)求過(guò)來(lái)時(shí),這個(gè)proxy server就會(huì)根據(jù)HTTP請(qǐng)求中HTTP_HOST 字段去consul去查,有哪些后端是用這個(gè)域名名稱(chēng)來(lái)注冊(cè)服務(wù)的,并根據(jù)指定的算法,取出一臺(tái)后端來(lái),把這個(gè)HTTP請(qǐng)求Proxy過(guò)去。每個(gè)具體的業(yè)務(wù),可能運(yùn)行在我們5臺(tái)機(jī)器中的任何一臺(tái)之中的docker上,也可能是多個(gè)docker實(shí)例上。所以這里有一個(gè)機(jī)制,選擇哪個(gè)實(shí)際的docker實(shí)例來(lái)服務(wù)這個(gè)請(qǐng)求的問(wèn)題。我們現(xiàn)在支持隨機(jī)選取、按客戶(hù)端IP地址做hash之后選取、按URL做Hash選取、按負(fù)載選取幾種方式。
WEB服務(wù)的服務(wù)注冊(cè)
基于php+laralel和nodejs+koajs兩種場(chǎng)景,我們制作了自己的docker鏡像。這個(gè)鏡像除開(kāi)可以將php+nginx和nodejs構(gòu)建的web服務(wù)運(yùn)行起來(lái)之外,還包含一個(gè)golang寫(xiě)的consul客戶(hù)端。在docker容器里,這個(gè)客戶(hù)端隨著php+nginx或是nodejs的web服務(wù)一起啟動(dòng),啟動(dòng)之后會(huì)向宿主機(jī)的consul 進(jìn)程注冊(cè)自己這個(gè)服務(wù),注冊(cè)的時(shí)候會(huì)通知說(shuō),某某應(yīng)用,在某某IP某某端口提供服務(wù)啦,如果前面有到**.app.12zan.net的請(qǐng)求你可以轉(zhuǎn)發(fā)給我;同時(shí)會(huì)每隔一秒上報(bào)自己的進(jìn)程數(shù)、當(dāng)前機(jī)器CPU占用、內(nèi)存占用情況。也是一樣的簡(jiǎn)單,幾百行g(shù)olang代碼,就鼓搗出了這個(gè)consul客戶(hù)端。為什么使用golang呢?第一個(gè)原因當(dāng)然是因?yàn)閏onsul天生是golang陣營(yíng),第二個(gè),是因?yàn)槲覀兊膁ocker容器種類(lèi)較多,所以這個(gè)客戶(hù)端直接就是在Mac上跨平臺(tái)編譯出來(lái)的在linux64平臺(tái)上運(yùn)行的,不管docker容器是python為基準(zhǔn)的還是ruby為基準(zhǔn)的,還是nodejs的,只要把這個(gè)二進(jìn)制文件拷貝進(jìn)去就能正確運(yùn)行,不像別的語(yǔ)言需要解決依賴(lài)問(wèn)題。
我們還開(kāi)發(fā)了一個(gè)web console界面,在這里,我們可以注冊(cè)app,也可以為app新增實(shí)例。注冊(cè)app時(shí),我們要指定代碼倉(cāng)庫(kù)的地址(對(duì)了,我們的代碼管理是用的golang寫(xiě)的gogs),指定對(duì)外服務(wù)的域名,指定是nodejs應(yīng)用還是php+laravel應(yīng)用。添加應(yīng)用之后,可以在這個(gè)應(yīng)用下新建實(shí)例,讓系統(tǒng)在指定的IP上去跑這個(gè)實(shí)例。實(shí)例運(yùn)行的過(guò)程實(shí)際就是下發(fā)一個(gè)通知到某個(gè)機(jī)器上,去執(zhí)行一個(gè)docker實(shí)例啟動(dòng)的過(guò)程。docker啟動(dòng)的時(shí)候帶了一些環(huán)境變量,比如當(dāng)前內(nèi)網(wǎng)IP、docker監(jiān)聽(tīng)的端口、對(duì)外提供服務(wù)時(shí)是用何域名提供服務(wù)。
日志和存儲(chǔ)
前面這種架構(gòu)有一個(gè)問(wèn)題,就是后端可能是在任何一臺(tái)機(jī)器上運(yùn)行的,今天可能是A,明天可能是B,那我要是把文件存在A上了是不是讓B來(lái)提供服務(wù)的時(shí)候就掛掉了?所以我們想了這么一個(gè)辦法(也是因?yàn)楦F。。。。),我們把所有的文件都挪到阿里云的OSS服務(wù)上。同時(shí)為了不管是Nodejs應(yīng)用還是php應(yīng)用 還是python寫(xiě)的應(yīng)用都能做到把用戶(hù)上傳的文件或是系統(tǒng)生成的文件存到oss上面,我們很省事地寫(xiě)了一個(gè)ossUploader,編譯好的可執(zhí)行文件發(fā)布,只需要執(zhí)行它,傳進(jìn)來(lái)本地路徑和oss上的目標(biāo)路徑,就保證給你上傳到oss上去就完整,不需要再在nodejs、php、python、ruby、java各種平臺(tái)下都琢磨一遍oss的SDK。
對(duì)日志的處理是一樣的, 所有的日志文件的內(nèi)容,都會(huì)被一個(gè)golang寫(xiě)的工具gtail監(jiān)聽(tīng)著(就像linux 的tail -f命令一樣),所有新產(chǎn)生的內(nèi)容都會(huì)被gtail挪到oss上去存儲(chǔ)。當(dāng)然,也是可執(zhí)行文件發(fā)布的。
這個(gè)實(shí)現(xiàn)之后, 我們的實(shí)際業(yè)務(wù)就真正可以在5臺(tái)機(jī)器上之間任意騰挪了。
消息廣播
得益于golang的一些開(kāi)源倉(cāng)庫(kù),我們還做了一些好玩的東西。
比如,看到https://github.com/gorilla/we...,我們?nèi)滩蛔]了一個(gè)websocket server,或是說(shuō)叫群聊服務(wù)器更好一點(diǎn)。
接下來(lái),我們看到有一個(gè)golang的庫(kù)叫g(shù)o-mysql-elasticsearch,偽裝了一個(gè)mysql的slave,去MySQL的master機(jī)器上去讀binlog,讀到binlog以后就將MySQL里的數(shù)據(jù)發(fā)送給ElasticSearch去索引數(shù)據(jù)。
我們就結(jié)合了一個(gè),把這兩個(gè)結(jié)合起來(lái),修改了一下go-mysql-elastichsearch,讓它監(jiān)聽(tīng)到MySQL的數(shù)據(jù)變更之后,在WebSocket server的某個(gè)群聊里推送出來(lái),形成一個(gè)數(shù)據(jù)變更的廣播。
再接下來(lái)我們就可以用nodejs寫(xiě)一個(gè)應(yīng)用,連上這個(gè)websocket server,加入特定的某個(gè)群聊,就源源不斷地收聽(tīng)到數(shù)據(jù)變更的消息。這個(gè)nodejs端的代碼就非常簡(jiǎn)潔了,只需要不到100行代碼可以做各種好玩的事情,比如監(jiān)聽(tīng)到用戶(hù)留言表有新增,可以發(fā)郵件讓運(yùn)營(yíng)馬上去審核。還有比如說(shuō),每當(dāng)訂單表有成交的時(shí)候,我們某個(gè)小小的nodejs應(yīng)用因?yàn)楸O(jiān)聽(tīng)了數(shù)據(jù)庫(kù)消息,第一時(shí)間就知道了,馬上就去追溯用戶(hù)來(lái)源,來(lái)計(jì)算返利;同時(shí)這個(gè)nodejs的代碼更新是和訂單主邏輯完全不相關(guān)的,寫(xiě)這個(gè)業(yè)務(wù)的開(kāi)發(fā)人員只需要知道訂單表的結(jié)構(gòu),不需要了解訂單應(yīng)用后臺(tái)代碼。
【原文鏈接】
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/27553.html
摘要:原文地址優(yōu)化配置結(jié)構(gòu)及實(shí)現(xiàn)圖片上傳項(xiàng)目地址如果對(duì)你有所幫助,歡迎點(diǎn)個(gè) 原文地址:優(yōu)化配置結(jié)構(gòu)及實(shí)現(xiàn)圖片上傳項(xiàng)目地址:https://github.com/EDDYCJY/go... 如果對(duì)你有所幫助,歡迎點(diǎn)個(gè) Star
摘要:在本次上,京東云將在大會(huì)上為對(duì)云原生感興趣的研發(fā)和運(yùn)維人員帶來(lái)利用延遲加載快速啟動(dòng)容器的話(huà)題分享。今天聊的主角云原生也是一樣。 showImg(https://segmentfault.com/img/bVbtNqp?w=688&h=113); showImg(https://segmentfault.com/img/bVbtQaR?w=684&h=327); showImg(http...
摘要:在本次上,京東云將在大會(huì)上為對(duì)云原生感興趣的研發(fā)和運(yùn)維人員帶來(lái)利用延遲加載快速啟動(dòng)容器的話(huà)題分享。今天聊的主角云原生也是一樣。 showImg(https://segmentfault.com/img/bVbtNqp?w=688&h=113); showImg(https://segmentfault.com/img/bVbtQaR?w=684&h=327); showImg(http...
摘要:語(yǔ)言的生日年前的今天,語(yǔ)言以開(kāi)源方式向全球發(fā)布簡(jiǎn)介語(yǔ)言又稱(chēng),是谷歌開(kāi)發(fā)的一種靜態(tài)強(qiáng)類(lèi)型編譯型并發(fā)型,并具有垃圾回收功能的編程語(yǔ)言。語(yǔ)言有時(shí)被描述為類(lèi)似語(yǔ)言,或者是世紀(jì)的語(yǔ)言。語(yǔ)言有一個(gè)清晰易懂的輕量級(jí)類(lèi)型系統(tǒng),在類(lèi)型之間也沒(méi)有層級(jí)之說(shuō)。 Go語(yǔ)言的生日 12年前的今天→ 2009.11.10...
閱讀 3596·2023-04-26 02:24
閱讀 931·2023-04-25 14:47
閱讀 2478·2021-11-24 11:16
閱讀 1711·2021-11-24 09:38
閱讀 1571·2021-11-18 10:07
閱讀 2061·2021-09-22 15:49
閱讀 1589·2019-08-30 15:55
閱讀 875·2019-08-26 13:38