自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go 插件系統(tǒng),一個(gè)涼了快半截的特性?

開發(fā) 后端
目前在 Go 工程中普遍還沒廣泛的使用起來,覆蓋率不高。在 Go issues 上吐槽挺多,甚至感覺有點(diǎn)像涼了半截的樣子。

[[417690]]

本文轉(zhuǎn)載自微信公眾號(hào)「腦子進(jìn)煎魚了」,作者陳煎魚。轉(zhuǎn)載本文請(qǐng)聯(lián)系腦子進(jìn)煎魚了公眾號(hào)。

大家好,我是煎魚。

在 Go 語言中,有一個(gè)好像很好用,但卻比較少人提及的功能,那就是 Go Plugin。

目前在 Go 工程中普遍還沒廣泛的使用起來,覆蓋率不高。在 Go issues 上吐槽挺多,甚至感覺有點(diǎn)像涼了半截的樣子。

前段時(shí)間小咸魚的同事問了他這功能怎么用,他正想甩出一個(gè)鏈接,但發(fā)現(xiàn)...煎魚竟然沒寫過,這不,Go 知識(shí)板塊的文章地圖得補(bǔ)全。

今天煎魚就大家一起學(xué)習(xí) Go Plugin,看看為什么會(huì)說感覺 “有點(diǎn)像涼了半截” 的樣子,打開來看看這個(gè)問題在哪。

是什么

Go Team 最早在 Go1.7 實(shí)驗(yàn),在 Go1.8 正式引入了 Go Plugin 的機(jī)制。于 2016 年發(fā)布,一開始僅支持 Linux 實(shí)現(xiàn):

Go Plugin 機(jī)制實(shí)現(xiàn)了 Go 插件的加載和符號(hào)解析,能夠支持將我們所編寫的 Go 包編譯為共享庫(.so)。

這樣 Go 工程就可以加載所編譯好的 Go Plugin(已經(jīng)變成了共享庫文件),在程序中調(diào)用共享庫中的函數(shù)、常量、變量等使用。也稱其為 Go 語言中的熱插拔的插件系統(tǒng)。

截止 Go1.17 為止,Go Plugin 僅支持在 Linux、FreeBSD 和 MacOS 上運(yùn)行,還不支持 Windows。

為什么需要

Go 語言是靜態(tài)語言,正常我們寫一個(gè)程序,分如下兩個(gè)角度來看:

  • 從代碼編寫的角度來看:我們?cè)诔绦蚓帉懙臅r(shí)候就已經(jīng)把所有的功能實(shí)現(xiàn)給確定了,不會(huì)發(fā)生什么根本性的變化。
  • 從程序的角度來看:在 Go 進(jìn)行編譯時(shí),就已經(jīng)把所有引用的標(biāo)準(zhǔn)庫、第三方庫等都編譯打包好進(jìn)二進(jìn)制文件了,因此也就無法在運(yùn)行時(shí)去動(dòng)態(tài)加載,所以沒法有其它的可能性。

那么為什么需要 Go Plugin 呢,原因如下:

  • 可插拔的插件:程序能夠隨時(shí)的安裝插件,也能夠卸載他,獲得更多運(yùn)行時(shí)的自定義能力。
  • 可動(dòng)態(tài)加載運(yùn)行時(shí)模塊:隨時(shí)安裝了插件,自然也就需要可自行決定運(yùn)行哪個(gè)插件的模塊了。
  • 可獨(dú)立開發(fā)插件、模塊:主系統(tǒng)和子插件,可能由不同的團(tuán)隊(duì)開發(fā)和提供,也更有價(jià)值。

其實(shí)本質(zhì)上還是希望程序能夠在運(yùn)行時(shí)實(shí)現(xiàn)動(dòng)態(tài)的外部加載,根據(jù)不同的條件、場(chǎng)景加載不同的插件功能。

使用方法

通用概念

Go 官方給出的例子非常簡(jiǎn)單,只需要在 Go 編譯時(shí)指定為插件就可以了。

編譯的命令例子如下:

  1. go build -buildmode=plugin 

當(dāng)一個(gè)插件初次被打開時(shí),所有尚未成為程序一部分的包的init函數(shù)被調(diào)用。不過主函數(shù)不被運(yùn)行。需要注意一個(gè)插件只會(huì)被初始化一次,插件不能被關(guān)閉。

其共有如下幾個(gè) API:

  1. type Plugin 
  2.     func Open(path string) (*Plugin, error) 
  3.     func (p *Plugin) Lookup(symName string) (Symbol, error) 
  4. type Symbol 
  • Plugin.Open:開啟一個(gè) Go 插件。如果一個(gè)路徑已經(jīng)被打開,那么將返回現(xiàn)有的 *Plugin。
  • Plugin.Lookup:在插件中搜索名所傳入的符號(hào),符號(hào)是任何導(dǎo)出的變量或函數(shù)。如果沒有找到該符號(hào),它會(huì)報(bào)告一個(gè)錯(cuò)誤。

主要就是細(xì)分為插件和符號(hào),符號(hào)(Symbol)本身是一個(gè) interface,在調(diào)用 Plugin 相關(guān)方法后還是需要進(jìn)一步斷言才能使用。

實(shí)際編寫

了解基本定義后,我們定義一個(gè)插件,一般我們會(huì)有個(gè) plugins/ 的目錄,作為主程序的附屬插件集。

插件的代碼如下:

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. var V int 
  6.  
  7. func F() { 
  8.  fmt.Printf("腦子進(jìn)了 %d 次煎魚 \n", V) 

包名必須為 main,在該插件根目錄運(yùn)行:

  1. go build -buildmode=plugin -o plugin.so main.go 

就可以看到在編譯的目錄下多出了 plugin.so 文件,這就是這個(gè)插件經(jīng)過編譯后的動(dòng)態(tài)庫 .so 文件。

隨后只需在主程序加載這個(gè)插件就可以了,如下:

  1. import ( 
  2.  "plugin" 
  3.  
  4. func main() { 
  5.  p, err := plugin.Open("plugin.so"
  6.  if err != nil { 
  7.   panic(err) 
  8.  } 
  9.  v, err := p.Lookup("V"
  10.  if err != nil { 
  11.   panic(err) 
  12.  } 
  13.  f, err := p.Lookup("F"
  14.  if err != nil { 
  15.   panic(err) 
  16.  } 
  17.  
  18.  *v.(*int) = 999 
  19.  f.(func())() 

輸出結(jié)果:

  1. 腦子進(jìn)了 999 次煎魚  

在程序中,我們先調(diào)用了 plugin.Open 方法打開了前面所編譯的 plugin.so 動(dòng)態(tài)庫。

緊接著調(diào)用 plugin.Lookup 方法,定位到了變量 V 和 方法 F,但由于其返回值都是 Symbol(interface),因此我們需要對(duì)其進(jìn)行類型斷言,隨時(shí)才可以調(diào)用和使用。

至此完成了一個(gè)插件的基本使用。

為什么不被需要

在前面我們提到了大量 Go Plugin 的優(yōu)點(diǎn),也演示了其 Plugin 代碼編寫起來有多么的簡(jiǎn)單和方便。

但,為什么 Go Plugin 已經(jīng)發(fā)布了 4 年依然沒有被大規(guī)模應(yīng)用,甚至對(duì)于不少業(yè)務(wù)開發(fā)來講是不被需要的呢,或是壓根不知道有這東西?

究其原因,我個(gè)人認(rèn)為一個(gè)東西的廣泛應(yīng)用要至少符合以下三大點(diǎn):

  • 基數(shù):需要的場(chǎng)景多。
  • 上手:方便且易用。
  • 質(zhì)量:沒有大問題。

比較折騰的人的是,Go Plugin 這三大點(diǎn)都欠一些火候,綜合導(dǎo)致了該功能的沒有大規(guī)模應(yīng)用。

像是要應(yīng)用 Go Plugin 有諸如下約束:

  • 環(huán)境問題:不支持 Windows 等(暫無計(jì)劃,#19282),MacOS 有些問題,一開始只支持 Linux,其他的也是后面慢慢增加的支持。
  • Go 版本問題:Plugin 構(gòu)建環(huán)境和第三方包的依賴版本需要保持一致。
  • 特性問題:Plugin 特性的缺失,例如不支持插件的關(guān)閉,暫時(shí)無新計(jì)劃支持(#20461)。

總結(jié)

在 Go issues 中暢游時(shí),能看到許多小伙伴在以往 4 年踩過的坑和無奈。甚至有一個(gè)高贊回答(#19282)表示:插件功能主要是一個(gè)技術(shù)演示,由于一些不道德的原因,被作為語言的穩(wěn)定功能發(fā)布(The plugin feature is mostly a tech demo that for some unholy reason got released as a stable feature of the language.)。

目前 Go Plugin 并不是 Go Team 的優(yōu)先事項(xiàng),在 Windows/Mac 的支持存在問題。GOPATH 有問題,不同 GO 版本也有問題。更是建議如果您想要插件,請(qǐng)走較慢的 grpc 路線,因?yàn)樗鼈兪怯行У牟寮?/p>

也可以參考為數(shù)不多的一些 Go Plugin 用戶的方案,例如:tidb,甚至寫了個(gè)指導(dǎo)文檔。

但如果要在生產(chǎn)正式使用,勸你還是需要慎重考慮,又或是再等等...等更完善的那一天?

參考

Go Package plugin

Why is there no windows support for plugins?

plugin: add Windows support

plugin: Add support for closing plugins

如何評(píng)價(jià) Go 標(biāo)準(zhǔn)庫中新增的 plugin 包?

 

一文搞懂Go語言的plugin

 

責(zé)任編輯:武曉燕 來源: 腦子進(jìn)煎魚了
相關(guān)推薦

2015-07-07 12:03:01

2020-09-02 07:22:17

JavaScript插件框架

2023-01-12 08:47:26

二項(xiàng)式楊輝斐波那契

2015-10-12 15:50:07

PaaS云平臺(tái)開發(fā)go

2023-11-09 09:02:26

TypeScriptas const

2023-03-01 10:19:23

2016-03-08 09:52:22

xcode插件開發(fā)

2023-02-26 01:37:57

goORM代碼

2022-06-15 08:14:40

Go線程遞歸

2014-10-15 11:01:02

Web應(yīng)用測(cè)試應(yīng)用

2023-05-10 08:05:41

GoWeb應(yīng)用

2024-03-19 13:51:31

JavaScript插件

2014-08-15 10:34:42

快數(shù)據(jù)大數(shù)據(jù)

2021-05-06 10:52:09

Java Spring Bo框架

2014-06-16 09:11:29

快數(shù)據(jù)大數(shù)據(jù)

2024-07-19 10:31:15

2011-10-19 09:30:23

jQuery

2021-03-16 08:56:35

Go interface面試

2023-10-04 00:18:00

云原生Go語言

2024-01-03 15:09:21

云原生Go語言
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)