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

【Kubernetes】第十一篇 - 滚动发布的介绍与实现

一,前言

上一篇,介绍了灰度发布和流量切分的集中方式,以及如何实现 k8s 的灰度发布;

本篇,介绍滚动发布的实现;


二,滚动发布简介

滚动发布

  • 滚动发布,则是我们一般所说的无宕机发布。其发布方式如同名称一样,一次取出一台/多台服务器(看策略配置)进行新版本更新。当取出的服务器新版确保无问题后,接着采用同等方式更新后面的服务器
  • k8s创建副本应用程序的最佳方法就是部署(Deployment),部署自动创建副本集(ReplicaSet),副本集可以精确地控制每次替换的Pod数量,从而可以很好的实现滚动更新
  • k8s每次使用一个新的副本控制器(replication controller)来替换已存在的副本控制器,从而始终使用一个新的Pod模板来替换旧的pod模板
    • 创建一个新的 replication controller;
    • 增加或减少 pod 副本数量,直到满足当前批次期望的数量;
    • 删除掉旧的 replication controller;

发布流程和策略

  • 优点

    • 不需要停机更新,无感知平滑更新;
    • 版本更新成本小,不需要新旧版本共存;
  • 缺点

    • 更新时间长:每次只更新一个/多个镜像,需要频繁连续等待服务启动缓冲
    • 旧版本环境无法得到备份:始终只有一个环境存在
    • 回滚版本异常:如果滚动发布到一半出了问题,回滚时需要使用同样的滚动策略回滚旧版本

三、环境初始化

由于 k8s-node 资源问题,先清理一下 k8s-node 上的资源占用;

查看资源情况

[root@k8s-master deployment]# kubectl get deploy
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
nginx     0/3     3            0           2d1h
pay-v1    0/3     3            0           6h52m
user-v1   0/3     3            0           8m11s
user-v2   0/3     3            0           5h11m[root@k8s-master deployment]# kubectl get service
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes        ClusterIP   10.96.0.1        <none>        443/TCP        2d16h
nginx             NodePort    10.107.223.32    <none>        80:32117/TCP   2d1h
service-pay-v1    NodePort    10.106.98.218    <none>        80:30872/TCP   6h32m
service-user-v1   NodePort    10.104.13.40     <none>        80:31071/TCP   28h
service-user-v2   NodePort    10.100.196.142   <none>        80:30289/TCP   5h12m[root@k8s-master deployment]# kubectl get pods
NAME                       READY   STATUS             RESTARTS   AGE
mysql-g2zst                0/1     CrashLoopBackOff   53         2d
nginx-6799fc88d8-2wvl2     1/1     Running            1          2d1h
nginx-6799fc88d8-lkct4     1/1     Running            1          2d1h
nginx-6799fc88d8-pktqq     1/1     Running            1          2d1h
pay-v1-655587b6f5-lpft2    1/1     Running            1          6h41m
pay-v1-655587b6f5-pcnrp    1/1     Running            2          6h42m
pay-v1-655587b6f5-spj85    1/1     Running            1          6h41m
user-v1-5895c69847-8tkm9   0/1     Pending            0          9m18s
user-v1-5895c69847-swp52   0/1     Pending            0          9m18s
user-v1-5895c69847-xr4r8   0/1     Pending            0          9m18s
user-v2-fc9d84585-2zztd    1/1     Running            2          5h13m
user-v2-fc9d84585-ss2ss    1/1     Running            1          5h13m
user-v2-fc9d84585-xrvnf    1/1     Running            1          5h13m

删除无用 pod

注意:想要删除 pod,需要删除掉 deployment,否则副本依然还在;

以 nginx 为例:目前的有 3 个正在运行的 nginx 副本

[root@k8s-master deployment]# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
mysql-4nq2q                0/1     Pending   0          4m19s
nginx-6799fc88d8-2wvl2     1/1     Running   1          2d1h
nginx-6799fc88d8-lkct4     1/1     Running   1          2d2h
nginx-6799fc88d8-pktqq     1/1     Running   1          2d1h
pay-v1-655587b6f5-lpft2    1/1     Running   1          6h53m
pay-v1-655587b6f5-pcnrp    1/1     Running   2          6h53m
pay-v1-655587b6f5-spj85    1/1     Running   1          6h53m
user-v1-5895c69847-8tkm9   0/1     Pending   0          20m
user-v1-5895c69847-swp52   0/1     Pending   0          20m
user-v1-5895c69847-xr4r8   0/1     Pending   0          20m
user-v2-fc9d84585-2zztd    1/1     Running   2          5h24m
user-v2-fc9d84585-ss2ss    1/1     Running   1          5h24m
user-v2-fc9d84585-xrvnf    1/1     Running   1          5h24m[root@k8s-master deployment]# kubectl get deploy
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
nginx     0/3     3            0           2d2h
pay-v1    0/3     3            0           7h8m
user-v1   0/3     3            0           23m
user-v2   0/3     3            0           5h27m

删除 nginx 的 deploy 后,pod 状态变为 Terminating

[root@k8s-master deployment]# kubectl delete deployment nginx
deployment.apps "nginx" deleted[root@k8s-master deployment]# kubectl get pods
NAME                       READY   STATUS        RESTARTS   AGE
mysql-4nq2q                0/1     Pending       0          9m50s
nginx-6799fc88d8-2wvl2     1/1     Terminating   1          2d1h
nginx-6799fc88d8-lkct4     1/1     Terminating   1          2d2h
nginx-6799fc88d8-pktqq     1/1     Terminating   1          2d1h
pay-v1-655587b6f5-lpft2    1/1     Terminating   1          6h58m
pay-v1-655587b6f5-pcnrp    1/1     Terminating   2          6h59m
pay-v1-655587b6f5-spj85    1/1     Terminating   1          6h58m
user-v1-5895c69847-8tkm9   0/1     Pending       0          26m
user-v1-5895c69847-swp52   0/1     Pending       0          26m
user-v1-5895c69847-xr4r8   0/1     Pending       0          26m
user-v2-fc9d84585-2zztd    1/1     Terminating   2          5h30m
user-v2-fc9d84585-ss2ss    1/1     Terminating   1          5h30m
user-v2-fc9d84585-xrvnf    1/1     Terminating   1          5h30m

继续再删除 pod

[root@k8s-master deployment]# kubectl delete pod nginx-6799fc88d8-2wvl2 --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "nginx-6799fc88d8-2wvl2" force deleted[root@k8s-master deployment]# kubectl get pods
NAME                       READY   STATUS        RESTARTS   AGE
mysql-4nq2q                0/1     Pending       0          14m
nginx-6799fc88d8-lkct4     1/1     Terminating   1          2d2h
nginx-6799fc88d8-pktqq     1/1     Terminating   1          2d1h
pay-v1-655587b6f5-lpft2    1/1     Terminating   1          7h3m
pay-v1-655587b6f5-pcnrp    1/1     Terminating   2          7h3m
pay-v1-655587b6f5-spj85    1/1     Terminating   1          7h3m
user-v1-5895c69847-8tkm9   0/1     Pending       0          30m
user-v1-5895c69847-swp52   0/1     Pending       0          30m
user-v1-5895c69847-xr4r8   0/1     Pending       0          30m
user-v2-fc9d84585-2zztd    1/1     Terminating   2          5h34m
user-v2-fc9d84585-ss2ss    1/1     Terminating   1          5h34m
user-v2-fc9d84585-xrvnf    1/1     Terminating   1          5h34m

重复操作,删除全部无用 pod

这个 mysql 删除不掉

[root@k8s-master deployment]# kubectl get deploy
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
user-v1   0/3     3            0           33m[root@k8s-master deployment]# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
mysql-xqsgz                0/1     Pending   0          13s
user-v1-5895c69847-8tkm9   0/1     Pending   0          35m
user-v1-5895c69847-swp52   0/1     Pending   0          35m
user-v1-5895c69847-xr4r8   0/1     Pending   0          35m

删除 Service

kubectl delete service service-pay-v1 service-user-v2 nginx[root@k8s-master deployment]# kubectl get svc
NAME              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes        ClusterIP   10.96.0.1      <none>        443/TCP        2d16h
service-user-v1   NodePort    10.104.13.40   <none>        80:31071/TCP   28h

重启阿里云服务

[root@k8s-master deployment]# kubectl get nodes
NAME         STATUS   ROLES                  AGE     VERSION
k8s-master   Ready    control-plane,master   2d16h   v1.20.4
k8s-node     Ready    <none>                 2d16h   v1.20.4[root@k8s-master deployment]# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
user-v1-5895c69847-8zs9n   1/1     Running   0          20m
user-v1-5895c69847-tdkhj   1/1     Running   0          20m
user-v1-5895c69847-xcdwl   1/1     Running   0          20m

测试连接

[root@k8s-master deployment]# curl http://172.17.178.106:31071
user-v1
[root@k8s-master deployment]# curl http://172.17.178.105:31071
user-v1

四,实现滚动更新

重新做一下,用 user-v1 测试滚动更新

目前基于 deployment-user-v1.yaml 创建了 deployment 部署实例;

基于 user-service-v1.yaml 创建了 service,并创建了 3 个 pod 副本

修改 deployment 配置,实现滚动更新

将 v1 升级成 v3,原始 deployment-user-v1.yaml:

[root@k8s-master deployment]# cat deployment-user-v1.yaml apiVersion: apps/v1  #API版本号
kind: Deployment     #资源类型部署
metadata:name: user-v1      #资源名称
spec:selector:matchLabels:app: user-v1   #告诉deployment根据规则匹配相应的Pod进行控制和管理,matchLabels字段匹配Pod的label值replicas: 3        #声明Pod副本的数量template:metadata:labels:app: user-v1 #Pod名称spec:            #描述Pod内的容器信息containers:- name: nginx  #容器的名称image: nginx:user-v1 #镜像ports:- containerPort: 80 #容器内映射的端口

修改 deployment-user-v1.yaml

apiVersion: apps/v1  #API 配置版本
kind: Deployment     #资源类型
metadata:name: user-v1     #资源名称
spec:
+ minReadySeconds: 1
+ strategy:
+   type: RollingUpdate
+   rollingUpdate:
+     maxSurge: 1
+     maxUnavailable: 0
+ selector:
+   matchLabels:
+     app: user-v1 #告诉deployment根据规则匹配相应的Pod进行控制和管理,matchLabels字段匹配Pod的label值replicas: 10 #声明一个 Pod,副本的数量template:metadata:labels:app: user-v1 #Pod的名称spec:   #组内创建的 Pod 信息containers:- name: nginx #容器的名称
+       image: nginx:user-v3 #使用哪个镜像ports:- containerPort: 80 #容器内映射的端口

相关参数介绍

参数含义备注
minReadySeconds容器接受流量延缓时间:单位为秒,默认为0。如果没有设置的话,k8s会认为容器启动成功后就可以用了。设置该值可以延缓容器流量切分容器启动好了,并不代表服务启动好了,比如还要去连接数据库,初始化缓存等服务初始化工作
strategy.type = RollingUpdateReplicaSet 发布类型,声明为滚动发布,默认也为滚动发布
strategy.rollingUpdate.maxSurge最多Pod数量:为数字类型/百分比。如果 maxSurge 设置为1,replicas 设置为10,则在发布过程中pod数量最多为10 + 1个(多出来的为旧版本pod,平滑期不可用状态)。maxUnavailable 为 0 时,该值也不能设置为0
strategy.rollingUpdate.maxUnavailable升级中最多不可用pod的数量:为数字类型/百分比。当 maxSurge 为 0 时,该值也不能设置为0

扩容数量,是不包括激增量的

pod 最大数量 = 容量 + 激增数

应用配置

[root@k8s-master deployment]# kubectl apply -f deployment-user-v1.yaml 
deployment.apps/user-v1 configured

分析更新过程

// 更新前
[root@k8s-master deployment]# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
user-v1-5895c69847-9mdm8   1/1     Running   0          2m49s
user-v1-5895c69847-wjzfh   1/1     Running   0          2m51s
user-v1-5895c69847-x8n7z   1/1     Running   0          2m54s// 开始更新
[root@k8s-master deployment]# kubectl apply -f deployment-user-v1.yaml 
deployment.apps/user-v1 configured// 更新中
[root@k8s-master deployment]# kubectl get pods
NAME                       READY   STATUS              RESTARTS   AGE
user-v1-5895c69847-9mdm8   1/1     Terminating         0          3m27s
user-v1-5895c69847-wjzfh   1/1     Running             0          3m29s
user-v1-5895c69847-x8n7z   1/1     Running             0          3m32s
user-v1-8cc9f4fb5-52hmd    0/1     ContainerCreating   0          0s
user-v1-8cc9f4fb5-zqj2l    1/1     Running             0          3s// 更新完成
[root@k8s-master deployment]# kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
user-v1-8cc9f4fb5-52hmd   1/1     Running   0          48s
user-v1-8cc9f4fb5-6l7mz   1/1     Running   0          46s
user-v1-8cc9f4fb5-zqj2l   1/1     Running   0          51s

验证使用镜像是否变更:

[root@k8s-master deployment]# kubectl describe pod user-v1-8cc9f4fb5-zqj2l
Name:         user-v1-8cc9f4fb5-zqj2l
Namespace:    default
Priority:     0
Node:         k8s-node/172.17.178.106
Start Time:   Fri, 24 Dec 2021 18:30:57 +0800
Labels:       app=user-v1pod-template-hash=8cc9f4fb5
Annotations:  <none>
Status:       Running
IP:           10.244.1.67
IPs:IP:           10.244.1.67
Controlled By:  ReplicaSet/user-v1-8cc9f4fb5
Containers:nginx:Container ID:   docker://436d2058c9a6a85000b2c32a3a87c1b7c892427894db1c7d851adb953ba01e88Image:          nginx:user-v3Image ID:       nginx@sha256:c3826e7a5cd2abc9f0e92fe02fe4897ab4346539438ce4f6c811371677f7494bPort:           80/TCPHost Port:      0/TCPState:          RunningStarted:      Fri, 24 Dec 2021 18:30:58 +0800Ready:          TrueRestart Count:  0Environment:    <none>Mounts:/var/run/secrets/kubernetes.io/serviceaccount from default-token-q4qxd (ro)
Conditions:Type              StatusInitialized       True Ready             True ContainersReady   True PodScheduled      True 
Volumes:default-token-q4qxd:Type:        Secret (a volume populated by a Secret)SecretName:  default-token-q4qxdOptional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300snode.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:Type    Reason     Age   From               Message----    ------     ----  ----               -------Normal  Scheduled  7m8s  default-scheduler  Successfully assigned default/user-v1-8cc9f4fb5-zqj2l to k8s-nodeNormal  Pulled     7m8s  kubelet            Container image "nginx:user-v3" already present on machineNormal  Created    7m8s  kubelet            Created container nginxNormal  Started    7m8s  kubelet            Started container nginx

是 nginx:user-v3,说明应用已更新成功;

访问 service-user-v1

curl http://172.17.178.105:31071
curl http://172.17.178.106:31071[root@k8s-master deployment]# curl http://172.17.178.105:31071
user-v3
[root@k8s-master deployment]# curl http://172.17.178.106:31071
user-v3

五,结尾

下一篇,服务的可用性探针;

相关文章:

【Kubernetes】第十一篇 - 滚动发布的介绍与实现

一&#xff0c;前言 上一篇&#xff0c;介绍了灰度发布和流量切分的集中方式&#xff0c;以及如何实现 k8s 的灰度发布&#xff1b; 本篇&#xff0c;介绍滚动发布的实现&#xff1b; 二&#xff0c;滚动发布简介 滚动发布 滚动发布&#xff0c;则是我们一般所说的无宕机发…...

【尊享版】如何系统构建你的思维认知模型?

超友们&#xff0c;早上好&#xff0c;国庆节快乐&#xff5e; 今天为你带来的分享是《如何系统构建你的思维认知模型&#xff1f;》&#xff0c;主要分为三个部分&#xff1a; 第一部分&#xff1a;【实现爆发式成长的 10 个思维模型】 第二部分&#xff1a;【6 个不可不知的…...

urho3D编码约定

缩进样式类似于Allman&#xff08;BSD&#xff09;&#xff0c;即在控制语句的下一行使用大括号&#xff0c;在同一级别缩进。在switch-case语句中&#xff0c;case与switch语句处于相同的缩进级别。 缩进使用4个空格而不是制表符。不应保留空行上的缩进。 类和结构名称以大写…...

Overleaf推广奖励:增加合作者的数量、解锁Dropbox同步和项目修改历史

Overleaf推广奖励 Overleaf是一个LaTeX\LaTeXLATE​X在线编译器&#xff0c;它可以让你与合作者共同在线编辑文档。但是默认的免费账号仅能邀请一个合作者。那么如何增加合作者的数量呢&#xff1f; Overleaf推出了一个奖励计划&#xff0c;你邀请其他人注册Overleaf&#xf…...

ChatGPT的互补工具Perplexity的详细使用方法(持续更新)

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,科大讯飞比赛第三名,CCF比赛第四名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…...

【Linux驱动开发100问】如何编译Linux内核?

&#x1f947;今日学习目标&#xff1a;如何编译Linux内核&#xff1f; &#x1f935;‍♂️ 创作者&#xff1a;JamesBin ⏰预计时间&#xff1a;10分钟 &#x1f389;个人主页&#xff1a;嵌入式悦翔园个人主页 &#x1f341;专栏介绍&#xff1a;Linux驱动开发100问 如何编译…...

15、条件概率、全概率公式、贝叶斯公式、马尔科夫链

条件概率定义&#xff1a;设A、B是两个事件&#xff0c;且&#xff0c;P(A) > 0 则称 为事件A发生的条件下事件B的条件概率对这个式子进行变形&#xff0c;即可得到概率的乘法公式&#xff1a;P(A) > 0 时&#xff0c;则P(B) > 0 时&#xff0c;则乍一看&#xff0c;…...

Eureka服务注册与发现

注册中心是分布式开发的核心组件之一&#xff0c;而Eureka是spring cloud推荐的注册中心实现。简单分析一下Eureka的原理。Eureka基础概念与流程1、服务注册在微服务架构中&#xff0c;一个服务提供者本质上也是一个Eureka客户端。启动时&#xff0c;会调用Eureka所提供的服务注…...

20230226 引用类型和指针类型的区别 - chatGPT

绝了&#xff0c;把chatGPT当百度之后真爽&#xff01; 引用类型和指针类型都是C语言中的重要概念&#xff0c;它们都提供了访问和操作内存的方法&#xff0c;但它们之间有几个关键的区别。 1. 定义和初始化方式不同 指针类型的变量定义和初始化的方式是通过使用*符号来声明…...

《操作系统》——第二章 进程与线程

目录 2.1.1进程的概念、组成、特征 2.1.2进程的状态与转换、进程的组织 2.1.3进程控制 2.1.4进程通信 2.1.5线程的概念 2.1.6线程的实现方式和多线程模型 2.2.1调度的概念、层次 2.2.2进程调度的时机、切换与过程、方式 2.2.4调度算法的评价指标 2.2.5调度算法(1) 2…...

网络原理之初识

目录 一. 网络互连 1. 局域网 2. 广域网 二. 网络通信基础 1. IP 地址 2. 端口号 3. 网络协议 4. 协议分层 5. TCP/IP 五层网络模型 &#xff08;简述&#xff09; 6. 网络数据传输的基本流程 一. 网络互连 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&am…...

CAN总线开发一本全(4) - FlexCAN的驱动程序

CAN总线开发一本全&#xff08;4&#xff09; - FlexCAN的驱动程序 苏勇&#xff0c;2023年2月 文章目录CAN总线开发一本全&#xff08;4&#xff09; - FlexCAN的驱动程序引言从MindSDK获取FlexCAN驱动程序数据结构配置通信引擎的结构体类型访问MB的结构体类型配置ID过滤器的…...

如何分析linux tcp/ip 丢包问题

引用手把手教你用Dropwatch诊断问题通过dropwatch定位系统内核丢包Finding out if/why a server is dropping packetsgithub source coed: pavel-odintsov/drop_watchHow to drop a packet in Linux in more ways than one试试Linux下的ip命令&#xff0c;ifconfig已经过时了Ho…...

旅游规划(树型dp)

W 市的交通规划出现了重大问题&#xff0c;市政府下定决心在全市各大交通路口安排疏导员来疏导密集的车流。 但由于人员不足&#xff0c;W 市市长决定只在最需要安排人员的路口安排人员。 具体来说&#xff0c;W 市的交通网络十分简单&#xff0c;由 n 个交叉路口和 n−1 条街道…...

【C++】string类的模拟实现

当你将放弃作为一种习惯&#xff0c;你一辈子也不会有出息… 文章目录一、Default member functions1.Constructor2.Copy constructor&#xff08;代码重构&#xff1a;传统写法和现代写法&#xff09;3.operator&#xff08;代码重构&#xff1a;传统写法和现代写法&#xff…...

笔记(一)——STL容器

容器分类&#xff1a;序列式容器&#xff1a;每个元素都有固定位置&#xff0c;取决于插入的时机和地点&#xff0c;和元素无关&#xff0c;如vector、deque、list、stack、queue。关联式容器&#xff1a;元素位置取决于特定的排序准则&#xff0c;和插入顺序无关&#xff0c;如…...

红黑树

红黑树是一个相对的平衡&#xff0c;减少了旋转的消耗 一个节点不是红的就是黑的根节点是黑的一个节点是红的&#xff0c;孩子是黑的&#xff08;没有连续的红色节点&#xff09;对于每个节点&#xff0c;从该节点到后代节点的简单路径&#xff0c;都包含相同的黑色&#xff0…...

RIP路由协议的更新(电子科技大学TCP/IP第二次实验)

一&#xff0e;实验目的 1、掌握 RIP 协议在路由更新时的发送信息和发送方式 2、掌握 RIP 协议的路由更新算法 二&#xff0e;预备知识 1、静态路由选择和动态路由选择 2、内部网关协议和外部网关协议 3、距离向量路由选择 三&#xff0e;实验原理 RIP 协议&#xff08…...

基于JWT实现用户身份认证

常见场景 账号/密码登录、手机号验证码登录、微信扫码登录 解决方案 基于Session认证方案 什么是session认证方案 服务端生成httpsession认证(内存-sessionId)sessionId写到浏览器cookie浏览器请求的header中自动带sessionId到服务端服务端校验sessionId是否合法 优点 .…...

SaltStack 远程命令执行漏洞(CVE-2020-16846)

目录 (一)漏洞描述 (二)漏洞复现 1、在vulhub上启动docker 2、访问docker靶机 https /ip:8000...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...