免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      一文詳解|Go 分布式鏈路追蹤實現(xiàn)原理

      一文詳解|Go 分布式鏈路追蹤實現(xiàn)原理

      分布式、微服務(wù)架構(gòu)下,應(yīng)用一個請求往往貫穿多個分布式服務(wù),這給應(yīng)用的故障排查、性能優(yōu)化帶來新的挑戰(zhàn)。分布式鏈路追蹤作為解決分布式應(yīng)用可觀測問題的重要技術(shù),愈發(fā)成為分布式應(yīng)用不可缺少的基礎(chǔ)設(shè)施。本文將詳細介紹分布式鏈路的核心概念、架構(gòu)原理和相關(guān)開源標準協(xié)議,并分享我們在實現(xiàn)無侵入 Go 采集 Sdk 方面的一些實踐。

      為什么需要分布式鏈路追蹤系統(tǒng)

      微服務(wù)架構(gòu)給運維、排障帶來新挑戰(zhàn)

      在分布式架構(gòu)下,當用戶從瀏覽器客戶端發(fā)起一個請求時,后端處理邏輯往往貫穿多個分布式服務(wù),這時會浮現(xiàn)很多問題,比如:

    1. 請求整體耗時較長,具體慢在哪個服務(wù)?
    2. 請求過程中出錯了,具體是哪個服務(wù)報錯?
    3. 某個服務(wù)的請求量如何,接口成功率如何?
    4. 回答這些問題變得不是那么簡單,我們不僅僅需要知道某一個服務(wù)的接口處理統(tǒng)計數(shù)據(jù),還需要了解兩個服務(wù)之間的接口調(diào)用依賴關(guān)系,只有建立起整個請求在多個服務(wù)間的時空順序,才能更好的幫助我們理解和定位問題,而這,正是分布式鏈路追蹤系統(tǒng)可以解決的。

      分布式鏈路追蹤系統(tǒng)如何幫助我們

      分布式鏈路追蹤技術(shù)的核心思想:在用戶一次分布式請求服務(wù)的調(diào) 過程中,將請求在所有子系統(tǒng)間的調(diào)用過程和時空關(guān)系追蹤記錄下來,還原成調(diào)用鏈路集中展示,信息包括各個服務(wù)節(jié)點上的耗時、請求具體到達哪臺機器上、每個服務(wù)節(jié)點的請求狀態(tài)等等。

      如上圖所示,通過分布式鏈路追蹤構(gòu)建出完整的請求鏈路后,可以很直觀地看到請求耗時主要耗費在哪個服務(wù)環(huán)節(jié),幫助我們更快速聚焦問題。 同時,還可以對采集的鏈路數(shù)據(jù)做進一步的分析,從而可以建立整個系統(tǒng)各服務(wù)間的依賴關(guān)系、以及流量情況,幫助我們更好地排查系統(tǒng)的循環(huán)依賴、熱點服務(wù)等問題。

      分布式鏈路追蹤系統(tǒng)架構(gòu)概覽

      核心概念

      在分布式鏈路追蹤系統(tǒng)中,最核心的概念,便是鏈路追蹤的數(shù)據(jù)模型定義,主要包括 Trace 和 Span。

      其中,Trace 是一個邏輯概念,表示一次(分布式)請求經(jīng)過的所有局部操作(Span)構(gòu)成的一條完整的有向無環(huán)圖,其中所有的 Span 的 TraceId 相同。 Span 則是真實的數(shù)據(jù)實體模型,表示一次(分布式)請求過程的一個步驟或操作,代表系統(tǒng)中一個邏輯運行單元,Span 之間通過嵌套或者順序排列建立因果關(guān)系。Span 數(shù)據(jù)在采集端生成,之后上報到服務(wù)端,做進一步的處理。其包含如下關(guān)鍵屬性:

      • Name:操作名稱,如一個 RPC 方法的名稱,一個函數(shù)名
      • StartTime/EndTime:起始時間和結(jié)束時間,操作的生命周期
      • ParentSpanId:父級 Span 的 ID
      • Attributes:屬性,一組 鍵值對構(gòu)成的集合
      • Event:操作期間發(fā)生的事件
      • SpanContext:Span 上下文內(nèi)容,通常用于在 Span 間傳播,其核心字段包括 TraceId、SpanId

      一般架構(gòu)

      分布式鏈路追蹤系統(tǒng)的核心任務(wù)是:圍繞 Span 的生成、傳播、采集、處理、存儲、可視化、分析,構(gòu)建分布式鏈路追蹤系統(tǒng)。其一般的架構(gòu)如下如所示:

      • 我們看到,在應(yīng)用端需要通過侵入或者非侵入的方式,注入 Tracing Sdk,以跟蹤、生成、傳播和上報請求調(diào)用鏈路數(shù)據(jù);
      • Collect agent 一般是在靠近應(yīng)用側(cè)的一個邊緣計算層,主要用于提高 Tracing Sdk 的寫性能,和減少 back-end 的計算壓力;
      • 采集的鏈路跟蹤數(shù)據(jù)上報到后端時,首先經(jīng)過 Gateway 做一個鑒權(quán),之后進入 kafka 這樣的 MQ 進行消息的緩沖存儲;
      • 在數(shù)據(jù)寫入存儲層之前,我們可能需要對消息隊列中的數(shù)據(jù)做一些清洗和分析的操作,清洗是為了規(guī)范和適配不同的數(shù)據(jù)源上報的數(shù)據(jù),分析通常是為了支持更高級的業(yè)務(wù)功能,比如流量統(tǒng)計、錯誤分析等,這部分通常采用flink這類的流處理框架來完成;
      • 存儲層會是服務(wù)端設(shè)計選型的一個重點,要考慮數(shù)據(jù)量級和查詢場景的特點來設(shè)計選型,通常的選擇包括使用 Elasticsearch、Cassandra、或 Clickhouse 這類開源產(chǎn)品;
      • 流處理分析后的結(jié)果,一方面作為存儲持久化下來,另一方面也會進入告警系統(tǒng),以主動發(fā)現(xiàn)問題來通知用戶,如錯誤率超過指定閾值發(fā)出告警通知這樣的需求等。

      剛才講的,是一個通用的架構(gòu),我們并沒有涉及每個模塊的細節(jié),尤其是服務(wù)端,每個模塊細講起來都要很花些功夫,受篇幅所限,我們把注意力集中到靠近應(yīng)用側(cè)的 Tracing Sdk,重點看看在應(yīng)用側(cè)具體是如何實現(xiàn)鏈路數(shù)據(jù)的跟蹤和采集的。

      協(xié)議標準和開源實現(xiàn)

      剛才我們提到 Tracing Sdk,其實這只是一個概念,具體到實現(xiàn),選擇可能會非常多,這其中的原因,主要是因為:

    5. 不同的編程語言的應(yīng)用,可能采用不同技術(shù)原理來實現(xiàn)對調(diào)用鏈的跟蹤
    6. 不同的鏈路追蹤后端,可能采用不同的數(shù)據(jù)傳輸協(xié)議
    7. 當前,流行的鏈路追蹤后端,比如 Zipin、Jaeger、PinPoint、Skywalking、Erda,都有供應(yīng)用集成的 sdk,導(dǎo)致我們在切換后端時應(yīng)用側(cè)可能也需要做較大的調(diào)整。 社區(qū)也出現(xiàn)過不同的協(xié)議,試圖解決采集側(cè)的這種亂象,比如 OpenTracing、OpenCensus 協(xié)議,這兩個協(xié)議也分別有一些大廠跟進支持,但最近幾年,這兩者已經(jīng)走向了融合統(tǒng)一,產(chǎn)生了一個新的標準 OpenTelemetry,這兩年發(fā)展迅猛,已經(jīng)逐漸成為行業(yè)標準。

      OpenTelemetry 定義了數(shù)據(jù)采集的標準 api,并提供了一組針對多語言的開箱即用的 sdk 實現(xiàn)工具,這樣,應(yīng)用只需要與 OpenTelemetry 核心 api 包強耦合,不需要與特定的實現(xiàn)強耦合。

      應(yīng)用側(cè)調(diào)用鏈跟蹤實現(xiàn)方案概覽

      應(yīng)用側(cè)核心任務(wù)

      應(yīng)用側(cè)圍繞 Span,有三個核心任務(wù)要完成:

    8. 生成 Span:操作開始構(gòu)建 Span 并填充 StartTime,操作完成時填充 EndTime 信息,期間可追加 Attributes、Event 等
    9. 傳播 Span:進程內(nèi)通過 context.Context、進程間通過請求的 header 作為 SpanContext 的載體,傳播的核心信息是 TraceId 和 ParentSpanId
    10. 上報 Span:生成的 Span 通過 tracing exporter 發(fā)送給 collect agent / back-end server
    11. 要實現(xiàn) Span 的生成和傳播,要求我們能夠攔截應(yīng)用的關(guān)鍵操作(函數(shù))過程,并添加 Span 相關(guān)的邏輯。實現(xiàn)這個目的會有很多方法,不過,在羅列這些方法之前,我們先看看在 OpenTelemetry 提供的 go sdk 中是如何做的。

      基于 OTEL 庫實現(xiàn)調(diào)用攔截

      OpenTelemetry 的 go sdk 實現(xiàn)調(diào)用鏈攔截的基本思路是:基于 AOP 的思想,采用裝飾器模式,通過包裝替換目標包(如 net/http)的核心接口或組件,實現(xiàn)在核心調(diào)用過程前后添加 Span 相關(guān)邏輯。當然,這樣的做法是有一定的侵入性的,需要手動替換使用原接口實現(xiàn)的代碼調(diào)用改為包裝接口實現(xiàn)。 我們以一個 http server 的例子來說明,在 go 語言中,具體是如何做的:

      假設(shè)有兩個服務(wù) serverA 和 serverB,其中 serverA 的接口收到請求后,內(nèi)部會通過 httpclient 進一步發(fā)起到 serverB 的請求,那么 serverA 的核心代碼可能如下圖所示:

      以 serverA 節(jié)點為例,在 serverA 節(jié)點應(yīng)該產(chǎn)生至少兩個 Span:

    12. Span1,記錄 httpServer 收到一個請求后內(nèi)部整體處理過程的一個耗時情況
    13. Span2,記錄 httpServer 處理請求過程中,發(fā)起的另一個到 serverB 的 http 請求的耗時情況
    14. 并且 Span1 應(yīng)該是 Span2 的 ParentSpan
    15. 我們可以借助 OpenTelemetry 提供的 sdk 來實現(xiàn) Span 的生成、傳播和上報,上報的邏輯受篇幅所限我們不再詳述,重點來看看如何生成這兩個 Span,并使這兩個 Span 之間建立關(guān)聯(lián),即 Span 的生成和傳播 。

      HttpServer Handler 生成 Span 過程

      對于 httpserver 來講,我們知道其核心就是 http.Handler 這個接口。因此,可以通過實現(xiàn)一個針對 http.Handler 接口的攔截器,來負責 Span 的生成和傳播。

      package httptype Handler interface { ServeHTTP(ResponseWriter, *Request)}http.ListenAndServe(“:8090”, http.DefaultServeMux)

      要使用 OpenTelemetry Sdk 提供的 http.Handler 裝飾器,需要如下調(diào)整 http.ListenAndServe 方法:

      import ( “net/http” “go.opentelemetry.io/otel” “go.opentelemetry.io/otel/sdk/trace” “go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp”)wrappedHttpHandler := otelhttp.NewHandler(http.DefaultServeMux, …)http.ListenAndServe(“:8090”, wrappedHttpHandler)

      如圖所示,wrppedHttpHandler 中將主要實現(xiàn)如下邏輯(精簡考慮,此處部分為偽代碼): ① ctx := tracer.Extract(r.ctx, r.Header) :從請求的 header 中提取 traceparent header 并解析,提取 TraceId和 SpanId,進而構(gòu)建 SpanContext 對象,并最終存儲在 ctx 中;

      ② ctx, span := tracer.Start(ctx, genOperation(r)) :生成跟蹤當前請求處理過程的 Span(即前文所述的Span1),并記錄開始時間,這時會從 ctx 中讀取 SpanContext,將 SpanContext.TraceId 作為當前 Span 的TraceId,將 SpanContext.SpanId 作為當前 Span的ParentSpanId,然后將自己作為新的 SpanContext 寫入返回的 ctx 中;

      ③ r.WithContext(ctx) :將新生成的 SpanContext 添加到請求 r 的 context 中,以便被攔截的 handler 內(nèi)部在處理過程中,可以從 r.ctx 中拿到 Span1 的 SpanId 作為其 ParentSpanId 屬性,從而建立 Span 之間的父子關(guān)系;

      ④ span.End() :當 innerHttpHandler.ServeHTTP(w,r) 執(zhí)行完成后,就需要對 Span1 記錄一下處理完成的時間,然后將它發(fā)送給 exporter 上報到服務(wù)端。

      HttpClient 請求生成 Span 過程

      我們再接著看 serverA 內(nèi)部去請求 serverB 時的 httpclient 請求是如何生成 Span 的(即前文說的 Span2)。我們知道,httpclient 發(fā)送請求的關(guān)鍵操作是 http.RoundTriper 接口:

      package httptype RoundTripper interface { RoundTrip(*Request) (*Response, error)}

      OpenTelemetry 提供了基于這個接口的一個攔截器實現(xiàn),我們需要使用這個實現(xiàn)包裝一下 httpclient 原來使用的 RoundTripper 實現(xiàn),代碼調(diào)整如下:

      import ( “net/http” “go.opentelemetry.io/otel” “go.opentelemetry.io/otel/sdk/trace” “go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp”)wrappedTransport := otelhttp.NewTransport(http.DefaultTransport)client := http.Client{Transport: wrappedTransport}

      如圖所示,wrappedTransport 將主要完成以下任務(wù)(精簡考慮,此處部分為偽代碼): ① req, _ := http.NewRequestWithContext(r.ctx, “GET”,url, nil) :這里我們將上一步 http.Handler 的請求的 ctx,傳遞到 httpclient 要發(fā)出的 request 中,這樣在之后我們就可以從 request.Context() 中提取出 Span1 的信息,來建立 Span 之間的關(guān)聯(lián);

      ② ctx, span := tracer.Start(r.Context(), url) :執(zhí)行 client.Do() 之后,將首先進入 WrappedTransport.RoundTrip() 方法,這里生成新的 Span(Span2),開始記錄 httpclient 請求的耗時情況,與前文一樣,Start 方法內(nèi)部會從 r.Context() 中提取出 Span1 的 SpanContext,并將其 SpanId 作為當前 Span(Span2)的 ParentSpanId,從而建立了 Span 之間的嵌套關(guān)系,同時返回的 ctx 中保存的 SpanContext 將是新生成的 Span(Span2)的信息;

      ③ tracer.Inject(ctx, r.Header) :這一步的目的是將當前 SpanContext 中的 TraceId 和 SpanId 等信息寫入到 r.Header 中,以便能夠隨著 http 請求發(fā)送到 serverB,之后在 serverB 中與當前 Span 建立關(guān)聯(lián);

      ④ span.End() :等待 httpclient 請求發(fā)送到 serverB 并收到響應(yīng)以后,標記當前 Span 跟蹤結(jié)束,設(shè)置 EndTime 并提交給 exporter 以上報到服務(wù)端。

      基于 OTEL 庫實現(xiàn)調(diào)用鏈跟蹤總結(jié)

      我們比較詳細的介紹了使用 OpenTelemetry 庫,是如何實現(xiàn)鏈路的關(guān)鍵信息(TraceId、SpanId)是如何在進程間和進程內(nèi)傳播的,我們對這種跟蹤實現(xiàn)方式做個小的總結(jié):

      如上分析所展示的,使用這種方式的話,對代碼還是有一定的侵入性,并且對代碼有另一個要求,就是保持 context.Context 對象在各操作間的傳遞,比如,剛才我們在 serverA 中創(chuàng)建 httpclient 請求時,使用的是 http.NewRequestWithContext(r.ctx, …) 而非 http.NewRequest(…) 方法,另外開啟 goroutine 的異步場景也需要注意 ctx 的傳遞。

      非侵入調(diào)用鏈跟蹤實現(xiàn)思路

      我們剛才詳細展示了基于常規(guī)的一種具有一定侵入性的實現(xiàn),其侵入性主要表現(xiàn)在:我們需要顯式的手動添加代碼使用具有跟蹤功能的組件包裝原代碼,這進一步會導(dǎo)致應(yīng)用代碼需要顯式的引用具體版本的 OpenTelemetry instrumentation 包,這不利于可觀測代碼的獨立維護和升級。 那我們有沒有可以實現(xiàn)非侵入跟蹤調(diào)用鏈的方案可選? 所謂無侵入,其實也只是集成的方式不同,集成的目標其實是差不多的,最終都是要通過某種方式,實現(xiàn)對關(guān)鍵調(diào)用函數(shù)的攔截,并加入特殊邏輯,無侵入重點在于代碼無需修改或極少修改。

      上圖列出了現(xiàn)在可能的一些無侵入集成的實現(xiàn)思路,與 .net、java 這類有 IL 語言的編程語言不同,go 直接編譯為機器碼,導(dǎo)致無侵入的方案實現(xiàn)起來相對比較麻煩,具體有如下幾種思路:

    16. 編譯階段注入:可以擴展編譯器,修改編譯過程中的ast,插入跟蹤代碼,需要適配不同編譯器版本。
    17. 啟動階段注入:修改編譯后的機器碼,插入跟蹤代碼,需要適配不同 CPU 架構(gòu)。如 monkey, gohook。
    18. 運行階段注入:通過內(nèi)核提供的 eBPF 能力,監(jiān)聽程序關(guān)鍵函數(shù)執(zhí)行,插入跟蹤代碼,前景光明!如,tcpdump,bpftrace。
    19. Go 非侵入鏈路追蹤實現(xiàn)原理

      Erda 項目的核心代碼主要是基于 golang 編寫的,我們基于前文所述的 OpenTelemetry sdk,采用基于修改機器碼的的方式,實現(xiàn)了一種無侵入的鏈路追蹤方式。 前文提到,使用 OpenTelemetry sdk 需要代碼做一些調(diào)整,我們看看這些調(diào)整如何以非侵入的方式自動的完成:

      我們以 httpclient 為例,做簡要的解釋。 gohook 框架提供的 hook 接口的簽名如下:

      // target 要hook的目標函數(shù)// replacement 要替換為的函數(shù)// trampoline 將源函數(shù)入口拷貝到的位置,可用于從replcement跳轉(zhuǎn)回原targetfunc Hook(target, replacement, trampoline interface{}) error

      對于 http.Client ,我們可以選擇 hook DefaultTransport.RoundTrip() 方法,當該方法執(zhí)行時,我們通過 otelhttp.NewTransport() 包裝起原 DefaultTransport 對象,但需要注意的是,我們不能將 DefaultTransport 直接作為 otelhttp.NewTransport() 的參數(shù),因為其 RoundTrip() 方法已經(jīng)被我們替換了,而其原來真正的方法被寫到了 trampoline 中,所以這里我們需要一個中間層,來連接 DefaultTransport 與其原來的 RoundTrip 方法。具體代碼如下:

      //go:linkname RoundTrip net/http.(*Transport).RoundTrip//go:noinline// RoundTrip .func RoundTrip(t *http.Transport, req *http.Request) (*http.Response, error)//go:noinlinefunc originalRoundTrip(t *http.Transport, req *http.Request) (*http.Response, error) { return RoundTrip(t, req)}type wrappedTransport struct { t *http.Transport}//go:noinlinefunc (t *wrappedTransport) RoundTrip(req *http.Request) (*http.Response, error) { return originalRoundTrip(t.t, req)}//go:noinlinefunc tracedRoundTrip(t *http.Transport, req *http.Request) (*http.Response, error) { req = contextWithSpan(req) return otelhttp.NewTransport(&wrappedTransport{t: t}).RoundTrip(req)}//go:noinlinefunc contextWithSpan(req *http.Request) *http.Request { ctx := req.Context() if span := trace.SpanFromContext(ctx); !span.SpanContext().IsValid() { pctx := injectcontext.GetContext() if pctx != nil { if span := trace.SpanFromContext(pctx); span.SpanContext().IsValid() { ctx = trace.ContextWithSpan(ctx, span) req = req.WithContext(ctx) } } } return req}func init() { gohook.Hook(RoundTrip, tracedRoundTrip, originalRoundTrip)}

      我們使用 init() 函數(shù)實現(xiàn)了自動添加 hook,因此用戶程序里只需要在 main 文件中 import 該包,即可實現(xiàn)無侵入的集成。

      值得一提的是 req = contextWithSpan(req) 函數(shù),內(nèi)部會依次嘗試從 req.Context() 和 我們保存的 goroutineContext map 中檢查是否包含 SpanContext ,并將其賦值給 req ,這樣便可以解除了必須使用 http.NewRequestWithContext(…) 寫法的要求。

      詳細的代碼可以查看 Erda 倉庫: https://github.com/erda-project/erda-infra/tree/master/pkg/trace

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
      (0)
      用戶投稿
      上一篇 2022年6月29日 11:45
      下一篇 2022年6月29日 11:45

      相關(guān)推薦

      • 分析|經(jīng)過休賽期操作實力提升最大的隊伍:前三森林狼76人尼克斯

        (原文發(fā)表于8月15日,作者為露天看臺網(wǎng)站的Andy Bailey,文章內(nèi)容不代表譯者觀點) 今年的休賽期掀起了一股球員轉(zhuǎn)會的浪潮,除了選秀之外,還有幾十名球員通過交易或者自由球員…

        2022年8月20日
      • 16-25!中國女排決賽首局開門黑,慘敗日本隊!絕對核心失誤多

        7月11日晚上,U20女排亞錦賽進行決賽的較量,中國女排過招日本女排。日本隊是衛(wèi)冕冠軍,且在小組賽階段跟中國隊已經(jīng)交手,不過當時太低迷,以0-3的比分慘敗,如今決賽相遇,勢必要完成…

        2022年7月18日
      • 解決華為手機聲音小的問題

        大家用華為手機時候有時會聲音小,其實方法很簡單,就是在打電話時候或者微信語音時候打開免提,之后再設(shè)置里面把音樂,視頻游戲,通話設(shè)置到最大音量就解決華為手機聲音小的問題。

        2022年8月5日
      • 數(shù)據(jù)分析崗位是否會被人工智能技術(shù)替代

          首先,當前數(shù)據(jù)分析領(lǐng)域已經(jīng)在廣泛使用人工智能相關(guān)技術(shù)了,機器學(xué)習(xí)本身就是數(shù)據(jù)分析的兩種基本方式之一,在當前大數(shù)據(jù)和大算力的推動下,機器學(xué)習(xí)在數(shù)據(jù)分析領(lǐng)域正發(fā)揮著越來越重要的作用…

        2022年6月23日
      • 用了這個護膚方法,老公說我年輕了二十歲

        天天熬夜導(dǎo)致膚色越來越發(fā)黃了 特別是上了年紀 更要注重護膚的日常 朋友給我推薦了維她白水乳之后 我就在堅持用 感覺還蠻不錯的 皮膚白了很多啦

        2022年6月28日
      • 魏牌拿鐵DHT26.3萬元

        7月25日,魏牌拿鐵DHT-PHEV正式上市,新車共推出大杯、超大杯、超大杯四驅(qū)3款車型,售價為22.9-26.3萬元。作為魏牌全面轉(zhuǎn)型高端新能源的重磅力作,拿鐵DHT-PHEV擁…

        2022年7月26日
      • TikTok生態(tài)圈手把手教你-TikTok安卓下載教程

        步驟一:手機調(diào)試 安卓與iOS本質(zhì)上需要設(shè)置的內(nèi)容沒有太大的區(qū)別,復(fù)雜程度而言各有各的說法,主要還是看使用的人更習(xí)慣于哪個系統(tǒng)的操作。 安卓手機系統(tǒng)配置推薦:系統(tǒng)Android7.…

        2022年6月14日
      • 7月30日:曝光最新崩盤跑路和即將出事的問題平臺

        1、ELE元素世界:有網(wǎng)友爆料稱,這個項目就是大騙子通緝犯張鵬的韭菜盤,大家一定要遠離! 張鵬這人可謂是老傳銷犯了,開過無數(shù)盤子,列舉幾個:全民集團、DCF、美生、天音短視頻、亞交…

        2022年7月31日
      • 「CSGO」8月2號更新:段位系統(tǒng)調(diào)整,勝利一場即可顯示隱藏段位

        1、2022年8月2日CS:GO進行了一項更新:競技模式段位系統(tǒng)正在重新進行一些調(diào)整。當你啟動CS:GO后,會發(fā)現(xiàn)段位不顯示了,你必須贏得一場競技比賽才會顯示您的最新段位。大部分玩…

        2022年8月4日
      • 中國A股:新能源車延伸;5大充電樁概念股有望成為黑馬

        什么是充電樁: 充電樁其功能類似于加油站里面的加油機,可以固定在地面或墻壁,安裝于公共建筑(公共樓宇、商場、公共停車場等)和居民小區(qū)停車場或充電站內(nèi),可以根據(jù)不同的電壓等級為各種型…

        2022年7月8日

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時間:周一至周五,10:30-18:30,節(jié)假日休息