本文目錄一覽:
- 1、在項目中使用Protobuf協議實現數據傳輸(二)
- 2、windos平台下php中怎麼使用protobuf-CSDN論壇
- 3、了解一下ProtoBuf
- 4、php 怎麼用protobuf
- 5、gRPC入坑記
- 6、如何查看php是否支持protobuf
在項目中使用Protobuf協議實現數據傳輸(二)
上篇已經簡單的分析了什麼是ProtoBuf協議的優缺點、簡單的環境配置、項目中的簡單使用和一些編寫.Proto文件的注意點,下面我們更加深入一下ProtoBuf的語法及高級使用(非常感謝Carson_Ho大神的博文指導)
作用 :防止不同 .proto 項目間命名 發生衝突
ProtoBuf包的解析過程如下 :
作用 :影響 特定環境下 的處理方式,但不改變整個文件聲明的含義
常用Option選項 :(因為使用有限,簡單列舉常見的)
作用 :真正用於描述 數據結構
在.proto消息模型中主要有 消息對象欄位
組成 :欄位 = 欄位修飾符 + 欄位類型 +欄位名 +標識號(主要針對proto2以前版本)
欄位 = 欄位類型 +欄位名 +標識號(主要針對proto3及以後版本)
一個消息對象 可以將 其他消息對象類型 用作欄位類型
關於ProtoBuf在項目中的實踐的高級用法請關註:下一篇博客:在項目中使用Protobuf協議實現數據傳輸(三)
windos平台下php中怎麼使用protobuf-CSDN論壇
當兩個進程在進行遠程通信時,
彼此可以發送各種類型的數據。
無論是何種類型的數據,都會以二進位序列的形式在網路上傳送。發送方需要把這個對象轉換為位元組序列,才能在網路上傳送;接收方則需要把位元組序列再恢復為對象。 把對象轉換為位元組序列的…
了解一下ProtoBuf
我們在進行網路通信調用的時候,總是需要將內存的數據塊經過序列化,轉換成為一種可以通過網路流進行傳輸的格式。而這種格式在經過了傳輸之後再經過序列化,能還原成我們預想中的數據結構。
那麼我們對於這種用於中間網路傳輸的數據格式就有一定的要求。首先它可以準確地描述數據內容,在此基礎上我們則希望它盡量的小。
最開始流行起來的是XML,可擴展標記語言。由於它可以用來標記數據、定義數據類型,所以用戶可以自己定義數據自己的語言,從而讓對不同的數據結構化成統一的格式稱為了可能。
而另外一個我們熟知的則是JSON(JavaScript Object Notation, JS 對象簡譜)。儘管JSON中缺少了XML中的標籤屬性等描述方式,但是足夠簡介和清晰的層次結構使得其成為了必XML更受歡迎的數據交換格式。
同一份數據顯然JSON的數據量比XML所使用的空間更少。那麼空間省略在哪裡呢?一方面是json使用更簡單的字元來定義數據間的關聯關係;另一方面是JSON減少了對數據類型的描述。但是丟少的數據類型再哪裡呢?
以Java中的 OpenFeign 舉例,JSON中缺少的類型定義被定義道程序中的介面中了。當進行序列化與反序列化時,JSON格式並不記錄數據的類型,具體的數據類型在序列化方與反序列化方通過事先約定的介面來進行定義。這樣就減少了信息傳輸過程中的信息量,從而讓數據得以壓縮。
但是JSON由於沒有定義數據類型,所以在傳輸的過程中實際上就都是文本流,那麼這種方法還可以進一步壓縮嗎?
結合上文的討論,我們先說結論:方法是有的,並寫當前的實現方式是ProtoBuf。但在此之前我們先來了解一下ProtoBuf。
我們可以先看看官方給出的定義與描述:
同樣的,ProtoBuf也是一種支持序列化反序列化的方法,並且他具有很多優點:
實際上,ProtoBuf提供了一種通用的數據描述方式,這種定義數據的方式是通用的,就如同JSON或者XML一樣。
接下來我們來來回答本節一開始的問題,針對JSON來說,ProtoBuf是如何將體積變得更小的呢?答案很簡單,就是為數據序列化反序列化提供更多的先驗知識。
本文暫不過度深入ProtoBuf原理,但是可以通過一張圖來進行簡要說明():
ProtoBuf中的數據是按順序進行排列,而整體的結構為若干個field,每一個field中由 Tag-[Length]-Value 組成。Length是可選的,而是否存在Length是通過Tag的類型來決定的。也就是說如果是指定的類型,比如int64,那我們就可以知道Value的長度,也就不用在依靠Length來對其空間進行描述(redis中的壓縮列表也是這個思想)。
那麼field應該對應的是什麼欄位呢?這個則是在序列化與反序列化時在ProtoBuf的服務端與客戶端之間進行預先定義的。而因為提前定義了field的類型、排序,所以field本身可以不用對欄位名、欄位位置進行描述,只需要根據欄位類型選用合適的二進位序列化方法,將欄位本身的value值進行序列化傳輸即可。
稍微總結一下:
ProtoBuf通過對傳輸欄位的名稱、順序進行預定義,從而在傳輸結構中只需要順序的記錄每個欄位的類型標籤和二進位值。
儘管上文和官方中都是以XML或者JSON來對ProtoBuf進行對比。但是因為ProtoBuf本身就是二進位序列化方式,所以從壓縮比上比較感覺有點欺負人。
對應的在Java中二進位常用的序列化器有Kryo和Hessian。但事實上,由於Kryo和Hessian中都需要對Java類名和欄位信息進行存儲。而ProtoBuf則只有Tag-Length-Value的數據對,且Value更是有針對性的特殊編碼,所以空間佔用小的很多。
Kryo是專門針對Java進行優化了的。所以在使用的便捷性上來說Kryo則更加方便。但ProtoBuf是跨平台的,且由於進行了欄位的順序定義,所以似的ProtoBuf定義後的介面是可以向前兼容的(只向後追加欄位),而這種優勢是Kryo所沒有的。
ProtoBuf是跨語言的,使用ProtoBuf的第一步是先定一個 proto 文件 ,而由於ProtoBuf 2和3語言版本的不同,其定義格式會有所不同,具體的細節還是得參考官方文檔:
對於ProtoBuf 3 的定義文檔我們可以按如下方法定義:
其中message關鍵字是定義的文件名,而 string、int32則是預定的欄位類型,repeated則是描述欄位為可重複任意多次的欄位。
ProtoBuf通過這種形式的文件定義了傳輸信息的文件結構。
但是之前小節中我們知道了ProtoBuf是通過 Tag-[Length]-Value 組成的數據組來進行信息傳輸的,那麼proto文件中定義的內容如何轉換為實際傳輸的對象呢?
ProtoBuf的做法是,為每一種語言提供一個生成器protoc。通過使用protoc則可以根據.proto文件生成為一組java文件。對應的官方語法演示樣例為:
官方的生成參考為:
生成後的java文件將提供對應的實體以及數據的構造方法等文件,從而支持後續的使用。
需要注意的是,ProtoBuf是本質上是序列化方法,具體是通過Spring Cloud 的OpenFeign進行介面調用,還是通過grpc進行介面調用,都是可以的。
本文對ProtoBuff進行了概念的整理,並沒有對每個細節都進行深入的梳理,可以當作概念科普來進行閱讀。
php 怎麼用protobuf
PHP 是一種新型的 CGI 程序編寫語言.應該說是個嵌入式腳本文件。和ASP、JSP有很多類似的功能。唯一不同的是,ASP要整站的解釋在傳遞,而PHP則可以嵌入HTML代碼里,和HTML一起發送。要讀.PHP文件就要用PHP解釋器。現在用的是PHP V4.3.0有支持 Windows和 Unix/Linux的版本。當然你還要在自己機子上虛擬主機,可以用很出名的Apache軟體。php可以用文本編輯器(如記事本、emeditor、phpedit等)打開。如果要運行它得安裝相應的php解釋器和web服務支持才行。希望對你有幫助,謝謝
gRPC入坑記
概要
由於gRPC主要是谷歌開發的,由於一些已知的原因,gRPC跑demo還是不那麼順利的。單獨寫這一篇,主要是gRPC安裝過程中的坑太多了,記錄下來讓大家少走彎路。
主要的坑:
本文講解gRPC demo的同時,會介紹如何解決這些坑。本文對應的Github地址: 。該倉庫存儲了demo示例,以及部分系統編譯好的二進位包,大家覺得有些步驟里耗時實在太長了,可以直接clone該倉庫,複製二進位包到對應目錄(僅限測試開發,生產環境還是老老實實自己編譯吧)。
升級GCC
gRPC命令行工具編譯需要使用 GCC4.8及以上版本。CentOS6系列的內置版本是GCC4.7。
如果你的系統GCC版本=4.8,可以忽略本節。如果僅使用golang、java,請忽略本節。
如果需要升級gcc至4.8或更高版本,建議直接採用安裝SCL源之後安裝devtoolset-6(devtoolset-6目前gcc版本為6.3),因為devtoolset-4及之前的版本都已經結束支持,只能通過其他方法安裝。
升級到gcc 6.3:
需要注意的是scl命令啟用只是 臨時 的,退出shell或重啟就會恢復原系統gcc版本。如果要長期使用gcc 6.3的話:
這樣退出shell重新打開就是新版的gcc了。其它版本同理。
升級到gcc 7.3:
已經停止支持的devtoolset4(gcc 5.2)及之前版本的安裝方法,可能比較慢,大家感興趣的話可以嘗試。
編譯gRPC命令行工具
gRPC分C、JAVA、GO、NodeJS版本,C版本包括C++, Python, Ruby, Objective-C, PHP, C#,這些語言都是基於C版本開發的,共用代碼庫一個代碼庫。
如果使用C版本的gRPC,最終要從源碼里編譯出下列工具:
這些工具作為插件供proto編譯器使用。需要先下載 grpc/grpc github上的源碼。
這裡有2個坑:
1、grpc/grpc倉庫比較大,鑒於國內訪問的網速,建議使用國內鏡像。碼雲()提供了同步更新的鏡像地址:
這樣下載速度提高了不少。
2、git submodule update這個命令實際就是在下載.gitmodules文件里定義的第三方依賴項到third_party目錄,這個依賴項有很多,大家可以打開.gitmodules文件查看下詳情。依賴的倉庫都在github上,下載沒幾個小時是下載不下來的,就等著慢慢下載吧。
回頭想想,我們花費了很多時間,結果只是為了得到grpc的proto編譯插件。
PHP相關支持
PHP暫時不支持作為grpc的服務端。作為客戶端是可以的,需要機器安裝:
其中protoc和protobuf c擴展已經在 Protobuf 小試牛刀 介紹過了,這裡不再贅述。上一小節里如果安裝成功,那麼grpc_php_plugin也是有了的。下面介紹如何安裝PHP版的gRPC庫。
安裝grpc c擴展:
要求:GCC編譯器需要4.8及以上版本。可以使用pecl安裝:
也可以指定版本:
或者下載源碼()安裝:
grpc/grpc代碼庫里也有PHP擴展的C源碼,在grpc/src/php/ext/grpc目錄,進去也可以直接編譯。
編譯完成後在php.ini里添加,使用php –ri grpc可以查看信息。
安裝完C擴展後,還需要使用composer安裝grpc的庫:
gRPC示例
編寫gRPC proto
一共定義了三個文件:
其中 User 作為 Model定義,Response 用於 RPC統一返回定義,GreeterService 則是服務介面定義。
限於篇幅,proto文件詳見 倉庫的proto目錄。
GreeterService.proto文件內容如下:
這裡面定義了一個service,相當於定義了一個服務介面,我們把方法名、參數定義好了,後面需要去實現它。由於gRPC不支持PHP作為服務端,這裡我們使用Golang作為服務端。
首先需要使用proto工具編譯出golang的代碼:
執行成功,會在 Pb_Go目錄里生成Go代碼:
如果需要生成PHP客戶端的代碼,則需要使用grpc php的命令行工具grpc_php_plugin,前面小結如果執行成功,這個工具已經有了。然後:
最終生成的文件:
注意:編譯那裡如果我們不加–grpc_out=../$out –plugin=protoc-gen-grpc=/usr/local/bin/grpc_php_plugin,生成的PHP類是沒有GreeterClient的。這個文件是gRPC編譯工具自動生成的,用於連接gRPC服務端。
go編寫服務
我們用Golang寫服務端。上面雖然生成了Golang的部分代碼,但真正的服務還沒有寫呢。
main.go
首先我們新建個main.go,代碼不多,我直接貼出來:
然後就可以編譯了。
有個大坑:go build main.go的時候會先下載go.mod里定義的依賴(依賴比較多,詳情查看:),其中下面這條非常慢,倉庫太大了,雖然重定向到github:
為了快速下載,我在碼雲上做了鏡像,地址:gitee.com/52fhy/google-api-go-client 。改了之後下載快多了。
編譯成功後,生成了二進位文件main。我們可以直接運行:
go test
為了測試我們寫的服務是否正常,可以寫測試用例:
test_client.go
運行:
運行有點慢,感覺依賴的庫多了。
php客戶端
使用gRPC PHP客戶端,確保你已經安裝了:
示例:
client_test.php
運行後輸出:
常見問題
1、CentOS6使用 go mod獲取第三方依賴包unknown revision xxx錯誤
解決:其實go mod調用鏈中會用到一些git指令,當git版本比較舊時,調用失敗產生錯誤,並給出歧義的提示信息。方法就是升級git版本,CentOS6自帶的git是1.7版本。升級完畢後,再嘗試go mod。
快速升級方法:
centos6:
2、PHP報錯:Fatal error: Class ‘Google\Protobuf\Internal\Message’ not found
解決:請安裝PHP的protobuf c擴展。
3、PHP報錯:Fatal error: Class ‘\Grpc\BaseStub’ not found
解決:使用composer require grpc/grpc安裝grpc。另外對應的grpc C擴展也要安裝。
4、下載 github release包很慢怎麼辦?
解決:下載Mac版 Free Download Manager 下載工具可以解決Github 下載緩慢或失敗問題。速度嗖嗖的。
參考
1、為CentOS 6、7升級gcc至4.8、4.9、5.2、6.3、7.3等高版本
2、centos 6.x/7.x使用yum升級git版本 – 夜空
3、Protobuf 小試牛刀 – 飛鴻影
(本文完)
如何查看php是否支持protobuf
首先要知道,protobuf是google提供的一個開源序列化框架,類似於XML,JSON這樣的數據表示語言,詳情訪問protobuf的google官方網站。
為什麼要使用呢!
使用protobuf主要是, 一條消息數據,用protobuf序列化後的大小是json的10分之一,xml格式的20分之一,是二進位序列化的10分之一。
其次要知道,protobuf原生支持程序語言c++,java,python;其它的語言需要第三方或者自己寫,序列化和反序列化的效率不保證。若是真要在php中使用,網路也很多,層次不齊,可斟酌!
參考:
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/283363.html