
題圖來(lái)自我在四月份借元代吳澄的《勉學(xué)吟》組詩(shī)中一句,再湊一句,做的一首小(shun)拙(kou)詩(shī)(liu)。當(dāng)時(shí)的我正處在一個(gè)挺糾結(jié)的狀態(tài)中,聊以此來(lái)給自己打氣。
轉(zhuǎn)眼又過(guò)了大半年,2016年的陽(yáng)歷陰歷都已落幕,在新年伊始再回頭看看這過(guò)去一年,真是特別有感觸。因?yàn)檫@一年過(guò)得可謂跌宕起伏精彩紛呈,所有努力的、新鮮的、憧憬的、不確定的、甚至是后悔的經(jīng)歷,到最后都?xì)w為充實(shí)的成長(zhǎng)。在這篇文章里我先數(shù)一數(shù)自己這一年在技術(shù)上的些許收獲。
年初

在2016年開(kāi)年之時(shí),我在數(shù)據(jù)組做游戲數(shù)據(jù)的撈取、計(jì)算和存儲(chǔ)等工程相關(guān)的東西,也做了一兩個(gè)報(bào)表網(wǎng)站的API。其中一個(gè)網(wǎng)站的API算是2015年末寫的吧,用了一些在當(dāng)時(shí)部門里比較沒(méi)人試過(guò)的東西,比如用OpenResty來(lái)異步化DB連接、動(dòng)態(tài)加載DB Model、和SA合作嘗試Docker部署之類的(萬(wàn)分感謝SA大大提供的Docker Swarm集群),現(xiàn)在看來(lái)挺有過(guò)度設(shè)計(jì)的嫌疑,一些配置也沒(méi)有達(dá)到最佳實(shí)踐,但是至少那個(gè)站在挺少的資源配給下,做到了還算不錯(cuò)的性能。
后來(lái)一個(gè)同事把這個(gè)網(wǎng)站前后端一口氣都接走了。老板們安排讓我把工作重心完全轉(zhuǎn)到用PySpark來(lái)做我們電商平臺(tái)的數(shù)據(jù)工程。就是在這段時(shí)間,我開(kāi)始接觸Spark上的RDD和Dataframe API。由于Spark的MapReduce編程范式要求,代碼里函數(shù)化的程度比之前的項(xiàng)目都高不少,尤其用了非常非常多的閉包來(lái)傳遞上下文,也算是比較少有的函數(shù)式編程練習(xí)機(jī)會(huì)了。
年中

要說(shuō)用Spark有什么遺憾的話,最大的應(yīng)該是當(dāng)時(shí)還沒(méi)來(lái)得及用上Luigi或者Airflow之類比較現(xiàn)代的pipeline管理工具,只是初步調(diào)研了一圈;另一個(gè)是當(dāng)時(shí)一直做著工程上的東西,沒(méi)有機(jī)會(huì)接觸分析和建模層面,就沒(méi)有怎么接觸到Spark的MLlib API。不過(guò)這個(gè)也不算太可惜,因?yàn)槲液髞?lái)被抓到了一個(gè)新部門,重點(diǎn)幫公司的大游戲做營(yíng)收優(yōu)化。于是我在Spark集群內(nèi)網(wǎng)里要到了一臺(tái)機(jī)子,搭了個(gè)Jupyter,在上面跑Pandas和Scikit-learn。在這個(gè)部門,我需要開(kāi)始短平快地用腳本從游戲數(shù)據(jù)生成報(bào)表,然后提供給運(yùn)營(yíng)組的同事做精確營(yíng)銷之類的準(zhǔn)定——需求服務(wù)面的專一性和時(shí)效性就決定了用Spark取出來(lái)的數(shù)據(jù)量小到一定程度時(shí),就可以盡量用一些抽象程度高的API和類庫(kù)來(lái)節(jié)省時(shí)間,不需要考慮計(jì)算過(guò)程的可擴(kuò)展性。
其實(shí)做報(bào)表吧,也不全是我工作所有內(nèi)容,平時(shí)還是有一些數(shù)據(jù)準(zhǔn)備工作是比較工程化的。在一些項(xiàng)目里,我們需要直接用Hadoop的接口操作HDFS,于是就用上了Scala——這也算是今年比較獨(dú)特的技術(shù)經(jīng)驗(yàn)了。關(guān)于對(duì)Scala的愛(ài)恨情仇,在另一篇博客里有比較詳細(xì)的描述,這里就不展開(kāi)了。
年末

年末是全年最開(kāi)心的階段,開(kāi)心到我都不知道要配什么圖好了……
我被最初招我進(jìn)公司的老板調(diào)回一開(kāi)始的部門,專心做游戲活動(dòng)宣傳網(wǎng)站及API。在此之前我雖然有很長(zhǎng)時(shí)間在這個(gè)部門里,但主要做的網(wǎng)站比較報(bào)表向,以內(nèi)部使用為主,項(xiàng)目比較注重?cái)?shù)據(jù)計(jì)算流程;現(xiàn)在在這個(gè)組里做面向外部玩家和用戶的網(wǎng)站,就更加注重網(wǎng)站外觀注重服務(wù)性能。
我們組里氣氛特別自由開(kāi)放,項(xiàng)目更新周期也短一些,很多想推進(jìn)的改動(dòng)都可以去嘗試,效果好的話,在新項(xiàng)目里推廣開(kāi)也是很快的事情。我們已經(jīng)順利地把很多活動(dòng)宣傳網(wǎng)站放到Docker上了,運(yùn)維就可以交給SA,不再需要自己去服務(wù)器里重啟,有性能需求的時(shí)候也可以隨時(shí)橫向擴(kuò)容;本地開(kāi)發(fā)環(huán)境的架設(shè)用docker-compose以后方便了很多,不再需要用一個(gè)專門的開(kāi)發(fā)虛擬機(jī)來(lái)為項(xiàng)目各種安裝依賴包各種改自己本地測(cè)試DB連接參數(shù)。新的項(xiàng)目到手時(shí)候還有一套挺順手的Cookiecutter模板來(lái)生成比較簡(jiǎn)潔的基本項(xiàng)目結(jié)構(gòu)。這些流程上的改變,希望都能讓組里筒子們?cè)陂_(kāi)發(fā)體驗(yàn)上有所提高吧。
這里插一段題(zhao)外(pin)話(tie):我能知道Cookiecutter這個(gè)工具還要感謝我們廠贊助了坡縣PyCon 2016,讓我能直接圍觀Python社區(qū)里的新鮮玩意。會(huì)上有兩個(gè)Keynote Speakers(Greenfeld夫婦)就是Cookiecutter的作者。如果沒(méi)有這次PyCon SG的參會(huì)經(jīng)驗(yàn),我們可能還得自己造輪子來(lái)準(zhǔn)備模板項(xiàng)目。喜歡在開(kāi)發(fā)社區(qū)交流學(xué)習(xí)的朋友想來(lái)我們廠的話,歡迎簡(jiǎn)信上找我喲。
再回到技術(shù)總結(jié),在性能上我們的改進(jìn)也不少。我們之前在一些WSGI的異步部署配置上沒(méi)有做到很好的實(shí)踐。在跟其他部門的前輩們學(xué)習(xí)之后,我把他們的一些經(jīng)驗(yàn)借鑒到我們組的項(xiàng)目中,性能提升挺明顯的。在此也要感謝一下我們廠能從國(guó)內(nèi)一線大廠挖來(lái)這么多大牛,讓我這在坡縣成長(zhǎng)的小碼農(nóng)也能偷師一發(fā)。
還有一個(gè)我們性能相關(guān)的調(diào)整在于對(duì)Nginx的調(diào)研。我們?cè)谕茝V了前后端分離的網(wǎng)站架構(gòu)之后,對(duì)API的性能就可以有更好的細(xì)粒度控制——有一些報(bào)文很長(zhǎng)而更新時(shí)效不敏感的API,就可以提到Nginx的緩存里。這樣的調(diào)整對(duì)單API的吞吐量提升非常明顯,明顯到這些API對(duì)服務(wù)器的壓力簡(jiǎn)直都可以忽略不計(jì)。
其實(shí)我們的調(diào)研不止于Nginx的核心功能,還用上了OpenResty——在我用OpenResty寫完一個(gè)性能要求比較高的API做嘗試之后,陸續(xù)又有兩個(gè)同事用上了OpenResty。目前服務(wù)跑得挺穩(wěn)定的,用了OpenResty的同事反饋也不錯(cuò)。之后我們可能還會(huì)繼續(xù)用OpenResty給我們的內(nèi)部API做統(tǒng)一網(wǎng)關(guān)什么的,都已經(jīng)寫進(jìn)2017的愿望列表里啦。
最后提一下我在2016農(nóng)歷年末的一個(gè)嘗試,兩年以來(lái)一直很想通過(guò)Vue來(lái)學(xué)習(xí)前端姿勢(shì)的我,終于下決心用Vue來(lái)寫一個(gè)比較復(fù)雜的游戲活動(dòng)站。一開(kāi)始還只用了vue-cli默認(rèn)的Webpack項(xiàng)目模板,到現(xiàn)在已經(jīng)用上Vue + vuex + vue-router的全家桶了。不過(guò)由于手生,開(kāi)發(fā)過(guò)程中有一些小的磕磕碰碰,但是現(xiàn)在還不至于影響業(yè)務(wù)設(shè)計(jì)——希望自己的前端能力可以趕快成長(zhǎng)起來(lái) :)
不知不覺(jué)已經(jīng)嘚吧嘚吧寫了這么一大串亂七八糟的流水賬,who cares 反正也沒(méi)什么人會(huì)看。
2017,繼續(xù)加油吧!