分布式追踪

img

目录

文章目录

    • 目录
    • 自定义指标
      • 1.删除标签
      • 2.添加指标
      • 3.禁用指标
    • 分布式追踪
      • 上下文传递
      • Jaeger
    • 关于我
    • 最后
    • 最后

自定义指标

除了 Istio 自带的指标外,我们还可以自定义指标,要自定指标需要用到 Istio 提供的 Telemetry API,该 API 能够灵活地配置指标、访问日志和追踪数据。Telemetry API 现在已经成为 Istio 中的主流 API。

需要注意的是,Telemetry API 无法与 EnvoyFilter 一起使用,请查看此问题 issue。

从 Istio 版本 1.18 版本开始,Prometheus 的 EnvoyFilter 默认不会被安装, 而是通过 meshConfig.defaultProviders 来启用它,我们应该使用 Telemetry API 来进一步定制遥测流程,新的 Telemetry API 不但语义更加清晰,功能也一样没少。

对于 Istio 1.18 之前的版本,应该使用以下的 IstioOperator 配置进行安装:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  values:
    telemetry:
      enabled: true
      v2:
        enabled: false

Telemetry 资源对象的定义如下所示:

$ kubectl explain Telemetry.spec
GROUP:      telemetry.istio.io
KIND:       Telemetry
VERSION:    v1alpha1

FIELD: spec <Object>

DESCRIPTION:
    Telemetry configuration for workloads. See more details at:
    https://istio.io/docs/reference/config/telemetry.html

FIELDS:
  accessLogging <[]Object>
    Optional.

  metrics       <[]Object>
    Optional.

  selector      <Object>
    Optional.

  tracing       <[]Object>
    Optional.

可以看到 Telemetry 资源对象包含了 accessLoggingmetricsselectortracing 四个字段,其中 accessLoggingtracing 字段用于配置访问日志和追踪数据,而 metrics 字段用于配置指标数据,selector 字段用于配置哪些工作负载需要采集指标数据。

我们这里先来看下 metrics 字段的配置,该字段的定义如下所示:

$ kubectl explain Telemetry.spec.metrics
GROUP:      telemetry.istio.io
KIND:       Telemetry
VERSION:    v1alpha1

FIELD: metrics <[]Object>

DESCRIPTION:
    Optional.

FIELDS:
  overrides     <[]Object>
    Optional.

  providers     <[]Object>
    Optional.

  reportingInterval     <string>
    Optional.

可以看到 metrics 字段包含了 overridesprovidersreportingInterval 三个字段。

  • overrides 字段用于配置指标数据的采集方式。
  • providers 字段用于配置指标数据的提供者,这里一般配置为 prometheus
  • reportingInterval 字段用于配置指标数据的上报间隔,可选的。目前仅支持 TCP 度量,但将来可能会将其用于长时间的 HTTP 流。默认持续时间为 5 秒。

1.删除标签

🚩 实战:自定义指标-删除标签-2023.12.4(测试成功)

实验环境:

k8s v1.27.6(containerd://1.6.20)(cni:flannel:v0.22.2)
istio v1.19.3(--set profile=demo)

实验软件:

链接:https://pan.baidu.com/s/1pMnJxgL63oTlGFlhrfnXsA?pwd=7yqb
提取码:7yqb
2023.11.5-实战:BookInfo 示例应用-2023.11.5(测试成功)

image-20231105111842627

比如以前需要在 Istio 配置的 meshConfig 部分配置遥测,这种方式不是很方便。比如我们想从 Istio 指标中删除一些标签以减少基数,那么你的配置中可能有这样一个部分:

# istiooperator.yaml
telemetry:
  enabled: true
  v2:
    enabled: true
    prometheus:
      enabled: true
      configOverride:
        outboundSidecar:
          debug: false
          stat_prefix: istio
          metrics:
            - tags_to_remove:
                - destination_canonical_service
                  ...

现在我们可以通过 Telemetry API 来配置,如下所示:

#remove-tags.yaml
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: remove-tags
  namespace: istio-system
spec:
  metrics:
    - providers:
        - name: prometheus # 指定指标数据的提供者
      overrides:
        - match: # 提供覆盖的范围,可用于选择个别指标,以及生成指标的工作负载模式(服务器和/或客户端)。如果未指定,则overrides 将应用于两种操作模式(客户端和服务器)的所有指标。
            metric: ALL_METRICS # Istio 标准指标之一
            mode: CLIENT_AND_SERVER # 控制选择的指标生成模式:客户端和/或服务端。
          tagOverrides: # 要覆盖的标签列表
            destination_canonical_service:
              operation: REMOVE
          # disabled: true  # 是否禁用指标

在上面的 Telemetry 资源对象中我们指定了一个 metrics 字段,表示用来自定义指标的,然后通过 providers.name 字段指定指标数据的提供者为 prometheus,然后最重要的是 overrides 字段,用于配置指标数据的采集方式。

其中 overrides.match.metric 字段用来指定要覆盖的 Istio 标准指标,支持指标如下所示:

名称描述
ALL_METRICS使用这个枚举表示应将覆盖应用于所有 Istio 默认指标。
REQUEST_COUNT对应用程序的请求计数器,适用于 HTTP、HTTP/2 和 GRPC 流量。Prometheus 提供商将此指标导出为:istio_requests_total。Stackdriver 提供商将此指标导出为:istio.io/service/server/request_count(服务器模式)istio.io/service/client/request_count(客户端模式)
REQUEST_DURATION请求持续时间的直方图,适用于 HTTP、HTTP/2 和 GRPC 流量。Prometheus 提供商将此指标导出为:istio_request_duration_milliseconds。Stackdriver 提供商将此指标导出为:istio.io/service/server/response_latencies(服务器模式)istio.io/service/client/roundtrip_latencies(客户端模式)
REQUEST_SIZE请求体大小的直方图,适用于 HTTP、HTTP/2 和 GRPC 流量。Prometheus 提供商将此指标导出为:istio_request_bytes。Stackdriver 提供商将此指标导出为:istio.io/service/server/request_bytes(服务器模式)istio.io/service/client/request_bytes(客户端模式)
RESPONSE_SIZE响应体大小的直方图,适用于 HTTP、HTTP/2 和 GRPC 流量。Prometheus 提供商将此指标导出为:istio_response_bytes。Stackdriver 提供商将此指标导出为:istio.io/service/server/response_bytes(服务器模式)istio.io/service/client/response_bytes(客户端模式)
TCP_OPENED_CONNECTIONS工作负载生命周期中打开的 TCP 连接计数器。Prometheus 提供商将此指标导出为:istio_tcp_connections_opened_total。Stackdriver 提供商将此指标导出为:istio.io/service/server/connection_open_count(服务器模式)istio.io/service/client/connection_open_count(客户端模式)
TCP_CLOSED_CONNECTIONS工作负载生命周期中关闭的 TCP 连接计数器。Prometheus 提供商将此指标导出为:istio_tcp_connections_closed_total。Stackdriver 提供商将此指标导出为:istio.io/service/server/connection_close_count(服务器模式)istio.io/service/client/connection_close_count(客户端模式)
TCP_SENT_BYTESTCP 连接期间发送的响应字节计数器。Prometheus 提供商将此指标导出为:istio_tcp_sent_bytes_total。Stackdriver 提供商将此指标导出为:istio.io/service/server/sent_bytes_count(服务器模式)istio.io/service/client/sent_bytes_count(客户端模式)
TCP_RECEIVED_BYTESTCP 连接期间接收的请求字节计数器。Prometheus 提供商将此指标导出为:istio_tcp_received_bytes_total。Stackdriver 提供商将此指标导出为:istio.io/service/server/received_bytes_count(服务器模式)istio.io/service/client/received_bytes_count(客户端模式)
GRPC_REQUEST_MESSAGES每发送一个 gRPC 消息时递增的客户端计数器。Prometheus 提供商将此指标导出为:istio_request_messages_total
GRPC_RESPONSE_MESSAGES每发送一个 gRPC 消息时递增的服务器计数器。Prometheus 提供商将此指标导出为:istio_response_messages_total

比如我们这里配置的指标为 ALL_METRICS 则表示要覆盖所有的 Istio 标准指标。

overrides.match.mode 则表示选择网络流量中底层负载的角色,如果负载是流量的目标(从负载的角度看,流量方向是入站),则将其视为作为 SERVER 运行。如果负载是网络流量的源头,则被视为处于 CLIENT 模式(流量从负载出站)。

名称描述
CLIENT_AND_SERVER选择适用于工作负载既是网络流量的源头,又是目标的场景。
CLIENT选择适用于工作负载是网络流量的源头的场景。
SERVER选择适用于工作负载是网络流量的目标的场景。

另外的 tagOverrides 字段表示要覆盖选定的指标中的标签名称和标签表达式的集合,该字段中的 key 是标签的名称,value 是对标签执行的操作,可以添加、删除标签,或覆盖其默认值。

字段类型描述是否必需
operationOperation操作控制是否更新/添加一个标签,或者移除它。
valuestring当操作为 UPSERT时才考虑值。值是基于属性的 CEL 表达式。例如:string(destination.port)request.host。Istio 暴露所有标准的 Envoy 属性。此外,Istio 也将节点元数据作为属性暴露出来。更多信息请参见 自定义指标文档。

对应的操作 Operator 可以配置 UPSERTREMOVE 两个操作:

名称描述
UPSERT使用提供的值表达式插入或更新标签。如果使用 UPSERT操作,则必须指定 value字段。
REMOVE指定标签在生成时不应包含在指标中。
  • 现在我们直接应用上面的这个资源对象,然后我们再去访问下 productpage 应用,再次验证下指标数据中是否包含我们移除的 destination_canonical_service 标签。
istioctl dashboard prometheus --address 0.0.0.0

看下当前指标:(是含有这个destination_canonical_service 标签的)

部署资源,再次验证:

[root@master1 istio]#kubectl apply -f remove-tags.yaml 
telemetry.telemetry.istio.io/remove-tags created
[root@master1 istio]#kubectl get telemetries.telemetry.istio.io -nistio-system
NAME          AGE
remove-tags   21s

#重新去访问一次
istioctl dashboard prometheus --address 0.0.0.0

img

从上面的结果可以看到,我们已经成功删除了 destination_canonical_service 标签,这样就可以减少指标数据的基数了,可以用同样的方法再去删除一些不需要的标签。

另外需要注意在 Telemetry 对象中我们还可以通过 selector 字段来配置哪些工作负载应用这个遥测策略,如果未设置,遥测策略将应用于与遥测策略相同的命名空间中的所有工作负载,当然如果是在 istio-system 命名空间中则会应用于所有命名空间中的工作负载。

测试结束。😘

2.添加指标

🚩 实战:自定义指标-删除标签-2023.12.4

实验环境:

k8s v1.27.6(containerd://1.6.20)(cni:flannel:v0.22.2)
istio v1.19.3(--set profile=demo)

实验软件:

链接:https://pan.baidu.com/s/1pMnJxgL63oTlGFlhrfnXsA?pwd=7yqb
提取码:7yqb
2023.11.5-实战:BookInfo 示例应用-2023.11.5(测试成功)

image-20231105111842627

  • 上面我们已经介绍了如何删除指标中的标签,那么我们也可以通过 Telemetry API 来添加指标中的标签,如下所示:
#add-tags.yaml
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: add-tags
spec:
  metrics:
    - overrides:
        - match:
            metric: REQUEST_COUNT
            mode: CLIENT
          tagOverrides:
            destination_x:
              operation: UPSERT
              value: "upstream_peer.labels['app'].value" # 必须加上双引号
        - match:
            metric: REQUEST_COUNT
          tagOverrides:
            destination_port:
              value: "string(destination.port)"
            request_host:
              value: "request.host"
      providers:
        - name: prometheus

在上面的这个资源对象中我们在 tagOverrides 中首先添加了如下的配置:

destination_x:
  operation: UPSERT
  value: "upstream_peer.labels['app'].value"

表示我们要添加一个名为 destination_x 的标签,然后通过 value 字段指定标签的值为 upstream_peer.labels['app'].value,这个值是一个 CEL 表达式(common expression)(必须在 JSON 中用双引号引用字符串)。Istio 暴露了所有标准的 Envoy 属性,对于出站请求,对等方元数据作为上游对等方(upstream_peer)的属性可用;对于入站请求,对等方元数据作为下游对等方(downstream_peer)的属性可用,包含以下字段:

属性类型
namestringPod 名
namespacestringPod 所在命名空间
labelsmap工作负载标签
ownerstring工作负载 owner
workload_namestring工作负载名称
platform_metadatamap平台元数据
istio_versionstring代理的版本标识
mesh_idstring网格唯一 ID
app_containerslist<string>应用容器的名称列表
cluster_idstring工作负载所属的集群标识

例如,用于出站配置中的对等应用标签的表达式是 upstream_peer.labels['app'].value,所以上面我们最终添加的 destination_x 这个标签的值为上游对等方的 app 标签的值。

另外添加的两个标签 destination_portrequest_host 的值分别为 string(destination.port)request.host,这两个值就来源于暴露的 Envoy 属性。

另外这个资源对象我们指定的是 default 命名空间,则只会对 default 命名空间中的工作负载应用这个遥测策略。

  • 同样应用这个资源对象后,再次访问 productpage 应用产生指标,现在我们可以看到指标中已经包含了我们添加的标签了。
[root@master1 istio]#kubectl apply -f add-tags.yaml 
telemetry.telemetry.istio.io/add-tags created
[root@master1 istio]#kubectl get telemetries.telemetry.istio.io 
NAME       AGE
add-tags   20s

#istioctl dashboard prometheus --address 0.0.0.0

img

测试结束。😘

  • 奇怪:我这里没有现象……(prometheus都已经删除重建过了的…… 先搁置吧。)

3.禁用指标

对于禁用指标则相对更简单了。

比如我们通过以下配置禁用所有指标:

apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: remove-all-metrics
  namespace: istio-system
spec:
  metrics:
    - providers:
        - name: prometheus
      overrides:
        - disabled: true
          match:
            mode: CLIENT_AND_SERVER
            metric: ALL_METRICS

通过以下配置禁用 REQUEST_COUNT 指标:

apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: remove-request-count
  namespace: istio-system
spec:
  metrics:
    - providers:
        - name: prometheus
      overrides:
        - disabled: true
          match:
            mode: CLIENT_AND_SERVER
            metric: REQUEST_COUNT

通过以下配置禁用客户端的 REQUEST_COUNT 指标:

apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: remove-client
  namespace: istio-system
spec:
  metrics:
    - providers:
        - name: prometheus
      overrides:
        - disabled: true
          match:
            mode: CLIENT
            metric: REQUEST_COUNT

通过以下配置禁用服务端的 REQUEST_COUNT 指标:

apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: remove-server
  namespace: istio-system
spec:
  metrics:
    - providers:
        - name: prometheus
      overrides:
        - disabled: true
          match:
            mode: SERVER
            metric: REQUEST_COUNT

到这里我们就了解了如何通过 Telemetry API 来自定义指标了,这样我们就可以根据自身的需求来定制了。

分布式追踪

分布式追踪可以让用户对跨多个分布式服务网格的请求进行追踪分析,可以通过可视化的方式更加深入地了解请求的延迟,序列化和并行度。Istio 利用 Envoy 的分布式追踪功能提供了开箱即用的追踪集成,Istio 提供了安装各种追踪后端服务的选项,并且通过配置代理来自动发送追踪 Span 到分布式追踪系统服务,比如 Zipkin、Jaeger、Lightstep、Skywalking 等后端服务。

img

一次完整的链路是由多个 span 组成的,每个 span 代表了一次请求的一部分,每个 span 都有一个唯一的 ID,这个 ID 用来标识这个 span,同时还有一个父 span 的 ID,用来标识这个 span 的父 span,这样就可以将多个 span 组成一个链路了。将不同的 span 关联到一起的方式是通过将父 span 的 ID 传递给子 span,这样就可以将多个 span 关联起来了,也就是上下文传递

上下文传递

尽管 Istio 代理能够自动发送 Span,但需要一些附加信息才能将这些 Span 加到同一个调用链,所以当代理发送 Span 信息的时候,应用程序需要附加适当的 HTTP 请求头信息,这样才能够把多个 Span 加到同一个调用链。

要做到这一点,每个应用程序必须从每个传入的请求中收集请求头(Header),并将这些请求头转发到传入请求所触发的所有传出请求。 具体选择转发哪些请求头取决于所配置的跟踪后端。

img

虽然 Istio 代理能够自动发送 span 信息,但它们需要一些提示来将整个跟踪关联起来。应用程序需要传播适当的 HTTP 头,以便当代理发送 span 信息时,span 能够正确地关联到单个跟踪中。为了实现这一点,应用程序需要从传入的请求中收集和传播头信息到所有的外发请求。要传播的头信息的选择取决于所使用的跟踪配置。

首先所有应用程序必须转发以下请求头:

  • x-request-id:这是 Envoy 专用的请求头,用于对日志和追踪进行一致的采样。

对于 Zipkin、Jaeger、Stackdriver 和 OpenCensus Agent,应转发 B3 请求头格式:

  • x-b3-traceid
  • x-b3-spanid
  • x-b3-parentspanid
  • x-b3-sampled
  • x-b3-flags

这些是 Zipkin、Jaeger、OpenCensus 和许多其他工具支持的请求头。

B3 是一个跟踪上下文传播的格式,它起源于 Zipkin 项目,但后来被其他许多分布式跟踪工具所采用。B3 的名字来源于 BigBrotherBird,它的主要目的是为了在服务之间传播跟踪上下文。它是由一组特定的 HTTP 头部组成的,可以传递跟踪信息,如 trace ID、span ID、采样决策等。

对于 Datadog,应转发以下请求头,对于许多语言和框架而言,这些转发由 Datadog 客户端库自动处理。

  • x-datadog-trace-id
  • x-datadog-parent-id
  • x-datadog-sampling-priority

对于 Lightstep,应转发 OpenTracing span 上下文请求头:

  • x-ot-span-context

对于 Stackdriver 和 OpenCensus Agent,可以使用以下任一请求头来替代 B3 多请求头格式。

  • grpc-trace-bin:标准的 gRPC 追踪头。
  • traceparent:追踪所用的 W3C 追踪上下文标准,受所有 OpenCensus、OpenTelemetry 和 Jaeger 客户端库所支持。
  • x-cloud-trace-context:由 Google Cloud 产品 API 使用。

W3C Trace Context 规范为追踪上下文传播数据的交换定义了一种普遍认同的格式 - 称为追踪上下文Trace Context 是一个在分布式追踪中用于跨服务和跨进程传递 trace 数据的标准。它定义了如何在 HTTP headers 中编码 trace 数据,以便在不同的服务间传递这些数据。具体来说,Trace Context 包含两个部分:traceparenttracestate

  • traceparent 以便携、固定长度的格式描述了传入请求在其追踪链路中的位置。它的设计重点是快速解析,每个跟踪工具都必须正确设置 traceparent,即使它仅依赖于 tracestate 中的供应商特定信息。
  • tracestate 通过一组 name/value 键值对表示来扩展带有供应商特定数据的 traceparent。将信息存储在 tracestate 中是可选的。

使用 W3C 跟踪上下文上下文传播接收 HTTP 请求可能如下所示:

GET /my-service HTTP/1.1
Host: myhost.com
traceparent: 00–0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331–01
tracestate: abc=00f067aa0ba902b7,xyz=99f067aa0ba902b7

traceparent 字段

Traceparent HTTP Header 字段标识跟踪系统中的传入请求,这是一个必要的部分,它由 4 个部分组成,所有字段都使用 16 进制编码:

  • version:系统适配的追踪上下文版本,当前版本是 00
  • trace-id:一个全局唯一的 ID,用于标识整个 trace,它是一个 32 个字符的十六进制字符串。
  • parent-id:一个服务内唯一的 ID,用于标识调用链中的当前操作(通常是一个函数或者请求处理器)。它是一个 16 个字符的十六进制字符串。
  • trace-flags:用于控制 trace 的行为,例如是否需要被采样等。

img

比如我们有一个前端应用中的一个接口中添加了 Trace Context,它的 traceparent 就是这样的:

img

比如我们这里一次 HTTP 请求中通过 Header 传递的 Traceparent 值为 00-a237a2ca46023ce3e1d214ad2866c9c0-d00a29e113663fed-01,对应到 Jaeger UI 中 trace id 为 a237a2ca46023ce3e1d214ad2866c9c0,parent id(也就是父级的 span id)为 d00a29e113663fed,trace flags 为 01

img

tracestate 字段

tracestate 这是一个可选的部分,用于跨多个服务传递额外的 trace 信息。它是一个键值对列表,列表中的每一项都由一个服务添加。服务可以在 tracestate 中添加一些自定义的数据,例如服务的版本、部署环境等。

Jaeger

接下来我们来看下如何在 Istio 中集成 Jaeger,Jaeger 是一个开源的分布式追踪系统,它由 Uber 开源,用于监视和故障排除复杂的分布式系统。同样我们这里还是以 Bookinfo 为例进行说明。

  • 首先要安装 Jaeger,我们这里只是演示,可以直接使用下面的方式进行安装:
$ kubectl apply -f samples/addons/jaeger.yaml
$ kubectl get pods -n istio-system -l app=jaeger
NAME                     READY   STATUS    RESTARTS         AGE
jaeger-db6bdfcb4-qpmmv   1/1     Running   20 (5h40m ago)   29d
$ kubectl get svc -n istio-system
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                      AGE
jaeger-collector       ClusterIP      10.107.60.208    <none>        14268/TCP,14250/TCP,9411/TCP,4317/TCP,4318/TCP                               29d
tracing                ClusterIP      10.98.235.44     <none>        80/TCP,16685/TCP                                                             29d
zipkin                 ClusterIP      10.98.118.194    <none>        9411/TCP                                                                     29d
# ......

如果是要在生产环境中使用 Jaeger,则需要参考官方文档进行部署。

  • 安装 Jaeger 完毕后,需要指定 Istio Envoy Proxy 代理向 Deployment 发送流量,可以使用 --set meshConfig.defaultConfig.tracing.zipkin.address=jaeger-collector:9411 进行配置,此外默认的采样率为 1%,可以通过 --set meshConfig.defaultConfig.tracing.sampling=100 来修改采样率。
istioctl install --set profile=demo --set meshConfig.defaultConfig.tracing.zipkin.address=jaeger-collector:9411 --set meshConfig.defaultConfig.tracing.sampling=100 -y
  • 现在我们就可以通过下面的命令来查看 Jaeger UI 了:
istioctl dashboard jaeger --address 0.0.0.0

[root@master1 ~]#kubectl get istiooperators.install.istio.io -nistio-system
NAME              REVISION   STATUS   AGE
installed-state                       26d

[root@master1 ~]#kubectl get istiooperators.install.istio.io -nistio-system -oyaml
……
    meshConfig:
      accessLogFile: /dev/stdout
      defaultConfig:
        proxyMetadata: {}
        tracing:
          sampling: 100
          zipkin:
            address: jaeger-collector:9411

http://172.29.9.61:16686/

img

  • 接下来我们只需要访问下 Bookinfo 应用,然后在 Jaeger UI 中就可以看到追踪数据了。要查看追踪数据,必须向服务发送请求。请求的数量取决于 Istio 的采样率,采样率在安装 Istio 时设置,默认采样速率为 1%。在第一个跟踪可见之前,我们需要发送至少 100 个请求。使用以下命令向 productpage 服务发送 100 个请求:
for i in $(seq 1 100); do curl -s -o /dev/null "http://$GATEWAY_URL/productpage"; done


for i in $(seq 1 100); do curl -s -o /dev/null "http://172.29.9.61:31666/productpage"; done
  • 从仪表盘左边面板的 Service 下拉列表中选择 productpage.default 并点击 Find Traces:

img

奇怪哇:我这里只有2个服务哦。。。

  • 然后我们可以点击访问 /productpage 的链路详细信息:

img

追踪信息由一组 Span 组成,每个 Span 对应一个 Bookinfo Service。这些 Service 在执行 /productpage 请求时被调用,或是 Istio 内部组件,例如:istio-ingressgateway

  • 在系统架构页面也可以看到对应的 DAG 图:

img

关于我

我的博客主旨:

  • 排版美观,语言精炼;
  • 文档即手册,步骤明细,拒绝埋坑,提供源码;
  • 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!

🍀 微信二维码
x2675263825 (舍得), qq:2675263825。

image-20230107215114763

🍀 微信公众号
《云原生架构师实战》

image-20230107215126971

🍀 个人博客站点

http://onedayxyy.cn/

🍀 语雀

https://www.yuque.com/xyy-onlyone

🍀 csdn

https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

image-20230107215149885

🍀 知乎

https://www.zhihu.com/people/foryouone

image-20230107215203185

最后

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!

690384132)]

🍀 微信公众号
《云原生架构师实战》

[外链图片转存中…(img-6x2RM7AH-1701690384133)]

🍀 个人博客站点

http://onedayxyy.cn/

[外链图片转存中…(img-oZnYMCzV-1701690384133)]

[外链图片转存中…(img-SrUrEOAh-1701690384134)]

🍀 语雀

https://www.yuque.com/xyy-onlyone

[外链图片转存中…(img-tkH0lDiV-1701690384134)]

🍀 csdn

https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

[外链图片转存中…(img-VSRnaRiY-1701690384134)]

🍀 知乎

https://www.zhihu.com/people/foryouone

[外链图片转存中…(img-z6nY6FJF-1701690384135)]

最后

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!

[外链图片转存中…(img-3dUX2kKM-1701690384136)]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/216642.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【小程序】02-项目的基本组成

pages&#xff1a;用来存放所有小程序的页面utils&#xff1a;用来存放工具性质的模块&#xff08;例如&#xff1a;格式化时间的自定义模块&#xff09;app.js&#xff1a;小程序项目的入口文件app.json&#xff1a;小程序项目的全局配置文件app.wxss&#xff1a;小程序项目的…

selenium中元素定位正确但是操作失败,6种解决办法全搞定

selenium中元素定位正确但是操作失败的原因无外乎以下4种&#xff1a; 01 页面没加载好 解决方法&#xff1a;添加等待方法&#xff0c;如&#xff1a;time.sleep() 02 页面提交需要等待给数据后台 解决方法&#xff1a;添加等待方法&#xff0c;如&#xff1a;time.sleep(…

DSShop移动商城网店系统 反序列化RCE漏洞复现

0x01 产品简介 DSShop是长沙德尚网络科技有限公司推出的一款单店铺移动商城网店系统,能够帮助企业和个人快速构建手机移动商城,并减少二次开发带来的成本。 以其丰富的营销功能,精细化的用户运营,解决电商引流、推广难题,帮助企业打造生态级B2C盈利模式商业平台。完备的电商…

线程变量引发的session混乱问题

最近不是在救火&#xff0c;就是在救火的路上。 也没什么特别可写的&#xff0c;今天记录下最近遇到的一个问题&#xff0c;个人觉得挺有意思&#xff0c; 待有缘人阅读 言归正传&#xff0c;售后反馈&#xff1a; 营业查询中付款方式为第三方支付的几条银行缴费&#xff0c;创…

信息化系列——企业信息化建设(2)

企业信息化建设常见问题 1、信息化意识薄弱 目前&#xff0c;仍有许多企业的管理者在信息化方面表现出薄弱的认识&#xff0c;他们对信息化建设的重视程度显得捉襟见肘。结果&#xff0c;企业在信息化建设的人力、物力支持方面投入甚微&#xff0c;导致信息化建设难以完成顶层…

HDFS客户端及API操作实验

实验二 HDFS客户端及API操作 实验目的&#xff1a; 1.掌握HDFS的客户端操作&#xff0c;包括上传文件、下载文件、重命名、查看目录等&#xff1b; 2.掌握HDFS的Java API使用&#xff0c;能够利用Java API实现上传、下载等常用操作&#xff1b; 实验内容&#xff1a; HDF…

go写文件后出现大量NUL字符问题记录

目录 背景 看看修改前 修改后 原因 背景 写文件完成后发现&#xff1a; size明显也和正常的不相等。 看看修改前 buf : make([]byte, 64) buffer : bytes.NewBuffer(buf)// ...其它逻辑使得buffer有值// 打开即将要写入的文件&#xff0c;不存在则创建 f, err : os.Open…

Java中线程池相关的七个参数

在Java中&#xff0c;线程池的七个参数是指线程池的相关配置参数&#xff0c;用来控制线程池的行为和性能。这些参数包括&#xff1a; 1. 核心线程数&#xff08;corePoolSize&#xff09;&#xff1a;线程池中保持的最小线程数&#xff0c;即使线程处于空闲状态&#xff0c;也…

C++进阶篇6---lambda表达式

目录 一、lambda表达式 1.引入 2、lambda表达式语法 二、包装器---function 1.引入 2.包装器介绍 三、bind 一、lambda表达式 1.引入 class Person { public:Person(int age,string name):_age(age),_name(name){} //private://方便后面的举例int _age;string _name…

ROS话题通信基本操作(python)

目录 一、发布 1、实现步骤 2、代码实例 二、接收 1、实现步骤 2、代码实例 三、配置运行 1、修改CMakeLists.txt 2、修改可执行权限 3、运行结果 一、发布 1、实现步骤 1.导包 2.初始化 ROS 节点:命名(唯一) 3.实例化 发布者 对象 4.组织被发布的数据&#xff0c;…

浅谈Django之单元测试

一、什么是单元测试 单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。如果测试通过则说明我们这个函数或功能能够正常工作&#xff0c;如果失败要么测试用例不正确&#xff0c;要么函数有bug需要修复。 二、如何使用单元测试 from django.test imp…

Spring Cloud + Vue前后端分离-第2章 使用Maven搭建SpringCloud项目

第2章 使用Maven搭建SpringCloud项目 Maven两大核心功能&#xff1a; 依赖管理&#xff08;Jar包管理&#xff09; 构建项目&#xff08;项目打包&#xff09; 使用Eureka搭建注册中心 使用spring initializr创建spring cloud项目 SpringCloud和Maven简介 SpringBoot和Spr…

[ISCTF 2023]——Web、Misc较全详细Writeup、Re、Crypto部分Writeup

前言 由于懒我直接把上交的wp稍加修改拉上来了&#xff0c;凑活看 文章目录 前言Pwntest_ncnc_shell ReverseCreakmeEasyRebabyReeasy_z3mix_reeasy_flower_tea Webwhere_is_the_flag圣杯战争!!!绕进你的心里easy_websitewafrez_ini1z_Ssqldouble_picklewebincludefuzz!恐怖G…

全网最新最全的自动化测试:python+pytest接口自动化-接口测试基础

接口定义 一般我们所说的接口即API&#xff0c;那什么又是API呢&#xff0c;百度给的定义如下&#xff1a; API&#xff08;Application Programming Interface&#xff0c;应用程序接口&#xff09;是一些预先定义的接口&#xff08;如函数、HTTP接口&#xff09;&#xff0c…

从0到1的跨境电商创业经验分享!个人如何做跨境电商创业?

近年来&#xff0c;跨境电商成为了一种非常流行的创业方式&#xff0c;都知道国内贸易不好做&#xff0c;许多卖家都想通过跨境电商创业&#xff0c;但他们不知道具体的过程&#xff0c;今天龙哥我就分享一下我自己在跨境电商创业总结出来的经验&#xff0c;帮助你在跨境电商领…

【powerjob】定时任务调度器 xxl-job和powerjob对比

文章目录 同类产品对比资源及部署相关资源占用对比&#xff1a;部署方式&#xff1a;xxl job :调度器&#xff1a;执行器&#xff1a; powerjob&#xff1a;调度器&#xff1a;执行器&#xff1a; 总结 背景&#xff1a; 目前系统的定时任务主要通过Spring框架自带的Scheduled注…

buuctf [极客大挑战 2019]Havefun1

解题思路&#xff1a; 小习惯 本题先看看源码或者检查一下&#xff0c;可能这是俺的一个小习惯。 源码里面都看到了php的代码 php代码解析&#xff1a; $cat$_GET[cat]; echo $cat; if($catdog){ echo Syc{cat_cat_cat_cat}; } 1.$ca…

新手村之SQL——分组与子查询

1.GROUP BY GROUP BY 函数就是 SQL 中用来实现分组的函数&#xff0c;其用于结合聚合函数&#xff0c;能根据给定数据列的每个成员对查询结果进行分组统计&#xff0c;最终得到一个分组汇总表。 mysql> SELECT country, COUNT(country) AS teacher_count-> FROM teacher…

T-SQL的多表查询

前面讲述过的所有查询都是基于单个数据库表的查询。如果一个查询需要对多个表进行操作&#xff0c;就称为联接查询&#xff0c;联接查询的结果集或结果称为表之间的联接。 联接查询实际上是通过各个表之间共同列的关联性来查询数据的&#xff0c;它是关系数据库查询最主要的特征…

听GPT 讲Rust源代码--src/tools(7)

File: rust/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs 在Rust源代码中&#xff0c;rust-analyzer/crates/ide/src/inlay_hints/chaining.rs这个文件的作用是生成Rust代码中的链式调用提示。 具体来说&#xff0c;当我们使用链式调用时&#xff0c;例如A…