日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

鏈路追蹤

本文介紹Java 11運行環(huán)境的鏈路追蹤相關(guān)內(nèi)容。

背景信息

阿里云鏈路追蹤服務(wù)(Tracing Analysis)基于OpenTracing標準,兼容開源社區(qū),為分布式應(yīng)用的開發(fā)者提供了完整地分布式調(diào)用鏈查詢和診斷、分布式拓撲動態(tài)發(fā)現(xiàn)、應(yīng)用性能實時匯總等功能。

函數(shù)計算與鏈路追蹤集成后,支持使用Jaeger SDKOpenTelemetry上傳鏈路信息,使您能夠跟蹤函數(shù)的執(zhí)行,幫助您快速分析和診斷Serverless架構(gòu)下的性能瓶頸,提高Serverless場景的開發(fā)診斷效率。

功能簡介

您可以在函數(shù)計算控制臺配置鏈路追蹤。具體操作,請參見配置鏈路追蹤

為服務(wù)開啟鏈路追蹤后,函數(shù)計算會自動記錄請求在系統(tǒng)側(cè)的耗時,包含冷啟動耗時、Initializer函數(shù)的耗時和函數(shù)的執(zhí)行時間等。關(guān)于下圖中系統(tǒng)Span的說明,請參見Span名稱說明鏈路追蹤

如您還需查看函數(shù)內(nèi)業(yè)務(wù)側(cè)的耗時,例如,在函數(shù)內(nèi)訪問RDS,NAS等服務(wù)的耗時,可以通過創(chuàng)建自定義Span來實現(xiàn)。

示例代碼

函數(shù)計算的鏈路分析基于OpenTracing協(xié)議的Jaeger實現(xiàn),Java運行時提供以下兩種創(chuàng)建自定義Span的方式。

使用OpenTelemetry(推薦)

在Java語言的代碼中,您可以通過OpenTelemetry SDK手動埋點將數(shù)據(jù)上報到鏈路追蹤服務(wù)端。完整的示例代碼,請參見java-tracing-openTelemetry

示例代碼解析如下。

  • pom.xml文件中添加依賴。

      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.aliyun.fc.runtime</groupId>
          <artifactId>fc-java-core</artifactId>
          <version>1.4.1</version>
        </dependency>
        <dependency>
          <groupId>io.opentelemetry</groupId>
          <artifactId>opentelemetry-api</artifactId>
          <version>1.19.0</version>
        </dependency>
        <dependency>
          <groupId>io.opentelemetry</groupId>
          <artifactId>opentelemetry-sdk</artifactId>
          <version>1.19.0</version>
        </dependency>
        <dependency>
          <groupId>io.opentelemetry</groupId>
          <artifactId>opentelemetry-semconv</artifactId>
          <version>1.19.0-alpha</version>
        </dependency>
        <dependency>
          <groupId>io.opentelemetry</groupId>
          <artifactId>opentelemetry-exporter-jaeger-thrift</artifactId>
          <version>1.19.0</version>
        </dependency>
        <dependency>
          <groupId>io.jaegertracing</groupId>
          <artifactId>jaeger-thrift</artifactId>
          <version>1.8.1</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-simple</artifactId>
          <version>1.6.6</version>
        </dependency>
      </dependencies>
  • 上報數(shù)據(jù)到鏈路追蹤服務(wù)端。

    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        String endpoint = context.getTracing().getJaegerEndpoint();
        try {
            ExampleConfiguration.initOpenTelemetry(endpoint);
        } catch (TTransportException e) {
            throw new RuntimeException(e);
        }
    
        SpanContext spanContext = contextFromString(context.getTracing().getSpanContext());
    
        startMySpan(io.opentelemetry.context.Context.current().with(Span.wrap(spanContext)));
    }
  • 創(chuàng)建一個全局OpenTelemetry對象,提供對Tracers的訪問。

    static OpenTelemetry initOpenTelemetry(String jaegerEndpoint) throws TTransportException {
        // 導(dǎo)出traces到Jaeger
        JaegerThriftSpanExporter jaegerExporter =
            JaegerThriftSpanExporter.builder()
            .setThriftSender(new Builder(jaegerEndpoint).build())
            .setEndpoint(jaegerEndpoint)
            .build();
    
        Resource serviceNameResource =
            Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, "otel-jaeger-example"));
    
        // 設(shè)置由Jaeger Exporter處理Span
        SdkTracerProvider tracerProvider =
            SdkTracerProvider.builder()
            .addSpanProcessor(SimpleSpanProcessor.create(jaegerExporter))
            .setResource(Resource.getDefault().merge(serviceNameResource))
            .build();
        OpenTelemetrySdk openTelemetry =
            OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).buildAndRegisterGlobal();
    
        // JVM退出時關(guān)閉SDK
        Runtime.getRuntime().addShutdownHook(new Thread(tracerProvider::close));
    
        return openTelemetry;
    }
  • 獲取上下文的Tracing信息,轉(zhuǎn)換為SpanContext。

    SpanContext contextFromString(String value) throws IOException {
        {
            if (value != null && !value.equals("")) {
                String[] parts = value.split(":");
                if (parts.length != 4) {
                    throw new RuntimeException(value);
                } else {
                    String traceId = parts[0];
                    if (traceId.length() <= 32 && traceId.length() >= 1) {
                        return SpanContext.createFromRemoteParent("0000000000000000"+parts[0], parts[1], TraceFlags.getSampled(), TraceState.getDefault());
                    } else {
                        throw new RuntimeException("Trace id [" + traceId + "] length is not withing 1 and 32");
                    }
                }
            } else {
                throw new RuntimeException();
            }
        }
    }
  • 創(chuàng)建tracer并通過轉(zhuǎn)換的Context創(chuàng)建子Span。每一個Span代表調(diào)用鏈中被命名并計時的連續(xù)性執(zhí)行片段,您也可以基于該Span繼續(xù)創(chuàng)建子Span。

    void startMySpan(io.opentelemetry.context.Context ctx){
        Tracer tracer = GlobalOpenTelemetry.getTracer("fc-Trace");
        Span parentSpan = tracer.spanBuilder("fc-operation").setParent(ctx).startSpan();
        parentSpan.setAttribute("version","fc-v1");
        try {
            TimeUnit.MILLISECONDS.sleep(150);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        child(parentSpan.storeInContext(ctx));
        parentSpan.end();
    }
    
    void child(io.opentelemetry.context.Context ctx){
        Tracer tracer = GlobalOpenTelemetry.getTracer("fc-Trace");
        Span childSpan = tracer.spanBuilder("fc-operation-child").setParent(ctx).startSpan();
        childSpan.addEvent("timeout");
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        childSpan.end();
    }

使用Jaeger SDK

您可以通過Jaeger SDK埋點,將數(shù)據(jù)上報到鏈路追蹤服務(wù)端。完整的示例代碼,請參見java-tracing

示例代碼解析如下。

  • pom.xml文件中添加依賴。

    <dependencies>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
      </dependency>
      <dependency>
        <groupId>com.aliyun.fc.runtime</groupId>
        <artifactId>fc-java-core</artifactId>
        <version>1.4.1</version>
      </dependency>
      <dependency>
        <groupId>io.jaegertracing</groupId>
        <artifactId>jaeger-client</artifactId>
        <version>1.8.1</version>
      </dependency>
      <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.6.6</version>
      </dependency>
    </dependencies>
  • 上報數(shù)據(jù)到鏈路追蹤服務(wù)端。

    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
    
        registerTracer(context);
    
        JaegerSpanContext spanContext = contextFromString(context.getTracing().getSpanContext());
    
        startMySpan(spanContext);
    }
  • 根據(jù)上下文的Tracing信息創(chuàng)建一個tracer

    void registerTracer(Context context){
        io.jaegertracing.Configuration config = new io.jaegertracing.Configuration("FCTracer");
        io.jaegertracing.Configuration.SenderConfiguration sender = new io.jaegertracing.Configuration.SenderConfiguration();
        sender.withEndpoint(context.getTracing().getJaegerEndpoint());
        config.withSampler(new io.jaegertracing.Configuration.SamplerConfiguration().withType("const").withParam(1));
        config.withReporter(new io.jaegertracing.Configuration.ReporterConfiguration().withSender(sender).withMaxQueueSize(10000));
        GlobalTracer.register(config.getTracer());
    }
  • 轉(zhuǎn)換spanContext并創(chuàng)建自定義Span,您也可以基于該Span繼續(xù)創(chuàng)建子Span。

    static JaegerSpanContext contextFromString(String value) throws MalformedTracerStateStringException, EmptyTracerStateStringException {
        if (value != null && !value.equals("")) {
            String[] parts = value.split(":");
            if (parts.length != 4) {
                throw new MalformedTracerStateStringException(value);
            } else {
                String traceId = parts[0];
                if (traceId.length() <= 32 && traceId.length() >= 1) {
                    return new JaegerSpanContext(0L, (new BigInteger(traceId, 16)).longValue(), (new BigInteger(parts[1], 16)).longValue(), (new BigInteger(parts[2], 16)).longValue(), (new BigInteger(parts[3], 16)).byteValue());
                } else {
                    throw new TraceIdOutOfBoundException("Trace id [" + traceId + "] length is not withing 1 and 32");
                }
            }
        } else {
            throw new EmptyTracerStateStringException();
        }
    }