当前位置: 首页 > news >正文

响应式网站用什么工具做/深圳谷歌优化seo

响应式网站用什么工具做,深圳谷歌优化seo,北京市住房和城乡建设委员网站,有关做化工机械的网站从源码解析Kruise原地升级原理 本文从源码的角度分析 Kruise 原地升级相关功能的实现。 本篇Kruise版本为v1.5.2。 Kruise项目地址: https://github.com/openkruise/kruise 更多云原生、K8S相关文章请点击【专栏】查看! 原地升级的概念 当我们使用deployment等Wor…

从源码解析Kruise原地升级原理

本文从源码的角度分析 Kruise 原地升级相关功能的实现。

本篇Kruise版本为v1.5.2。

Kruise项目地址: https://github.com/openkruise/kruise

更多云原生、K8S相关文章请点击【专栏】查看!

原地升级的概念

当我们使用deploymentWorkload, 我们更改镜像版本时,k8s会删除原有pod进行重建,重建后pod的相关属性都有可能会变化, 比如uid、node、ipd等。

原地升级的目的就是保持pod的相关属性不变,只更改镜像版本。

下面的测试可以帮助理解kubelet的原地升级功能。

测试一: 修改deployment镜像版本

比如当前deployment使用nginx作为镜像, 且有一个pod实例:

~|⇒ kubectl get deployment test -o jsonpath="{.spec.template.spec.containers[0]}"
{"image":"nginx","imagePullPolicy":"Always","name":"nginx","resources":{},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File"}
~|⇒ kubectl get pod
NAME                    READY   STATUS    RESTARTS      AGE
test-5746d4c59f-nwc6q   1/1     Running   0             10m
web-0                   1/1     Running   1 (71m ago)   18d

修改镜像版本后, pod会被重建:

~|⇒ kubectl edit deployment test
deployment.apps/test edited
~|⇒ kubectl get pod
NAME                    READY   STATUS              RESTARTS      AGE
test-5746d4c59f-nwc6q   1/1     Running             0             11m
test-674d57777c-8qc7c   0/1     ContainerCreating   0             2s
web-0                   1/1     Running             1 (72m ago)   18d
~|⇒ kubectl get pod
NAME                    READY   STATUS    RESTARTS      AGE
test-674d57777c-8qc7c   1/1     Running   0             42s

可以看到,pod被重建后,pod的名称(以及其他属性)发生了变化。

测试二: 修改pod的镜像版本

比如当前deployment使用nginx:1.25作为镜像, 且有一个pod实例:

~|⇒ kubectl get deployment test -o jsonpath="{.spec.template.spec.containers[0]}"
{"image":"nginx:1.25","imagePullPolicy":"Always","name":"nginx","resources":{},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File"}%
~|⇒ kubectl get pod
NAME                    READY   STATUS    RESTARTS      AGE
test-76f8989b6c-8s9s2   1/1     Running   0             3m17s

直接修改pod的镜像版本后, pod不会被重建(但是会增加一次restart):

~|⇒ kubectl edit pod test-76f8989b6c-8s9s2
pod/test-76f8989b6c-8s9s2 edited
~|⇒ kubectl get pod
NAME                    READY   STATUS    RESTARTS      AGE
test-76f8989b6c-8s9s2   1/1     Running   1 (4s ago)    5m38s

pod的镜像版本变动后,并不会逆向同步到deployment。

~|⇒ kubectl get deployment test -o jsonpath="{.spec.template.spec.containers[0]}"
{"image":"nginx:1.25","imagePullPolicy":"Always","name":"nginx","resources":{},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File"}%

但是pod的镜像版本变化了, uid、名称的属性都没有变化。

-- old
apiVersion: v1
kind: Pod
metadata:creationTimestamp: "2024-02-20T03:53:34Z"generateName: test-76f8989b6c-labels:app: testpod-template-hash: 76f8989b6cname: test-76f8989b6c-8s9s2namespace: defaultownerReferences:- apiVersion: apps/v1blockOwnerDeletion: truecontroller: truekind: ReplicaSetname: test-76f8989b6cuid: 68434490-0948-4c88-bf59-e1f63887e02fresourceVersion: "2160531"uid: 9f5fb37b-01ae-45a6-b50f-fc2385b6e317
spec:containers:- image: nginx:1.25imagePullPolicy: Alwaysname: nginx
--- new
apiVersion: v1
kind: Pod
metadata:creationTimestamp: "2024-02-20T03:53:34Z"generateName: test-76f8989b6c-labels:app: testpod-template-hash: 76f8989b6cname: test-76f8989b6c-8s9s2namespace: defaultownerReferences:- apiVersion: apps/v1blockOwnerDeletion: truecontroller: truekind: ReplicaSetname: test-76f8989b6cuid: 68434490-0948-4c88-bf59-e1f63887e02fresourceVersion: "2161008"uid: 9f5fb37b-01ae-45a6-b50f-fc2385b6e317
spec:containers:- image: nginx:1.25.4imagePullPolicy: Alwaysname: nginx

测试三: 停止pod内容器

依旧是“测试二”中的pod:

~|⇒ kubectl get pod
NAME                    READY   STATUS    RESTARTS        AGE
test-76f8989b6c-8s9s2   1/1     Running   1 (112m ago)    118m

找到其对应的容器, 对其进行停止操作:

# 正在运行无法直接删除, 可以强制删除或者先停止
$ docker rm 518f1b0accada9c9587cd5d7655cbda0bc7a33bebaf11f0ec99877b6a9c92222
Error response from daemon: You cannot remove a running container 518f1b0accada9c9587cd5d7655cbda0bc7a33bebaf11f0ec99877b6a9c92222. Stop the container before attempting removal or force remove
$ docker stop 518f1b0accada9c9587cd5d7655cbda0bc7a33bebaf11f0ec99877b6a9c92222
518f1b0accada9c9587cd5d7655cbda0bc7a33bebaf11f0ec99877b6a9c92222
# 已经停止
$ docker ps | grep 518f1b0accada9c9587cd5d7655cbda0bc7a33bebaf11f0ec99877b6a9c92222
# 拉起了新的容器
$ docker ps | grep nginx
ebb42aafa572   nginx                             "/docker-entrypoint.…"   3 minutes ago   Up 3 minutes             k8s_nginx_test-76f8989b6c-8s9s2_default_9f5fb37b-01ae-45a6-b50f-fc2385b6e317_2

容器停止后, 会被kubelet中的Runonce方法拉起, pod的属性不会变化, 状态中的containerID会更新。

结论

pod本身其实具备原地升级的能力,所以简单来说(一个pod多个容器仅其中一个升级的状况会更复杂), 对deployment实现原地升级只需要几步就可以做到:

  1. 修改workload镜像版本,但是需要拦截pod重建动作
  2. 提前拉取新版镜像, 加快过程
  3. 更新pod镜像版本,重新启动容器

kruise原地升级原理

Container Restart

在这里插入图片描述

ContainerRecreateRequest是一个CRD,可以帮助用户重启/重建存量 Pod 中一个或多个容器。下文称之为CRR

和 Kruise 提供的原地升级类似,当一个容器重建的时候,Pod 中的其他容器还保持正常运行。重建完成后,Pod 中除了该容器的 restartCount 增加以外不会有什么其他变化。 注意,之前临时写到旧容器 rootfs 中的文件会丢失,但是 volume mount 挂载卷中的数据都还存在。

CRR的具体管理者是kruise-daemon进程。

kruise-daemon 除此之外还会管理NnodeImageCRD

CRR资源管理的实现在pkg/daemon/containerrecreate

资源的处理最终会由Controller.sync方法执行

func (c *Controller) sync(key string) (retErr error) {namespace, podName, err := cache.SplitMetaNamespaceKey(key)objectList, err := c.crrInformer.GetIndexer().ByIndex(CRRPodNameIndex, podName)crrList := make([]*appsv1alpha1.ContainerRecreateRequest, 0, len(objectList))// 弹出一个CRR进行处理crr, err := c.pickRecreateRequest(crrList)if err != nil || crr == nil {return err}// ...// 省略一些状态判断return c.manage(crr)
}func (c *Controller) manage(crr *appsv1alpha1.ContainerRecreateRequest) error {runtimeManager, err := c.newRuntimeManager(c.runtimeFactory, crr)pod := convertCRRToPod(crr)podStatus, err := runtimeManager.GetPodStatus(pod.UID, pod.Name, pod.Namespace)newCRRContainerRecreateStates := getCurrentCRRContainersRecreateStates(crr, podStatus)if !reflect.DeepEqual(crr.Status.ContainerRecreateStates, newCRRContainerRecreateStates) {return c.patchCRRContainerRecreateStates(crr, newCRRContainerRecreateStates)}var completedCount intfor i := range newCRRContainerRecreateStates {state := &newCRRContainerRecreateStates[i]// ...// 省略一些状态判断// 从pod状态中获取容器id,调用cri停止对应容器err := runtimeManager.KillContainer(pod, kubeContainerStatus.ID, state.Name, msg, nil)if err != nil {if crr.Spec.Strategy.FailurePolicy == appsv1alpha1.ContainerRecreateRequestFailurePolicyIgnore {continue}return c.patchCRRContainerRecreateStates(crr, newCRRContainerRecreateStates)}state.IsKilled = truestate.Phase = appsv1alpha1.ContainerRecreateRequestRecreatingbreak}// 更新CCR状态if !reflect.DeepEqual(crr.Status.ContainerRecreateStates, newCRRContainerRecreateStates) {return c.patchCRRContainerRecreateStates(crr, newCRRContainerRecreateStates)}if completedCount == len(newCRRContainerRecreateStates) {return c.completeCRRStatus(crr, "")}if crr.Spec.Strategy != nil && crr.Spec.Strategy.MinStartedSeconds > 0 {c.queue.AddAfter(objectKey(crr), time.Duration(crr.Spec.Strategy.MinStartedSeconds)*time.Second)}return nil
}

可以看到整体逻辑比较简单, 主要是越过上层workload资源,直接停止对应的容器,利用k8s kubelet本身的container状态监控机制再次拉起, 完成原地重启。

总的来说所,他与我们手动去删除容器的操作大体相同, 不过帮我们省略其中查找容器、登陆node的重复操作, 并提供了一些状态控制机制。

apiVersion: apps.kruise.io/v1alpha1
kind: ContainerRecreateRequest
metadata:namespace: pod-namespacename: xxx
spec:podName: pod-namecontainers:       # 要重建的容器名字列表,至少要有 1 个- name: app- name: sidecarstrategy:failurePolicy: Fail                 # 'Fail' 或 'Ignore',表示一旦有某个容器停止或重建失败, CRR 立即结束orderedRecreate: false              # 'true' 表示要等前一个容器重建完成了,再开始重建下一个terminationGracePeriodSeconds: 30   # 等待容器优雅退出的时间,不填默认用 Pod 中定义的unreadyGracePeriodSeconds: 3        # 在重建之前先把 Pod 设为 not ready,并等待这段时间后再开始执行重建minStartedSeconds: 10               # 重建后新容器至少保持运行这段时间,才认为该容器重建成功activeDeadlineSeconds: 300        # 如果 CRR 执行超过这个时间,则直接标记为结束(未结束的容器标记为失败)ttlSecondsAfterFinished: 1800     # CRR 结束后,过了这段时间自动被删除掉

cloneSet原地升级

在这里插入图片描述

原地升级与上面的CRR的原理基本相同, 不过多了一步修改信息的操作(如image、annotation).

kruise中支持原地升级的workload类型, 基本上用的是同一套代码逻辑, 我们以cloneSet为例进行分析。

代码路径: pkg/controller/cloneset

本文中不会对代码实现全部展开分析, 会更加偏向于整体流程的理解。

controller

kruise controller中通过Reconciler来实现workload状态同步,interface定义如下:

type Reconciler interface {Reconcile(context.Context, Request) (Result, error)
}

workload会实现这个interface,并在其中实现状态同步的逻辑。这里面就包含原地升级。

我们忽略cloneSet控制器中其他的逻辑, 只关注原地升级, 最终定位到sync/cloneset_update.go/realControl.updatePod这个方法。

func (c *realControl) updatePod(cs *appsv1alpha1.CloneSet, coreControl clonesetcore.Control,updateRevision *apps.ControllerRevision, revisions []*apps.ControllerRevision,pod *v1.Pod, pvcs []*v1.PersistentVolumeClaim,
) (time.Duration, error) {if cs.Spec.UpdateStrategy.Type == appsv1alpha1.InPlaceIfPossibleCloneSetUpdateStrategyType ||// ...// 省略一些状态判断// 判断是否可以原地升级if c.inplaceControl.CanUpdateInPlace(oldRevision, updateRevision, coreControl.GetUpdateOptions()) {// ...// 省略一些状态判断// 原地升级opts := coreControl.GetUpdateOptions()opts.AdditionalFuncs = append(opts.AdditionalFuncs, lifecycle.SetPodLifecycle(appspub.LifecycleStateUpdating))// 执行升级动作res := c.inplaceControl.Update(pod, oldRevision, updateRevision, opts)if res.InPlaceUpdate {if res.UpdateErr == nil {clonesetutils.ResourceVersionExpectations.Expect(&metav1.ObjectMeta{UID: pod.UID, ResourceVersion: res.NewResourceVersion})return res.DelayDuration, nil}return res.DelayDuration, res.UpdateErr}}if cs.Spec.UpdateStrategy.Type == appsv1alpha1.InPlaceOnlyCloneSetUpdateStrategyType {return 0, fmt.Errorf("find Pod %s update strategy is InPlaceOnly but can not update in-place", pod.Name)}}// 省略状态更新// ...return 0, nil
}

可以看到, 关键的处理逻辑在c.inplaceControl这个对象中。这个对象是inplaceupdate.Interface类型。

inplaceupdate

查看文件pkg/util/inplaceupdate/inplace_update.go

type Interface interface {// 判断是否可以原地升级CanUpdateInPlace(oldRevision, newRevision *apps.ControllerRevision, opts *UpdateOptions) bool// 执行原地升级Update(pod *v1.Pod, oldRevision, newRevision *apps.ControllerRevision, opts *UpdateOptions) UpdateResult// 刷新一些状态信息Refresh(pod *v1.Pod, opts *UpdateOptions) RefreshResult
}

UpdateOptions包含了一些重要的函数, 比如需要计算更新的字段、更新字段等。

type UpdateOptions struct {GracePeriodSeconds int32AdditionalFuncs    []func(*v1.Pod)// 计算更新的字段, 也用于判断是否可以原地升级CalculateSpec                  func(oldRevision, newRevision *apps.ControllerRevision, opts *UpdateOptions) *UpdateSpec// 更新字段PatchSpecToPod                 func(pod *v1.Pod, spec *UpdateSpec, state *appspub.InPlaceUpdateState) (*v1.Pod, error)// 检查更新状态CheckPodUpdateCompleted        func(pod *v1.Pod) error// 检查容器更新状态CheckContainersUpdateCompleted func(pod *v1.Pod, state *appspub.InPlaceUpdateState) errorGetRevision                    func(rev *apps.ControllerRevision) string
}
// 默认CalculateSpec函数, 这里体现出只支持label、annotation、镜像的更新的原地升级
func defaultCalculateInPlaceUpdateSpec(oldRevision, newRevision *apps.ControllerRevision, opts *UpdateOptions) *UpdateSpec {// ...for _, op := range patches {// 计算更新镜像op.Path = strings.Replace(op.Path, "/spec/template", "", 1)if !strings.HasPrefix(op.Path, "/spec/") {if strings.HasPrefix(op.Path, "/metadata/") {metadataPatches = append(metadataPatches, op)continue}return nil}if op.Operation != "replace" || !containerImagePatchRexp.MatchString(op.Path) {return nil}// for example: /spec/containers/0/imagewords := strings.Split(op.Path, "/")idx, _ := strconv.Atoi(words[3])if len(oldTemp.Spec.Containers) <= idx {return nil}updateSpec.ContainerImages[oldTemp.Spec.Containers[idx].Name] = op.Value.(string)}if len(metadataPatches) > 0 {// 计算lbels、annotations的更新if utilfeature.DefaultFeatureGate.Enabled(features.InPlaceUpdateEnvFromMetadata) {for _, op := range metadataPatches {//...for i := range newTemp.Spec.Containers {c := &newTemp.Spec.Containers[i]objMeta := updateSpec.ContainerRefMetadata[c.Name]switch words[2] {case "labels":// ...case "annotations":// ...}updateSpec.ContainerRefMetadata[c.Name] = objMetaupdateSpec.UpdateEnvFromMetadata = true}}}// ...updateSpec.MetaDataPatch = patchBytes}return updateSpec
}
// 默认CheckContainersUpdateCompleted函数, 实际CheckPodUpdateCompleted也是调用的这个
func defaultCheckContainersInPlaceUpdateCompleted(pod *v1.Pod, inPlaceUpdateState *appspub.InPlaceUpdateState) error {// ...containerImages := make(map[string]string, len(pod.Spec.Containers))for i := range pod.Spec.Containers {c := &pod.Spec.Containers[i]containerImages[c.Name] = c.Imageif len(strings.Split(c.Image, ":")) <= 1 {containerImages[c.Name] = fmt.Sprintf("%s:latest", c.Image)}}for _, cs := range pod.Status.ContainerStatuses {if oldStatus, ok := inPlaceUpdateState.LastContainerStatuses[cs.Name]; ok {// 通过判断镜像id是否变化来判断是否更新if oldStatus.ImageID == cs.ImageID {if containerImages[cs.Name] != cs.Image {return fmt.Errorf("container %s imageID not changed", cs.Name)}}delete(inPlaceUpdateState.LastContainerStatuses, cs.Name)}}// ...return nil
}

realControl实现了inplaceupdate.Interface

func (c *realControl) CanUpdateInPlace(oldRevision, newRevision *apps.ControllerRevision, opts *UpdateOptions) bool {opts = SetOptionsDefaults(opts)// 判断是否可以原地升级, 通过计算更新的字段来判断return opts.CalculateSpec(oldRevision, newRevision, opts) != nil
}
func (c *realControl) Update(pod *v1.Pod, oldRevision, newRevision *apps.ControllerRevision, opts *UpdateOptions) UpdateResult {opts = SetOptionsDefaults(opts)// 1. 计算更新字段spec := opts.CalculateSpec(oldRevision, newRevision, opts)// 2. 更新状态if containsReadinessGate(pod) {newCondition := v1.PodCondition{Type:               appspub.InPlaceUpdateReady,LastTransitionTime: metav1.NewTime(Clock.Now()),Status:             v1.ConditionFalse,Reason:             "StartInPlaceUpdate",}if err := c.updateCondition(pod, newCondition); err != nil {return UpdateResult{InPlaceUpdate: true, UpdateErr: err}}}// 3.更新镜像信息newResourceVersion, err := c.updatePodInPlace(pod, spec, opts)// ...return UpdateResult{InPlaceUpdate: true, DelayDuration: delayDuration, NewResourceVersion: newResourceVersion}
}
// 3.更新镜像信息
// newResourceVersion, err := c.updatePodInPlace(pod, spec, opts)
func (c *realControl) updatePodInPlace(pod *v1.Pod, spec *UpdateSpec, opts *UpdateOptions) (string, error) {var newResourceVersion stringretryErr := retry.RetryOnConflict(retry.DefaultBackoff, func() error {// 1. 准备:获取podclone, err := c.podAdapter.GetPod(pod.Namespace, pod.Name)// 2. 准备:设置Annotations, 记录相关信息inPlaceUpdateState := appspub.InPlaceUpdateState{Revision:              spec.Revision,UpdateTimestamp:       metav1.NewTime(Clock.Now()),UpdateEnvFromMetadata: spec.UpdateEnvFromMetadata,}inPlaceUpdateStateJSON, _ := json.Marshal(inPlaceUpdateState)clone.Annotations[appspub.InPlaceUpdateStateKey] = string(inPlaceUpdateStateJSON)delete(clone.Annotations, appspub.InPlaceUpdateStateKeyOld)// 3. 更新podif spec.GraceSeconds <= 0 {// GraceSeconds <= 0时会立即更新pod状态为notreadyif clone, err = opts.PatchSpecToPod(clone, spec, &inPlaceUpdateState); err != nil {return err}appspub.RemoveInPlaceUpdateGrace(clone)} else {inPlaceUpdateSpecJSON, _ := json.Marshal(spec)clone.Annotations[appspub.InPlaceUpdateGraceKey] = string(inPlaceUpdateSpecJSON)}// 执行更新,这时会调用k8s API将数据更新到server, 后续的容器重建工作由kubelet完成newPod, updateErr := c.podAdapter.UpdatePod(clone)if updateErr == nil {newResourceVersion = newPod.ResourceVersion}return updateErr})return newResourceVersion, retryErr
}

总结

原地升级的原理比较简单, 主要还是利用了pod自身的特性和kubelet的拉起功能。

kruise中仅对自己的CRD Workload支持原地升级, 其实也可以扩展到对原生资源的支持(如一开始的测试),但会存在一些问题和限制(如测试二中deployment的镜像版本不会发生改变)。

相关文章:

从源码解析Kruise(K8S)原地升级原理

从源码解析Kruise原地升级原理 本文从源码的角度分析 Kruise 原地升级相关功能的实现。 本篇Kruise版本为v1.5.2。 Kruise项目地址: https://github.com/openkruise/kruise 更多云原生、K8S相关文章请点击【专栏】查看&#xff01; 原地升级的概念 当我们使用deployment等Wor…...

2024年【广东省安全员C证第四批(专职安全生产管理人员)】复审考试及广东省安全员C证第四批(专职安全生产管理人员)模拟考试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 广东省安全员C证第四批&#xff08;专职安全生产管理人员&#xff09;复审考试是安全生产模拟考试一点通总题库中生成的一套广东省安全员C证第四批&#xff08;专职安全生产管理人员&#xff09;模拟考试题&#xff0…...

udp服务器【Linux网络编程】

目录 一、UDP服务器 1、创建套接字 2、绑定套接字 3、运行 1&#xff09;读取数据 2&#xff09;发送数据 二、UDP客户端 创建套接字&#xff1a; 客户端不用手动bind 收发数据 处理消息和网络通信解耦 三、应用场景 1、服务端执行命令 2、Windows上的客户端 3…...

【k8s资源调度-Deployment】

1、标签和选择器 1.1 标签Label 配置文件&#xff1a;在各类资源的sepc.metadata.label 中进行配置通过kubectl 命令行创建修改标签&#xff0c;语法如下 创建临时label&#xff1a;kubectl label po <资源名称> apphello -n <命令空间&#xff08;可不加&#xff0…...

【Oracle】玩转Oracle数据库(五):PL/SQL编程

前言 嗨&#xff0c;各位数据库达人&#xff01;准备好迎接数据库编程的新挑战了吗&#xff1f;今天我们要探索的是Oracle数据库中的神秘魔法——PL/SQL编程&#xff01;&#x1f52e;&#x1f4bb; 在这篇博文【Oracle】玩转Oracle数据库&#xff08;五&#xff09;&#xff1…...

JavaScript流程控制

文章目录 1. 顺序结构2. 分支结构2.1 if 语句2.2 if else 双分支语句2.3 if else if 多分支语句三元表达式 2.4 switch 语句switch 语句和 if else if语句区别 3. 循环结构3.1 for 循环断点调试 3.2 双重 for 循环3.3 while 循环3.4 do while 循环3.5 contiue break 关键字 4. …...

五个使用Delphi语言进行开发的案例

案例一&#xff1a;学生信息管理系统 某学校需要开发一个学生信息管理系统&#xff0c;用于记录学生的基本信息、成绩和考勤情况等。开发者使用Delphi语言进行开发&#xff0c;设计了一个包含多个窗体的应用程序。主窗体用于展示学生的列表和基本信息&#xff0c;其他窗体则用…...

蓝桥杯第1374题——锻造兵器

题目描述 小明一共有n块锻造石&#xff0c;第块锻造石的属性值为ai. 现在小明决定从这n块锻造石中任取两块来锻造兵器 通过周密计算&#xff0c;小明得出&#xff0c;只有当两块锻造石的属性值的差值等于C&#xff0c;兵器才能锻造成功 请你帮小明算算&#xff0c;他有多少种选…...

坚鹏:政府数字化转型数字机关、数据共享及电子政务类案例研究

政府数字化转型数字机关、数据共享及电子政务类案例研究 课程背景&#xff1a; 很多地方政府存在以下问题&#xff1a; 不清楚政府数字化转型的数字机关类成功案例 不清楚政府数字化转型的数据共享类成功案例 不清楚政府数字化转型的电子政务类成功案例 课程特色&…...

【架构】面向人工智能 (AI) 的硬件的可靠性(2021)

由于激进的技术扩展&#xff0c;现代系统越来越容易受到可靠性威胁的影响&#xff0c;例如软错误、老化和工艺变化。这些威胁在硬件级别表现为位翻转&#xff0c;并且根据位置&#xff0c;可能会损坏输出&#xff0c;从而导致不准确或潜在的灾难性结果。 传统的缓解技术基于冗…...

Unity3D MVC开发模式与开发流程详解

前言 MVC&#xff08;Model-View-Controller&#xff09;是一种常用的软件架构模式。将MVC应用于Unity3D开发可以提高项目的可维护性和可扩展性&#xff0c;使代码更加清晰和易于理解。本文将详细介绍Unity3D中MVC开发模式的应用以及开发流程&#xff0c;并给出技术详解和代码…...

简单介绍一下Android里面的IntentFirewall

源码链接 https://android.googlesource.com/platform/frameworks/base//633dc9b/services/java/com/android/server/firewall/IntentFirewall.java 源码如下&#xff1a; package com.android.server.firewall; import android.content.Intent; import android.content.Inte…...

Stable Diffusion 3 发布及其重大改进

1. 引言 就在 OpenAI 发布可以生成令人瞠目的视频的 Sora 和谷歌披露支持多达 150 万个Token上下文的 Gemini 1.5 的几天后&#xff0c;Stability AI 最近展示了 Stable Diffusion 3 的预览版。 闲话少说&#xff0c;我们快来看看吧&#xff01; 2. 什么是Stable Diffusion…...

【后端】springboot项目

文章目录 1. 2.3.7.RELEASE版本搭建1.1 pom文件1.1.1 方式一1.1.2 方式二 1.2 启动类1.3 测试类 2. 引入Value乱码问题解决 【后端目录贴】 1. 2.3.7.RELEASE版本搭建 1.1 pom文件 1.1.1 方式一 <parent><groupId>org.springframework.boot</groupId><…...

React Native调用摄像头画面及拍照和保存图片到相册全流程

今天主要做了一个demo,功能很简单,就是调用手机摄像头画面,并且可以通过按钮控制拍照以及将图片保存到手机相册的功能,接下来我将从创建项目开始一步一步完成这个demo,各位只需要复制粘贴即可 创建React Native项目 npx react-native init yx_rnDemo --version 0.70.6 // 这里…...

Kubernetes基本部署概念

文章目录 命名空间&#xff08;Namespaecs&#xff09;查看命名空间查看带有命名空间对象下资源 文件存储持久卷&#xff08;pv&#xff0c;Persistent Volumes&#xff09;卷容量卷模式&#xff08;volumeMode&#xff09;访问模式&#xff08;accessModes&#xff09;回收策略…...

QT c++ 海康红外热像仪

//本文描述2通道海康通道红外热像仪预览和抓图 #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); userID-1; …...

OpenAI 的 GPTs 提示词泄露攻击与防护实战:防御卷(一)

前面的OpenAI DevDay活动上&#xff0c;GPTs技术的亮相引起了广泛关注。随着GPTs的创建权限开放给Plus用户&#xff0c;社区里迅速涌现了各种有趣的GPT应用&#xff0c;这些都是利用了Prompt提示词的灵活性。这不仅展示了技术的创新潜力&#xff0c;也让人们开始思考如何获取他…...

中科大计网学习记录笔记(十五):可靠数据传输的原理

前前言&#xff1a;看过本节的朋友应该都知道本节长度长的吓人&#xff0c;但其实内容含量和之前的差不多&#xff0c;老师在本节课举的例子和解释比较多&#xff0c;所以大家坚持看完是一定可以理解透彻的。本节课大部分是在提出问题和解决问题&#xff0c;先明确出现的问题是…...

五种多目标优化算法(MOGWO、MOJS、NSWOA、MOPSO、MOAHA)性能对比(提供MATLAB代码)

一、5种多目标优化算法简介 1.1MOGWO 1.2MOJS 1.3NSWOA 1.4MOPSO 1.5MOAHA 二、5种多目标优化算法性能对比 为了测试5种算法的性能将其求解9个多目标测试函数&#xff08;zdt1、zdt2 、zdt3、 zdt4、 zdt6 、Schaffer、 Kursawe 、Viennet2、 Viennet3&#xff09;&#xff0…...

力扣:93. 复原 IP 地址

回溯&#xff1a; 1.先定义一个接收的集合&#xff0c;之后再定义一个记录小数点的变量。之后编写回溯函数&#xff0c;终止条件为小数点的个数为3时&#xff0c;同时要判断最后一段的组合的值是否属于ip地址的范围。之后再用for循环来遍历ip地址的组合&#xff0c;先判断组合…...

利用序列化和反序列化实现深拷贝

利用序列化和反序列化可以实现对象的深拷贝,具体步骤如下: 将要深拷贝的对象序列化为字节流。从字节流中反序列化出一个新的对象,即完成了深拷贝。下面是一个示例代码: import java.io.*;class MyClass implements Serializable {private static final long serialVersion…...

【AHK】68键键盘键位布局优化/esc改退格键/回车键

本人习惯使用~作为退格键&#xff0c;但是由于keychron 68键的布局只能用esc平替~来修改&#xff0c;然后也将回车键通过alt和大小写锁定键一起触发 esc::bs ;次步骤与下面步骤相对应&#xff0c;如果是用send bs方式则下面的不生效^esc:: ;通过建立 保留esc功能 send {esc} re…...

计算机体系架构初步入门

&#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xff08;HPC&#xff09;开发基础教程 &#x1f380;CSDN主页 发狂的小花 &#x1f304;人生秘诀&#xff1a;学习的本质就是极致重复! 目录 1 计算机五大…...

常见的序列化数据结构方法及其优缺点汇总

文章目录 1. JSON (JavaScript Object Notation)2. XML (eXtensible Markup Language)3. YAML (YAML Aint Markup Language)4. Protobuf (Protocol Buffers)5. MessagePack6. BSON (Binary JSON)7. Avro8. Thrift9. CBOR (Concise Binary Object Representation) 将常见的序列化…...

华清远见嵌入式学习——驱动开发——作业1

作业要求&#xff1a; 通过字符设备驱动分步注册过程实现LED驱动的编写&#xff0c;编写应用程序测试&#xff0c;发布到CSDN 作业答案&#xff1a; 运行效果&#xff1a; 驱动代码&#xff1a; #include <linux/init.h> #include <linux/module.h> #include &l…...

小苯的IDE括号问题(CD) -----牛客小白月赛87(双链表)

C题&#xff1a;C-小苯的IDE括号问题&#xff08;easy&#xff09;_牛客小白月赛87 (nowcoder.com) D题&#xff1a; D-小苯的IDE括号问题&#xff08;hard&#xff09;_牛客小白月赛87 (nowcoder.com) C题代码&#xff1a; #include<bits/stdc.h>using namespace std…...

Redis如何修改key名称

点击上方蓝字关注我 近期出现过多次修改Redis中key名字的场景&#xff0c;本次简介一下如何修改Redis中key名称的方法。 1. 命令行方式修改在Redis中&#xff0c;可以使用rename命令来修改Key的名称。这个命令的基本语法如下&#xff1a; RENAME old_key new_key 在这里&#…...

浅谈redis之SDS

SDS 什么是SDSSDS结构len的作用free的作用buf的作用简单示例 SDS机制重新分配内存分配内存机制小于1MB情况大于1MB情况为什么这样分配 惰性释放内存 什么是SDS SDS&#xff1a;全名 simple dynamic string&#xff0c;意为简单动态字符串&#xff0c;作为redis里的一种数据结构…...

数据结构知识点总结-线性表(1)-线性表的定义、基本操作、顺序表表示

线性表 定义 线性表是具有相同数据类型的N&#xff08;N>0&#xff09;个元素的有限序列&#xff0c;其中N为表长&#xff0c;当N0时线性表是一张空表。 线性表的逻辑特征&#xff1a;每个非空的线性表都有一个表头元素和表尾元素&#xff0c;中间的每个元素有且仅有一个直…...