Kruise Rollout 全链路灰度实践

2024-01-25 05:52

本文主要是介绍Kruise Rollout 全链路灰度实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者:旦酱、十眠

什么是全链路灰度?

在发布应用的过程中,我们通常希望用少量特定流量来验证新版本的发布是否正常,以保障整体稳定性。这个过程被称为灰度发布。关于灰度发布,我们通过逐步增加发布的范围,来验证新版本的稳定性。如果新版本出现问题,我们也能及时发现,控制影响范围,保障整体的稳定性。

图片

灰度发布一般具有以下特点:

  • 逐步增加发布的影响范围,拒绝一次性全部发布。
  • 阶段性的发布过程,可以通过金丝雀发布方式小心验证,以验证新版本的稳定性;
  • 可暂停、可回滚、可继续、可自动化状态流转,以便灵活地控制发布过程并确保稳定性;

据调研数据 70% 的线上问题都是由于变更导致,我们常说安全生产三板斧,可灰度、可观测、可回滚,也是为了控制变更带来的风险与影响面。 通过采用灰度发布的方式,我们能够更加稳健地发布新版本,避免因发布过程中出现的问题而带来的损失。

全链路灰度是微服务场景下灰度发布方案的最佳实践,通常每个微服务都会有灰度环境或分组来接受灰度流量。我们希望进入上游灰度环境的流量也能进入下游灰度的环境中,确保1个请求始终在灰度环境中传递,从而形成流量“泳道”。在“泳道”内的流量链路中,即使这个调用链路上有一些微服务应用不存在灰度环境,那么这些微服务应用在请求下游应用的时候依然能够回到下游应用的灰度环境中。

图片

全链路灰度为微服务发布保驾护航

这种方式可以根据服务的实际情况,可以对单个服务可以进行独立的发布和流量控制,也可以控制多个服务同时进行发布变更,从而保证整个系统的稳定性。同时,还可以采用自动化的部署方式,实现快速、可靠的发布过程,提高发布效率和稳定性。

Istio 全链路灰度技术解析

如何通过 Istio 实现全链路灰度能力,想必大家都很关心这个话题,今天我们就详细谈一下基于 istio 实现全链路灰度能力的几个关键技术细节。

流量标签全链路透传

在对微服务进行全链路灰度的过程中,一个最需要考虑的问题是流量中 header 透传的问题,一些微服务会仅保留特定的 header 进行透传,而去除其它 header,利用 Kruise Rollout,可以有效减少发布中对网关资源进行配置的复杂性,但却无法解决 header 透传的问题。如何保证灰度标识能够在链路中一直传递下去呢?分布式链路追踪技术对大型分布式系统中请求调用链路进行详细记录,核心思想就是通过一个全局唯一的 traceid 和每一条的 spanid 来记录请求链路所经过的节点以及请求耗时,其中 traceid 是需要整个链路传递的。借助于分布式链路追踪思想,我们也可以传递一些自定义信息,比如灰度标识。业界常见的分布式链路追踪产品都支持链路传递用户自定义的数据,其数据处理流程如下图所示:

图片

我们可以借助 Tracing Baggage 机制在全链路中传递对应染色标识,因为大部分 Tracing 框架都支持 Baggage 概念及能力,如:OpenTelemetry、Skywalking、Jaeger 等等。我们只需要在 Envoy outbound Filter 中讲指定的透传 key 如 x-mse-tag 从 Tracing 协议指定位置的 Baggage 中读出 x-mse-tag 对应的值,并塞入到 Http 的 Header 中,供 Envoy 进行路由。

流量路由

通过对服务下所有节点按照标签名和标签值不同进行分组,使得订阅该服务节点信息的服务消费端可以按需访问该服务的某个分组,即所有节点的一个子集。服务消费端可以使用服务提供者节点上的任何标签信息,根据所选标签的实际含义,消费端可以将标签路由应用到更多的业务场景中。

图片

在 Istio 中我们可以通过 Istio Gateway、DestinationRule 和 VirtualService 配置路由和外部访问;

节点打标

如何给服务节点添加不同的标签?我们只要在业务应用描述资源 Deployment 中的 Pod 模板中为节点添加标签即可。在使用 Kubernetes Service 作为服务发现的业务系统中,服务提供者通过向 ApiServer 提交 Service 资源完成服务暴露,服务消费端监听与该 Service 资源下关联的 Endpoint 资源,从 Endpoint 资源中获取关联的业务 Pod 资源,读取上面的 Labels 数据并作为该节点的元数据信息。

图片

为什么选择 Kruise Rollout?

从上述技术细节中可以看出,实现基于 Istio 的全链路灰度操作非常复杂且成本较高。首先,需要创建灰度的 Deployment 并打上灰度的节点标识。其次,还需要配置 Istio 的流量路由 CRD,包括每一跳请求的 VirtualService 和 DestinationRule 规则,并且这些流量规则还需要与请求标识相配合。如果只是纸上谈谈技术细节,可能还能勉强理解,但如果真要实践起来,成本确实非常高。同时,如果在配置过程中出现错误,可能会导致生产流量出现问题,对业务造成重大影响。为了降低全链路灰度实践的成本,不得不提 Kruise Rollout 了。

Kruise Rollout [ 1] 是 OpenKruise 社区开源提出的一个渐进式交付框架。其设计理念是提供一组能够将流量发布与实例灰度相结合,支持金丝雀、蓝绿、A/B Testing 等多样化发布形式,以及支持基于 Prometheus Metrics 等自定义 Metrics 实现发布过程自动化,无感对接、易扩展的旁路式标准 Kubernetes 发布组件。

图片

从上图中我们可以看到 OpenKruise Rollout 能够将复杂的灰度发布过程自动化,因此通过 OpenKruise Rollout 可以大幅度降低全链路灰度的实施成本,对于使用者来说只需要配置 Kruise Rollout 的 CRD,然后直接进行应用发布,即可实现全链路灰度发布。

Kruise + Istio 全链路灰度实践

谈完技术实现的细节,下面我们就开始基于 Kruise Rollout 跟 Istio 的全链路灰度能力实践。

配置服务

首先部署两个服务 mocka 和 mockb,服务 mocka 会调用服务 mockb,⚠️服务只会保留流量中的 header my-request-id 而去除其它 header(我们也可以通过接入 OpenTelemetry 实现动态流量标签透传), 整个服务的访问可以表示为:

图片

服务的配置文件为:

apiVersion: v1
kind: Service
metadata:name: mockanamespace: e2elabels:app: mockaservice: mocka
spec:ports:- port: 8000name: httpselector:app: mocka
---
apiVersion: apps/v1
kind: Deployment
metadata:name: mocka-basenamespace: e2elabels:app: mocka
spec:replicas: 1selector:matchLabels:app: mockatemplate:metadata:labels:app: mockaversion: basespec:containers:- name: defaultimage: registry.cn-beijing.aliyuncs.com/aliacs-app-catalog/go-http-sample:1.0imagePullPolicy: Alwaysenv:- name: versionvalue: base- name: appvalue: mocka- name: upstream_urlvalue: "http://mockb:8000/"ports:- containerPort: 8000
---
apiVersion: v1
kind: Service
metadata:name: mockbnamespace: e2elabels:app: mockbservice: mockb
spec:ports:- port: 8000name: httpselector:app: mockb
---
apiVersion: apps/v1
kind: Deployment
metadata:name: mockb-basenamespace: e2elabels:app: mockb
spec:replicas: 1selector:matchLabels:app: mockbtemplate:metadata:labels:app: mockbversion: basespec:containers:- name: defaultimage: registry.cn-beijing.aliyuncs.com/aliacs-app-catalog/go-http-sample:1.0imagePullPolicy: Alwaysenv:- name: versionvalue: base- name: appvalue: mockbports:- containerPort: 8000

服务的 header 部分处理代码如下所示:

// All URLs will be handled by this function
m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {requestId := r.Header.Get("my-request-id")fmt.Printf("receive request: my-request-id: %s\n", requestId)response := fmt.Sprintf("-> %s(version: %s, ip: %s)", app, version, ip)if url != "" {// 新请求只发送my-request-idcontent := doReq(url, requestId)response = response + content}w.Write([]byte(response))
})

之后部署 Istio Gateway、DestinationRule 和 VirtualService 配置路由和外部访问:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:name: gatewaynamespace: e2e
spec:selector:istio: ingressgatewayservers:- hosts:- "*"port:name: httpnumber: 80protocol: HTTP
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:name: dr-mockanamespace: e2e
spec:host: mockatrafficPolicy:loadBalancer:simple: ROUND_ROBINsubsets:- labels:version: basename: version-base
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:name: dr-mockbnamespace: e2e
spec:host: mockbtrafficPolicy:loadBalancer:simple: ROUND_ROBINsubsets:- labels:version: basename: version-base
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:name: vs-mockanamespace: e2e
spec:gateways:- simple-gatewayhosts:- "*"http:- route:- destination:host: mockasubset: version-base
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:name: vs-mockbnamespace: e2e
spec:hosts:- mockbhttp:- route:- destination:host: mockbsubset: version-base

部署完成后整个结构如下图所示:

图片

在本地集群中,可以通过运行如下指令获取 Gateway 入口 ip 以及 port 对服务进行访问:

kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}'
kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}'

此时运行 curl http://GATEWAY_IP:PORT 可以得到如下结果:

-> mocka(version: base, ip: 10.244.1.36)-> mockb(version: base, ip: 10.244.1.37)

配置 Rollout 和 TrafficRouting 规则

之后部署 Rollout,分别对 mocka 和 mockb 进行控制。Rollout 以及 TrafficRouting 配置的策略如下:

  • 添加了匹配 my-request-id=canary 的 header 规则,包含指定 header 的流量会走灰度环境
  • 为发布的 pod 添加了 label istio.service.tag=gray 以及 version=canary

⚠️pod label 的添加规则是什么?

在配置中为新版本 pod 打上了两个 label,其中 istio.service.tag=gray 的目的是为了在 DestinationRule 中指定包含该 label 的 pod 作为一个 subset,lua 脚本会为 DestinationRule 自动添加该 Subset。添加 version=canary 的目的是为了覆盖原始版本中的 version=baselabel,如果不覆盖该 label, 原始 DestinationRule 也会将稳定版本的流量导入新版本 pod 中。

apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:name: rollouts-anamespace: demoannotations:rollouts.kruise.io/rolling-style: canaryrollouts.kruise.io/trafficrouting: mocka-tr
spec:disabled: falseobjectRef:workloadRef:apiVersion: apps/v1kind: Deploymentname: mocka-basestrategy:canary:steps:- replicas: 1patchPodTemplateMetadata:labels:istio.service.tag: grayversion: canary
---
apiVersion: rollouts.kruise.io/v1alpha1
kind: TrafficRouting
metadata:name: mocka-trnamespace: demo
spec:strategy:matches:- headers:- type: Exactname: my-request-idvalue: canaryobjectRef:- service: mockacustomNetworkRefs:- apiVersion: networking.istio.io/v1alpha3kind: VirtualServicename: vs-mocka- apiVersion: networking.istio.io/v1beta1kind: DestinationRulename: dr-mocka
---
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:name: rollouts-bnamespace: demoannotations:rollouts.kruise.io/rolling-style: canaryrollouts.kruise.io/trafficrouting: mockb-tr
spec:disabled: falseobjectRef:workloadRef:apiVersion: apps/v1kind: Deploymentname: mockb-basestrategy:canary:steps:- replicas: 1patchPodTemplateMetadata:labels:istio.service.tag: grayversion: canary
---
apiVersion: rollouts.kruise.io/v1alpha1
kind: TrafficRouting
metadata:name: mockb-trnamespace: demo
spec:strategy:matches:- headers:- type: Exactname: my-request-idvalue: canaryobjectRef:- service: mockbcustomNetworkRefs:- apiVersion: networking.istio.io/v1alpha3kind: VirtualServicename: vs-mockb- apiVersion: networking.istio.io/v1beta1kind: DestinationRulename: dr-mockb

开始灰度发布

修改 mocka 和 mockb 中的环境变量为 version=canary 开始发布。Kruise Rollout 将自动获取网关资源并进行修改,此时查看 VirtualService 和 DestinationRule 可以得到,VirtualService 定义了路由规则将带有 my-request-id=canary 的 header 的流量路由至 canary 版本。DestinationRule 添加了对于包含 label istio.service.tag=gray 新的 Subset。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"networking.istio.io/v1beta1","kind":"VirtualService","metadata":{"annotations":{},"name":"vs-mocka","namespace":"demo"},"spec":{"gateways":["simple-gateway"],"hosts":["*"],"http":[{"route":[{"destination":{"host":"mocka","subset":"version-base"}}]}]}}rollouts.kruise.io/origin-spec-configuration: '{"spec":{"gateways":["simple-gateway"],"hosts":["*"],"http":[{"route":[{"destination":{"host":"mocka","subset":"version-base"}}]}]},"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"networking.istio.io/v1beta1\",\"kind\":\"VirtualService\",\"metadata\":{\"annotations\":{},\"name\":\"vs-mocka\",\"namespace\":\"demo\"},\"spec\":{\"gateways\":[\"simple-gateway\"],\"hosts\":[\"*\"],\"http\":[{\"route\":[{\"destination\":{\"host\":\"mocka\",\"subset\":\"version-base\"}}]}]}}\n"}}'creationTimestamp: "2023-09-12T07:49:15Z"generation: 40name: vs-mockanamespace: demoresourceVersion: "98670"uid: c7da3a99-789c-4f1e-93a4-caaee41cbe06
spec:gateways:- simple-gatewayhosts:- '*'http:# -- lua脚本自动添加的规则- match:- headers:my-request-id:exact: canaryroute:- destination:host: mockasubset: canary# --- route:- destination:host: mockasubset: version-base
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"networking.istio.io/v1beta1","kind":"VirtualService","metadata":{"annotations":{},"name":"vs-mockb","namespace":"demo"},"spec":{"hosts":["mockb"],"http":[{"route":[{"destination":{"host":"mockb","subset":"version-base"}}]}]}}rollouts.kruise.io/origin-spec-configuration: '{"spec":{"hosts":["mockb"],"http":[{"route":[{"destination":{"host":"mockb","subset":"version-base"}}]}]},"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"networking.istio.io/v1beta1\",\"kind\":\"VirtualService\",\"metadata\":{\"annotations\":{},\"name\":\"vs-mockb\",\"namespace\":\"demo\"},\"spec\":{\"hosts\":[\"mockb\"],\"http\":[{\"route\":[{\"destination\":{\"host\":\"mockb\",\"subset\":\"version-base\"}}]}]}}\n"}}'creationTimestamp: "2023-09-12T07:49:16Z"generation: 40name: vs-mockbnamespace: demoresourceVersion: "98677"uid: 7c96ee2b-96ce-48e4-ba6d-cf94171ed854
spec:hosts:- mockbhttp:# -- lua脚本自动添加的规则- match:- headers:my-request-id:exact: canaryroute:- destination:host: mockbsubset: canary# -- - route:- destination:host: mockbsubset: version-base
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"networking.istio.io/v1beta1","kind":"DestinationRule","metadata":{"annotations":{},"name":"dr-mocka","namespace":"demo"},"spec":{"host":"mocka","subsets":[{"labels":{"version":"base"},"name":"version-base"}],"trafficPolicy":{"loadBalancer":{"simple":"ROUND_ROBIN"}}}}rollouts.kruise.io/origin-spec-configuration: '{"spec":{"host":"mocka","subsets":[{"labels":{"version":"base"},"name":"version-base"}],"trafficPolicy":{"loadBalancer":{"simple":"ROUND_ROBIN"}}},"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"networking.istio.io/v1beta1\",\"kind\":\"DestinationRule\",\"metadata\":{\"annotations\":{},\"name\":\"dr-mocka\",\"namespace\":\"demo\"},\"spec\":{\"host\":\"mocka\",\"subsets\":[{\"labels\":{\"version\":\"base\"},\"name\":\"version-base\"}],\"trafficPolicy\":{\"loadBalancer\":{\"simple\":\"ROUND_ROBIN\"}}}}\n"}}'creationTimestamp: "2023-09-12T07:49:15Z"generation: 12name: dr-mockanamespace: demoresourceVersion: "98672"uid: a6f49044-e889-473c-b188-edbdb8ee347f
spec:host: mockasubsets:- labels:version: basename: version-base# -- lua脚本自动添加的规则- labels:istio.service.tag: grayname: canary# --trafficPolicy:loadBalancer:simple: ROUND_ROBIN
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"networking.istio.io/v1beta1","kind":"DestinationRule","metadata":{"annotations":{},"name":"dr-mockb","namespace":"demo"},"spec":{"host":"mockb","subsets":[{"labels":{"version":"base"},"name":"version-base"}],"trafficPolicy":{"loadBalancer":{"simple":"ROUND_ROBIN"}}}}rollouts.kruise.io/origin-spec-configuration: '{"spec":{"host":"mockb","subsets":[{"labels":{"version":"base"},"name":"version-base"}],"trafficPolicy":{"loadBalancer":{"simple":"ROUND_ROBIN"}}},"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"networking.istio.io/v1beta1\",\"kind\":\"DestinationRule\",\"metadata\":{\"annotations\":{},\"name\":\"dr-mockb\",\"namespace\":\"demo\"},\"spec\":{\"host\":\"mockb\",\"subsets\":[{\"labels\":{\"version\":\"base\"},\"name\":\"version-base\"}],\"trafficPolicy\":{\"loadBalancer\":{\"simple\":\"ROUND_ROBIN\"}}}}\n"}}'creationTimestamp: "2023-09-12T07:49:15Z"generation: 12name: dr-mockbnamespace: demoresourceVersion: "98678"uid: 4bd0f6c5-efa1-4558-9e31-6f7615c21f9a
spec:host: mockbsubsets:- labels:version: basename: version-base# -- lua脚本自动添加的规则- labels:istio.service.tag: grayname: canary# --trafficPolicy:loadBalancer:simple: ROUND_ROBIN

此时运行 curl http://GATEWAY_IP:PORT 可以得到如下结果,所有流量均通过 base 版本服务。

-> mocka(version: base, ip: 10.244.1.36)-> mockb(version: base, ip: 10.244.1.37)

此时运行 curl -H http://GATEWAY_IP:PORT -Hmy-request-id:canary 可以得到如下结果,所有流量均通过 canary 版本服务。

-> mocka(version: canary, ip: 10.244.1.41)-> mockb(version: canary, ip: 10.244.1.42)

此时整个服务的流量可以表示为下图,包含 headermy-request-id=canary 的流量全部走灰度环境,其它流量全部走基线环境:

图片

(可选)利用 EnvoyFilter 进行流量染色

我们可以通过编写 EnvoyFilter 进一步简化流量染色的步骤,在之前的例子中,在请求的时候包含了可以透传的 header my-request-id,如果想要实现更加通用的 header 请求规则,例如包含 agent=pc 的流量全部走灰度环境,其它则走基线环境,则可以通过 EnvoyFilter 在入口网关进行染色。以下定义了一个 EnvoyFilter,该 EnvoyFilter 定义了一个 Lua 脚本,会对包含 agent=pc 的流量染色,为其添加 my-request-id=canary,而其它流量则添加 my-request-id=base。


apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: http-request-labelling-according-sourcenamespace: istio-system
spec:workloadSelector:labels:app: istio-ingressgatewayconfigPatches:- applyTo: HTTP_FILTERmatch:context: GATEWAYlistener:filterChain:filter:name: "envoy.filters.network.http_connection_manager"subFilter:name: "envoy.filters.http.router"patch:operation: INSERT_BEFOREvalue:name: envoy.luatyped_config:"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"inlineCode: |function envoy_on_request(request_handle)local header = "agent"headers = request_handle:headers()version = headers:get(header)if (version ~= nil) thenif (version == "pc") thenheaders:add("my-request-id","canary")elseheaders:add("my-request-id","base")endelseheaders:add("my-request-id","base")endend

保持其它配置不变,此时运行 curl http://GATEWAY_IP:PORT 可以得到如下结果,所有流量均通过 base 版本服务。

-> mocka(version: base, ip: 10.244.1.36)-> mockb(version: base, ip: 10.244.1.37)

此时运行 curl -H http://GATEWAY_IP:PORT -Hagent:pc 可以得到如下结果,EnvoyFilter 自动为该流量添加 headermy-request-id=canary,因此所有流量均通过新版本服务。

-> mocka(version: canary, ip: 10.244.1.41)-> mockb(version: canary, ip: 10.244.1.42)

完整的全链路灰度方案

Kruise Rollout 除了支持开源的 Istio 实现全链路灰度外,还支持与 MSE 实现完整的全链路灰度方案,我们可以通过如下操作文档 [ 2] 快速实现体系化的全链路灰度能力。

图片MSE 全链路灰度可以有效地控制流量在前端、网关、后端各个微服务等组件中闭环,不仅仅是 RPC/Http 的流量,对于异步调用比如 MQ 流量也支持符合全链路“泳道”调用的规则。通过 Kruise Rollout 跟 MSE 可以帮助我们更加便捷地实现微服务全链路灰度发布,提高微服务场景下发布的效率和稳定性。

加入 OpenKruise 社区

最后,非常欢迎你通过 Github/Slack/钉钉/微信 等方式加入我们来参与 OpenKruise 开源社区。

  • 加入社区 Slack channel (English)
  • 加入社区钉钉群:搜索群号 23330762 (Chinese)
  • 加入社区微信群(新):添加用户 openkruise 并让机器人拉你入群 (Chinese)

相关链接:

[1] Kruise Rollout

https://openkruise.io/rollouts/introduction

[2] 操作文档

https://help.aliyun.com/zh/mse/user-guide/implement-mse-based-end-to-end-canary-release-by-using-kruise-rollouts?spm=a2c4g.11186623.0.0.1d5a79dezV82UH

这篇关于Kruise Rollout 全链路灰度实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/642274

相关文章

Docker多阶段镜像构建与缓存利用性能优化实践指南

《Docker多阶段镜像构建与缓存利用性能优化实践指南》这篇文章将从原理层面深入解析Docker多阶段构建与缓存机制,结合实际项目示例,说明如何有效利用构建缓存,组织镜像层次,最大化提升构建速度并减少... 目录一、技术背景与应用场景二、核心原理深入分析三、关键 dockerfile 解读3.1 Docke

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

MySQL分库分表的实践示例

《MySQL分库分表的实践示例》MySQL分库分表适用于数据量大或并发压力高的场景,核心技术包括水平/垂直分片和分库,需应对分布式事务、跨库查询等挑战,通过中间件和解决方案实现,最佳实践为合理策略、备... 目录一、分库分表的触发条件1.1 数据量阈值1.2 并发压力二、分库分表的核心技术模块2.1 水平分

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

Java整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro