最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

go實現(xiàn)thrift的網(wǎng)絡(luò)傳輸性能及需要注意問題示例解析

 更新時間:2023年09月06日 14:11:24   作者:donnie4w  
這篇文章主要為大家介紹了go實現(xiàn)thrift的網(wǎng)絡(luò)傳輸性能及需要注意問題示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

thrift簡介

thrift應(yīng)該是目前支持編程語言種類最多的跨語言 rpc服務(wù)框架, http://thrift.apache.org/

thrift實現(xiàn)了完整的網(wǎng)絡(luò)服務(wù),所以一般使用thrift時,會使用到thrift的服務(wù)框架。當(dāng)然,也可以用自己已經(jīng)實現(xiàn)的網(wǎng)絡(luò)服務(wù),用io流對接thrift接口的輸入輸出流實現(xiàn)thrift的接入。

無論是用thrift的網(wǎng)絡(luò)實現(xiàn),還是自己實現(xiàn)的網(wǎng)絡(luò)服務(wù),只要對接thrift,在調(diào)用thrift接口實現(xiàn)rpc時,都是走thrift的網(wǎng)絡(luò)傳輸方式。

thrift的網(wǎng)絡(luò)傳輸實現(xiàn)方式 不適合也不支持壓力較大的網(wǎng)絡(luò)傳輸需求。實際上,調(diào)用一次thrift接口,并不是只調(diào)一次網(wǎng)絡(luò)io寫數(shù)據(jù),而是拆分為多次寫數(shù)據(jù)傳送。

調(diào)用一個thrift 的接口發(fā)送數(shù)據(jù)時,thrift會將這個操作拆分為幾個操作:

調(diào)用thrift的方法時:thrift會找到這個方法所在的對象,調(diào)用write方法,

在write方法在,分別對各個參數(shù),依次調(diào)用 writeFieldBegin,writeXXX(具體參數(shù)類型) ,WriteFieldStop 等函數(shù)
每次調(diào)用也同時調(diào)用網(wǎng)絡(luò)io寫相應(yīng)數(shù)據(jù).

以目前最新的thrift-0.18.1實現(xiàn)為例

go的實現(xiàn)

func (p *ItnetPonMergeArgs) Write(ctx context.Context, oprot thrift.TProtocol) error {
  if err := oprot.WriteStructBegin(ctx, "PonMerge_args"); err != nil {
    return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) }
  if p != nil {
    if err := p.writeField1(ctx, oprot); err != nil { return err }
    if err := p.writeField2(ctx, oprot); err != nil { return err }
  }
  if err := oprot.WriteFieldStop(ctx); err != nil {
    return thrift.PrependError("write field stop error: ", err) }
  if err := oprot.WriteStructEnd(ctx); err != nil {
    return thrift.PrependError("write struct stop error: ", err) }
  return nil
}
//第一個參數(shù)
func (p *ItnetPonMergeArgs) writeField1(ctx context.Context, oprot thrift.TProtocol) (err error) {
  if err := oprot.WriteFieldBegin(ctx, "pblist", thrift.LIST, 1); err != nil { //WriteFieldBegin
    return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:pblist: ", p), err) }
  if err := oprot.WriteListBegin(ctx, thrift.STRUCT, len(p.Pblist)); err != nil {
    return thrift.PrependError("error writing list begin: ", err)
  }
  for _, v := range p.Pblist { 
    if err := v.Write(ctx, oprot); err != nil {
      return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err)
    }
  }
  if err := oprot.WriteListEnd(ctx); err != nil {
    return thrift.PrependError("error writing list end: ", err)
  }
  if err := oprot.WriteFieldEnd(ctx); err != nil {
    return thrift.PrependError(fmt.Sprintf("%T write field end error 1:pblist: ", p), err) }
  return err
}
//第二個參數(shù),操作類似第一個參數(shù)
func (p *ItnetPonMergeArgs) writeField2(ctx context.Context, oprot thrift.TProtocol) (err error) {
  if err := oprot.WriteFieldBegin(ctx, "id", thrift.I64, 2); err != nil {
    return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:id: ", p), err) }
  if err := oprot.WriteI64(ctx, int64(p.ID)); err != nil {
  return thrift.PrependError(fmt.Sprintf("%T.id (2) field write error: ", p), err) }
  if err := oprot.WriteFieldEnd(ctx); err != nil {
    return thrift.PrependError(fmt.Sprintf("%T write field end error 2:id: ", p), err) }
  return err
}

調(diào)用Pon(ItnetPonMergeArgs)方法的thrift傳輸順序

Write->

  • writeField1->WriteFieldBegin-> WriteByte-> io
  • -> Write16 -> io
  • ->WriteBinary-> Write32 -> io
  • ->Write -> io
  • writeField2->WriteFieldBegin-> WriteByte -> io
  • ->Write16 -> io
  • ->Write64-> Write -> io
  • WriteFieldStop ->io

可以看到,一次簡單的方法調(diào)用,如果方法中有兩個參數(shù), 則至少有8次io流寫數(shù)據(jù)調(diào)用。

如果參數(shù)多時,或是參數(shù)中一個結(jié)構(gòu)體的變量多時,則會有更多的io流寫數(shù)據(jù)調(diào)用。

在海量的網(wǎng)絡(luò)傳輸中,這樣的傳輸方式,網(wǎng)絡(luò)io流寫數(shù)據(jù)調(diào)用成倍增加,海量網(wǎng)絡(luò)io數(shù)據(jù)寫入導(dǎo)致性能急劇下降。

thrift設(shè)計的傳輸層提供了zlib協(xié)議壓縮,在zlib壓縮發(fā)送的情況下,將數(shù)據(jù)進行了整體壓縮收發(fā),zlib分為2次發(fā)送后,接收端再解壓;

以go為例子:

可以在 compress/flate 看到zlib的寫數(shù)據(jù)最終io寫入調(diào)用:

func (d *compressor) syncFlush() error {
    if d.err != nil {
        return d.err
    }
    d.sync = true
    d.step(d)
    if d.err == nil {
        d.w.writeStoredHeader(0, false)   //第一次調(diào)用
        d.w.flush()                       //第二次調(diào)用
        d.err = d.w.err
    }
    d.sync = false
    return d.err
}
//兩次io數(shù)據(jù)寫入

所以,在海量調(diào)用thrift方法的情況下,zlib模式的性能要遠(yuǎn)超非zlib的情況。但是zlib壓縮會比較消耗內(nèi)存,大量使用時可能導(dǎo)致頻繁gc,也可能導(dǎo)致性能下降。當(dāng)然,即使如此,大部分情況下zlib傳輸依然比非zlib傳輸?shù)男阅芤迷S多。

其他語言的實現(xiàn)

比如 java:

public void write(org.apache.thrift.protocol.TProtocol oprot, SelectByIdxLimit_args struct) throws org.apache.thrift.TException {
        struct.validate();
        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.name != null) {
          oprot.writeFieldBegin(NAME_FIELD_DESC);  //io調(diào)用
          oprot.writeString(struct.name);          //io調(diào)用
          oprot.writeFieldEnd();
        }
        if (struct.column != null) {
          oprot.writeFieldBegin(COLUMN_FIELD_DESC);  //io調(diào)用
          oprot.writeString(struct.column);           //io調(diào)用
          oprot.writeFieldEnd();
        }
        if (struct.value != null) {
          oprot.writeFieldBegin(VALUE_FIELD_DESC);   //io調(diào)用
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.value.size()));
            for (java.nio.ByteBuffer _iter49 : struct.value)
            {
              oprot.writeBinary(_iter49);          //io調(diào)用
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(START_ID_FIELD_DESC); //io調(diào)用
        oprot.writeI64(struct.startId);             //io調(diào)用       
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);    //io調(diào)用
        oprot.writeI64(struct.limit);                //io調(diào)用
        oprot.writeFieldEnd();
        oprot.writeFieldStop();                    //io調(diào)用
        oprot.writeStructEnd();
      }

傳輸方式都是相似的

實現(xiàn)方式各個語言都相似,當(dāng)然,數(shù)據(jù)寫入順序肯定是一樣的。

以上就是go實現(xiàn)thrift的網(wǎng)絡(luò)及傳輸性能需要注意問題示例解析的詳細(xì)內(nèi)容,更多關(guān)于go thrift的網(wǎng)絡(luò)傳輸?shù)馁Y料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語言實現(xiàn)字符串搜索算法Boyer-Moore

    Go語言實現(xiàn)字符串搜索算法Boyer-Moore

    Boyer-Moore?算法是一種非常高效的字符串搜索算法,被廣泛的應(yīng)用于多種字符串搜索場景,下面我們就來學(xué)習(xí)一下如何利用Go語言實現(xiàn)這一字符串搜索算法吧
    2023-11-11
  • Go語言-為什么返回值為接口類型,卻返回結(jié)構(gòu)體

    Go語言-為什么返回值為接口類型,卻返回結(jié)構(gòu)體

    這篇文章主要介紹了Go語言返回值為接口類型,卻返回結(jié)構(gòu)體的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • go語言的工作空間和GOPATH環(huán)境變量介紹

    go語言的工作空間和GOPATH環(huán)境變量介紹

    這篇文章主要介紹了go語言的工作空間和GOPATH環(huán)境變量介紹,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • go中redis使用的示例代碼

    go中redis使用的示例代碼

    本文主要介紹了在Go語言中使用Redis進行數(shù)據(jù)存儲和管理,包括單機模式、哨兵模式和集群模式的部署及使用,具有一定的參考價值,感興趣的可以了解一下
    2025-05-05
  • Golang?Mutex?原理詳細(xì)解析

    Golang?Mutex?原理詳細(xì)解析

    這篇文章主要介紹了Golang?Mutex原理詳細(xì)解析,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • golang第三方庫mux的實現(xiàn)

    golang第三方庫mux的實現(xiàn)

    Gorilla/mux 是 Go 語言中功能更全面的路由庫,支持參數(shù)匹配、正則、中間件、子路由分組等,本文主要介紹了golang第三方庫mux的實現(xiàn),感興趣的可以了解一下
    2025-06-06
  • go編譯標(biāo)簽build?tag注釋里語法詳解

    go編譯標(biāo)簽build?tag注釋里語法詳解

    這篇文章主要為大家介紹了go編譯標(biāo)簽build?tag注釋里語法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • 淺析go中Ticker,Timer和Tick的用法與區(qū)別

    淺析go中Ticker,Timer和Tick的用法與區(qū)別

    在go面試的時候,面試官經(jīng)常會問time包的Ticker,Timer以及Tick的區(qū)別,一般在超時控制的時候用的比較多,今天就跟隨小編一起來詳細(xì)學(xué)一下這幾個的區(qū)別吧
    2023-10-10
  • Golang 關(guān)于Gin框架請求參數(shù)的獲取方法

    Golang 關(guān)于Gin框架請求參數(shù)的獲取方法

    Gin是Go語言的Web框架,提供路由和中間件支持,本文介紹如何使用Gin獲取HTTP請求參數(shù),包括URLPath參數(shù)、URLQuery參數(shù)、HTTPBody參數(shù)和Header參數(shù),詳解直接獲取和綁定到結(jié)構(gòu)體兩種方法,幫助開發(fā)者高效處理Web請求
    2024-10-10
  • Mango?Cache緩存管理庫TinyLFU源碼解析

    Mango?Cache緩存管理庫TinyLFU源碼解析

    這篇文章主要為大家介紹了Mango?Cache緩存管理庫TinyLFU源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09

最新評論

南和县| 郯城县| 沈丘县| 轮台县| 安乡县| 蒙阴县| 南澳县| 方城县| 新安县| 横峰县| 高青县| 永丰县| 北宁市| 牙克石市| 黄浦区| 盐城市| 高平市| 天峻县| 宕昌县| 达尔| 陆河县| 曲水县| 环江| 瑞丽市| 沂源县| 图木舒克市| 乐安县| 南皮县| 山丹县| 许昌县| 湖州市| 阿鲁科尔沁旗| 仁化县| 友谊县| 揭东县| 灵丘县| 常德市| 涞水县| 海盐县| 嘉禾县| 清镇市|