當(dāng)客戶端在 發(fā)出POST請求時/albums,您希望將請求正文中描述的專輯添加到現(xiàn)有專輯數(shù)據(jù)中。
創(chuàng)新互聯(lián)技術(shù)團(tuán)隊10余年來致力于為客戶提供做網(wǎng)站、網(wǎng)站設(shè)計、成都品牌網(wǎng)站建設(shè)、成都營銷網(wǎng)站建設(shè)、搜索引擎SEO優(yōu)化等服務(wù)。經(jīng)過多年發(fā)展,公司擁有經(jīng)驗豐富的技術(shù)團(tuán)隊,先后服務(wù)、推廣了上千網(wǎng)站,包括各類中小企業(yè)、企事單位、高校等機(jī)構(gòu)單位。
為此,您將編寫以下內(nèi)容:
1、編寫代碼
a.添加代碼以將專輯數(shù)據(jù)添加到專輯列表。
在此代碼中:
1)用于Context.BindJSON 將請求正文綁定到newAlbum。
2) album將從 JSON 初始化的結(jié)構(gòu)附加到albums 切片。
3)向響應(yīng)添加201狀態(tài)代碼,以及表示您添加的專輯的 JSON。
b.更改您的main函數(shù),使其包含該router.POST函數(shù),如下所示。
在此代碼中:
1)將路徑中的POST方法與 /albumspostAlbums函數(shù)相關(guān)聯(lián)。
使用 Gin,您可以將處理程序與 HTTP 方法和路徑組合相關(guān)聯(lián)。這樣,您可以根據(jù)客戶端使用的方法將發(fā)送到單個路徑的請求單獨路由。
a.如果服務(wù)器從上一節(jié)開始仍在運行,請停止它。
b.從包含 main.go 的目錄中的命令行,運行代碼。
c.從不同的命令行窗口,用于curl向正在運行的 Web 服務(wù)發(fā)出請求。
該命令應(yīng)顯示添加專輯的標(biāo)題和 JSON。
d.與上一節(jié)一樣,使用curl檢索完整的專輯列表,您可以使用它來確認(rèn)添加了新專輯。
該命令應(yīng)顯示專輯列表。
當(dāng)客戶端向 發(fā)出請求時GET /albums/[id],您希望返回 ID 與id路徑參數(shù)匹配的專輯。
為此,您將:
a.在您在上一節(jié)中添加的函數(shù)下方postAlbums,粘貼以下代碼以檢索特定專輯。
此getAlbumByID函數(shù)將提取請求路徑中的 ID,然后找到匹配的專輯。
在此代碼中:
(1)Context.Param用于從 URL 中檢索id路徑參數(shù)。當(dāng)您將此處理程序映射到路徑時,您將在路徑中包含參數(shù)的占位符。
(2)循環(huán)album切片中的結(jié)構(gòu),尋找其ID 字段值與id參數(shù)值匹配的結(jié)構(gòu)。如果找到,則將該album結(jié)構(gòu)序列化為 JSON,并將其作為帶有200 OK HTTP 代碼的響應(yīng)返回。
如上所述,實際使用中的服務(wù)可能會使用數(shù)據(jù)庫查詢來執(zhí)行此查找。
(3)如果找不到專輯,則返回 HTTP 404錯誤。
b.最后,更改您的main,使其包含對router.GET的新調(diào)用,路徑現(xiàn)在為/albums/:id ,如以下示例所示。
在此代碼中:
(1)將/albums/:id路徑與getAlbumByID功能相關(guān)聯(lián)。在 Gin 中,路徑中項目前面的冒號表示該項目是路徑參數(shù)。
a.如果服務(wù)器從上一節(jié)開始仍在運行,請停止它。
b.在包含 main.go 的目錄中的命令行中,運行代碼以啟動服務(wù)器。
c.從不同的命令行窗口,用于curl向正在運行的 Web 服務(wù)發(fā)出請求。
該命令應(yīng)顯示您使用其 ID 的專輯的 JSON。如果找不到專輯,您將收到帶有錯誤消息的 JSON。
恭喜!您剛剛使用 Go 和 Gin 編寫了一個簡單的 RESTful Web 服務(wù)。
本節(jié)包含您使用本教程構(gòu)建的應(yīng)用程序的代碼。
1、值接收者和指針接收者
所謂指針接收者和值接收者這兩個概念,用GO寫了一陣子代碼的人都了解了,這里只做簡要說明一下,也就是對于一個給定結(jié)構(gòu),咱們對結(jié)構(gòu)進(jìn)行方法包裝的時候,固定必傳的參數(shù),用來指向這個對象結(jié)構(gòu)自身的一個參數(shù),在go中也就是形式如下:
我們對結(jié)構(gòu)體testStruct進(jìn)行了包裝,提供了兩個方法,sum和modify,其中sum的方法接收者為a testStruct,這個就是值接收者,而modify的接收者為a *testStruct就是指針接收者,也就是說固定對象指針,一個傳遞的是指針地址,而另外一個直接傳遞的是結(jié)構(gòu)值拷貝了
對指針有一定了解的,都可以知道,指針傳遞過去的,可以直接修改結(jié)構(gòu)內(nèi)部內(nèi)容,而值傳遞過去的,無論如何修改這個接收者的數(shù)據(jù),不會對原對象結(jié)構(gòu)產(chǎn)生影響。而對于咱們包裝結(jié)構(gòu)對象的時候,到底是使用指針還是使用值接收者,這個實際上沒有太大的定論,就我個人的觀點來說,如果結(jié)構(gòu)體占有的內(nèi)存空間不大(kb級別),而又不需要修改內(nèi)部的,同時結(jié)構(gòu)對象內(nèi)部沒有同步對象比如(sync包中的mutex,rwlock,waitgroup等之類的結(jié)構(gòu)的話,可以直接值傳遞,實際上值copy也沒有咱們想象的那么慢,很多時候,都用指針,最后的gc回收掃描可能都比咱們這個傳遞copy的消耗大) p="" /kb級別),而又不需要修改內(nèi)部的,同時結(jié)構(gòu)對象內(nèi)部沒有同步對象比如(sync包中的mutex,rwlock,waitgroup等之類的結(jié)構(gòu)的話,可以直接值傳遞,實際上值copy也沒有咱們想象的那么慢,很多時候,都用指針,最后的gc回收掃描可能都比咱們這個傳遞copy的消耗大)
2、實現(xiàn)接口的值接收者和指針接收者有啥區(qū)別
也就是比如定義如下
這里面的值接收者和指針接收者有什么區(qū)別,這里咱來寫一個測試
通過這個測試用例可以發(fā)現(xiàn),指針接收者實現(xiàn)的接口可以同時支持轉(zhuǎn)移到值接收者接口和指針接收者接口,而用值接收者實現(xiàn)的接口,則無法轉(zhuǎn)移到使用指針接收者實現(xiàn)的接口,為啥子呢?目前網(wǎng)上或者各類資料上都是給的一個很官方很官方,而且很書面話難以理解的說明,大致意思如下:
這是目前網(wǎng)絡(luò)或者各種資料上都是差不多是這樣說的,看似講了,實際上就說了一個結(jié)果,根本就沒說出來一個為什么。這樣的總結(jié)出來,一個初學(xué)者的角度來看,是很不好理解的,初學(xué)者要么就是死記硬背,要么就是生搬硬套,甚至直到寫了好多好多代碼了,都還沒有搞明白一個為啥子,只是會用了而已,從長遠(yuǎn)來說這是不利于自身提高的。
有這兩個本質(zhì)點,咱們自己來思考一下,如果你來實現(xiàn)這個編譯器的時候,用指針接收的時候,指針接收者,默認(rèn)就能直接獲取支持,而值接收者實現(xiàn)接口的咱們可以直接來一個解指針就變成了值,就能匹配上值接收者實現(xiàn)的接口了,反過來說,如果值接收者,此時要匹配指針接收者,如何匹配呢,取一個地址就變成了指針了,此時數(shù)據(jù)類型確實是匹配了,但是,地址指向的數(shù)據(jù)區(qū)不對了,因為我們剛剛說了值接收者拷貝了一個新值之后是完全的一個新的對象,這個新對象和原始對象一點關(guān)系都沒有,咱們?nèi)〉刂?,取的也是這個新對象地址,對這個地址進(jìn)行操作,也是這個新對象的內(nèi)部數(shù)據(jù),和原始數(shù)據(jù)內(nèi)部沒有任何關(guān)系,所以由此就能推斷出,這個是為啥子值接收者不能匹配上指針接收者,而指針接收者卻可以匹配上值接收者了。
1、在某個作用域內(nèi)部,所有定義的字符串的數(shù)據(jù)區(qū)相同
這個很好驗證,代碼如下:
2、字符串相加會產(chǎn)生一個新串
這個也很好驗證
3、字符串真的是不可變的嗎
實際上從字符串的結(jié)構(gòu)
從這個結(jié)構(gòu),就能大致的推斷出來,字符串設(shè)計成這樣就不具備直接擴(kuò)容+來增加新數(shù)據(jù),而如果咱們直接使用string[index] = 'a',用這種方式,就不能編譯通過,官方也確定說字符串是不可變的。那么真的是不可變的嗎?
通過上面的結(jié)構(gòu),在加上go的slice切片的數(shù)據(jù)結(jié)構(gòu)
由此可見,咱們可以將字符串通過指針方式強(qiáng)轉(zhuǎn)為一個byte數(shù)組指針,然后通過byte切片來修改,試試
編譯通過,運行報錯
unexpected fault address 0xae2e27
fatal error: fault
這個錯誤,基本上就是一個內(nèi)存的保護(hù)錯誤,是寫異常,所以說明了,這個肯定做了內(nèi)存寫保護(hù),那么直接修改一下內(nèi)存區(qū)的屬性,去掉他的寫保護(hù),就能寫了
以下代碼都是在Win平臺,Go1.18,Win上修改內(nèi)存權(quán)限屬性,使用VirtualProtect,代碼如下
此時運行,就能發(fā)現(xiàn)tstr的內(nèi)容被咱們變了,這種情況實際上在實際開發(fā)中不具有實際意義,因為本身在語言層面,已經(jīng)做了層層限制,咱們這是屬于非法強(qiáng)制的操作方式,是流氓行為,那么是否有比較溫和一點的操作方式呢?答案是有的,且往下看。
通過上面,我們已經(jīng)用到了字符串結(jié)構(gòu),切片結(jié)構(gòu),要想字符串內(nèi)容可變,那么咱們自己構(gòu)造字符串的數(shù)據(jù)內(nèi)容區(qū)域,且讓這個數(shù)據(jù)區(qū)木有內(nèi)存寫保護(hù)不就行了,內(nèi)容區(qū)可變,GO原生態(tài)的byte數(shù)組不就行嘛,所以咱們自己構(gòu)造一下
此時我們直接修改buffer的內(nèi)容,就是直接修改了str的數(shù)據(jù)內(nèi)容了。而又不會像前面的一樣遇到內(nèi)存寫保護(hù)
4、字符串轉(zhuǎn)換優(yōu)化時可能碰到的坑
通過前面討論的字符串的可變性的方法,咱們可以知道,很多時候,[]byte到字符串的轉(zhuǎn)變,可以直接構(gòu)造其結(jié)構(gòu),而共享數(shù)據(jù),從而達(dá)到減少數(shù)據(jù)內(nèi)存copy的方式來進(jìn)行優(yōu)化,再使用這些優(yōu)化的時候,一定需要注意,字符串或者數(shù)組的生命周期,是否會存在被改寫的情況,從而導(dǎo)致前后不一致的問題。
比如下面這段代碼:
大家可以猜想一下,這個最后里面的數(shù)據(jù)mmp中,"test"的value是多少,"abcd"的value是多少,然后想想為什么,且等端午之后,再來分解
TiDB 是 PingCAP 自主研發(fā)的開源分布式關(guān)系型數(shù)據(jù)庫,具備商業(yè)級數(shù)據(jù)庫的數(shù)據(jù)可靠性,可用性,安全性等特性,支持在線彈性水平擴(kuò)展,兼容 MySQL 協(xié)議及生態(tài),創(chuàng)新性實現(xiàn) OLTP 及 OLAP 融合。
TiDB 3.0 版本顯著提升了大規(guī)模集群的穩(wěn)定性,集群支持 150+ 存儲節(jié)點,300+TB 存儲容量長期穩(wěn)定運行。易用性方面引入大量降低用戶運維成本的優(yōu)化,包括引入 Information_Schema 中的多個實用系統(tǒng)視圖、EXPLAIN ANALYZE、SQL Trace 等。在性能方面,特別是 OLTP 性能方面,3.0 比 2.1 也有大幅提升,其中 TPC-C 性能提升約 4.5 倍,Sysbench 性能提升約 1.5 倍,OLAP 方面,TPC-H 50G Q15 因?qū)崿F(xiàn) View 可以執(zhí)行,至此 TPC-H 22 個 Query 均可正常運行。新功能方面增加了窗口函數(shù)、視圖(實驗特性)、分區(qū)表、插件系統(tǒng)、悲觀鎖(實驗特性)。
截止本文發(fā)稿時 TiDB 已在 500+ 用戶的生產(chǎn)環(huán)境中長期穩(wěn)定運行,涵蓋金融、保險、制造,互聯(lián)網(wǎng), 游戲 等領(lǐng)域,涉及交易、數(shù)據(jù)中臺、 歷史 庫等多個業(yè)務(wù)場景。不同業(yè)務(wù)場景對關(guān)系型數(shù)據(jù)庫的訴求可用 “百花齊放”來形容,但對關(guān)系數(shù)據(jù)庫最根本的訴求未發(fā)生任何變化,如數(shù)據(jù)可靠性,系統(tǒng)穩(wěn)定性,可擴(kuò)展性,安全性,易用性等。請跟隨我們的腳步梳理 TiDB 3.0 有什么樣的驚喜。
3.0 與 2.1 版本相比,顯著提升了大規(guī)模集群的穩(wěn)定性,支持單集群 150+ 存儲節(jié)點,300+TB 存儲容量長期穩(wěn)定運行,主要的優(yōu)化點如下:
1. 優(yōu)化 Raft 副本之間的心跳機(jī)制,按照 Region 的活躍程度調(diào)整心跳頻率,減小冷數(shù)據(jù)對集群的負(fù)擔(dān)。
2. 熱點調(diào)度策略支持更多參數(shù)配置,采用更高優(yōu)先級,并提升熱點調(diào)度的準(zhǔn)確性。
3. 優(yōu)化 PD 調(diào)度流程,提供調(diào)度限流機(jī)制,提升系統(tǒng)穩(wěn)定性。
4. 新增分布式 GC 功能,提升 GC 的性能,降低大集群 GC 時間,提升系統(tǒng)穩(wěn)定性。
眾所周知,數(shù)據(jù)庫查詢計劃的穩(wěn)定性對業(yè)務(wù)至關(guān)重要,TiDB 3.0 版本采用多種優(yōu)化手段提升查詢計劃的穩(wěn)定性,如下:
1. 新增 Fast Analyze 功能,提升收集統(tǒng)計信息的速度,降低集群資源的消耗及對業(yè)務(wù)的影響。
2. 新增 Incremental Analyze 功能,提升收集單調(diào)遞增的索引統(tǒng)計信息的速度,降低集群資源的消耗及對業(yè)務(wù)的影響。
3. 在 CM-Sketch 中新增 TopN 的統(tǒng)計信息,緩解 CM-Sketch 哈希沖突導(dǎo)致估算偏大,提升代價估算的準(zhǔn)確性,提升查詢計劃的穩(wěn)定性。
4. 引入 Skyline Pruning 框架,利用規(guī)則防止查詢計劃過度依賴統(tǒng)計信息,緩解因統(tǒng)計信息滯后導(dǎo)致選擇的查詢計劃不是最優(yōu)的情況,提升查詢計劃的穩(wěn)定性。
5. 新增 SQL Plan Management 功能,支持在查詢計劃不準(zhǔn)確時手動綁定查詢計劃,提升查詢計劃的穩(wěn)定性。
1. OLTP
3.0 與 2.1 版本相比 Sysbench 的 Point Select,Update Index,Update Non-Index 均提升約 1.5 倍,TPC-C 性能提升約 4.5 倍。主要的優(yōu)化點如下:
1. TiDB 持續(xù)優(yōu)化 SQL 執(zhí)行器,包括:優(yōu)化 NOT EXISTS 子查詢轉(zhuǎn)化為 Anti Semi Join,優(yōu)化多表 Join 時 Join 順序選擇等。
2. 優(yōu)化 Index Join 邏輯,擴(kuò)大 Index Join 算子的適用場景并提升代價估算的準(zhǔn)確性。
3. TiKV 批量接收和發(fā)送消息功能,提升寫入密集的場景的 TPS 約 7%,讀密集的場景提升約 30%。
4. TiKV 優(yōu)化內(nèi)存管理,減少 Iterator Key Bound Option 的內(nèi)存分配和拷貝,多個 Column Families 共享 block cache 提升 cache 命中率等手段大幅提升性能。
5. 引入 Titan 存儲引擎插件,提升 Value 值超過 1KB 時性能,緩解 RocksDB 寫放大問題,減少磁盤 IO 的占用。
6. TiKV 新增多線程 Raftstore 和 Apply 功能,提升單節(jié)點內(nèi)可擴(kuò)展性,進(jìn)而提升單節(jié)點內(nèi)并發(fā)處理能力和資源利用率,降低延時,大幅提升集群寫入能力。
TiDB Lightning 性能與 2019 年年初相比提升 3 倍,從 100GB/h 提升到 300GB/h,即 28MB/s 提升到 85MB/s,優(yōu)化點,如下:
1. 提升 SQL 轉(zhuǎn)化成 KV Pairs 的性能,減少不必要的開銷。
2. 提升單表導(dǎo)入性能,單表支持批量導(dǎo)入。
3. 提升 TiKV-Importer 導(dǎo)入數(shù)據(jù)性能,支持將數(shù)據(jù)和索引分別導(dǎo)入。
4. TiKV-Importer 支持上傳 SST 文件限速功能。
RBAC(Role-Based Access Control,基于角色的權(quán)限訪問控制) 是商業(yè)系統(tǒng)中最常見的權(quán)限管理技術(shù)之一,通過 RBAC 思想可以構(gòu)建最簡單“用戶-角色-權(quán)限”的訪問權(quán)限控制模型。RBAC 中用戶與角色關(guān)聯(lián),權(quán)限與角色關(guān)聯(lián),角色與權(quán)限之間一般是多對多的關(guān)系,用戶通過成為什么樣的角色獲取該角色所擁有的權(quán)限,達(dá)到簡化權(quán)限管理的目的,通過此版本的迭代 RBAC 功能開發(fā)完成。
IP 白名單功能(企業(yè)版特性) :TiDB 提供基于 IP 白名單實現(xiàn)網(wǎng)絡(luò)安全訪問控制,用戶可根據(jù)實際情況配置相關(guān)的訪問策略。
Audit log 功能(企業(yè)版特性) :Audit log 記錄用戶對數(shù)據(jù)庫所執(zhí)行的操作,通過記錄 Audit log 用戶可以對數(shù)據(jù)庫進(jìn)行故障分析,行為分析,安全審計等,幫助用戶獲取數(shù)據(jù)執(zhí)行情況。
加密存儲(企業(yè)版特性) :TiDB 利用 RocksDB 自身加密功能,實現(xiàn)加密存儲的功能,保證所有寫入到磁盤的數(shù)據(jù)都經(jīng)過加密,降低數(shù)據(jù)泄露的風(fēng)險。
完善權(quán)限語句的權(quán)限檢查 ,新增 ANALYZE,USE,SET GLOBAL,SHOW PROCESSLIST 語句權(quán)限檢查。
1. 新增 SQL 方式查詢慢查詢,豐富 TiDB 慢查詢?nèi)罩緝?nèi)容,如:Coprocessor 任務(wù)數(shù),平均/最長/90% 執(zhí)行/等待時間,執(zhí)行/等待時間最長的 TiKV 地址,簡化慢查詢定位工作,提高排查慢查詢問題效率,提升產(chǎn)品易用性。
2. 新增系統(tǒng)配置項合法性檢查,優(yōu)化系統(tǒng)監(jiān)控項等,提升產(chǎn)品易用性。
3. 新增對 TableReader、IndexReader 和 IndexLookupReader 算子內(nèi)存使用情況統(tǒng)計信息,提高 Query 內(nèi)存使用統(tǒng)計的準(zhǔn)確性,提升處理內(nèi)存消耗較大語句的效率。
4. 制定日志規(guī)范,重構(gòu)日志系統(tǒng),統(tǒng)一日志格式,方便用戶理解日志內(nèi)容,有助于通過工具對日志進(jìn)行定量分析。
5. 新增 EXPLAIN ANALYZE 功能,提升SQL 調(diào)優(yōu)的易用性。
6. 新增 SQL 語句 Trace 功能,方便排查問題。
7. 新增通過 unix_socket 方式連接數(shù)據(jù)庫。
8. 新增快速恢復(fù)被刪除表功能,當(dāng)誤刪除數(shù)據(jù)時可通過此功能快速恢復(fù)數(shù)據(jù)。
TiDB 3.0 新增 TiFlash 組件,解決復(fù)雜分析及 HTAP 場景。TiFlash 是列式存儲系統(tǒng),與行存儲系統(tǒng)實時同步,具備低延時,高性能,事務(wù)一致性讀等特性。 通過 Raft 協(xié)議從 TiKV 中實時同步行存數(shù)據(jù)并轉(zhuǎn)化成列存儲格式持久化到一組獨立的節(jié)點,解決行列混合存儲以及資源隔離性問題。TiFlash 可用作行存儲系統(tǒng)(TiKV)實時鏡像,實時鏡像可獨立于行存儲系統(tǒng),將行存儲及列存儲從物理隔離開,提供完善的資源隔離方案,HTAP 場景最優(yōu)推薦方案;亦可用作行存儲表的索引,配合行存儲對外提供智能的 OLAP 服務(wù),提升約 10 倍復(fù)雜的混合查詢的性能。
TiFlash 目前處于 Beta 階段,計劃 2019 年 12 月 31 日之前 GA,歡迎大家申請試用。
未來我們會繼續(xù)投入到系統(tǒng)穩(wěn)定性,易用性,性能,彈性擴(kuò)展方面,向用戶提供極致的彈性伸縮能力,極致的性能體驗,極致的用戶體驗。
穩(wěn)定性方面 V4.0 版本將繼續(xù)完善 V3.0 未 GA 的重大特性,例如:悲觀事務(wù)模型,View,Table Partition,Titan 行存儲引擎,TiFlash 列存儲引擎;引入近似物理備份恢復(fù)解決分布數(shù)據(jù)庫備份恢復(fù)難題;優(yōu)化 PD 調(diào)度功能等。
性能方面 V4.0 版本將繼續(xù)優(yōu)化事務(wù)處理流程,減少事務(wù)資源消耗,提升性能,例如:1PC,省去獲取 commit ts 操作等。
彈性擴(kuò)展方面,PD 將提供彈性擴(kuò)展所需的元信息供外部系統(tǒng)調(diào)用,外部系統(tǒng)可根據(jù)元信息及負(fù)載情況動態(tài)伸縮集群規(guī)模,達(dá)成節(jié)省成本的目標(biāo)。
我們相信戰(zhàn)勝“未知”最好的武器就是社區(qū)的力量,基礎(chǔ)軟件需要堅定地走開源路線。截止發(fā)稿我們已經(jīng)完成 41 篇源碼閱讀文章。TiDB 開源社區(qū)總計 265 位 Contributor,6 位 Committer,在這里我們對社區(qū)貢獻(xiàn)者表示由衷的感謝,希望更多志同道合的人能加入進(jìn)來,也希望大家在 TiDB 這個開源社區(qū)能夠有所收獲。
TiDB 3.0 GA Release Notes:
近期正在探索前端、后端、系統(tǒng)端各類常用組件與工具,對其一些常見的組件進(jìn)行再次整理一下,形成標(biāo)準(zhǔn)化組件專題,后續(xù)該專題將包含各類語言中的一些常用組件。歡迎大家進(jìn)行持續(xù)關(guān)注。
本節(jié)我們分享的是基于Golang實現(xiàn)的高性能和彈性的流處理器 benthos ,它能夠以各種代理模式連接各種 源 和 接收器,并對有效負(fù)載執(zhí)行 水合、濃縮、轉(zhuǎn)換和過濾 。
它帶有 強(qiáng)大的映射語言 ,易于部署和監(jiān)控,并且可以作為靜態(tài)二進(jìn)制文件、docker 映像或 無服務(wù)器函數(shù) 放入您的管道,使其成為云原生。
Benthos 是完全聲明性的,流管道在單個配置文件中定義,允許您指定連接器和處理階段列表:
Apache Pulsar, AWS (DynamoDB, Kinesis, S3, SQS, SNS), Azure (Blob storage, Queue storage, Table storage), Cassandra, Elasticsearch, File, GCP (Pub/Sub, Cloud storage), HDFS, HTTP (server and client, including websockets), Kafka, Memcached, MQTT, Nanomsg, NATS, NATS JetStream, NATS Streaming, NSQ, AMQP 0.91 (RabbitMQ), AMQP 1, Redis (streams, list, pubsub, hashes), MongoDB, SQL (MySQL, PostgreSQL, Clickhouse, MSSQL), Stdin/Stdout, TCP UDP, sockets and ZMQ4.
1、docker安裝
具體使用方式可以參見該 文檔
有關(guān)如何配置更高級的流處理概念(例如流連接、擴(kuò)充工作流等)的指導(dǎo),請查看 說明書部分。
有關(guān)在 Go 中構(gòu)建您自己的自定義插件的指導(dǎo),請查看 公共 API。
LiteIDE是一款專門為Go語言開發(fā)的跨平臺輕量級集成開發(fā)環(huán)境(IDE),由QT編寫。
LiteIDE主要特點: 支持主流操作系統(tǒng)
Windows
Linux
MacOS X Go編譯環(huán)境管理和切換
管理和切換多個Go編譯環(huán)境
支持Go語言交叉編譯 與Go標(biāo)準(zhǔn)一致的項目管理方式
基于GOPATH的包瀏覽器
基于GOPATH的編譯系統(tǒng)
基于GOPATH的Api文檔檢索 Go語言的編輯支持
類瀏覽器和大綱顯示
Gocode(代碼自動完成工具)的完美支持
Go語言文檔查看和Api快速檢索
代碼表達(dá)式信息顯示F1
源代碼定義跳轉(zhuǎn)支持F2
Gdb斷點和調(diào)試支持
gofmt自動格式化支持 其他特征
支持多國語言界面顯示
完全插件體系結(jié)構(gòu)
支持編輯器配色方案
基于Kate的語法顯示支持
基于全文的單詞自動完成
支持鍵盤快捷鍵綁定方案
Markdown文檔編輯支持
實時預(yù)覽和同步顯示
自定義CSS顯示
可導(dǎo)出HTML和PDF文檔
批量轉(zhuǎn)換/合并為HTML/PDF文檔 Sublime Text 2(以下簡稱Sublime)+ GoSublime + gocode + MarGo的組合。
其優(yōu)點有: 自動化提示代碼。 保存的時候自動格式化代碼,讓您編寫的代碼更加美觀,符合Go的標(biāo)準(zhǔn)。 支持項目管理 支持語法高亮 熟悉Java的讀者應(yīng)該對于idea不陌生,idea是通過一個插件來支持go語言的高亮語法,代碼提示和重構(gòu)實現(xiàn)。
三次握手:
1. 主動發(fā)起連接請求端(客戶端),發(fā)送 SYN 標(biāo)志位,攜帶數(shù)據(jù)包、包號
2. 被動接收連接請求端(服務(wù)器),接收 SYN,回復(fù) ACK,攜帶應(yīng)答序列號。同時,發(fā)送SYN標(biāo)志位,攜帶數(shù)據(jù)包、包號
3. 主動發(fā)起連接請求端(客戶端),接收SYN 標(biāo)志位,回復(fù) ACK。
被動端(服務(wù)器)接收 ACK —— 標(biāo)志著 三次握手建立完成( Accept()/Dial() 返回 )
四次揮手:
1. 主動請求斷開連接端(客戶端), 發(fā)送 FIN標(biāo)志,攜帶數(shù)據(jù)包
2. 被動接受斷開連接端(服務(wù)器), 發(fā)送 ACK標(biāo)志,攜帶應(yīng)答序列號。 —— 半關(guān)閉完成。
3. 被動接受斷開連接端(服務(wù)器), 發(fā)送 FIN標(biāo)志,攜帶數(shù)據(jù)包
4. 主動請求斷開連接端(客戶端), 發(fā)送 最后一個 ACK標(biāo)志,攜帶應(yīng)答序列號?!?發(fā)送完成,客戶端不會直接退出,等 2MSL時長。
等 2MSL待目的:確保服務(wù)器 收到最后一個ACK
滑動窗口:
通知對端本地存儲數(shù)據(jù)的 緩沖區(qū)容量?!?write 函數(shù)在對端 緩沖區(qū)滿時,有可能阻塞。
TCP狀態(tài)轉(zhuǎn)換:
1. 主動發(fā)起連接請求端:
CLOSED —— 發(fā)送SYN —— SYN_SENT(了解) —— 接收ACK、SYN,回發(fā) ACK —— ESTABLISHED (數(shù)據(jù)通信)
2. 主動關(guān)閉連接請求端:
ESTABLISHED —— 發(fā)送FIN —— FIN_WAIT_1 —— 接收ACK —— FIN_WAIT_2 (半關(guān)閉、主動端)
—— 接收FIN、回復(fù)ACK —— TIME_WAIT (主動端) —— 等 2MSL 時長 —— CLOSED
3. 被動建立連接請求端:
CLOSED —— LISTEN —— 接收SYN、發(fā)送ACK、SYN —— SYN_RCVD —— 接收 ACK —— ESTABLISHED (數(shù)據(jù)通信)
4. 被動斷開連接請求端:
ESTABLISHED —— 接收 FIN、發(fā)送 ACK —— CLOSE_WAIT —— 發(fā)送 FIN —— LAST_ACK —— 接收ACK —— CLOSED
windows下查看TCP狀態(tài)轉(zhuǎn)換:
netstat -an | findstr? 端口號
Linux下查看TCP狀態(tài)轉(zhuǎn)換:
netstat -an | grep? 端口號
TCP和UDP對比:?
TCP: 面向連接的可靠的數(shù)據(jù)包傳遞。 針對不穩(wěn)定的 網(wǎng)絡(luò)層,完全彌補(bǔ)。ACK
UDP:無連接不可靠的報文傳輸。 針對不穩(wěn)定的 網(wǎng)絡(luò)層,完全不彌補(bǔ)。還原網(wǎng)絡(luò)真實狀態(tài)。
優(yōu)點???????????????????????????????????????????????????????????? 缺點
TCP: 可靠、順序、穩(wěn)定 ???????????????????????????????????? 系統(tǒng)資源消耗大,程序?qū)崿F(xiàn)繁復(fù)、速度慢
UDP:系統(tǒng)資源消耗小,程序?qū)崿F(xiàn)簡單、速度快 ???????????????????????? 不可靠、無序、不穩(wěn)定
使用場景:
TCP:大文件、可靠數(shù)據(jù)傳輸。 對數(shù)據(jù)的 穩(wěn)定性、準(zhǔn)確性、一致性要求較高的場合。
UDP:應(yīng)用于對數(shù)據(jù)時效性要求較高的場合。 網(wǎng)絡(luò)直播、電話會議、視頻直播、網(wǎng)絡(luò)游戲。
UDP-CS-Server實現(xiàn)流程:
1.? 創(chuàng)建 udp地址結(jié)構(gòu) ResolveUDPAddr(“協(xié)議”, “IP:port”) —— udpAddr 本質(zhì) struct{IP、port}
2.? 創(chuàng)建用于 數(shù)據(jù)通信的 socket ListenUDP(“協(xié)議”, udpAddr ) —— udpConn (socket)
3.? 從客戶端讀取數(shù)據(jù),獲取對端的地址 udpConn.ReadFromUDP() —— 返回:n,clientAddr, err
4.? 發(fā)送數(shù)據(jù)包給 客戶端 udpConn.WriteToUDP("數(shù)據(jù)", clientAddr)
UDP-CS-Client實現(xiàn)流程:
1.? 創(chuàng)建用于通信的 socket。 net.Dial("udp", "服務(wù)器IP:port") —— udpConn (socket)
2.? 以后流程參見 TCP客戶端實現(xiàn)源碼。
UDPserver默認(rèn)就支持并發(fā)!
------------------------------------
命令行參數(shù): 在main函數(shù)啟動時,向整個程序傳參。 【重點】
語法: go run xxx.go ? argv1 argv2? argv3? argv4 。。。
xxx.exe:? 第 0 個參數(shù)。
argv1 :第 1 個參數(shù)。
argv2 :第 2 個參數(shù)。
argv3 :第 3 個參數(shù)。
argv4 :第 4 個參數(shù)。
使用: list := os.Args? 提取所有命令行參數(shù)。
獲取文件屬性函數(shù):
os.stat(文件訪問絕對路徑) —— fileInfo 接口
fileInfo 包含 兩個接口。
Name() 獲取文件名。 不帶訪問路徑
Size() 獲取文件大小。
網(wǎng)絡(luò)文件傳輸 —— 發(fā)送端(客戶端)
1.? 獲取命令行參數(shù),得到文件名(帶路徑)filePath list := os.Args
2.? 使用 os.stat() 獲取 文件名(不帶路徑)fileName
3.? 創(chuàng)建 用于數(shù)據(jù)傳輸?shù)?socket? net.Dial("tcp", “服務(wù)器IP+port”) —— conn
4.? 發(fā)送文件名(不帶路徑)? 給接收端, conn.write()
5.? 讀取 接收端回發(fā)“ok”,判斷無誤。封裝函數(shù) sendFile(filePath, conn) 發(fā)送文件內(nèi)容
6.? 實現(xiàn) sendFile(filePath,? conn)
1) 只讀打開文件 os.Open(filePath)
for {
2) 從文件中讀數(shù)據(jù)? f.Read(buf)
3) 將讀到的數(shù)據(jù)寫到socket中? conn.write(buf[:n])
4)判斷讀取文件的 結(jié)尾。 io.EOF. 跳出循環(huán)
}
網(wǎng)絡(luò)文件傳輸 —— 接收端(服務(wù)器)
1. 創(chuàng)建用于監(jiān)聽的 socket net.Listen() —— listener
2. 借助listener 創(chuàng)建用于 通信的 socket listener.Accpet()? —— conn
3. 讀取 conn.read() 發(fā)送端的 文件名, 保存至本地。
4. 回發(fā) “ok”應(yīng)答 發(fā)送端。
5. 封裝函數(shù),接收文件內(nèi)容 recvFile(文件路徑)
1) f = os.Create(帶有路徑的文件名)
for {
2)從 socket中讀取發(fā)送端發(fā)送的 文件內(nèi)容 。 conn.read(buf)
3)? 將讀到的數(shù)據(jù) 保存至本地文件 f.Write(buf[:n])
4)? 判斷 讀取conn 結(jié)束, 代表文件傳輸完成。 n == 0? break
}