基于opentracing + jaeger 實(shí)現(xiàn)全鏈路追蹤

[TOC]

鏈路追蹤

當(dāng)代互聯(lián)網(wǎng)服務(wù)龄广,通常都是用復(fù)雜晶渠,大規(guī)模分布式集群來(lái)實(shí)現(xiàn)妄痪,微服務(wù)化萍倡,這些軟件模塊分布在不同的機(jī)器趴久,不同的數(shù)據(jù)中心缀旁,由不同團(tuán)隊(duì)鸳谜,語(yǔ)言開(kāi)發(fā)而成本刽。因此挪蹭,需要工具幫助理解亭饵,分析這些系統(tǒng)、定位問(wèn)題梁厉,做到追蹤每一個(gè)請(qǐng)求的完整調(diào)用鏈路辜羊,收集性能數(shù)據(jù),反饋到服務(wù)治理中词顾,鏈路追蹤系統(tǒng)應(yīng)運(yùn)而生八秃。

現(xiàn)有大部分 APM(Application Performance Management) 理論模型大多借鑒 google dapper 論文,Twitter的zipkin肉盹,Uber的 jaeger昔驱,淘寶的鷹眼,大眾的cat上忍,京東的Hydra等骤肛。

微服務(wù)問(wèn)題:

  1. 故障定位難
  2. 鏈路梳理難
  3. 容量預(yù)估難

舉個(gè)例子纳本,一個(gè)場(chǎng)景下,一個(gè)請(qǐng)求進(jìn)來(lái)腋颠,入口服務(wù)是 serviceA饮醇, serviceA 接到請(qǐng)求后訪問(wèn)數(shù)據(jù)庫(kù)讀取用戶(hù)數(shù)據(jù),然后向 serviceB 發(fā)起 rpc秕豫,serviceB 收到 rpc 請(qǐng)求時(shí)同時(shí)向后端服務(wù) serviceC 和 serviceD 發(fā)起請(qǐng)求,等待請(qǐng)求回復(fù)后再返回 serviceA 的 rpc 調(diào)用观蓄。如果我們發(fā)現(xiàn)發(fā)起的請(qǐng)求失敗混移,或者請(qǐng)求的時(shí)延很大,我們?cè)撊绾稳ザㄎ荒兀?/p>

基于這個(gè)需求侮穿,我們將服務(wù)介入追蹤系統(tǒng)歌径。

分布式追蹤系統(tǒng)發(fā)展很快,種類(lèi)繁多亲茅,但核心步驟一般有三個(gè):代碼埋點(diǎn)回铛,數(shù)據(jù)存儲(chǔ)、查詢(xún)展示

在數(shù)據(jù)采集過(guò)程克锣,需要侵入用戶(hù)代碼做埋點(diǎn)茵肃,不同系統(tǒng)的API不兼容會(huì)導(dǎo)致切換追蹤系統(tǒng)需要做很大的改動(dòng)。為了解決這個(gè)問(wèn)題袭祟,誕生了opentracing 規(guī)范验残。

   +-------------+  +---------+  +----------+  +------------+
   | Application |  | Library |  |   OSS    |  |  RPC/IPC   |
   |    Code     |  |  Code   |  | Services |  | Frameworks |
   +-------------+  +---------+  +----------+  +------------+
          |              |             |             |
          |              |             |             |
          v              v             v             v
     +-----------------------------------------------------+
     | · · · · · · · · · · OpenTracing · · · · · · · · · · |
     +-----------------------------------------------------+
       |               |                |               |
       |               |                |               |
       v               v                v               v
 +-----------+  +-------------+  +-------------+  +-----------+
 |  Tracing  |  |   Logging   |  |   Metrics   |  |  Tracing  |
 | System A  |  | Framework B |  | Framework C |  | System D  |
 +-----------+  +-------------+  +-------------+  +-----------+

OpenTracing

opentracing (中文)是一套分布式追蹤協(xié)議,與平臺(tái)巾乳,語(yǔ)言無(wú)關(guān)您没,統(tǒng)一接口,方便開(kāi)發(fā)接入不同的分布式追蹤系統(tǒng)胆绊。

  • 語(yǔ)義規(guī)范 : 描述定義的數(shù)據(jù)模型 Tracer氨鹏,Sapn 和 SpanContext 等;

  • 語(yǔ)義慣例 : 羅列出 tag 和 logging 操作時(shí)压状,標(biāo)準(zhǔn)的key值仆抵;

Trace 和 sapn

opentracing 中的 Trace(調(diào)用鏈)通過(guò)歸屬此鏈的 Span 來(lái)隱性定義。一條 Trace 可以認(rèn)為一個(gè)有多個(gè) Span 組成的有向無(wú)環(huán)圖(DAG圖)何缓,Span 是一個(gè)邏輯執(zhí)行單元肢础,Span 與 Span 的因果關(guān)系命名為 References。

opentracing 定義兩種關(guān)系:

  • Childof:如下例子中碌廓, SpanC 是 childof SpanA
  • FollowsFrom:如下例子中传轰,SpanG 是 followsFrom SpanF

例子 Trace 包含 8個(gè) Span,

 [Span A]  ←←←(the root span)
            |
     +------+------+
     |             |
 [Span B]      [Span C] ←←←(Span C is a `ChildOf` Span A)
     |             |
 [Span D]      +---+-------+
               |           |
           [Span E]    [Span F] >>> [Span G] >>> [Span H]
                                       ↑
                                       ↑
                                       ↑
                         (Span G `FollowsFrom` Span F)

通過(guò)時(shí)間軸顯示一個(gè) Tracer 更加直觀谷婆,

––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time

 [Span A···················································]
   [Span B··············································]
      [Span D··········································]
    [Span C········································]
         [Span E·······]        [Span F··] [Span G··] [Span H··]

每個(gè)Span封裝了如下?tīng)顟B(tài):

  • 操作名稱(chēng)
  • 開(kāi)始時(shí)間戳
  • 結(jié)束時(shí)間戳
  • 一組零或多個(gè)鍵:值結(jié)構(gòu)的 Span標(biāo)簽 (Tags)慨蛙。鍵必須是字符串辽聊。值可以是字符串,布爾或數(shù)值類(lèi)型.
  • 一組零或多個(gè) Span日志 (Logs)期贫,其中每個(gè)都是一個(gè)鍵:值映射并與一個(gè)時(shí)間戳配對(duì)跟匆。鍵必須是字符串,值可以是任何類(lèi)型通砍。 并非所有的 OpenTracing 實(shí)現(xiàn)都必須支持每種值類(lèi)型玛臂。
  • 一個(gè) SpanContext (見(jiàn)下文)
  • 零或多個(gè)因果相關(guān)的 Span 間的 References (通過(guò)那些相關(guān)的 SpanSpanContext )

每個(gè) SpanContext 封裝了如下?tīng)顟B(tài):

  • 任何需要跟跨進(jìn)程 Span 關(guān)聯(lián)的,依賴(lài)于 OpenTracing 實(shí)現(xiàn)的狀態(tài)(例如 Trace 和 Span 的 id)

  • 鍵:值結(jié)構(gòu)的跨進(jìn)程的 Baggage Items(區(qū)別于 span tag封孙,baggage 是全局范圍迹冤,在 span 間保持傳遞,而tag 是 span 內(nèi)部虎忌,不會(huì)被子 span 繼承使用泡徙。)

InjectExtract 操作

跨進(jìn)程,機(jī)器通訊膜蠢,通過(guò)傳遞 Spancontext 來(lái)提供足夠的信息建立 span 間的關(guān)系堪藐。SpanContext 通過(guò) Inject 操作向 Carrier 中增加,傳遞后通過(guò) ExtractedCarrier 中取出挑围。

關(guān)于inject 和 extract

Sampling,采樣

OpenTracing API 不強(qiáng)調(diào)采樣的概念礁竞,但是大多數(shù)追蹤系統(tǒng)通過(guò)不同方式實(shí)現(xiàn)采樣。有些情況下杉辙,應(yīng)用系統(tǒng)需要通知追蹤程序苏章,這條特定的調(diào)用需要被記錄,即使根據(jù)默認(rèn)采樣規(guī)則奏瞬,它不需要被記錄枫绅。sampling.priority tag 提供這樣的方式。追蹤系統(tǒng)不保證一定采納這個(gè)參數(shù)硼端,但是會(huì)盡可能的保留這條調(diào)用并淋。
sampling.priority - integer

  • 如果大于 0, 追蹤系統(tǒng)盡可能保存這條調(diào)用鏈

  • 等于 0, 追蹤系統(tǒng)不保存這條調(diào)用鏈

  • 如果此tag沒(méi)有提供,追蹤系統(tǒng)使用自己的默認(rèn)采樣規(guī)則

OpenTracing 多語(yǔ)言支持

提供不同語(yǔ)言的 API珍昨,用于在自己的應(yīng)用程序中執(zhí)行鏈路記錄县耽。

Jaeger

Jaeger (?yā-g?r) 是Uber開(kāi)發(fā)的一套分布式追蹤系統(tǒng),受啟發(fā)于 dapper 和 OpenZipkin镣典,兼容 OpenTracing 標(biāo)準(zhǔn)兔毙,CNCF的開(kāi)源項(xiàng)目。

系統(tǒng)框架

image.png
  • Jaeger Client - 為不同語(yǔ)言實(shí)現(xiàn)了符合 OpenTracing 標(biāo)準(zhǔn)的 SDK兄春。應(yīng)用程序通過(guò) API 寫(xiě)入數(shù)據(jù)澎剥,client library 把 trace 信息按照應(yīng)用程序指定的采樣策略傳遞給 jaeger-agent。
  • Agent - 是一個(gè)監(jiān)聽(tīng)在 UDP 端口上接收 span 數(shù)據(jù)的網(wǎng)絡(luò)守護(hù)進(jìn)程赶舆,它會(huì)將數(shù)據(jù)批量發(fā)送給 collector哑姚。它被設(shè)計(jì)成一個(gè)基礎(chǔ)組件祭饭,推薦部署到所有的宿主機(jī)上。Agent 將 client library 和 collector 解耦叙量,為 client library 屏蔽了路由和發(fā)現(xiàn) collector 的細(xì)節(jié)倡蝙。
  • Collector - 接收 jaeger-agent 發(fā)送來(lái)的數(shù)據(jù),然后將數(shù)據(jù)寫(xiě)入后端存儲(chǔ)绞佩。Collector 被設(shè)計(jì)成無(wú)狀態(tài)的組件寺鸥,因此您可以同時(shí)運(yùn)行任意數(shù)量的 jaeger-collector。
  • Data Store - 后端存儲(chǔ)被設(shè)計(jì)成一個(gè)可插拔的組件品山,支持將數(shù)據(jù)寫(xiě)入 cassandra析既、elastic search。
  • Query - 接收查詢(xún)請(qǐng)求谆奥,然后從后端存儲(chǔ)系統(tǒng)中檢索 trace 并通過(guò) UI 進(jìn)行展示。Query 是無(wú)狀態(tài)的拂玻,您可以啟動(dòng)多個(gè)實(shí)例酸些,把它們部署在 nginx 這樣的負(fù)載均衡器后面。

官方釋放部署的鏡像到 dockerhub檐蚜,所以部署 jaeger 非常方便魄懂,如果是本地測(cè)試,可以直接用 jaeger 提供的 all-in-one 鏡像部署闯第。

快速搭建市栗,all-in-one

執(zhí)行一下命令,可以在本機(jī)拉起一個(gè) jaeger 環(huán)境咳短,上報(bào)的鏈路數(shù)據(jù)保存在本地內(nèi)存填帽,所以只能用于測(cè)試。

$ docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
  -p 5775:5775/udp \kaixiao
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 9411:9411 \
  jaegertracing/all-in-one:latest

通過(guò) http://localhost:16686 可以在瀏覽器查看 Jaeger UI

官方提供的一個(gè)例子: HotROD

采樣速率

生產(chǎn)環(huán)境系統(tǒng)性能很重要咙好,所以對(duì)于所有的請(qǐng)求都開(kāi)啟 Trace 顯然會(huì)帶來(lái)比較大的壓力篡腌,另外,大量的數(shù)據(jù)也會(huì)帶來(lái)很大存儲(chǔ)壓力勾效。為此嘹悼,jaeger 支持設(shè)置采樣速率,根據(jù)系統(tǒng)實(shí)際情況設(shè)置合適的采樣頻率层宫。

Jaeger 官方提供了多種采集策略杨伙,使用者可以按需選擇使用

  1. const,全量采集萌腿,采樣率設(shè)置0,1 分別對(duì)應(yīng)打開(kāi)和關(guān)閉
  2. probabilistic 限匣,概率采集,默認(rèn)萬(wàn)份之一毁菱,0~1之間取值膛腐,
  3. rateLimiting 睛约,限速采集,每秒只能采集一定量的數(shù)據(jù)
  4. remote 哲身,一種動(dòng)態(tài)采集策略辩涝,根據(jù)當(dāng)前系統(tǒng)的訪問(wèn)量調(diào)節(jié)采集策略

追蹤實(shí)踐 - go

go 程序中集成鏈路追蹤并上報(bào)到 jaeger 需要用到一下兩個(gè)包 opentracing go api 和 jaeger go 客戶(hù)端。

一個(gè)簡(jiǎn)單的 trace

以下代碼上報(bào)一個(gè)包含一個(gè) span 的 trace勘天,程序在初始化階段通過(guò)環(huán)境變量獲取 jaeger 的配置并初始化全局 tracer怔揩。之后便可以通過(guò)這個(gè) tracer 開(kāi)啟 span(root span) 記錄程序鏈路。

package main
import (
    "fmt"
    "io"
    "time"

    opentracing "github.com/opentracing/opentracing-go"
    jaeger "github.com/uber/jaeger-client-go"
    jaegercfg "github.com/uber/jaeger-client-go/config"
)
// InitJaeger ...
func InitJaeger(service string) (opentracing.Tracer, io.Closer) {
    cfg, err := jaegercfg.FromEnv()
    /*
        cfg.Sampler.Type = "const"
        cfg.Sampler.Param = 1
        cfg.Reporter.LocalAgentHostPort = "127.0.0.1:6831"
        cfg.Reporter.LogSpans = true
    */
    tracer, closer, err := cfg.New(service, jaegercfg.Logger(jaeger.StdLogger))
    if err != nil {
        panic(fmt.Sprintf("ERROR: cannot init Jaeger: %v\n", err))
    }
    return tracer, closer
}

func main() {
    tracer, closer := InitJaeger("hello-world")
    defer closer.Close()
    opentracing.InitGlobalTracer(tracer)

    helloStr := "hello jaeger"
    span := tracer.StartSpan("say-hello")
    time.Sleep(time.Duration(2) * time.Millisecond)
    println(helloStr)
    span.Finish() 
}

然后通過(guò) jaeger ui 可以看到本次上報(bào)的 trace脯丝。

$ export JAEGER_DISABLED=false
$ export JAEGER_SAMPLER_TYPE="const"
$ export JAEGER_SAMPLER_PARAM=1
$ export JAEGER_REPORTER_LOG_SPANS=true
$ export JAEGER_AGENT_HOST="127.0.0.1"
$ export JAEGER_AGENT_PORT=6831
$ go run ./test.go
2019/06/09 23:01:31 Initializing logging reporter
hello jaeger
2019/06/09 23:01:31 Reporting span 2813d696ced4431:2813d696ced4431:0:1

在開(kāi)啟 span 記錄一個(gè)過(guò)程時(shí)商膊,還可以通過(guò) api 進(jìn)行 tag,logs等操作 宠进,并能在 UI 看到相應(yīng)設(shè)置的鍵z值

span.SetTag("value", helloStr)
span.LogFields(
    log.String("event", "sayhello"),
    log.String("value", helloStr),
)
//span.LogKV("event", "sayhello") // 單一設(shè)置

tag 和 logs 在opentarcing中提到一些推薦命名:語(yǔ)義慣例

使用 tag 是用于描述 span 中的特性晕拆,是對(duì)整個(gè)過(guò)程而言,而 log 是用于記錄 span 這個(gè)過(guò)程中的一個(gè)時(shí)間材蹬,因?yàn)橛涗?log 時(shí)會(huì)攜帶一個(gè)發(fā)生的時(shí)間戳实幕,是有先后之分的。

baggage

相比 tag堤器,log 限制在 span 中昆庇, baggage 同樣提供保存鍵值對(duì)設(shè)置,但是 baggage 數(shù)據(jù)有效是全 trace 的闸溃,所以使用的時(shí)候避免設(shè)置不必要的值整吆,導(dǎo)致傳遞開(kāi)銷(xiāo)。

// set
span.SetBaggageItem("greeting", greeting)
// get
greeting := span.BaggageItem("greeting")

使用上下文傳遞 span

當(dāng)我們提到調(diào)用鏈辉川,一般涉及多個(gè)函數(shù)表蝙,多個(gè)進(jìn)程甚至多個(gè)機(jī)器上運(yùn)行的過(guò)程,用 tracer 開(kāi)啟 root span 后乓旗,需要向其他過(guò)程傳遞以保持他們之間的關(guān)聯(lián)性勇哗,我們通過(guò)上下文來(lái)存儲(chǔ) span 并傳遞。

// 存儲(chǔ)到 context 中
ctx := context.Background()
ctx = opentracing.ContextWithSpan(ctx, span)
//....

// 其他過(guò)程獲取并開(kāi)始子 span
span, ctx := opentracing.StartSpanFromContext(ctx, "newspan")
defer span.Finish()
// StartSpanFromContext 會(huì)將新span保存到ctx中更新

或者先取出 parent span寸齐,然后在以 childof 開(kāi)啟span欲诺,需要手動(dòng)寫(xiě)入新 span 到 ctx中。

//獲取上一級(jí) span
parent := opentracing.SpanFromContext(ctx) 
span1 := opentracing.StartSpan("from-sayhello-1", opentracing.ChildOf(span2.Context()))
...
span1.Finish()
ctx = opentracing.ContextWithSpan(ctx, span2) //更新ctx

span2 := opentracing.StartSpan("from-sayhello-2", opentracing.ChildOf(span2.Context()))
...
span2.Finish()
ctx = opentracing.ContextWithSpan(ctx, span2) //更新ctx

tracing grpc 調(diào)用

由于 grpc 調(diào)用和服務(wù)端都聲明了 UnaryInterceptor 和 StreamInterceptor 兩回調(diào)函數(shù)渺鹦,因此只需要重寫(xiě)這兩個(gè)函數(shù)扰法,在函數(shù)中調(diào)用 opentracing 的借口進(jìn)行鏈路追蹤,并初始化客戶(hù)端或者服務(wù)端時(shí)候注冊(cè)進(jìn)去就可以毅厚。

相應(yīng)的函數(shù)已經(jīng)有現(xiàn)成的包 grpc-opentracing

使用如下:

var tracer opentracing.Tracer = ...
//client
conn, err := grpc.Dial(
    address,
    ... // other options
    grpc.WithUnaryInterceptor(
        otgrpc.OpenTracingClientInterceptor(tracer)),
    grpc.WithStreamInterceptor(
        otgrpc.OpenTracingStreamClientInterceptor(tracer)))


// server
s := grpc.NewServer(
    ... // other options
    grpc.UnaryInterceptor(
        otgrpc.OpenTracingServerInterceptor(tracer)),
    grpc.StreamInterceptor(
        otgrpc.OpenTracingStreamServerInterceptor(tracer)))

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末塞颁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祠锣,老刑警劉巖酷窥,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異伴网,居然都是意外死亡蓬推,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)澡腾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)沸伏,“玉大人,你說(shuō)我怎么就攤上這事动分∫阍悖” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵澜公,是天一觀的道長(zhǎng)姆另。 經(jīng)常有香客問(wèn)我,道長(zhǎng)坟乾,這世上最難降的妖魔是什么迹辐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮糊渊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘慧脱。我一直安慰自己渺绒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布菱鸥。 她就那樣靜靜地躺著宗兼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪氮采。 梳的紋絲不亂的頭發(fā)上殷绍,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音鹊漠,去河邊找鬼主到。 笑死,一個(gè)胖子當(dāng)著我的面吹牛躯概,可吹牛的內(nèi)容都是我干的登钥。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼娶靡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼牧牢!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤塔鳍,失蹤者是張志新(化名)和其女友劉穎伯铣,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體轮纫,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡腔寡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蜡感。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹬蚁。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖郑兴,靈堂內(nèi)的尸體忽然破棺而出犀斋,到底是詐尸還是另有隱情,我是刑警寧澤情连,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布叽粹,位于F島的核電站,受9級(jí)特大地震影響却舀,放射性物質(zhì)發(fā)生泄漏虫几。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一挽拔、第九天 我趴在偏房一處隱蔽的房頂上張望辆脸。 院中可真熱鬧,春花似錦螃诅、人聲如沸啡氢。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)倘是。三九已至,卻和暖如春袭艺,著一層夾襖步出監(jiān)牢的瞬間搀崭,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工猾编, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘤睹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓答倡,卻偏偏與公主長(zhǎng)得像默蚌,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子苇羡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 在各大廠分布式鏈路跟蹤系統(tǒng)架構(gòu)對(duì)比中已經(jīng)介紹了幾大框架的對(duì)比绸吸,如果想用免費(fèi)的可以用zipkin和pinpoint還...
    歡醉閱讀 1,855評(píng)論 2 2
  • 分布式鏈路追蹤(Distributed Tracing)鼻弧,也叫 分布式鏈路跟蹤,分布式跟蹤锦茁,分布式追蹤 等等攘轩。 本...
    Daniel_adu閱讀 33,692評(píng)論 0 20
  • 28歲的第一天,很平靜码俩。仿佛是再平常不過(guò)的一天度帮。 從凌晨開(kāi)始,收到了許多朋友的祝福稿存,生在這樣一個(gè)特別的日子笨篷,最大的...
    Yvonne不是我閱讀 346評(píng)論 0 0
  • 今天中午剛打掃完衛(wèi)生就接到孩子班主任的電話(huà)問(wèn)我接孩子了嗎?我說(shuō)沒(méi)瓣履,然后老師說(shuō)你現(xiàn)在有時(shí)間來(lái)一趟嗎率翅?我在學(xué)校門(mén)口等你...
    新的一天從早上開(kāi)始閱讀 181評(píng)論 0 1
  • 十月不遠(yuǎn)——給大海,請(qǐng)埋葬我的愛(ài)情 十月不遠(yuǎn) 遇見(jiàn)你不遠(yuǎn) 愛(ài)情不遠(yuǎn)——上帝盤(pán)旋的褲衩下 海水腥咸 因此大海不遠(yuǎn) 浪...
    九松子閱讀 258評(píng)論 1 1