golang發送tls,golang發送json

本文目錄一覽:

【golang】內存逃逸常見情況和避免方式

因為如果變數的內存發生逃逸,它的生命周期就是不可知的,其會被分配到堆上,而堆上分配內存不能像棧一樣會自動釋放,為了解放程序員雙手,專註於業務的實現,go實現了gc垃圾回收機制,但gc會影響程序運行性能,所以要盡量減少程序的gc操作。

1、在方法內把局部變數指針返回,被外部引用,其生命周期大於棧,則溢出。

2、發送指針或帶有指針的值到channel,因為編譯時候無法知道那個goroutine會在channel接受數據,編譯器無法知道什麼時候釋放。

3、在一個切片上存儲指針或帶指針的值。比如[]*string,導致切片內容逃逸,其引用值一直在堆上。

4、因為切片的append導致超出容量,切片重新分配地址,切片背後的存儲基於運行時的數據進行擴充,就會在堆上分配。

5、在interface類型上調用方法,在Interface調用方法是動態調度的,只有在運行時才知道。

1、go語言的介面類型方法調用是動態,因此不能在編譯階段確定,所有類型結構轉換成介面的過程會涉及到內存逃逸發生,在頻次訪問較高的函數盡量調用介面。

2、不要盲目使用變數指針作為參數,雖然減少了複製,但變數逃逸的開銷更大。

3、預先設定好slice長度,避免頻繁超出容量,重新分配。

golang net/http包 http請求的位元組碼讀取與解析。

先配置Header最長讀取時間、req最長讀取時間、req最大讀取長度默認6M。

RFC7230禁止\r\n參數,Url中只允許包含英文字母(a-zA-Z)、數字(0-9)、-_.~4個特殊字元以及所有保留字元。但go net/http包放寬了這個要求。

先構建newTextprotoReader,由於緩衝區是對象復用的,用完後要defer put。共完以以下解析任務:

TextprotoReader數據結構,將位元組碼Reader轉成文本Reader。

第一步,從第一行解析出method uri prototype。

第二步解析URL。url.URL數據結構:

解析Scheme,協議前綴(小寫)。有查詢參數?,則配置url.ForceQuery url.RawQuery。有認證信息///…//,則解析url.User url.Host。最後配置url.Path和url.RawPath,如果Path==RawPath,則RawPath=””。

第三步解析MIMEHeader。

第四步readTransfer。重新配置如下參數:RequestMethod ProtoMajor ProtoMinor Header Trailer ContentLength Close。對於Body,如果encodings支持chunked,讀取流用chunkedReader包裹。默認情況用LimitedReader,無body賦空的struct{}。

以下情況返回非空err,示得到正確的請求:

最後配置req.ctx req.RemoteAddr req.TLS body.doEarlyClose = true。

構建Response:

其中closeNotifyCh必須在構建時初始化,沒有content所以先置contentLength為-1。

配置w.cw並被w.w包裹。w.cw緩衝默認大小2M。

獲取Request可能出現如下錯誤:

先上響應數據結構:

response欄位可以分類為:大對象、緩衝、KV對或bool型的狀態參數。

大對象有:

狀態欄位:

chunkWriter數據結構:

chunkWriter包裹了Response,功能之一是完成Header設置,包括Content-Type Content-Length chunk-header。bufio.Writer是chunkWriter是緩衝包裹。

handler將響應寫入到response.w。

調用w.w.Flush()將w寫入到cw,注意到Flush()操作,如果未刷空緩存並報錯,觸發拷貝操作。報錯不會退回已寫出的數據。

進而調用cw.Write(),根據cw.chunking參數。

putBufioWriter(w.w)清空resp.w緩衝,如果池化放回sync.pool。

根據chunkWriter的定義,w.cw.close()負責cw的結束工作:寫入換行符和resp.trailers數據。

最後刷新TCP緩衝w.conn.bufw.Flush(),完成響應包發送。並正確關閉request。

【golang】高並發下TCP常見問題解決方案

首先,看一下TCP握手簡單描繪過程:

其握手過程原理,就不必說了,有很多詳細文章進行敘述,本文只關注研究重點。

在第三次握手過程中,如果伺服器收到ACK,就會與客戶端建立連接,此時內核會把連接從半連接隊列移除,然後創建新的連接,並將其添加到全連接隊列,等待進程調用。

如果伺服器繁忙,來不及調用連接導致全連接隊列溢出,伺服器就會放棄當前握手連接,發送RST給客戶端,即connection reset by peer。

在linux平台上,客戶端在進行高並發TCP連接處理時,最高並發數量都要受系統對用戶單一進程同時打開文件數量的限制(這是因為系統每個TCP都是SOCKET句柄,每個soker句柄都是一個文件),當打開連接超過限制,就會出現too many open files。

使用下指令查看最大句柄數量:

增加句柄解決方案

golang中怎麼處理socket長連接

實際上需要 3 個 goroutine,一個 read,一個 send,還有一個 handle。

read goroutine 讀,然後寫入 recevice chan。

write goroutine 把 send chan 的東西寫。

handle goroutine 是 conn 的主要處理邏輯,負責把 recevice chan 的東西讀出來 call 業務邏輯。

業務邏輯中要寫數據就直接寫入 send chan。

這樣就可以保證,業務邏輯的讀寫都是在 handle goroutine 上處理,而避免 race 產生。

如果需要定時任務(比如心跳),就在 handle goroutine 上加上一個 timer.C;

如果需要 goroutine 下發任務,在 handle goroutine 增加一個 task chan,hanlde 收到 task 後處理業務;

如果需要輸出結果,那就增加 result chan,業務邏輯把數據輸出即可。

—————————-

還有,如果我開2個goroutine的話,client斷開連接了,假設recv goroutine先發生err並且close(fd),那在send goroutine中該如何處理呢?有可能不應該這樣處理,那應該怎麼處理呢?

如果 net.Conn Close() 了,不論 Read() 阻塞還是 Write() 阻塞都會立即收到 err 返回。

一般來說,Write() 是不可能主動知道連接斷開的,除非是 SetDeadline() 猜測對方斷掉了,指定時間內沒有寫成功就認為是斷開。Read() 是可以主動收到對方發來的斷開(TCP FIN),但也沒辦法知道異常的斷開(當然也可以設置超時)。

無論是誰,是確實收到 FIN 還是 Deadline 猜測斷開,只要 Close() 大家就知道連接斷開了。

handle goroutine 還有一個用處就是:你的程序主動結束的時候,能正確的 close conn,讓對方知道你是真的斷開了,而不用去猜。

Go 實現 TLS 雙向認證

將會在 config 文件夾中生成 ca.key 和 ca.crt 文件

將會在 config 文件夾中生成 server.key 、 server.csr 和 server.crt 文件

簽名方式: SHA-256 ,默認的 SHA-1 簽名演算法安全性不夠高,Go 中會出現警告。

將會在 config 文件夾中生成 client.key 、 client.csr 和 client.crt 文件

簽名方式: SHA-256 ,默認的 SHA-1 簽名演算法安全性不夠高,Go 中會出現警告。

wireshark 截圖如下:

golang socket通信 怎麼把一個客戶端發送的數據推送給其他客戶端

Socket通信的原理還是比較簡單的, 它大致分為以下幾個步驟。 伺服器端的步驟如下。 (1)建立伺服器端的Socket,開始偵聽整個網路中的連接請求。 (2)當檢測到來自客戶端的連接請求時,向客戶端發送收到連接請求的信息,並建立與客戶端之間的…

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/275945.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-17 19:38
下一篇 2024-12-17 19:38

相關推薦

  • 使用Golang調用Python

    在現代軟體開發中,多種編程語言的協作是相當普遍的。其中一種使用場景是Golang調用Python,這使得在使用Python庫的同時,可以利用Golang的高性能和強大並發能力。這篇…

    編程 2025-04-29
  • JSON的MD5

    在Web開發過程中,JSON(JavaScript Object Notation)是最常用的數據格式之一。MD5(Message-Digest Algorithm 5)是一種常用…

    編程 2025-04-29
  • 使用Java將JSON寫入HDFS

    本篇文章將從以下幾個方面詳細闡述Java將JSON寫入HDFS的方法: 一、HDFS簡介 首先,先來了解一下Hadoop分散式文件系統(HDFS)。HDFS是一個可擴展性高的分散式…

    編程 2025-04-29
  • 使用Golang創建黑色背景圖片的方法

    本文將從多個方面介紹使用Golang創建黑色背景圖片的方法。 一、安裝必要的代碼庫和工具 在開始創建黑色背景圖片之前,我們需要先安裝必要的代碼庫和工具: go get -u git…

    編程 2025-04-29
  • 如何使用Newtonsoft datatable轉Json

    Newtonsoft DataTable 是一個基於.NET的JSON框架,也是一個用於序列化和反序列化JSON的強大工具。 在本文中,我們將學習如何使用Newtonsoft Da…

    編程 2025-04-28
  • JPRC – 輕鬆創建可讀性強的 JSON API

    本文將介紹一個全新的 JSON API 框架 JPRC,通過該框架,您可以輕鬆創建可讀性強的 JSON API,提高您的項目開發效率和代碼可維護性。接下來將從以下幾個方面對 JPR…

    編程 2025-04-27
  • 使用Python獲取JSON並解析

    本文將介紹如何使用Python獲取JSON數據並解析相關內容。通過使用Python的第三方庫,我們可以輕鬆地處理JSON數據,包括讀取、提取和操作JSON數據。 一、獲取JSON數…

    編程 2025-04-27
  • Python存為JSON的方法及實例

    本文將從以下多個方面對Python存為JSON做詳細的闡述。 一、JSON簡介 JSON(JavaScript Object Notation)是一種輕量級的數據交換格式,易於人閱…

    編程 2025-04-27
  • 使用Spread 8展示JSON數據

    使用Spread 8可以方便地展示JSON數據,本文將詳細介紹如何利用Spread 8展示JSON數據。 一、Spread 8簡介 Spread 8是一款強大的電子表格軟體,可以方…

    編程 2025-04-27
  • 如何在json轉實體類時忽略大小寫

    本文將從以下幾個方面介紹如何在json轉實體類時忽略大小寫。 一、使用Gson庫實現json轉實體類忽略大小寫 Gson是Google提供的Java JSON操作庫,它提供了簡單易…

    編程 2025-04-27

發表回復

登錄後才能評論