(轉)遊戲開發 應用Docker實現開發環境
來自專欄 Unity3d遊戲開發指南
簡單點
最近,跟一個大學金融系的同學交流,發現他對科技發展的動態非常了解,然而對於一些技術關鍵字的應用並不是很理解。
對於普通不懂技術的小白來說,如果去諮詢一些IT行業技術大牛,他們往往會獲得一個一臉懵逼的回答。比如說,他問我「雲計算」是什麼?百度百科:
雲計算[1] (cloud computing)是基於互聯網的相關服務的增加、使用和交付模式,通常涉及通過互聯網來提供動態易擴展且經常是虛擬化的資源。
???
別說一個技術小白了,就算現在我看完這句話,我也是一臉懵逼,難為大家了。站在技術小白的角度,去看看網上的一些「雲計算」的解釋,你會發現,還是那麼的難以理解。
用產品的口吻來說:用戶體驗不好。
我嘗試給他作出類比:
「古時候,人們家裡做一口井,水從井裡打出來,而現在,我們扭開水龍頭,水就來了; 10年前,你要裝軟體,得跑去電腦城買光碟,而現在,連上網打開應用商店,軟體盡在眼前——這就是雲計算」。
當然了,本來「雲計算」就是一個很廣的問題,這樣的解釋無非是拿出其中之一的應用場景作類比。但是它能幫助普通人更好的理解。
我覺得這是一個非常有趣的過程:用跨界思維,用擬物或擬人的方式,去提煉簡化一些看起來很複雜、枯燥的技術關鍵詞。
Docker是什麼?
回歸正題,我們討論Docker。估計喜歡瀏覽技術新聞資訊站的同學,都會知道Docker——傳說中改變世界的東西,它改變了應用的部署運維。那麼Docker是什麼?來看看百度百科:
Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後發布到任何流行的Linux機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何介面。
當初,看完它的解釋後,我的第一反應依舊是懵逼,因為它跟我們腦海中常見的物理機、虛擬機的概念相比,是一種未曾想像過的新事物。
鑒於所在工作環境周圍,還沒見過應用Docker在開發環境的同學(希望大牛雲集的項目不要鄙視),而我又覺得用通俗化的思路去解釋Docker思維是有價值的一件事,這也是本文的成文目的。
Docker圖標,小鯨魚
這是Docker的官方圖標——一隻大鯨魚,上面有各種各樣的集裝箱;鯨魚就像一個操作系統,上面裝著各種各樣的集裝箱——軟體。
也許你會問,這不跟我們iPhone應用一樣嗎?手機操作系統(鯨魚),裡面有各種各樣的App(集裝箱)。
但是,仔細想想,iPhone上的App,Android上能運行嗎?——不行。因為iPhone使用IPA格式的App包裝方法,而Android使用APK格式的App包裝方法,兩者部署上是非常的不一樣的。
能不能在Android上,運行iPhone應用,而又不使用損耗資源的虛擬機技術? 這就是Docker——它應用在PC平台上的,可以讓不同的操作系統平台,佔用很少的資源,運行同樣的軟體程序。
它就像一個提供開發型軟體的應用商店。以往,我們需要安裝MySQL資料庫,我們首先要想,我的操作系統是Windows?我的CPU是64位? 然後我們找到了MySQL Windows 64位版本進行下載,然後開始安裝,安裝在C盤?安裝完成後,把資料庫賬號密碼設置好?
而在Docker時代,我們只需要下載MySQL的Docker鏡像安裝就可以了。
這個思路推而廣之,Android上利用Docker運行iPhone應用什麼時候可以做到?這是技術上可行的,但這裡不作過多幻想了。
Docker不是什麼新生事物,早在2013年就誕生了,而它的核心技術cgroup早在2006年就寫進Linux內核了,直到這2年,才漸漸開始廣泛的應用。
Docker常見的場景,是部署和運維。今天,我們拋開技術細節、理論、運維需求,簡單談談Docker怎麼應用到我們日常遊戲開發環境當中,並讓團隊的工作流程起到什麼樣的優化。
快速搭建MySQL+Redis開發環境
Laradock是一個PHP的Docker開發環境,使用它可以極其方便的快速搭建PHP開發環境。 它不但包含了PHP語言執行環境,還包括了一系列相關工具,其中包括我們非常常用的MySQL、Redis。
在Laradock的官方文檔中,就有這樣的一句話:
Use Docker first and learn about it later.
先使用Docker,然後再學習它。
是的,先使用它,然後再深入學習Docker的一些很原理,一個自上而下的學習過程,可以讓你更加快速的理解和應用Docker。應用Laradock是一個很好的Docker學習起點。
要使用Laradock,首先你得安裝Docker。 一般有可以選擇下載Windows版Docker
或下載Mac版Docker,跟著安裝步驟安裝即可。而在國內,訪問Docker的鏡像倉庫非常的慢,因此,需要設置國內的加速鏡像倉庫(這裡使用DaoCloud)。
小鯨魚托盤圖標
安裝好Docker以後,會有小鯨魚的圖標出現在系統托盤上。右擊出現菜單(macOS系統則是左擊),並選擇「Settings」。
Docker加速器
Windows環境時,選中「Docker Daemon」界面,往"registry-mirrors"欄位里添加鏡像倉庫的地址。
為什麼要配置鏡像倉庫地址?像前面所說的,Docker有點像應用商店——把需要的開發軟體,下載並安裝。因此鏡像倉庫(Docker Hub)上儲存著各種各樣的「鏡像」,可理解成別人預先製作好的開發軟體。包括我們常見的MySQL、CentOS,其官方都會維護一份Docker鏡像。
使用Laradock,你可以使用它在GitHub上託管的源碼:
git clone https://github.com/laradock/laradockcd laradockdocker-compose up -d nginx mysql redis memcached
或者,如果連命令都不想輸入(或者git都還沒安裝),下載https://github.com/mr-kelly/laradock/archive/master.zip ,解壓後,在安裝好Windows環境雙擊執行start.bat批處理。
這樣的一條命令,呼叫Laradock下載、啟動了nginx、MySQL、redis、memcached四個主要容器。這幾個不同的Docker容器互相組合,並映射埠到本地。比如把localhost:80埠映射到nginx容器的80埠,把localhost:3306埠映射到MySQL容器的3306埠。
這時候,使用你的MySQL資料庫工具(比如Navicat),輸入連接地址localhost,賬號root,密碼root,你就能連上了MySQL容器中的MySQL資料庫程序了。
為什麼我會使用Laradock?
在以往,我一般會使用XAMPP來當作我的PHP HTTP開發環境——它內置了Apache、MySQL等開發組件,並且能以「綠色」軟體的方式安裝運行在我的電腦上。 直到有一次,XAMPP在我的macOS上,出現phpredis擴展無法訪問Redis的問題,折騰很久也沒找到具體的原因,最終轉而使用Docker搭建開發環境。
在日常的工作中,我們其實經常遇到這種情況:因為一些跟業務工作的一些小問題,比如裝系統啊、環境配置的坑啊等等,會耗費我們非常多的精力。
要真正的應用Docker到您的開發環境,需要根據項目業務、技術選型,來自定義Docker鏡像,比如說,一個使用Java+MySQL的項目,除了MySQL鏡像外,還需要Java運行時鏡像,多個鏡像互相組合。
可能你會疑惑,為什麼要弄成多個鏡像?使用一個Linux發行版鏡像,然後在上面安裝好Java、MySQL,再製作一個完整的鏡像不就行了嗎? 是的,這也是可行的,只是說這樣做法,類似於編程開發中的「耦合度高」,就是當這樣一個完整的開發環境鏡像在某一天需要修改時,比如說其中的MySQL版本更新了,就需要對這個鏡像進行重新製作。而拆分成多個鏡像互相組合,則只需要使用官方對應版本的新鏡像即可。
怎麼使用Docker進行鏡像的製作,官方的文檔很多,這裡就不重複「造輪子」了。Laradock的Github地址laradock/laradock: A Docker PHP development environment. ,上面有其更加詳細的使用方法。
應用Docker開發環境的場景
一個新人入職
新人工程師走進公司,會有一個熟悉工作環境的過程,其中一個耗時的環節,就是安裝開發環境。這是一個非常折騰人的過程,如果你是使用大型IDE的開發者,比如說安裝MySQL、SQLServer、Android SDK等大型開發軟體,這將是一個耗時的過程——首先你得找到軟體包,然後再進入漫長的安裝過程。最常見的實踐是公司內部共享,把這些常用軟體都共享出來,讓大家安裝。然而大家的習慣不同的,操作系統也不同,過程中依然會遇到種種兼容問題。
曾經一個做Android開發的朋友,在入職公司的第一周內——花了一周的時間,終於把開發環境搭建完成,讓Java工程編譯通過。
遊戲策劃跑單服
遊戲團隊開發的過程中,免不了出現非技術人員需要在自己機器上啟動遊戲伺服器進行測試的情況。因此,「搭建開發環境」這個技能,會出現非技術人員身上。跟程序員相比,非技術人員「搭建開發環境」或「配置伺服器環境」是相對更加難的事情,他們最需要的是有一種「雙擊就能運行」的單服運行體驗。 有一些非技術人員和程序員之間對話,是我們經常聽見的:
「嗯,這個功能我提交前測試是正常的——你的環境乾淨嗎?需要的數據都乾淨地重新生成了嗎?第三方庫的二進位文件更新了嗎?你們幾個人測試的版本一致嗎?要不你 Cleanup / 重啟 / 重新保存 / 重新建個賬號試試?」
然而實際的開發過程中,程序、策劃之間是缺乏換位思考的,程序員更喜歡直接在自己的工作上開碼,而不是為非自己工作範圍內的體驗進行優化。因此,「技術流」策劃甚是常見,不但了解軟連接硬鏈接的創建刪除、還熟悉各種各樣的SQL資料庫、還會通過Visual Studio編譯程序,甚至有很多都能直接編程的。
開發軟體
那麼能不能把裝好軟體的開發機整個做一個Ghost系統鏡像?
這確實是我前兩年項目所使用的方法:在一台電腦上,裝好所有開發環境軟體,然後使用Ghost打包一個系統鏡像。想法很美好,但是實際過程卻很難執行。一個鏡像大小動輒10多GB的佔用,克隆慢,恢復鏡像也慢;更要命的是,開發環境在研發過程中經常的變化,比方說想把舊有鏡像中的MySQL 4升級成MySQL 5,怎麼做? 不停的重新構建虛擬機鏡像? 太艱難。
後來我為了達到這樣的目的,完整的MySQL執行程序、MongoDB執行程序直接放到SVN上傳。從程序員角度來看,這是骯髒的,把一些無關重要的二進位文件進入到了代碼庫;但是從用戶體驗的角度來看,這是提高了非技術人員的使用體驗。
類似這個情況如果應用Docker後,我們大可以只需要把MySQL或MongoDB的Dockerfile定義文件上傳到SVN,非技術人員在首次啟動時就會自動從容器倉庫(內網或外網均可)拉取到對應的容器並啟動,快速並且規避兼容性問題。
一些Linux-only的程序
redis對Windows的支持非常有限,skynet遊戲框架不支持Windows平台,但是對於使用Windows的人來說,會使用一台虛擬機來進行開發。
而使用Docker,則可以改善這樣的開發環境:部署一個Linux容器,並把本地代碼文件映射到容器中,做到使用本地環境編輯代碼、使用Docker運行程序;Redis官方提供Docker版本,體積非常小,讓Windows下運行不再困難。
導入真實玩家數據
在項目運營中,出現的一些BUG,我們希望能模擬玩家的數據進行測試,這時候需要把一些玩家的數據導入,進行測試。一般來說,我們需要把資料庫的數據導出,然後再在開發環境中導入。
而如果運營的項目是使用Docker容器進行部署的,那我們只需要把這個容器整個拖回到本地執行,我們就能完整的模擬到真實數據環境了。 同樣,應用這樣的思路也可以進行資料庫的備份。
DevOps
說起Docker,總是免不了DevOps——開發運維一體化。這是一個很大很抽象的思想話題,但我們這裡只簡單的介紹其中一種應用:開發所使用的Docker容器,直接丟到生產伺服器,極簡部署。
比方說,我所在項目使用C#進行遊戲伺服器的開發,在Windows上使用.net Framework跑,實際運維環境則使用Mono。也就是說,實際運維環境中,如果出現了有.net Framework和Mono不同兼容性的BUG,這些BUG對開發人員來說都是前所未見、難以理解的——因為開發環境,跟運營環境,是完全不一樣的,這會引領開發人員進入另一場爬坑遊戲。
其他
Docker原理
Docker的兩大核心基礎技術是namespace和cgroup,它們早在2006年的就被寫進如Linux內核。
抽象來說,跟虛擬機不一樣的是,虛擬機技術,把CPU、內存等所有硬體用軟體化進行虛擬,形成一個虛擬的計算機環境;而Docker,則有點像「CPU中的虛擬CPU」、「內存中的虛擬內存」來對計算機進行資源隔離。
Vagrant
在使用Docker之前,我一直使用Vagrant來進行開發環境快速部署。它們的目的很相像,但是又不是那麼一回事。
Vagrant說白了,就是一個VirtualBox虛擬機的快速管理工具。以往使用虛擬機,我們需要安裝VirtualBox,需要下載Linux發行版鏡像,需要安裝,安裝後再安裝各種開發軟體。
而使用Vagrant,就像Docker一樣,只需要一條命令,就可以完成以上所有的工作了。 只是,說白了,Vagrant就是一個虛擬機管理工具,它就類似於你使用了一個CentOS Docker容器,然後在裡面安裝好所有的開發軟體。
在Web開發領域,看到很多程序員已經應用上Docker用於開發環境了;目前身邊的遊戲開發中還沒看到,也希望Docker慢慢普及開來。
本文只是非常片面的展現了Docker應用的冰山一角——搭建簡單開發環境。謹供你參考。
原作者:陳小霖 Kelly
九城學院遊戲編程乾貨分享專區:IT開發學院 - 泛IT開發驅動基地
推薦閱讀:
※給unity新手找不到工作的人傳授幾招
※使用頂點投射的方法製作實時陰影
※Unity中的單例模式、回調函數、消息分發的使用區別?
※一個簡單的探照燈shader
※Unity接入多個SDK的通用介面開發與資源管理(一)