分布式追踪
目录
文章目录
- 目录
- 自定义指标
- 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: truev2:enabled: false
Telemetry 资源对象的定义如下所示:
$ kubectl explain Telemetry.spec
GROUP: telemetry.istio.io
KIND: Telemetry
VERSION: v1alpha1FIELD: spec <Object>DESCRIPTION:Telemetry configuration for workloads. See more details at:https://istio.io/docs/reference/config/telemetry.htmlFIELDS:accessLogging <[]Object>Optional.metrics <[]Object>Optional.selector <Object>Optional.tracing <[]Object>Optional.
可以看到 Telemetry 资源对象包含了 accessLogging
、metrics
、selector
和 tracing
四个字段,其中 accessLogging
和 tracing
字段用于配置访问日志和追踪数据,而 metrics
字段用于配置指标数据,selector
字段用于配置哪些工作负载需要采集指标数据。
我们这里先来看下 metrics
字段的配置,该字段的定义如下所示:
$ kubectl explain Telemetry.spec.metrics
GROUP: telemetry.istio.io
KIND: Telemetry
VERSION: v1alpha1FIELD: metrics <[]Object>DESCRIPTION:Optional.FIELDS:overrides <[]Object>Optional.providers <[]Object>Optional.reportingInterval <string>Optional.
可以看到 metrics
字段包含了 overrides
、providers
和 reportingInterval
三个字段。
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(测试成功)
比如以前需要在 Istio 配置的 meshConfig
部分配置遥测,这种方式不是很方便。比如我们想从 Istio 指标中删除一些标签以减少基数,那么你的配置中可能有这样一个部分:
# istiooperator.yaml
telemetry:enabled: truev2:enabled: trueprometheus:enabled: trueconfigOverride:outboundSidecar:debug: falsestat_prefix: istiometrics:- tags_to_remove:- destination_canonical_service...
现在我们可以通过 Telemetry API 来配置,如下所示:
#remove-tags.yaml
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:name: remove-tagsnamespace: 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_BYTES | TCP 连接期间发送的响应字节计数器。Prometheus 提供商将此指标导出为:istio_tcp_sent_bytes_total 。Stackdriver 提供商将此指标导出为:istio.io/service/server/sent_bytes_count (服务器模式)istio.io/service/client/sent_bytes_count (客户端模式) |
TCP_RECEIVED_BYTES | TCP 连接期间接收的请求字节计数器。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 是对标签执行的操作,可以添加、删除标签,或覆盖其默认值。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
operation | Operation | 操作控制是否更新/添加一个标签,或者移除它。 | 否 |
value | string | 当操作为 UPSERT 时才考虑值。值是基于属性的 CEL 表达式。例如:string(destination.port) 和 request.host 。Istio 暴露所有标准的 Envoy 属性。此外,Istio 也将节点元数据作为属性暴露出来。更多信息请参见 自定义指标文档。 | 否 |
对应的操作 Operator
可以配置 UPSERT
和 REMOVE
两个操作:
名称 | 描述 |
---|---|
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
从上面的结果可以看到,我们已经成功删除了 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(测试成功)
- 上面我们已经介绍了如何删除指标中的标签,那么我们也可以通过 Telemetry API 来添加指标中的标签,如下所示:
#add-tags.yaml
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:name: add-tags
spec:metrics:- overrides:- match:metric: REQUEST_COUNTmode: CLIENTtagOverrides:destination_x:operation: UPSERTvalue: "upstream_peer.labels['app'].value" # 必须加上双引号- match:metric: REQUEST_COUNTtagOverrides:destination_port:value: "string(destination.port)"request_host:value: "request.host"providers:- name: prometheus
在上面的这个资源对象中我们在 tagOverrides
中首先添加了如下的配置:
destination_x:operation: UPSERTvalue: "upstream_peer.labels['app'].value"
表示我们要添加一个名为 destination_x
的标签,然后通过 value
字段指定标签的值为 upstream_peer.labels['app'].value
,这个值是一个 CEL
表达式(common expression)(必须在 JSON 中用双引号引用字符串)。Istio 暴露了所有标准的 Envoy 属性,对于出站请求,对等方元数据作为上游对等方(upstream_peer
)的属性可用;对于入站请求,对等方元数据作为下游对等方(downstream_peer
)的属性可用,包含以下字段:
属性 | 类型 | 值 |
---|---|---|
name | string | Pod 名 |
namespace | string | Pod 所在命名空间 |
labels | map | 工作负载标签 |
owner | string | 工作负载 owner |
workload_name | string | 工作负载名称 |
platform_metadata | map | 平台元数据 |
istio_version | string | 代理的版本标识 |
mesh_id | string | 网格唯一 ID |
app_containers | list<string> | 应用容器的名称列表 |
cluster_id | string | 工作负载所属的集群标识 |
例如,用于出站配置中的对等应用标签的表达式是 upstream_peer.labels['app'].value
,所以上面我们最终添加的 destination_x
这个标签的值为上游对等方的 app
标签的值。
另外添加的两个标签 destination_port
和 request_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
测试结束。😘
- 奇怪:我这里没有现象……(prometheus都已经删除重建过了的…… 先搁置吧。)
3.禁用指标
对于禁用指标则相对更简单了。
比如我们通过以下配置禁用所有指标:
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:name: remove-all-metricsnamespace: istio-system
spec:metrics:- providers:- name: prometheusoverrides:- disabled: truematch:mode: CLIENT_AND_SERVERmetric: ALL_METRICS
通过以下配置禁用 REQUEST_COUNT
指标:
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:name: remove-request-countnamespace: istio-system
spec:metrics:- providers:- name: prometheusoverrides:- disabled: truematch:mode: CLIENT_AND_SERVERmetric: REQUEST_COUNT
通过以下配置禁用客户端的 REQUEST_COUNT
指标:
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:name: remove-clientnamespace: istio-system
spec:metrics:- providers:- name: prometheusoverrides:- disabled: truematch:mode: CLIENTmetric: REQUEST_COUNT
通过以下配置禁用服务端的 REQUEST_COUNT
指标:
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:name: remove-servernamespace: istio-system
spec:metrics:- providers:- name: prometheusoverrides:- disabled: truematch:mode: SERVERmetric: REQUEST_COUNT
到这里我们就了解了如何通过 Telemetry API 来自定义指标了,这样我们就可以根据自身的需求来定制了。
分布式追踪
分布式追踪可以让用户对跨多个分布式服务网格的请求进行追踪分析,可以通过可视化的方式更加深入地了解请求的延迟,序列化和并行度。Istio 利用 Envoy 的分布式追踪功能提供了开箱即用的追踪集成,Istio 提供了安装各种追踪后端服务的选项,并且通过配置代理来自动发送追踪 Span 到分布式追踪系统服务,比如 Zipkin、Jaeger、Lightstep、Skywalking 等后端服务。
一次完整的链路是由多个 span 组成的,每个 span 代表了一次请求的一部分,每个 span 都有一个唯一的 ID,这个 ID 用来标识这个 span,同时还有一个父 span 的 ID,用来标识这个 span 的父 span,这样就可以将多个 span 组成一个链路了。将不同的 span 关联到一起的方式是通过将父 span 的 ID 传递给子 span,这样就可以将多个 span 关联起来了,也就是上下文传递。
上下文传递
尽管 Istio 代理能够自动发送 Span,但需要一些附加信息才能将这些 Span 加到同一个调用链,所以当代理发送 Span 信息的时候,应用程序需要附加适当的 HTTP 请求头信息,这样才能够把多个 Span 加到同一个调用链。
要做到这一点,每个应用程序必须从每个传入的请求中收集请求头(Header),并将这些请求头转发到传入请求所触发的所有传出请求。 具体选择转发哪些请求头取决于所配置的跟踪后端。
虽然 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 包含两个部分:traceparent
和 tracestate
。
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 的行为,例如是否需要被采样等。
比如我们有一个前端应用中的一个接口中添加了 Trace Context
,它的 traceparent
就是这样的:
比如我们这里一次 HTTP 请求中通过 Header 传递的 Traceparent
值为 00-a237a2ca46023ce3e1d214ad2866c9c0-d00a29e113663fed-01
,对应到 Jaeger UI 中 trace id 为 a237a2ca46023ce3e1d214ad2866c9c0
,parent id(也就是父级的 span id)为 d00a29e113663fed
,trace flags 为 01
。
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/stdoutdefaultConfig:proxyMetadata: {}tracing:sampling: 100zipkin:address: jaeger-collector:9411
http://172.29.9.61:16686/
- 接下来我们只需要访问下 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"; donefor i in $(seq 1 100); do curl -s -o /dev/null "http://172.29.9.61:31666/productpage"; done
- 从仪表盘左边面板的 Service 下拉列表中选择
productpage.default
并点击 Find Traces:
奇怪哇:我这里只有2个服务哦。。。
- 然后我们可以点击访问
/productpage
的链路详细信息:
追踪信息由一组 Span 组成,每个 Span 对应一个 Bookinfo Service。这些 Service 在执行 /productpage
请求时被调用,或是 Istio 内部组件,例如:istio-ingressgateway
。
- 在系统架构页面也可以看到对应的 DAG 图:
关于我
我的博客主旨:
- 排版美观,语言精炼;
- 文档即手册,步骤明细,拒绝埋坑,提供源码;
- 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!
🍀 微信二维码
x2675263825 (舍得), qq:2675263825。
🍀 微信公众号
《云原生架构师实战》
🍀 个人博客站点
http://onedayxyy.cn/
🍀 语雀
https://www.yuque.com/xyy-onlyone
🍀 csdn
https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421
🍀 知乎
https://www.zhihu.com/people/foryouone
最后
好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!
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)]
相关文章:

分布式追踪
目录 文章目录 目录自定义指标1.删除标签2.添加指标3.禁用指标 分布式追踪上下文传递Jaeger 关于我最后最后 自定义指标 除了 Istio 自带的指标外,我们还可以自定义指标,要自定指标需要用到 Istio 提供的 Telemetry API,该 API 能够灵活地配…...
make -c VS make -f
make 是一个用于构建(编译)项目的工具,它通过读取一个名为 Makefile 的文件来执行构建任务。make 命令有很多选项和参数,其中包括 -c 和 -f。 make -c: 作用:指定进入指定的目录并执行相应的 Makefile。 示…...

Unity 代码控制Color无变化
Unity中,我们给Color的赋值比较常用的方法是: 1、使用预定义颜色常量: Color color Color.white; //白色 Color color Color.black; //黑色 Color color Color.red; //红色 Color color Color.green; //绿色 Color color Color.blue; …...

【Erlang进阶学习】2、匿名函数
受到其它一些函数式编程开发语言的影响,在Erlang语言中,将函数作为一个对象,赋予其“变量”的属性,即为我们的匿名函数 或 简称 fun,它具有以下特性: (匿名函数:不是定义在Erlang模…...

肖sir__mysql之视图__009
mysql之视图 一、什么是视图 视图是一个虚拟表(逻辑表),它不在数据库中以存储形式保存(本身包含数据),是在使用视图的时候动态生成。 二、视图作用 1、查询数据库中的非常复的数据 例如:多表&a…...

FPGA falsh相关知识总结
1.存储容量是128M/8 Mb16MB 2.有256个sector扇区*每个扇区64KB16MB 3.一页256Byte 4.页编程地址0256 5:在调试SPI时序的时候一定注意,miso和mosi两个管脚只要没发送数据就一定要悬空(处于高组态),不然指令会通过两…...

升辉清洁IPO:广东清洁服务“一哥”还需要讲好全国化的故事
近日,广东物业清洁服务“一哥”升辉清洁第四次冲击IPO成功,拟于12月5日在香港主板挂牌上市。自2021年4月第一次递交招股书,时隔两年半,升辉清洁终于拿到了上市的门票。 天眼查显示,升辉清洁成立于2000年,主…...

Python自动化办公:PDF文件的分割与合并
我们平时办公中,可能需要对pdf进行合并或者分割,但奈何没有可以白嫖的工具,此时python就是一个万能工具库。 其中PyPDF2是一个用于处理PDF文件的Python库,它提供了分割和合并PDF文件的功能。 在本篇博客中,我们将详细…...
破解app思路
1.会看smali代码逻辑 一.快速定位关键代码 1.分析流程 搜索特征字符串 搜索关键 api 通过方法名来判断方法的功能 2.快速定位关键代码 反编译 APK 程序 AndroidManifest.xml>包名/系统版本/组件 程序的主 activity(程序入口界面) 每个 Android 程序…...

36.位运算符
一.什么是位运算符 按照二进制位来进行运算的运算符叫做位运算符,所以要先将操作数转换成二进制(补码)的形式在运算。C语言的中的位运算符有: 运算符作用举例结果& 按位与(and) 0&00; 0&10; …...
C#异常处理-throw语句
throw语句是我们手动引发异常的一个语句。 在程序执行过程中,当某些条件不符合我们的要求时,那么我们就可以使用throw语句手动抛出异常,那么就可以在异常发生的地方终止当前代码块的执行,此时我们就可以把控制权传递给调用堆栈中…...

PlantUML语法(全)及使用教程-时序图
目录 1. 参与者1.1、参与者说明1.2、背景色1.3、参与者顺序 2. 消息和箭头2.1、 文本对其方式2.2、响应信息显示在箭头下面2.3、箭头设置2.4、修改箭头颜色2.5、对消息排序 3. 页面标题、眉角、页脚4. 分割页面5. 生命线6. 填充区设置7. 注释8. 移除脚注9. 组合信息9.1、alt/el…...
231204 刷题日报
21. 合并两个有序链表 单调栈没看懂,晚上回家再说吧 380. O(1) 时间插入、删除和获取随机元素 今天被接雨水钉在耻辱柱,找时间再看吧...
PTA 7-229 sdut-C语言实验- 排序
给你N(N<100)个数,请你按照从小到大的顺序输出。 输入格式: 输入数据第一行是一个正整数N,第二行有N个整数。 输出格式: 输出一行,从小到大输出这N个数,中间用空格隔开。 输入样例: 5 1 4 3 2 5输出样例: 1 2 3 4 5 #include <stdio.h>…...

原生横向滚动条 吸附 页面底部
效果图 /** 横向滚动条 吸附 页面底部 */ export class StickyHorizontalScrollBar {constructor(options {}) {const { el, style } optionsthis.createScrollbar(style)this.insertScrollbar(el)this.setScrollbarSize()this.onEvent()}/** 创建滚轴组件元素 */createS…...

1+x网络系统建设与运维(中级)-练习3
一.设备命名 AR1 [Huawei]sysn AR1 [AR1] 同理可得,所有设备的命名如上图所示 二.VLAN LSW1 [LSW1]vlan 10 [LSW1-vlan10]q [LSW1]int g0/0/1 [LSW1-GigabitEthernet0/0/1]port link-type access [LSW1-GigabitEthernet0/0/1]port default vlan 10 [LSW1-GigabitEt…...
知识图谱07——图片中表格开源ocr识别
对比了多种ocr识别算法,最终选择了百度paddle官方的ocr算法 在所在的虚拟环境下运行 pip install paddleocr --userfrom paddleocr import PaddleOCR import os import csv# 创建 PaddleOCR 对象 ocr PaddleOCR(use_gpuTrue) # 无gpu时选择False# 指定图片文件夹…...
每日一练2023.12.4——正整数【PTA】
一时间网上一片求救声,急问这个怎么破。其实这段代码很简单,index数组就是arr数组的下标,index[0]2 对应 arr[2]1,index[1]0 对应 arr[0]8,index[2]3 对应 arr[3]0,以此类推…… 很容易得到电话号码是18013…...

golang之net/http模块学习
文章目录 开启服务开启访问静态文件获取现在时间按时间创建一个空的json文件按时间创建一个固定值的json文件 跨域请求处理输出是json 开启服务 package mainimport ("fmt""net/http" )//路由 func handler(w http.ResponseWriter, r *http.Request){fmt.…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...