本文目錄一覽:
- 1、使用golang編寫簡單的算法
- 2、怎樣學習GO語言?
- 3、golang多線程簡單邏輯
- 4、go語言實現一個簡單的簡單網關
- 5、golang對etcd的簡單操作
- 6、簡單聊聊Golang中defer預計算參數
使用golang編寫簡單的算法
通過編寫一些簡單的算法學習golang語言。
下面是插入排序算法golang語言的實現:
一般的寫法:
golang語言sort包裏面的寫法:
怎樣學習GO語言?
golang學習比較簡單,不過任何一門語言都不是孤立存在的,在這裡簡要說明一下golang開發的學習路線
1.golang基礎,包括go語言安裝,go語言語法,流程控制語句,函數,方法,面向對象概念,網絡編程,並發編程等
2.golang開發框架,包括beego,gin,Iris,Echo等
3.微服務開發
4.深入的話還可以學習算法部分。如果要接觸區塊鏈相關技術的話,還需要學習區塊鏈的加密算法等相關知識
5.如果要結合go實現應用的話,肯定離不開各種數據庫,比如關係型數據庫oracle、mysql,或者各類非關係型數據庫等等
6.如果需要開發界面的話,還需要學習網頁編程如html,javascript,vue,elementUI,bootstrap等網頁開發技術和框架。
7.在以上學習的基礎上還可以向架構方面深入學習。
鏈喬教育在線祝您學有所成。
golang多線程簡單邏輯
實現指定個核心最大化使用,比如核心總數減一。
必要的庫。
要使用的cpu數量,建議不全使用。
建立管道。
聲明使用的cpu數。
建立互斥關係,本例中主要為了實現所有線程執行完後再執行後續程序。
創建cpu數減1個線程
後面每個任務結束時要done一個wg,這裡根據具體情況加,是循環就在每個循環里加,保證後面能全部done即可
沒有緩衝的、阻塞式的往管道傳遞字符串。
Wait是等所有線程都執行完,即增加的數字被全done掉。
關閉管道。
假設已有的函數是ReadLogs,在它的基礎上加個Wg加函數名的新函數,我覺得這種方式不改變原有的,比較舒服。
大意是:循環從管道讀取字符串,讀不到了就跳出循環。
每個ReadLogs()之後加一個wg.Done(),相當於計數減一。
ReadLogs()就是要執行的任務,不再解釋。
就是開指定個線程。
管道阻塞傳值。
wg同步。
WgReadLogs循環接收。
go語言實現一個簡單的簡單網關
網關=反向代理+負載均衡+各種策略,技術實現也有多種多樣,有基於 nginx 使用 lua 的實現,比如 openresty、kong;也有基於 zuul 的通用網關;還有就是 golang 的網關,比如 tyk。
這篇文章主要是講如何基於 golang 實現一個簡單的網關。
轉自: troy.wang/docs/golang/posts/golang-gateway/
整理:go語言鍾文文檔:
啟動兩個後端 web 服務(代碼)
這裡使用命令行工具進行測試
具體代碼
直接使用基礎庫 httputil 提供的NewSingleHostReverseProxy即可,返回的reverseProxy對象實現了serveHttp方法,因此可以直接作為 handler。
具體代碼
director中定義回調函數,入參為*http.Request,決定如何構造向後端的請求,比如 host 是否向後傳遞,是否進行 url 重寫,對於 header 的處理,後端 target 的選擇等,都可以在這裡完成。
director在這裡具體做了:
modifyResponse中定義回調函數,入參為*http.Response,用於修改響應的信息,比如響應的 Body,響應的 Header 等信息。
最終依舊是返回一個ReverseProxy,然後將這個對象作為 handler 傳入即可。
參考 2.2 中的NewSingleHostReverseProxy,只需要實現一個類似的、支持多 targets 的方法即可,具體實現見後面。
作為一個網關服務,在上面 2.3 的基礎上,需要支持必要的負載均衡策略,比如:
隨便 random 一個整數作為索引,然後取對應的地址即可,實現比較簡單。
具體代碼
使用curIndex進行累加計數,一旦超過 rss 數組的長度,則重置。
具體代碼
輪詢帶權重,如果使用計數遞減的方式,如果權重是5,1,1那麼後端 rs 依次為a,a,a,a,a,b,c,a,a,a,a…,其中 a 後端會瞬間壓力過大;參考 nginx 內部的加權輪詢,或者應該稱之為平滑加權輪詢,思路是:
後端真實節點包含三個權重:
操作步驟:
具體代碼
一致性 hash 算法,主要是用於分佈式 cache 熱點/命中問題;這裡用於基於某 key 的 hash 值,路由到固定後端,但是只能是基本滿足流量綁定,一旦後端目標節點故障,會自動平移到環上最近的那麼個節點。
實現:
具體代碼
每一種不同的負載均衡算法,只需要實現添加以及獲取的接口即可。
然後使用工廠方法,根據傳入的參數,決定使用哪種負載均衡策略。
具體代碼
作為網關,中間件必不可少,這類包括請求響應的模式,一般稱作洋蔥模式,每一層都是中間件,一層層進去,然後一層層出來。
中間件的實現一般有兩種,一種是使用數組,然後配合 index 計數;一種是鏈式調用。
具體代碼
golang對etcd的簡單操作
首先獲取clientv3:
連接etcd:
kv是一個用於操作kv的連接,其實它本質上是用了client的conn,為了更加專註於鍵值對的操作,關閉client後也會使kv無法用。(kv的操作client也能實現)
設置一個超時的context:
context.WithTimeout()會返回一個timerCtx{},並在這個結構體里注入了超時時間。cancleFunc是一個取消操作的函數。put,get等操作是阻塞型操作,context里有一個用於管理超時的select,當時間一到就會隱式執行cancelFunc,使操作停止並返回錯誤。如果顯式的調用cancelFunc()則會立即停止操作,返回錯誤。
put操作:
由於etcd是有序存儲鍵值對的,還可以附加clientv3.WithFromKey(),clientv3.WithLimit()來實現分頁獲取的效果。
監聽etcd集群鍵的改變:
簡單聊聊Golang中defer預計算參數
什麼是defer
defer 可以保證方法可以在外圍函數返回之前調用。有點像其他言的 try finally
Go語言defer預計算參數
Go 語言中所有的函數調用都是傳值的,雖然 defer 是關鍵字,但是也繼承了這個特性。假設我們想要計算 main 函數運行的時間,可能會寫出以下的代碼:
結果是:
運行結果並不符合我們的預期,這個現象背後的原因是什麼呢?經過分析,我們會發現調用 defer 關鍵字會立刻拷貝函數中引用的外部參數,所以 time.Since(startedAt) 的結果不是在 main 函數退出之前計算的,而是在 defer 關鍵字調用時計算的【defer入棧的時候】,最終導致上述代碼輸出 0s
我們再來看個簡單例子來說明上述解釋:
當代碼運行到defer fmt.Println(test(i))的時候,會把defer右邊最外層函數的參數計算完畢,並傳遞進函數里,但不會執行函數體的代碼直到包裹defer的函數返回。我們先看會把defer右邊最外層函數的參數計算完畢,並傳遞進函數里這句話,對應例子就是先把test(i)算出來,此時i=1,計算test(1)得2,然後fmt.Println(2)入棧,等到最後程序運行完了再運行defer結果就是2(但不會執行函數體的代碼直到包裹defer的函數返回)。
我們再來看一個例子與匿名函數結合:
結果:
使用匿名函數,結果是101,相當於i給到test方法的是100,那為什麼呢?還是那句話:但不會執行函數體的代碼直到包裹defer的函數返回
也就是說他會把整個{ fmt.Println(test(i)) }()函數體入棧,等到最後程序運行完了再運行defer,此時的i是100,運行test後就是101了。
所以你要解決第一個打印為0s的問題,你就可以使用匿名函數來解決,如下:
結果:
原創文章,作者:DTEOJ,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/330458.html