Kruise Rollout:基于 Lua 脚本的可扩展流量调度方案

2023-11-06

前言

Kruise Rollout[1]是 OpenKruise 社区开源的渐进式交付框架。Kruise Rollout 支持配合流量和实例灰度的金丝雀发布、蓝绿发布、A/B Testing 发布,以及发布过程能够基于 Prometheus Metrics 指标自动化分批与暂停,并提供旁路的无感对接、兼容已有的多种工作负载(Deployment、CloneSet、DaemonSet)。

目前 Kruise Rollout 新增了流量调度支持自定义资源的能力,从而更好的支持渐进式发布中的流量调度。本文将对 Kruise Rollout 所提出的方案进行介绍。

什么是渐进式发布?

渐进式发布(Progressive Delivery)是一种软件部署和发布策略,旨在逐步将新版本或功能引入生产环境,以降低风险并确保系统的稳定性。一些常见的渐进式发布形式如下:

  • 金丝雀发布:在发布时会创建一个金丝雀版本的 Deployment 进行验证,当验证通过后,再进行全量的工作负载升级,并删除金丝雀版本的 Deployment。

  • A/B 测试:按照一定的规则将用户流量切分成 A、B 两个不相交通路,并将导入不同版本的 Pod 实例进行处理,以此来更好地观察、对比或者灰度新版本能力。

金丝雀发布、A/B 测试和蓝绿发布都是逐步测试和评估新功能或变更的策略,它们可以根据具体的需求和场景选择适合的部署和测试策略,并结合流量灰度等技术实现逐步发布和测试新版本或功能。

为什么需要对网关资源提供支持?

Kruise Rollout 目前已经对 Gateway API 提供了支持,那么为什么还需要对不同供应商的网关资源提供支持呢?在解释这个问题之前,我们先来简单介绍一下 Gateway API。

当前社区中不同的供应商都有自己的网关资源,并提出了自己的标准,而 Kubernetes 为了提供一个统一的网关资源标准,构建标准化的,独立于供应商的 API,提出了 Gateway API。目前,尽管 Gateway API 还处于开发阶段,但已经有很多项目表示支持或计划支持 Gateway API。包括:

  • Istio 是最流行的服务网格项目之一,Istio 1.9 版本计划引入实验性的 Gateway API 支持。用户可以通过 Gateway 和 HTTPRoute 资源来配置 Istio 的 Envoy 代理。
  • Apache APISIX 是一个动态、实时、高性能的 API 网关,APISIX 目前支持Gateway API 规范的 v1beta1 版本,用于其 Apache APISIX Ingress Controller。
  • Kong 是一个为混合云和多云环境构建的开源 API 网关,Kong 在 Kong Kubernetes Ingress Controller (KIC) 以及 Kong Gateway Operator 中支持 Gateway API。

然而由于目前 Gateway API 并不能覆盖供应商所提出网关资源的所有功能,并且仍然有大量用户使用供应商提供的网关资源,虽然用户可以通过开发 Gateway API 对网关资源进行适配,但这样的工作量较大,所以仅仅为 Gateway API 提供支持是远远不够的,尽管随着 Gateway API 特性的不断丰富,在未来,使用 Gateway API 将成为一种更加推荐的方式。因此,虽然 Kruise Rollout 目前已经提供了对 Gateway API 的支持,如何对现有供应商多种多样的网关资源提供支持仍然是一个重要的问题。

如何兼容社区多样的网关方案?

当前社区中已经存在许多广泛使用的供应商提供的网关资源,比如:Istio、Kong、Apisix 等,然而正如前文所述,这些资源的配置并没有形成统一的标准,因此无法设计出一套通用的代码对资源进行处理,这种情况给开发人员带来了一些不便和挑战。

argo-rollouts 与 flagger 兼容方案

为了能够兼容更多的社区网关资源,一些方案被提出,例如 flagger、argo-rollouts 为每一种网关资源都提供了代码实现。这些方案的实现相对简单,但也存在一些问题:

  • 面对大量的社区网关资源时,需要消耗大量精力进行实现
  • 每次实现都需要重新进行发布,自定义能力较差
  • 在某些环境下用户可能使用定制的网关资源,在这种情况下难以适配
  • 每一种资源都有不同的配置规则,配置较为复杂
  • 每添加一个新的网关资源都需要为其实现新的接口,维护难度较大

argo-rollouts 不同资源配置

因此,需要一种支持用户定制,可以灵活插拔的实现方案,以适配社区以及用户定制的多种多样的网关资源,来满足社区不同的用户的需求,增强 Kruise Rollout 的兼容性和扩展性。

为此,我们提出了一种基于 Lua 脚本的网关资源可扩展流量调度方案

Kruise Rollout:基于 Lua 脚本的可扩展流量调度

Kruise Rollout 使用基于 Lua 脚本的网关资源定制方案,本方案通过调用 Lua 脚本根据发布策略和网关资源原始状态来获取并更新资源的期待工作状态(状态包含 spec、labels 以及 annotations),可以使用户能够轻松地适配和集成不同类型的网关资源,而无需修改现有的代码和配置。

本方案对于网关资源的处理可以表示为上图,整个过程可以描述为:

  1. 用户定义了 Rollout 流量灰度规则、需要修改的资源等信息,开始金丝雀发布
  2. 根据 Rollout 配置获取指定资源
  3. 根据资源调用对应的 Lua 脚本
  4. 将资源当前状态转为字符串存入资源 annotation 中,并与发布策略一同输入 Lua 脚本
  5. 利用 Lua 脚本根据当前状态和发布策略处理得到新状态并更新资源
  6. 发布结束后,从 annotation 中获取资源的原始状态对资源进行恢复

通过使用 Kruise Rollout,用户可以:

  • 定制处理网关资源的 Lua 脚本,可以自由的实现对资源的处理逻辑,为更多资源提供支持
  • 利用一套通用的 Rollout 配置模版对不同资源进行配置,降低配置的复杂性,方便用户配置

同时,Kruise Rollout 采用的方案仅需要添加 5 个新接口即可实现对多种多样网关资源的支持。相比之下,其他方案例如 argo-rollouts 则为不同供应商的网关资源提供了不同的接口,对于 Istio 和 Apisix 来说,argo-rollouts 分别提供了 14 个和 4 个新的接口,而且,该方案随着对更多网关资源的支持,接口数量还会持续增长。相比之下,Kruise Rollout 并不需要为新的网关资源提供新的接口,这使得 Kruise Rollout 成为一种更简洁、更易于维护的选择,而不会增加过多的接口负担。同时,编写 Lua 脚本相对于开发 Gateway API 对网关资源进行适配,可以大大减小开发人员的工作量。

以下展示了一个利用 Lua 脚本对 Istio DestinationRule 进行处理的的示例。

1.首先定义 rollout 配置文件:

apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
...
spec:
  ...
      trafficRoutings:
      - service: mocka
        createCanaryService: false # 使用原有service,不创建新的canary service
        networkRefs: # 需要控制的网关资源
        - apiVersion: networking.istio.io/v1alpha3
          kind: DestinationRule
          name: ds-demo
      patchPodTemplateMetadata: 
        labels:
          version: canary # 为新版本pod打上label

2.对 Istio DestinationRule 进行处理的 Lua 脚本为:

local spec = obj.data.spec -- 获取资源的spec,obj.data为资源的状态信息
local canary = {} -- 初始化一条指向新版本的canary路由规则
canary.labels = {} -- 初始化canary路由规则的labels
canary.name = "canary" -- 定义canary路由规则名称
-- 循环处理rollout配置的新版本pod label
for k, v in pairs(obj.patchPodMetadata.labels) do 
  canary.labels[k] = v -- 向canary规则中加入pod label
end
table.insert(spec.subsets, canary) -- 向资源的spec.subsets中插入canary规则
return obj.data -- 返回资源状态

3.处理完的 DestinationRule 为:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
spec:
  ...
  subsets:
    - labels:           # -+
        version: canary #  |- Lua脚本处理后新插入的规则
      name: canary      # -+
    - labels:
        version: base
      name: version-base

Kruise Rollout 进行 Istio 资源流量调度实践

接下来介绍一个利用我们所提出方案对 Istio 进行支持的具体案例。

1. 首先部署如下图所示的服务。该服务由以下几部分构成:

    • 由 Ingress Gateway 作为外部流量网关
    • 通过 VirtualService 和 DestinationRule 将流量调度至 nginx pod 中
    • 利用 ConfigMap 作为主页 nginx pod 的主页

nginx 服务的 deployment 如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        version: base
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: html-volume
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html-volume
        configMap:
          name: nginx-configmap-base # 挂载ConfigMap作为index

2. 创建 rollout 资源,配置发布规则,该 rollout 分为两批发布:

    • 第一批将 20% 的流量转发至新发布的 pod 中
    • 第二批将带有 header version=canary 的流量转发至新版本 pod 中
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
  name: rollouts-demo
  annotations:
    rollouts.kruise.io/rolling-style: canary
spec:
  disabled: false
  objectRef:
    workloadRef:
      apiVersion: apps/v1
      kind: Deployment
      name: nginx-deployment
  strategy:
    canary:
      steps:
      - weight: 20 # 第一批转发20%的流量进入新版本pod
      - replicas: 1 # 第二批将包含version=canary header的流量转发入新版本pod
        matches:
        - headers:
          - type: Exact
            name: version
            value: canary
      trafficRoutings:
      - service: nginx-service # 旧版本pod使用的service
        createCanaryService: false # 不创建新的canary service,新旧pod共用一个service
        networkRefs: # 需要修改的网关资源
        - apiVersion: networking.istio.io/v1alpha3
          kind: VirtualService
          name: nginx-vs
        - apiVersion: networking.istio.io/v1beta1
          kind: DestinationRule
          name: nginx-dr
      patchPodTemplateMetadata: # 为新版本pod打上version=canary的label
        labels:
          version: canary

3. 修改 nginx 服务 deployment 中挂载的 ConfigMap 开始金丝雀发布。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
      ...
      volumes:
      - name: html-volume
        configMap:
          name: nginx-configmap-canary # 挂载新的ConfigMap作为index

4. 开始发布第一批,Kruise Rollout 自动调用定义的 Lua 脚本对 VirtualService 和 DestinationRule 资源进行修改,进行流量调度,将 20% 的流量转发至新版本 pod 中,此时整个服务的流量表示为下图所示:

5. 执行命令 kubectl-kruise rollout approve rollout/rollouts-demo,开始发布第二批,Kruise Rollout 自动调用定义的 Lua 脚本对 VirtualService 和 DestinationRule 资源进行修改,进行流量调度,将包含 version=canary header 的流量转发至新版本 pod 中,此时整个服务的流量表示为下图所示:

6. 执行命令 kubectl-kruise rollout approve rollout/rollouts-demo,发布结束,VirtualService 和 DestinationRule 资源恢复至发布前状态,所有流量路由至新版本 pod。

如何利用 Lua 脚本快速配置网关资源的流量调度

在调用 Lua 脚本获取资源状态新状态时,Kruise Rollout 支持两种 Lua 脚本调用方式,分别为:

  • 自定义的 Lua 脚本:用户自定义的,以 ConfigMap 的形式定义并在 Rollout 中调用
  • 已发布的 Lua 脚本:社区通用的、已经稳定的 Lua 脚本,随 Kruise Rollout 打包发布

Kruise Rollout 默认首先查找本地是否存在已发布的 Lua 脚本,这些脚本通常需要设计测试案例进行单元测试验证其可用性,具有更好的稳定性。测试案例的格式如下所示,Kruise Rollout 利用 Lua 脚本根据 rollout 中定义的发布策略对资源原始状态进行处理,得到发布过程中每一步的资源新状态,并与测试案例中 expected 中定义的期待状态进行对比,以验证 Lua 脚本是否按照预期工作。

rollout:
  # rollout配置
original:
  # 资源的原始状态
expected:
  # 发布过程中资源的期待状态

在资源的 Lua 脚本未发布的情况下,用户还可以快速的通过在 ConfigMap 中配置 Lua 脚本的方式由 Kruise Rollout 调用从而对资源进行处理。

apiVersion: v1
kind: ConfigMap
metadata:
  name: kruise-rollout-configuration
  namespace: kruise-rollout
data:
  # 键以lua.traffic.routing.Kind.CRDGroup的形式命名
  "lua.traffic.routing.DestinationRule.networking.istio.io": |
    --- 定义Lua脚本
    local spec = obj.data.spec
    local canary = {}
    canary.labels = {}
    canary.name = "canary"
    for k, v in pairs(obj.patchPodMetadata.labels) do
        canary.labels[k] = v
    end
    table.insert(spec.subsets, canary)
    return obj.data

详细的 Lua 脚本配置说明参见 Kruise Rollout 官网[2]

未来规划

  • 更多网关协议支持:Kruise Rollout 目前是以 Lua 脚本插件化的方式支持多类型的网关协议,我们后续会重点加大这方面的投入,但面对百花齐放的协议类型,单靠社区 Maintainer 的单薄力量还远远不够,希望更多的社区小伙伴加入我们,一起来不断完善这方面的内容。
  • 全链路灰度支持:全链路灰度是具有更加细粒度和全面的灰度发布模式,它涵盖了应用程序的所有服务,而不止对单一的服务进行灰度,可以更好的对新服务进行模拟和测试。目前可以通过社区的网关资源如 Istio 进行配置来实现,但人工配置往往需要消耗较大的精力。我们将对这一部分进行探索,从而实现对全链路灰度的支持。

相关链接:

[1] Kruise Rollout

https://github.com/openkruise/rollouts

[2] Kruise Rollout 官网

https://openkruise.io/rollouts/introduction

[3] 社区双周会

https://shimo.im/docs/gXqmeQOYBehZ4vqo

[4] Slack channel

https://kubernetes.slack.com/?redir=%2Farchives%2Fopenkruise

作者:潘梦源

点击立即免费试用云产品 开启云上实践之旅!

原文链接

本文为阿里云原创内容,未经允许不得转载。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kruise Rollout:基于 Lua 脚本的可扩展流量调度方案 的相关文章

  • 使用 FastCGI 运行 Lua 脚本

    我目前正在尝试找出使用 FastCGI 与 lighttpd 或 Nginx 一起运行 Lua 脚本的方法 我唯一能挖到的是WSAPI http keplerproject github com wsapi 开普勒计划的一部分 但我想知道是
  • lua中的权限问题

    是否需要在 corona build settings 中设置一些特定权限才能将高分永久保存在文件中 每次运行代码时都会出现 权限被拒绝 的错误 如何纠正这个错误 这是我尝试过的代码 function read score local f1
  • Eclipse/Maven:运行 JUnit 测试时未编译它们

    我正在使用 Maven 和 Eclipse m2eclipse 插件 开发一个项目 我在 JUnit 测试中遇到问题 有时 当在 Eclipse 中运行它们时 它们不会被编译 而是使用旧的类文件 当我删除类文件时 我得到ClassNotFo
  • 在 Eclipse Testrunner 中使用名称的 ParameterizedTest

    当您使用 Eclipse TestRunner 运行 JUnit 4 ParameterizedTest 时 图形表示相当愚蠢 对于每个测试 您都有一个名为 0 1 ETC 是否可以进行测试 0 1 等显式名称 实施一个toString测试
  • Lua 将字符串转换为数字 - 取决于语言环境

    刚刚注意到字符串 and tonumber 在 Lua 中是依赖于语言环境的 知道如何在不使用的情况下将字符串转换为数字tonumber 谢谢 例如将字符串 58 5 转换为 58 5 另外 当我尝试将带点的数字传递给函数时 该函数会转换
  • JUnit Eclipse 显示 System.out.print() 的

    我正在使用 JUnit 3 和 Eclipse 3 4 当我运行 JUnit 测试用例时 一切正常并且测试完美完成 唯一的事情是我想查看我正在运行的类的输出 所有类都具有一些输出值的基本 System out print 因此 当我运行测试
  • 为什么尝试使用 Hamcrest 的 hasItems 的代码无法编译?

    为什么这个不能编译 哦 怎么办 import static org junit Assert assertThat import static org junit matchers JUnitMatchers hasItems ArrayL
  • 如何在 emacs lua-mode 中配置缩进?

    完整的 emacs 新手在这里 我在 Ubuntu 上使用 emacs 23 1 1emacs 入门套件 https github com technomancy emacs starter kit 我主要在 lua 模式下工作 安装了pa
  • Lua 访问表的键和值

    我想在关卡编辑器中读取 Lua 文件 这样我就可以以可视化格式显示其数据供用户编辑 如果我有一个像这样的 Lua 表 properties Speed 10 TurnSpeed 5 Speed显然是关键并且10价值 我知道如果我知道像这样的
  • 如何在lua中获取shell脚本的返回码?

    我正在lua中执行一个脚本 os execute sh manager scripts update system sh f 我想获得脚本的输出 如果退出状态为 7 则返回 7 I tried local output os execute
  • Maven 不会运行测试

    跑步时mvn testmaven 不会运行所有测试类 当我通过添加显式提供一个类时 Dtest PropertyTests将运行测试 这是我的 pom xml
  • 有条件地忽略 JUnit 4 中的测试

    好的 所以 Ignore注释适合标记不应运行的测试用例 但是 有时我想忽略基于运行时信息的测试 例如 如果我有一个并发测试 需要在具有一定数量核心的计算机上运行 如果这个测试在单处理器机器上运行 我认为仅仅通过测试是不正确的 因为它还没有运
  • Espresso 和 Proguard 的 Java.lang.NoClassDefFoundError

    我对 Espresso 不太有经验 但我终于成功地运行了它 我有一个应用程序需要通过 Proguard 缩小才能处于 56K 方法之下 该应用程序以 3 秒的动画开始 因此我需要等到该动画结束才能继续 这就是我尝试用该方法做的事情waitF
  • 为什么 @RunWith(SpringJUnit4ClassRunner.class) 不起作用?

    我正在尝试使用 Spring 框架使用 JUnit 测试 CRUD 方法 下面的代码完美运行 Transactional public class TestJdbcDaoImpl SuppressWarnings deprecation B
  • gsub 的转义字符串

    我读了一个文件 local logfile io open log txt r data logfile read a print data output n w r 1 2 n t x re S 是的 日志文件看起来很糟糕 因为它充满了各
  • 推送 Lua 表

    我已经创建了一个Lua表C 但我不知道如何将该表推入堆栈顶部 以便我可以将其传递给 Lua 函数 有谁知道如何做到这一点 这是我当前的代码 lua createtable state libraries size 0 int table i
  • 如何在 Lua - Lightroom 插件中使用 HMAC

    首先我要提的是我对 Lua 真的很陌生 如果你认为我的问题太愚蠢 请耐心等待 这是我的要求 我需要使用 HMAC sha256 进行 Lightroom 插件开发 因为我使用它是为了安全 我试图使用这个但没有运气https code goo
  • 如何使用 Lua 运行可执行文件?

    我有一个可执行文件想要使用 Lua 运行 我该怎么做 似乎无法在任何地方找到有关此的任何文档 您可以使用 Lua 原生的 执行 命令 Example os execute c temp program exe 资料来源 Lua 指南 os
  • 在 lua 中加载 C++ 模块时出现“尝试索引字符串值”错误

    我正在尝试使用 lua 用 C 编写的函数 下面给出的是cpp文件 extern C include lua h include lauxlib h include lualib h static int add 5 lua State L
  • 为什么 @Bean 返回模拟工作但 @MockBean 在 Spring Boot 测试中跨线程保留 Mockito 状态时不起作用?

    我有一个 JMS Spring Boot 项目 我正在尝试与我的 JMS Listener 进行集成测试 并且我使用 mockito 模拟来模拟具有外部服务调用的 bean 在测试过程中 我遇到了一个问题Mockito when thenR

随机推荐

  • MySQL高级:(十二)MySQL事务日志

    笔记来源 MySQL数据库教程天花板 mysql安装到mysql高级 强 硬 文章目录 12 1 事务日志概述 12 2 redo日志 12 2 1 为什么需要redo日志 12 2 2 redo日志的好处 特点 12 2 3 redo日志
  • 【CI/CD】基于 Jenkins+Docker+Git 的简单 CI 流程实践(上)

    基于 Jenkins Docker Git 的简单 CI 流程实践 上 在如今的互联网时代 随着软件开发复杂度的不断提高 软件开发和发布管理也越来越重要 目前已经形成一套标准的流程 最重要的组成部分就是 持续集成 及 持续交付 部署 在此
  • 华为OD机试 - 叠积木(Java)

    题目描述 有一堆长方体积木 它们的宽度和高度都相同 但长度不一 小橙想把这堆积木叠成一面墙 墙的每层可以放一个积木 也可以将两个积木拼接起来 要求每层的长度相同 若必须用完这些积木 叠成的墙最多为多少层 输入描述 输入为一行 为各个积木的长
  • 如何检测勒索软件攻击

    什么是勒索软件 勒索软件又称勒索病毒 是一种特殊的恶意软件 又被归类为 阻断访问式攻击 denial of access attack 与其他病毒最大的不同在于攻击方法以及中毒方式 攻击方法 攻击它采用技术手段限制受害者访问系统或系统内的数
  • c++ 实现职工管理系统

    一 案例描述 某公司中的职工分为三种 普通员工 经理和老板 每个职工都有自己的职工编号 姓名 年龄 电话号码和岗位 管理系统需要实现的功能如下 添加职工信息 显示职工信息 删除离职职工 修改职工信息 查找职工信息 职工编号排序 清空职工信息
  • git回滚到指定版本,并提交到远程分支

    1 git reflog 可以查看所有分支的所有操作记录包括已经被删除的commit记录和reset的操作 2 git log 可以显示所有提交过的版本信息 二者的区别 用git log 则看不出来被删除的commitid 用git ref
  • cookie session总结

    Cookie是由服务器创建 然后通过响应发送给客户端的一个键值对 客户端会保存Cookie 并会标注出Cookie的来源 哪个服务器的Cookie Cookie规范 Cookie通过请求头和响应头在服务器与客户端之间传输 Cookie大小上
  • 踩坑:git或gitee之上传超过100M文件

    直接说 如果你是免费用户 g远程仓库是gitee 那么对不起 你没法上传超过100M的大文件 不支持git fls 只有企业项目 才支持 如果你的远程仓库是git 那么借助git fls就可以了 至于怎么使用 网上一大堆博客 我就不浪费篇幅
  • hive 使用 jndi 数据源时已经在 Tomcat 中配置好 但是在 java 代码中获取数据源就会报错

    这个是异常信息 javax naming NoInitialContextException Need to specify class name in environment or system property or as an app
  • kafka系统的架构

    系统的架构 主题topic和分区partition topic Kafka中存储数据的逻辑分类 你可以理解为数据库中 表 的概念 比如 将app端日志 微信小程序端日志 业务库订单表数据分别放入不同的topic partition分区 提升
  • 数值分析 第一章:绪论

    第一章 绪论 1 2误差基础知识 1 2 1误差来源 1 2 2误差度量 1 2 3初值误差传播 1 3 舍入误差分析及数值稳定性 1 2误差基础知识 1 2 1误差来源 数学模型与实际问题的差异称为模型误差 数学模型中常常还包含有一些参数
  • 一起学SF框架系列附-Springframework源码学习总结

    学习过程 学习Springframework6 0 8 前后将近4个月终于结束了 学习主要内容如图 红框 本次学习主要针对核心模块 Beans Context Core SpEL 完全独立于框架的 没深入学习 AOP 以SF应用的初始化过程
  • nginx开启gzip压缩功能遇到的坑

    nginx开启gzip压缩功能一大堆 网上大多数配置如下 server listen 8080 proxy http version 1 1 gzip on gzip min length 1k gzip buffers 4 16k gzi
  • tf.reduce_sum tensorflow维度上的操作

    tensorflow中有很多在维度上的操作 本例以常用的tf reduce sum进行说明 官方给的api reduce sum input tensor axis None keep dims False name None reduct
  • 闲谈IPv6-IPv6地址的scope到底是什么?

    周日 大早上六点多和疯子去菜市场买了菜 顺便打了一壶糯米烧酒 回来把我的正则安哥哄睡了之后 继续思考IPv6的细节 一台主机启动后 每一块网卡都会自动生成一个fe80打头的 链路本地地址 这个地址在Linux上你删都删不掉 不信你试试 在W
  • Notepad++找回未保存的文件(缓存)

    Notepad 找回未保存的文件 缓存 就吃晚饭的功夫 电脑重启了 然鹅我在Notepad 里面写的东西还没保存 当场石化 还好挽救回来了 以后一定要记得Ctrl S 参考链接 Notepad 找回自动保存缓存内容的文件
  • 小米画报的壁纸怎么保存_小米怎么保存不生虫?掌握方法,安心存放随时吃,方法简单很实用...

    小米在古时被称为 粟 它营养丰富 味道清香 是传统的健康食品 在北方 小米粥配鸡蛋 红糖历来都是补充营养 滋补身体的佳品 在过去 小米是作为主食食用的 现在我们一般会用小米熬粥来调剂饮食 不会天天食用 那么 我们平时如何储存才能让小米干净卫
  • 对象的内存布局

    Hotspot虚拟机中 对象在内存中存储的布局可以分为三块区域 对象头 Header 实例数据 Instance Data 对齐填充 Padding 对象头 比如hash码 对象所属的年代 对象锁 锁状态标识 偏向锁线程ID 偏向时间 数组
  • wireshark display reference: https://www.wireshark.org/docs/dfref/

    2019独角兽企业重金招聘Python工程师标准 gt gt gt Display Filter Reference Wireshark s most powerful feature is its vast array of displa
  • Kruise Rollout:基于 Lua 脚本的可扩展流量调度方案

    前言 Kruise Rollout 1 是 OpenKruise 社区开源的渐进式交付框架 Kruise Rollout 支持配合流量和实例灰度的金丝雀发布 蓝绿发布 A B Testing 发布 以及发布过程能够基于 Prometheus