1. 部署簡單
創(chuàng)新互聯(lián)從2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢想脫穎而出為使命,1280元陽高做網(wǎng)站,已為上家服務(wù),為陽高各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18980820575
Go
編譯生成的是一個(gè)靜態(tài)可執(zhí)行文件,除了glibc外沒有其他外部依賴。這讓部署變得異常方便:目標(biāo)機(jī)器上只需要一個(gè)基礎(chǔ)的系統(tǒng)和必要的管理、監(jiān)控工具,完全不需要操心應(yīng)用所需的各種包、庫的依賴關(guān)系,大大減輕了維護(hù)的負(fù)擔(dān)。
2. 并發(fā)性好
Goroutine和channel使得編寫高并發(fā)的服務(wù)端軟件變得相當(dāng)容易,很多情況下完全不需要考慮鎖機(jī)制以及由此帶來的各種問題。單個(gè)Go應(yīng)用也能有效的利用多個(gè)CPU核,并行執(zhí)行的性能好。
3. 良好的語言設(shè)計(jì)
從學(xué)術(shù)的角度講Go語言其實(shí)非常平庸,不支持許多高級的語言特性;但從工程的角度講,Go的設(shè)計(jì)是非常優(yōu)秀的:規(guī)范足夠簡單靈活,有其他語言基礎(chǔ)的程序員都能迅速上手。更重要的是
Go 自帶完善的工具鏈,大大提高了團(tuán)隊(duì)協(xié)作的一致性。
4. 執(zhí)行性能好
雖然不如 C 和 Java,但相比于其他編程語言,其執(zhí)行性能還是很好的,適合編寫一些瓶頸業(yè)務(wù),內(nèi)存占用也非常省。
英文原文鏈接【Go, the unwritten parts】 發(fā)表于2017/05/22 作者JBD是Go語言開發(fā)小組成員
檢查程序的執(zhí)行路徑和當(dāng)前狀態(tài)是非常有用的調(diào)試手段。核心文件(core file)包含了一個(gè)運(yùn)行進(jìn)程的內(nèi)存轉(zhuǎn)儲(chǔ)和狀態(tài)。它主要是用來作為事后調(diào)試程序用的。它也可以被用來查看一個(gè)運(yùn)行中的程序的狀態(tài)。這兩個(gè)使用場景使調(diào)試文件轉(zhuǎn)儲(chǔ)成為一個(gè)非常好的診斷手段。我們可以用這個(gè)方法來做事后診斷和分析線上的服務(wù)(production services)。
在這篇文章中,我們將用一個(gè)簡單的hello world網(wǎng)站服務(wù)作為例子。在現(xiàn)實(shí)中,我們的程序很容易就會(huì)變得很復(fù)雜。分析核心轉(zhuǎn)儲(chǔ)給我們提供了一個(gè)機(jī)會(huì)去重構(gòu)程序的狀態(tài)并且查看只有在某些條件/環(huán)境下才能重現(xiàn)的案例。
作者注 : 這個(gè)調(diào)試流程只在Linux上可行。我不是很確定它是否在其它Unixs系統(tǒng)上工作。macOS對此還不支持。Windows現(xiàn)在也不支持。
在我們開始前,需要確保核心轉(zhuǎn)儲(chǔ)的ulimit設(shè)置在合適的范圍。它的缺省值是0,意味著最大的核心文件大小是0。我通常在我的開發(fā)機(jī)器上將它設(shè)置成unlimited。使用以下命令:
接下來,你需要在你的機(jī)器上安裝 delve 。
下面我們使用的 main.go 文件。它注冊了一個(gè)簡單的請求處理函數(shù)(handler)然后啟動(dòng)了HTTP服務(wù)。
讓我們編譯并生產(chǎn)二進(jìn)制文件。
現(xiàn)在讓我們假設(shè),這個(gè)服務(wù)器出了些問題,但是我們并不是很確定問題的根源。你可能已經(jīng)在程序里加了很多輔助信息,但還是無法從這些調(diào)試信息中找出線索。通常在這種情況下,當(dāng)前進(jìn)程的快照會(huì)非常有用。我們可以用這個(gè)快照深入查看程序的當(dāng)前狀態(tài)。
有幾個(gè)方式來獲取核心文件。你可能已經(jīng)熟悉了奔潰轉(zhuǎn)儲(chǔ)(crash dumps)。它們是在一個(gè)程序奔潰的時(shí)候?qū)懭氪疟P的核心轉(zhuǎn)儲(chǔ)。Go語言在缺省設(shè)置下不會(huì)生產(chǎn)奔潰轉(zhuǎn)儲(chǔ)。但是當(dāng)你把 GOTRACEBACK 環(huán)境變量設(shè)置成“crash”,你就可以用 Ctrl+backslash 才觸發(fā)奔潰轉(zhuǎn)儲(chǔ)。如下圖所示:
上面的操作會(huì)使程序終止,將堆棧跟蹤(stack trace)打印出來,并把核心轉(zhuǎn)儲(chǔ)文件寫入磁盤。
另外個(gè)方法可以從一個(gè)運(yùn)行的程序獲得核心轉(zhuǎn)儲(chǔ)而不需要終止相應(yīng)的進(jìn)程。 gcore 可以生產(chǎn)核心文件而無需使運(yùn)行中的程序退出。
根據(jù)上面的操作,我們獲得了轉(zhuǎn)儲(chǔ)而沒有終止對應(yīng)的進(jìn)程。下一步就是把核心文件加載進(jìn)delve并開始分析。
差不多就這些。delve的常用操作都可以使用。你可以backtrace,list,查看變量等等。有些功能不可用因?yàn)槲覀兪褂玫暮诵霓D(zhuǎn)儲(chǔ)是一個(gè)快照而不是正在運(yùn)行的進(jìn)程。但是程序執(zhí)行路徑和狀態(tài)全部可以訪問。
其實(shí)并沒有不受待見,用的人還是很多的,解決一些特定領(lǐng)域的問題也很方便。
每種語言的流行程度主要取決于這個(gè)語言最著名的killer app的流行程度,C有Linux,Go有Docker
1.OpenResty是什么,適合什么場景下使用
和大部分知名開源軟件誕生在歐美國家不同,OpenResty自身和依賴的主要組件都是金磚國家的開發(fā)者發(fā)明的,這點(diǎn)還挺有意思。
Nginx是俄羅斯人發(fā)明的,Lua是巴西幾個(gè)教授發(fā)明的,中國人章亦春把LuaJITVM嵌入到Nginx中,實(shí)現(xiàn)了OpenResty這個(gè)高性能服務(wù)端解決方案。
通過OpenResty,你可以把nginx的各種功能進(jìn)行自由拼接,更重要的是,開發(fā)門檻并不高,這一切都是用強(qiáng)大輕巧的Lua語言來操控。
它主要的使用場景主要是:
在Lua中揉和和處理各種不同的nginx上游輸出(Proxy,Postgres,Redis,Memcached等)
在請求真正到達(dá)上游服務(wù)之前,Lua可以隨心所欲的做復(fù)雜的訪問控制和安全檢測
隨心所欲的操控響應(yīng)頭里面的信息
從外部存儲(chǔ)服務(wù)(比如Redis,Memcached,MySQL,Postgres)中獲取后端信息,并用這些信息來實(shí)時(shí)選擇哪一個(gè)后端來完成業(yè)務(wù)訪問
在內(nèi)容handler中隨意編寫復(fù)雜的Web應(yīng)用,使用同步但依然非阻塞的方式,訪問后端數(shù)據(jù)庫和其他存儲(chǔ)
在rewrite階段,通過Lua完成非常復(fù)雜的URLdispatch
用Lua可以為nginx子請求和任意location,實(shí)現(xiàn)高級緩存機(jī)制
組織OpenResty技術(shù)大會(huì)之前,我一直認(rèn)為自己是一個(gè)孤獨(dú)的OpenResty使用者,覺得自己在使用一個(gè)冷門的技術(shù)。
雖然大家都聽說過OpenResty或者ngx_lua,但感覺用在生產(chǎn)環(huán)境中使用的卻少之又少,除了幾個(gè)CDN公司外,好像沒有聽說過哪家知名互聯(lián)網(wǎng)公司在使用。而CDN行業(yè)之所以使用,很多是受到cloudflare技術(shù)棧的影響,OpenResty的作者也在國外這家CDN公司。
但辦完這個(gè)大會(huì),我發(fā)現(xiàn)使用者真的挺多,奇虎360的所有服務(wù)端團(tuán)隊(duì)都在使用,京東、百度、魅族、知乎、優(yōu)酷、新浪這些互聯(lián)網(wǎng)公司都在使用。有用來寫WAF、有做CDN調(diào)度、有做廣告系統(tǒng)、消息推送系統(tǒng),還有像我們部門一樣,用作APIserver的。有些還用在非常關(guān)鍵的業(yè)務(wù)上,比如開濤在高可用架構(gòu)分享的京東商品詳情頁,是我知道的ngx_lua最大規(guī)模的應(yīng)用。
2.奇虎企業(yè)安全服務(wù)端技術(shù)選型的標(biāo)準(zhǔn)
先說下3年多前做架構(gòu)選型的時(shí)候,我為什么會(huì)選擇OpenResty?
其實(shí)架構(gòu)如何設(shè)計(jì)并不重要,因?yàn)槊考夜荆總€(gè)團(tuán)隊(duì),他們的公司文化和技術(shù)背景各不相同,生搬硬套會(huì)適得其反。重要的是當(dāng)初為什么這么選擇,中途為什么調(diào)整。
我們的產(chǎn)品要求單機(jī)上面,服務(wù)端提供高性能的API接口,QPS至少過萬,未來需要支撐到10萬。我們并沒有急于去使用PHP、Python或者其他的語言來實(shí)現(xiàn)功能,而是先勾勒出一個(gè)理想化的技術(shù)模型。
這個(gè)模型應(yīng)該具備:
非阻塞的訪問網(wǎng)絡(luò)IO。在連接MySQL、Redis和發(fā)起HTTP請求時(shí),工作進(jìn)程不能傻傻的等待網(wǎng)絡(luò)IO的返回,而是需要支持事件驅(qū)動(dòng),用協(xié)程的方式讓CPU資源更有效的去處理其他請求。很多語言并不具備這樣的能力和周邊庫。
有完備的緩存機(jī)制。不僅需要支持Redis、Memcached等外部緩存,也應(yīng)該在自己的進(jìn)程內(nèi)有緩存系統(tǒng)。我們希望大部分的請求都能在一個(gè)進(jìn)程中得到數(shù)據(jù)并返回,這樣是最高效的方法,一旦有了網(wǎng)絡(luò)IO和進(jìn)程間的交互,性能就會(huì)受到很大影響。
同步的寫代碼邏輯,不要讓開發(fā)者感知到回調(diào)和異步。這個(gè)也很重要,程序員也是人,代碼應(yīng)該更符合人的思維習(xí)慣,顯式的回調(diào)和異步關(guān)鍵字,會(huì)打斷思路,也給調(diào)試帶來困難。
最好是站在巨人肩上,基于成熟的技術(shù)上搭建。采用一門全新誕生的語言和技術(shù),需要經(jīng)歷語言自身發(fā)展期頻繁調(diào)整的陣痛,還可能站錯(cuò)隊(duì)。
不僅支持Linux平臺,還需要支持Windows平臺,這個(gè)是我們產(chǎn)品很特別的需求,很多中小企業(yè)用戶還是習(xí)慣Windows的操作,不具備Linux的維護(hù)能力。
基于以上幾點(diǎn)的考慮,考察了當(dāng)時(shí)的一些方案,選擇了OpenResty。
首先,它最大的特點(diǎn)就是用同步的代碼邏輯實(shí)現(xiàn)非阻塞的調(diào)用,其次它有單進(jìn)程內(nèi)的LRUcache和進(jìn)程間的shareDICTcache,而且它是揉合nginx和LuaJIT而產(chǎn)生的。而且nginx有Windows版本,雖然有非常多的限制,但這些限制都是可以解決的,nginx官方Windows版本中不支持的特性,我們開源出來的版本都解決了。
第一次看到這樣的方案,我覺得它肯定會(huì)顛覆高性能服務(wù)端的開發(fā)。為什么呢?在我之前的公司里,每天會(huì)有近百億次的查詢請求,而服務(wù)器只用了十臺。
我們采用了nginxC模塊+內(nèi)置在nginx中的K-V數(shù)據(jù)庫(自己開發(fā)的),來實(shí)現(xiàn)所有的業(yè)務(wù)邏輯,達(dá)到這個(gè)目標(biāo)。聽上去很簡單,但是過程非常艱辛,兩三個(gè)十幾年工作經(jīng)驗(yàn)的大牛做了一年多才穩(wěn)定下來。絕大部分開發(fā)能力不足,只能望塵莫及。而且后續(xù)的調(diào)試和維護(hù),也會(huì)花費(fèi)不少精力。
但是OpenResty的出現(xiàn)改變了這一切,OpenResty非常的pythonic,適合人類的正常思維。新手經(jīng)過一兩個(gè)月的學(xué)習(xí),做出來的API,就可以達(dá)到nginxC模塊的性能,而且代碼量大大減少,也方便調(diào)試。
3.以奇虎和新浪為例,如何在項(xiàng)目中引入新技術(shù)
技術(shù)選型只是第一步,如何才能在一個(gè)產(chǎn)品或者項(xiàng)目中引入OpenResty這個(gè)新的技術(shù)呢?我拿奇虎企業(yè)安全和新浪移動(dòng)這兩家公司真實(shí)發(fā)生的案例給大家看看。我和新浪移動(dòng)的周晶,都是在一個(gè)有成熟產(chǎn)品的部門,用一兩個(gè)人的力量,把一個(gè)新技術(shù),替換掉了原有的技術(shù)架構(gòu)。但由于企業(yè)產(chǎn)品和個(gè)人產(chǎn)品的不同,方法有很大的不一樣。
先說我所在奇虎企業(yè)安全。我在2012年初加入這個(gè)部門,當(dāng)時(shí)產(chǎn)品主打免費(fèi),目標(biāo)用戶是小企業(yè)。所以架構(gòu)設(shè)計(jì)上面,只考慮了幾十點(diǎn)、幾百點(diǎn)的終端請求,使用了非常強(qiáng)綁定的Windows平臺技術(shù),而且傾向于不用開源軟件,自己新做一個(gè)更適合自己的框架。包括自己用C++開發(fā)的Webserver,自己寫的PHP路由和框架,數(shù)據(jù)存儲(chǔ)在sqlite里面。
我?guī)兔π薷牧藘蓚€(gè)月PHP的bug,看明白了技術(shù)架構(gòu)的思路之后,就去新開的一個(gè)產(chǎn)品線了。這是一個(gè)實(shí)驗(yàn)性的產(chǎn)品,主要面對央企和專用網(wǎng),一個(gè)網(wǎng)絡(luò)中有上百萬的終端。
剛開始沒有什么人關(guān)注,我就直接采用了Linux+OpenResty+Redis+Postgres的開源組件,性能測試甩之前的N條街。后面這個(gè)實(shí)驗(yàn)性的產(chǎn)品,和之前的產(chǎn)品,合并為一個(gè)產(chǎn)品,技術(shù)上面就割裂為兩套架構(gòu)。老功能用老架構(gòu),新功能用新架構(gòu)。
隨著越來越多大用戶的增加,原有的技術(shù)架構(gòu)開始捉襟見肘,技術(shù)債務(wù)越積壓越多。隨著用戶的抱怨,sqlite被拋棄,全面換成Postgres。但對于自己開發(fā)的框架還是有些敝帚自珍。
期間通過對比測試、OpenResty培訓(xùn)還有多次用戶性能問題排查,讓開發(fā)同學(xué)們都知道這門技術(shù)的優(yōu)勢。快被加班壓垮的開發(fā)同學(xué),逐漸開始選擇使用OpenResty而不是自研的框架,來進(jìn)行新功能的開發(fā),以及舊功能的遷移,來避免加班。
在產(chǎn)品重構(gòu)的時(shí)候,之前自研的服務(wù)端框架被完全拋棄,服務(wù)端開發(fā)的同學(xué)從8、9個(gè)人減少到3個(gè)人。在新技術(shù)的引入過程中,我們沒有采用強(qiáng)制的舉措,因?yàn)槠髽I(yè)產(chǎn)品需要穩(wěn)定,用戶處部署的版本更新很慢。
而新浪移動(dòng)周晶的實(shí)踐,對大家更有參考意義。新浪移動(dòng)最開始是基于Apache,用PHP來處理用戶請求。Apache是同步多進(jìn)程模型,在并發(fā)請求不多的情況下沒有問題。
但是總是會(huì)有突發(fā)新聞,比如馬航失聯(lián)、文章出軌等,突發(fā)的高流量把后臺壓垮了幾次。而且可以預(yù)見世界杯的流量也會(huì)很大,所以周晶花幾個(gè)月時(shí)間,用nginx替換了Apache,使用nginx的fast_cgi_cache,QPS提升了一個(gè)數(shù)量級。
新浪移動(dòng)后臺的接口都是使用PHP來實(shí)現(xiàn)的,在高并發(fā)下有些力不從心。而nginx簡單的緩存雖然能滿足性能,但不能滿足業(yè)務(wù)精細(xì)化和數(shù)據(jù)一致性的要求,需要找PHP之外的解決方案,前提是讓PHP的開發(fā)能夠舒適的使用。node.js的回調(diào)地獄、Go的調(diào)試不方便,都是一個(gè)阻礙。
他們最后選擇了OpenResty,而且基于OpenResty開源了一個(gè)Web框架Vanilla(香草),模仿了Yaf的使用習(xí)慣,讓PHP的開發(fā)更容易接受和上手。Vanilla已經(jīng)在新浪移動(dòng)開始使用,一些核心業(yè)務(wù),比如高清圖和體育直播,正在向這個(gè)框架遷移中。
4.入門痛點(diǎn),以及學(xué)習(xí)的正確方法
我和周晶的入門,都是自己摸著石頭過河。當(dāng)時(shí)除了Python社區(qū)「大媽」的那篇使用文章外,找不到其他的資料。
奇虎和新浪都用OpenResty成功替換了之前的技術(shù),但問題還是挺明顯,就是大家都認(rèn)為自己是孤獨(dú)的使用者,同事中基本沒有人認(rèn)同。在關(guān)鍵和支撐業(yè)務(wù)上,使用OpenResty有些不放心,都會(huì)在邊緣業(yè)務(wù)上先做嘗試和驗(yàn)證。
雖然OpenResty的性能做的很棒,比肩或者超過其他所有的高性能解決方案,但是擔(dān)心沒有學(xué)習(xí)資料、擔(dān)心招不到人、擔(dān)心沒人交流,可能還擔(dān)心作者章亦春哪天撂挑子不干了,這個(gè)項(xiàng)目就黃了。
高可用架構(gòu)群里的各位都是架構(gòu)師,是技術(shù)決策者,在引入一門新技術(shù)的時(shí)候,肯定會(huì)考慮到這些風(fēng)險(xiǎn)。比如小米科技馬利超在高可用架構(gòu)的分享,他們在搶購系統(tǒng)中曾經(jīng)使用過ngx_lua,雖然性能滿足需求,但是團(tuán)隊(duì)里面熟悉的人少,最后還是改成了Go語言實(shí)現(xiàn)。
如何解決這些擔(dān)憂?社區(qū)是有過思考和討論的,我們放在分享最后講。先從一個(gè)嘗試使用這門技術(shù)的開發(fā)者的角度看,OpenResty不少基礎(chǔ)工作沒有完善,友好程度不夠:
只能從源碼安裝,沒有apt-get、brew等軟件倉庫安裝方法;安裝第三方庫沒有PIP、NPM之類的包管理工具,需要去先谷歌,然后拷貝代碼文件到指定的目錄下,才能require使用。
代碼編寫需要修改nginx.conf和對應(yīng)的lua代碼,即使是helloworld也是如此。當(dāng)然你可以把代碼寫在nginx的配置文件里面,但是生產(chǎn)環(huán)境肯定是要分離的。這種編寫代碼的方式,不像是一個(gè)編程語言,和常規(guī)的編程方式不同。
有獨(dú)特的執(zhí)行階段概念,因?yàn)镺penResty是基于nginx的,所以也繼承它的這種概念。你的代碼邏輯,可能需要放在不同的階段里面運(yùn)行,才能獲取你想要的預(yù)期。而這些階段間信息如何傳遞,以及哪些API不能在某些階段使用,就會(huì)經(jīng)常攔住新手。
遇到問題只有郵件列表這一種方式來溝通,而郵件列表是被墻的。文檔也只有英文版本,導(dǎo)致很多新手的問題無法被解決。
沒有系統(tǒng)學(xué)習(xí)OpenResty的手段,大都是業(yè)務(wù)需要實(shí)現(xiàn)什么功能,就去文檔和API里面去找。至于方式對不對,能不能優(yōu)化,就不知道了。
升級sierra后調(diào)試出現(xiàn)cannot get thread count可以參考以下步驟
mkdir $GOPATH/src/github.com/derekparker/
cd $GOPATH/src/github.com/derekparker/
git clone
cd delve
git fetch origin pull/665/head
git checkout FETCH_HEAD
CERT=dlv-cert make install