初次使用golang和mongodb開發(fā)一個(gè)完整產(chǎn)品的一些筆記

緣起

幾個(gè)同行相約用業(yè)余時(shí)間開發(fā)一款社交應(yīng)用,客戶端就是微信公眾號(hào)H5,因?yàn)槭莻€(gè)人項(xiàng)目,我就不太想用自己擅長(zhǎng)的C++了,麻煩不說(shuō),寫起來(lái)也挺沒趣,之前斷斷續(xù)續(xù)也用golang寫了幾個(gè)服務(wù),覺得很適合用來(lái)寫后臺(tái),于是技術(shù)選型就敲定golang啦.
考慮到最好需要業(yè)務(wù)中用戶之間并無(wú)太多交集,用非關(guān)系型的nosql數(shù)據(jù)庫(kù)開發(fā)效率更高,在redis和mongodb之間猶豫了許久,最終選了mongodb,原因無(wú)他,redis實(shí)在是太熟悉,對(duì)這東西沒啥興趣了,而且redis純內(nèi)存對(duì)服務(wù)器成本要求也太大,萬(wàn)一到時(shí)候用戶量上去沒有日活,我redis開著吃那么多內(nèi)存浪費(fèi)錢嘛.所以就選了mongodb.

需求

產(chǎn)品需求大概就是提供一個(gè)看別人發(fā)的信息,同時(shí)可以領(lǐng)取紅包的功能
對(duì)于發(fā)送信息方,付出少量的金錢可以使自己的信息得到傳播,比如房屋招租, 尋狗啟事等
對(duì)于接收信息方,查閱信息即可以瓜分到現(xiàn)金,如果幫助傳播,則自己的份額+1,可以獲得更多的現(xiàn)金
盈利模式就是在用戶提現(xiàn)時(shí)收取幾個(gè)點(diǎn)的手續(xù)費(fèi).

任務(wù)拆分

根據(jù)以上需求,可以大概預(yù)算到,這樣一個(gè)項(xiàng)目后臺(tái)的核心功能
1.用戶體系
2.微信支付以及提現(xiàn)
3.便簽核心能力
4.用戶錢包,維護(hù)用戶余額

用戶體系

1.新用戶進(jìn)入自動(dòng)注冊(cè)和登錄
2.老用戶進(jìn)入自動(dòng)登錄
3.提供gin中間件,給每個(gè)登錄態(tài)接口鑒權(quán),檢查用戶登錄態(tài)是否有效

微信支付以及提現(xiàn)

  1. 用戶發(fā)布紅包便簽時(shí)提供微信支付功能
  2. 用戶通過(guò)查看便簽獲得的紅包,在存入余額后申請(qǐng)?zhí)岈F(xiàn),可以通過(guò)企業(yè)紅包成功提現(xiàn)到自己的微信號(hào)上
  3. 提現(xiàn)功能因?yàn)樾枰褂米C書,而微信官方并沒有提供golang的sdk, 所以借助于python實(shí)現(xiàn),通過(guò)celery任務(wù)管理框架和golang進(jìn)行通信

便簽核心能力

  1. 提供管理用戶便簽的能力,具體如下
  2. 發(fā)布便簽,先發(fā)布一個(gè)便簽,狀態(tài)設(shè)置為未支付,對(duì)未支付便簽進(jìn)行限制,不允許通過(guò)關(guān)注未支付便簽瓜分紅包和分享. 使用微信統(tǒng)一下單,獲取支付參數(shù)下發(fā)給前端,前端通過(guò)支付參數(shù)包調(diào)起微信支付,支付成功后收到回調(diào),回調(diào)中把便簽支付狀態(tài)修改為已支付,完成整個(gè)發(fā)布流程.
  3. 訂閱便簽,用戶通過(guò)訂閱和查看其他人發(fā)布的便簽獲得紅包瓜分份額,自己訂閱份額+1,分享出去后別人通過(guò)你的分享進(jìn)來(lái)便簽頁(yè),自己的訂閱份額也+1.
  4. 瓜分紅包,當(dāng)某個(gè)便簽的到達(dá)指定時(shí)間點(diǎn)后,用戶可以根據(jù)自己的份額進(jìn)行瓜分,瓜分到的現(xiàn)金存入余額.

用戶錢包,維護(hù)用戶余額

  1. 提供取現(xiàn)功能和存入余額功能
  2. 提現(xiàn)功能注意處理數(shù)據(jù)一致性,不能讓用戶通過(guò)并發(fā)手段把一份錢取多次,這里借助了mongodb的findAndModify功能,并發(fā)去寫入一個(gè)flag,最終寫入成功的只有一個(gè),只有寫成功的線程才可以繼續(xù)執(zhí)行下面的提現(xiàn)操作.
  3. 存入余額這里也需要注意數(shù)據(jù)一致性,不能讓用戶通過(guò)并發(fā)手段把一個(gè)紅包應(yīng)該分得的錢多次存入余額,這里借助了mongodb的findAndModify功能,并發(fā)去寫入一個(gè)flag,最終寫成功的只有一個(gè),只有寫成功的線程才可以繼續(xù)執(zhí)行下面的存入余額操作.

項(xiàng)目結(jié)構(gòu):

├── Authorize   //用戶認(rèn)證,包括用戶登錄,登陸后token鑒權(quán)
├── CeleryTasks  //Celery腳本, 用于訪問(wèn)微信api和海報(bào)生成
├── CeleryWrapper  //go訪問(wèn)celery的wrapper
├── cert  //微信證書
├── Common  //公共代碼,很多地方需要使用的公共函數(shù)放在這里,如從頭中獲取userId,生成一個(gè)新的userId,獲取一個(gè)mongodb的session等
├── config   //配置文件,如微信支付的相關(guān)配置,mongodb地址的配置等
├── ConfigManager  //配置管理器,用于在任何地方都可以方便的讀取配置
├── ErrorCodes   //錯(cuò)誤碼定義
├── Handlers   //消息處理代碼
├── ImageProcessor   //圖片處理器,因?yàn)楹?bào)生成部分最后使用celery配合wkhtmltopdf把html轉(zhuǎn)圖片,所以這部分代碼廢棄
├── Logger  //日志相關(guān)代碼,日志打印使用了logrus庫(kù),這里把logrus包裝成一個(gè)middleware和gin框架結(jié)合使用,最終的目的是讓gin框架把請(qǐng)求和回包日志用logrus打印出來(lái)
├── NoteManager  //便簽管理,和便簽相關(guān)的代碼都在這里面
├── Pay     //支付相關(guān)
│   └── WechatPay   //目前只支持微信支付,和微信支付相關(guān)的代碼都在這里
├── Resources   //圖片等靜態(tài)資源
└── UserManager   //用戶管理,和用戶相關(guān)的代碼都在這里

一些隨想

  1. 通過(guò)開發(fā)這個(gè)項(xiàng)目,讓自己對(duì)golang有一個(gè)比較全面的了解,熟悉了golang代碼的組織形式,第三方庫(kù)的路徑之類的golang開發(fā)環(huán)境特有的一些問(wèn)題
  2. golang嚴(yán)格定義了一些其他語(yǔ)言里面靈活的東西,比如括號(hào)問(wèn)題,函數(shù)的開始括號(hào)一定要在函數(shù)聲明的第一行,這一點(diǎn)我覺得很贊,其實(shí)很多東西不太需要自由,方案a也行b也行,但是如果沒人拍板就會(huì)制造混亂,如果硬性規(guī)定統(tǒng)一一下就很好.
  3. golang的警告不完全消除就不允許編譯通過(guò),這個(gè)特性我看到的時(shí)候心里默默點(diǎn)了個(gè)贊,但是開發(fā)完一套程序就想說(shuō)mmp了,很多時(shí)候?qū)憸y(cè)試代碼時(shí),經(jīng)常會(huì)屏蔽某些代碼,就會(huì)導(dǎo)致notused的warnning,然后導(dǎo)致程序無(wú)法編譯通過(guò),只有把聲明變量或者import的語(yǔ)句注釋掉才可以編譯過(guò),很難受.
  4. golang的代碼風(fēng)格是使用返回值來(lái)返回錯(cuò)誤碼, 因?yàn)間olang支持多返回值,所以通常第一個(gè)返回值表示真正要返回的數(shù)據(jù),第二個(gè)返回值表示錯(cuò)誤碼, 這個(gè)會(huì)導(dǎo)致錯(cuò)誤處理的代碼冗余,如果層級(jí)調(diào)用過(guò)深,每個(gè)層級(jí)都需要處理很多錯(cuò)誤碼.但是好處是編寫代碼的時(shí)候會(huì)自覺的處理好能想到的異常情況
  5. golang弱化了面向?qū)ο蟮母拍?其實(shí)我覺得面向?qū)ο笤趲啄昵昂芑?但是很多中小型項(xiàng)目基本上用不到,所以弄出什么單例模式,其實(shí)就是面向?qū)ο蟮耐嘶?golang可以允許函數(shù)單獨(dú)的存在,這一點(diǎn)我覺得非常贊.畢竟后臺(tái)開發(fā)更重要的是并發(fā)而不是所謂的模式.
  6. 從語(yǔ)言層面提供goroutine這種功能真的特別贊.有人說(shuō)C++也有協(xié)程(windows上叫纖程(Fiber)),這玩意其實(shí)不新鮮,2012年我們研發(fā)游戲時(shí)就用到過(guò),當(dāng)時(shí)沒有第三方庫(kù)可參考,都是自己手?jǐn)]代碼,后來(lái)在16年的時(shí)候看到騰訊出了一個(gè)libco,通過(guò)hook socket相關(guān)函數(shù)的方式無(wú)痛改造,把所有的socket操作都變成異步的. 我馬上把這個(gè)庫(kù)用在了當(dāng)時(shí)項(xiàng)目的thrift框架上, 記得當(dāng)時(shí)的成績(jī)是讓8核機(jī)器可以跑滿7個(gè)核, 比全同步只能跑滿4個(gè)核好了不少, 吞吐量也上去了, 但是費(fèi)了不少勁. 把thrift的線程池改造成了協(xié)程池. 所以用C++搞協(xié)程,要操心很多地方,主要是第三方庫(kù)不好改, 騰訊的libco算是另辟蹊徑了. golang的偉大之處是把這東西固化到語(yǔ)言里面,直接讓所有第三方庫(kù)全異步.
  7. golang作為最近幾年大火的語(yǔ)言,第三方庫(kù)卻始終跟不上,讓人很奇怪,比如mongodb這么多年了,竟然都沒有一個(gè)官方的drive, 最流行的mgo是一個(gè)第三方庫(kù).很多功能如果借助python實(shí)現(xiàn)會(huì)方便很多.這里不得不感慨python確實(shí)是開發(fā)效率很高的開發(fā)環(huán)境.
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末哈肖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子碉钠,更是在濱河造成了極大的恐慌跛璧,老刑警劉巖蹲堂,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡融虽,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門灼芭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)有额,“玉大人,你說(shuō)我怎么就攤上這事∽晃猓” “怎么了倒源?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)句狼。 經(jīng)常有香客問(wèn)我笋熬,道長(zhǎng),這世上最難降的妖魔是什么腻菇? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任胳螟,我火速辦了婚禮,結(jié)果婚禮上筹吐,老公的妹妹穿的比我還像新娘糖耸。我一直安慰自己,他們只是感情好丘薛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布嘉竟。 她就那樣靜靜地躺著,像睡著了一般洋侨。 火紅的嫁衣襯著肌膚如雪舍扰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天希坚,我揣著相機(jī)與錄音边苹,去河邊找鬼。 笑死裁僧,一個(gè)胖子當(dāng)著我的面吹牛个束,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播聊疲,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼茬底,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了售睹?” 一聲冷哼從身側(cè)響起桩警,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昌妹,沒想到半個(gè)月后捶枢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡飞崖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年烂叔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片固歪。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蒜鸡,死狀恐怖胯努,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情逢防,我是刑警寧澤叶沛,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站忘朝,受9級(jí)特大地震影響灰署,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜局嘁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一溉箕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧悦昵,春花似錦肴茄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至棋凳,卻和暖如春氓癌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贫橙。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留反粥,地道東北人卢肃。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像才顿,于是被迫代替她去往敵國(guó)和親莫湘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容