叽里呱啦 Nacos 1.1.4 升级 1.4.1 最佳实践

news2024/11/17 4:38:36

博主介绍:✌全网粉丝4W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战、定制、远程,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验✌

博主作品:《Java项目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+MySQL+Vue等前后端分离项目,可以在左边的分类专栏找到更多项目。《Uniapp项目案例》有几个有uniapp教程,企业实战开发。《微服务实战》专栏是本人的实战经验总结,《Spring家族及微服务系列》专注Spring、SpringMVC、SpringBoot、SpringCloud系列、Nacos等源码解读、热门面试题、架构设计等。除此之外还有不少文章等你来细细品味,更多惊喜等着你哦

🍅开源项目免费哦:点击这里克隆或者下载 ,已经发布Vue3版   🍅

🍅文末获取联系🍅精彩专栏推荐订阅👇🏻👇🏻 不然下次找不到哟

 Java项目案例《100套》

https://blog.csdn.net/qq_57756904/category_12173599.html

uniapp小程序《100套》

https://blog.csdn.net/qq_57756904/category_12199600.html

目录

一、1. Nacos 升级背景

二、Nacos 升级

1、Nacos 升级版本的选择

2、Nacos 升级方案的选择

3、Nacos 升级出错

三、Nacos 升级失败排查

1、Nacos 升级失败排查

1.1、Nacos Server初步日志排查

1.2、Nacos Client 初步日志排查

2、Nacos 升级过程复现

四、Nacos 升级失败排查

1、Nacos Server本地单机版Debug

2、Nacos 本地集群版 Debug

2.1、使用 Nacos Client 1.2.1的服务远程 Debug Nacos Server 1.1.4

2.2、使用 Nacos Client 1.2.1的服务远程Debug Nacos Server 1.4.1

3、Nacos 远程集群 debug

3.1、远程 Debug Nacos 集群的原因

3.2、如何远程debug Nacos Server集群

五、代码分析总结复盘

1、为什么 Nacos 升级会导致业务应用大面积无法提供服务?

2、为什么升级后的 Nacos 无法正常工作?

3、为什么升级其中一个节点时,没有马上发现问题并停止升级,而是把三个节点都升级了?

4、为什么回滚之后部分服务没有自动重新注册上来,需要重启服务才能注册?

5、既然高版本的客户端正常情况下是会带着 beat,为什么生产环境还会有大量持续的心跳失败错误?

6、为什么心跳持续报错但生产环境上没观察到服务被踢下线的情况?

7、为什么 fat 环境、rc 环境升级没问题, 线上环境升级出问题?

六、总结:

💖微服务实战


一、1. Nacos 升级背景

随着“叽里呱啦”业务的快速发展,产品的服务化和平台化在高速建设和迭代之中 。而 Java 技术栈为主的技术体系,搭建平台化和服务化,需要注册中心,经过技术选型之后我们选择了 Nacos 作为注册中心。

当时“叽里呱啦”技术体系主要以 Python 和 Java 为主。但是 Python 服务会通过 Nacos 服务发现调用 Java 服务。两套技术体系的存在,多多少少会存在一些问题,比如 Python 服务注册时的元数据,被 Java 客户端用于服务发现,过滤的时候引起 NPE 异常,当然也期望借此机会统一 Nacos 服务注册发现的客户端基线。

二、Nacos 升级

1、Nacos 升级版本的选择

由于空指针异常是 2020 年 6 月 19 号之后被 Fix,当时考虑到 Nacos 2.0 刚发布,因此将 Nacos 升级到 1.4.1 版本是当前最佳选择。

目前公司使用 Spring Cloud 构建微服务体系,Spring Cloud 版本主要是 H.SR4。此次升级需要把 Nacos Server 升级到 1.4.1 版本。经查看源码,得知 Spring Cloud Alibaba 2.2.5.RELEASE 是基于Spring Cloud H.SR8版本和 Nacos Client 1.4.1 版本构建,经过统计分析,当前大多数业务应用是基于H.SR4版本构建,升级到H.SR8版本可以平滑过渡。

因此综合考虑,选择将 Spring Cloud 基线统一到 Spring Cloud H.SR8 版本,从而最终统一 Spring Boot 和 Spring Cloud 基线。

 

2、Nacos 升级方案的选择

Nacos 升级方案比较简单,首先升级 follower,最后升级 leader,在升级的过程中,日志中会有一些少量报错(比如:com.netflix.client.ClientException: Load balancer does not have available server for client),但是正常的,等到全部升级完成之后,达到稳态,就不会报错。

3、Nacos 升级出错

Nacos 升级过程全程按照升级方案快速升级,在开发环境,测试环境和预发环境都已顺利升级。 但在升级线上环境时,升级之后发现 Nacos Server 服务列表出现空白,空白列表页如下图所示,通过F12查看网络请求,显示当前Nacos集群不可用。

通过查看可以看到,leader为null,如下图所示:

之后发现大量服务报错,选择回滚回 Nacos 1.1.4版本。回滚之后出现部分服务掉线,并且不会自动注册上来。 最后通过重启掉线服务,重新把服务注册上来了。 这里主要两个疑点: 1. 为什么升级后服务列表会为空? 2. 回滚后,为什么部分服务无法通过心跳机制自动注册上来,必须通过重启服务才能注册到 nacos 上?

三、Nacos 升级失败排查

1、Nacos 升级失败排查

Nacos 升级失败之后,排查思路刚开始主要是分析 Nacos Server 和 Nacos Client 日志。

1.1、Nacos Server初步日志排查

首先分析的是 Nacos Server中的日志,Nacos Server 主要的需要关注的日志列表如下截图所示:

在 Server 端 access log 里发现不少心跳请求的 400 错误:

10.19.169.55 - - [12/May/2021:00:00:00 +0800] "PUT /nacos/v1/ns/instance/beat?app=unknown&serviceName=xxx%40%40xxx-server&namespaceId=public&port=60600&clusterName=DEFAULT&ip=10.19.178.160 HTTP/1.1" 400 26 0 Nacos-Java-Client:v1.4.1,Nacos-Server:1.1.4 
10.19.21.39 - - [12/May/2021:00:00:00 +0800] "PUT /nacos/v1/ns/instance/beat?app=unknown&serviceName=xxx%40%40xxx-server&namespaceId=public&port=60600&clusterName=DEFAULT&ip=10.19.178.160 HTTP/1.1" 400 26 0 Nacos-Java-Client:v1.4.1,Nacos-Server:1.1.4 
10.19.169.55 - - [12/May/2021:00:00:00 +0800] "PUT /nacos/v1/ns/instance/beat?app=unknown&serviceName=xxx%40%40xxx-server&namespaceId=public&port=60600&clusterName=DEFAULT&ip=10.19.178.160 HTTP/1.1" 400 26 1 Nacos-Java-Client:v1.4.1,Nacos-Server:1.1.4

这里可以看到出错的心跳里,nacos 的客户端是 v1.4.1 版本,高于服务端的 1.1.4。

Lesson Learn: 中间件的客户端版本需要管控,保持和服务端的版本一致。

 

1.2、Nacos Client 初步日志排查

带着这个线索,查看报错服务的 nacos client 日志。 Nacos 客户端的日志一般存在 ~/logs/nacos 目录下,如下截图所示:

查看 Nacos Client 的 naming.log 文件发现示例报错日志如下截图所示:

可以看出 Nacos Client 发送心跳日志报错,通过观察生产上其它服务均发现类似报错,说明 Nacos Client向 Nacos Server发送心跳经常失败。但是心跳失败,服务却一直健在,没有被T掉,这个原因需要进一步排查落实。 其实上述报错一直存在,没有被发现的原因是平台化前期主要关注了业务应用日志,对于中间件客户端日志没有得到足够的关注

Nacos 作为中间件,不管是 Nacos Server或 Nacos Client 都应该将所有日志通过ELK收集,并实时监控告警.

根据 nacos server 和 client 端的日志线索,我们找到 nacos 官方的一个 issue :
Param ‘beat’ is required

结合这个 Issue 和查看 nacos server 的源代码和发布历史,发现 nacos server 从 1.2.0 开始心跳接口发生了变化:

  1. beat 参数从原来的 required 变成 optional
  2. beat 参数从原来的放在url 参数里,变成放在 body
  3. 增加了「轻量心跳」功能,开启时心跳里不会带着 beat 参数。这个功能客户端默认是关闭,而 server 端默认是开启。在心跳返回里显式地告诉客户端开启时,客户端才会开启,否则客户端这个功能总是会重置为关闭。

虽然心跳接口有变化,但是查看 1.1.4 server端的代码,还是能够兼容高版本 client 的心跳的。这个改动并不能解释回滚后不能自动注册的问题。

2、Nacos 升级过程复现

通过初步日志分析其实无法解决所有疑惑,因此需要进行复现,还原现场,进一步排查问题。由于生产环境用的是虚拟机,快速还原现场的方法是:直接克隆生产环境 Nacos 所在的机器,用于环境搭建。然后用带缓存的包,按照操作步骤重现。

复现时 Nacos Server 版本是1.1.4,而 Nacos Client 端是1.2.1版本或者其它大于1.1.4的版本。经过测试开发和运维的操作,成功复现生产环境 Nacos Server 升级失败的场景。

通过快速克隆虚拟机的方式,问题可以复现。但只看日志没有办法,查清问题,因此进一步排查问题只能死磕 debug 代码进一步结合生产日志排查。

四、Nacos 升级失败排查

1、Nacos Server本地单机版Debug

Nacos Server单机版debug比较简单,设置参数源码启动即可,但最终确认单机版 Nacos Server无法复现Param ‘beat’ is required的问题,经确认这个问题只存在于集群搭建的 Nacos Server。

2、Nacos 本地集群版 Debug

2.1、使用 Nacos Client 1.2.1的服务远程 Debug Nacos Server 1.1.4

  1. 从 github 上下载 Nacos 源码,copy成两份或三份,分别导入到 Idea 中,分别修改端口 8847,8848
  2. 修改配置 Nacos server 数据库连接信息
  3. 查看本机 IP,比如为172.18.7.124,进入 /Users/xujin/Nacos/conf, cluster.conf 配置文件如下:

172.18.7.124:8847 
172.18.7.124:8848
  1. 分别以Debug方式启动 Nacos Server
  2. 使用 Nacos Client 1.2.1搭建demo,从 Nacos Client的发送心跳的代码开始Debug代码 可以查看代码 com.alibaba.Nacos .client.naming.net.NamingProxy#sendBeat 通过本地集群Debug可以查出为什么心跳发送失败,出现Param ‘beat’ is required报错,但出现报错不被踢掉的原因以及服务踢掉之后,再也无法重新注册的问题很难排查。

2.2、使用 Nacos Client 1.2.1的服务远程Debug Nacos Server 1.4.1

按照上述方式进行本地debug,发现高版本的 Nacos Server 1.4.1版本已经向下兼容,因此不会出现Param ‘beat’ is required.的400报错

3、Nacos 远程集群 debug

3.1、远程 Debug Nacos 集群的原因

为什么要进行远程Debug Nacos 集群,原因是主要有以下两点:

  1. 为什么 Nacos Server从1.1.4升级到1.4.1失败之后,回滚到1.1.4版本业务应用就无法重新注册?
  2. 其实本地集群debug,无法排查从1.1.4升级到1.4.1失败,再回滚到1.1.4这个中间过程的发生了什么,因此只能用类似生产环境的升级方式去远程Debug.

3.2、如何远程debug Nacos Server集群

如何远程debug Spring Boot的应用网上的资料比较多,在这里将不进行阐述.通过查看 Nacos Server的启动脚本发现,Naocs Server已具备远程debug的条件,从下图可以看出已经开启了远程debug端口8000。

IDEA远程debug,配置如下图所示:

五、代码分析总结复盘

1、为什么 Nacos 升级会导致业务应用大面积无法提供服务?

Nacos server 升级并不会导致应用无法提供服务。这次的问题主要两个问题叠加:

  1. 升级后的 Nacos server 只是正常启动了,但实际上并没有正常工作。并且 Nacos server 集群的全部三个节点都被升级上去并处于这种无法正常工作的状态,导致 Nacos server 整体无法提供服务。
  2. 回滚 Nacos server 版本之后,部分业务应用使用的客户端版本高于 server ,缺少老版本 server 端需要的参数而无法自动注册到 Nacos server 上,导致这部分业务无法正常提供服务。

2、为什么升级后的 Nacos 无法正常工作?

经跟阿里负责 Nacos 开源核心开发者(感谢@彦林@涌月)一起排查,发现这次升级是从 rc 环境上把运行中的 Nacos Server直接打包压缩复制到生产环境用于升级,而复制过去的目录包含了rc 环境的缓存数据, Nacos Server启动时会读取缓存数据,从而会影响 Nacos Server 的正常工作。

如果这种异常的工作状态没有被发现,并且 Nacos server 集群的全部三个节点都被升级上去并处于这种无法工作的状态下,导致升级后的 Nacos 集群无法正常工作。 Nacos Server中的报错日志中发现RC环境 Nacos Server的Ip和端口

3、为什么升级其中一个节点时,没有马上发现问题并停止升级,而是把三个节点都升级了?

Nacos Server启动后 Nacos .log 和 start.out 里面无报错,显示successfully 并且 Nacos Server日志文件较多,没有查看所有的日志文件,后续将 Nacos Server的日志接入到ELK中查看

4、为什么回滚之后部分服务没有自动重新注册上来,需要重启服务才能注册?

目前生产上的 Nacos server 是1.1.4版本,但各个业务服务使用的 Nacos 客户端版本没有统一管控,有些使用的是比 server 端版本更高的客户端。 - 对于客户端版本小于等于 1.1.4 的服务,能够通过心跳自动重新注册。 - 对于1.1.4 之后的版本(1.2.0及以上), Nacos 的心跳接口发生了变化:

  • 1. beat 参数从原来的 required 变成 optional
  • 2. beat 参数从原来的放在url 参数里,变成放在 body 里
  • 3. 增加了「轻量心跳」功能,开启时心跳里不会带着 beat 参数。

这个功能客户端默认是关闭,而 server 端默认是开启。在心跳返回里显式地告诉客户端开启时,客户端才会开启,否则客户端这个功能总是会重置为关闭。

升级当天的场景:

  1. 1.2.0 以上的客户端在 server 端升级到 1.4.1 版本的时候,「轻量心跳」的开关被 server 端打开,如下图所示:

  2. 回滚之后,因为客户端「轻量心跳」被打开,上报的心跳没有带 beat 参数,而 1.1.4 的 server 端对于 beat 参数是 required 的,导致 400 报错,没有进入到后面的自动注册流程。

  1. 客户端在收到 response 后,由于 1.1.4 的 server 并没有「轻量心跳」的支持,本来应该重置「轻量心跳」为关闭的。但由于收到报错后抛了异常,后面的重置「轻量心跳」为 false 的操作被跳过,导致「轻量心跳」一直处于开启的状态,也就一直没有带上 beat 参数,于是心跳时 server 持续报错,无法自动注册。
  2. 客户端重启后,由于「轻量心跳」默认关闭,且 1.1.4 版本的 server 端也不会告诉客户端开启「轻量心跳」, beat 参数会一直携带,也就能正常自动注册了。

5、既然高版本的客户端正常情况下是会带着 beat,为什么生产环境还会有大量持续的心跳失败错误?

两个原因叠加起来导致的:

  • 1. 生产环境部分业务使用的客户端版本高于服务端版本(1.1.4)。beat 参数在 1.1.4 版本之后发生了较大变化(beat 参数从 required 变成 optional,由放在 url 参数 变成 放在 body 中)
  • 2. 1.1.4 版本 的 Nacos server 有 bug。Server 端对于临时服务的一致性采用的是 Distro 协议,当心跳发到不是自己负责的节点上时,会转发到负责的节点上面进行处理。但是转发时没有带上 body 信息,而高版本的客户端已经改为把 beat 参数放在 body 里,导致心跳报错。

6、为什么心跳持续报错但生产环境上没观察到服务被踢下线的情况?

  1. 只有当心跳发到不是自己负责的节点上时,才会发生转发,从而丢失 body 里 beat 参数
  2. 客户端发心跳出错时会重试 3 次
  3. 客户端每 5s 一次心跳,Server 端超过 30s 没有收到正确的心跳后才会把实例设为不健康。也就是客户端发送的心跳需要连续(1+3)*6=24次心跳都没发到负责的节点上时,实例才会被标记为不健康。3 个节点的集群,这个概率大约是 百万分之 5。
  4. 生产环境上一个服务一般都会至少有两个以上实例,一个实例不健康不影响服务。 综上,生产环境上很难观察到服务被下线的情况。但是会有大量的心跳出错重试的问题,需要尽快把 Nacos server 升级上去。

7、为什么 fat 环境、rc 环境升级没问题, 线上环境升级出问题?

升级 fat 环境和 rc 环境时.不是直接复制正在运行的 Nacos Server来升级,没有环境缓存的数据,因此升级后能正常工作。 中间件,作为最底层的基础设施,应该保证部署结构等各个环境保持一致.

六、总结:

  1. 升级生产环境时是从 rc 环境上把运行中的 Nacos server 直接复制到生产环境用于升级,而复制过去的目录包含了 rc 环境的缓存数据,会影响 Nacos server 的正常工作。
  2. 生产环境各个业务服务使用的 Nacos 客户端版本没有统一管控,有的版本比服务端高。而高版本的客户端在 server 端升级上去后,被开启了一些高版本的功能。回滚回低版本的 server 端时,这些高版本的功能低版本的 server 端无法兼容,导致回滚后无法自动注册,需要重启业务服务才能注册。
  3. Nacos Client和Nacos Server的日志应该实时收集进行监控告警

💖微服务实战

✨【微服务】SpringCloud的OpenFeign与Ribbon配置

✨集Oauth2+Jwt实现单点登录

✨Spring Cloud Alibaba微服务第29章之Rancher

✨Spring Cloud Alibaba微服务第27章之Jenkins

✨Spring Cloud Alibaba微服务第24章之Docker部署

✨Spring Cloud Alibaba微服务第23章之Oauth2授权码模式

✨Spring Cloud Alibaba微服务第22章之Oauth2

✨Spring Cloud Alibaba微服务第21章之分布式事务

✨Spring Cloud Alibaba微服务第18章之消息服务

✨Spring Cloud Alibaba微服务第16章之服务容错

✨Spring Cloud Alibaba微服务第14章之分库分表

✨Spring Cloud Alibaba微服务第11章之MyBatis-plus

✨Spring Cloud Alibaba微服务第8章之OpenFeign

✨Spring Cloud Alibaba微服务第7章之负载均衡Ribbon

✨SpringCloud Alibaba微服务第6章之Gateway

✨SpringCloud Alibaba微服务第4章之Nacos

✨SpringCloud Alibaba微服务开篇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/636773.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VTK学习之读取图片,vtkImageViewer2的使用

一、vtk中的vtkImageData VTK提供相对应的类对图像文件进行读写操作 测试下效果&#xff1a; int main() {//vtkSmartPointer<vtkBMPReader> reader vtkSmartPointer<vtkBMPReader>::New();//reader->SetFileName("**\\12.bmp");vtkSmartPointer&l…

【分享】Heic图片如何批量转换成jpg格式?

我们知道&#xff0c;Heic是苹果产品的专属图片格式&#xff0c;但不是所有Windows系统都可以查看&#xff0c;而且很多需要上传图片的平台也不支持Heic格式&#xff0c;这些情况就需要把Heic转换成JPG等常用的图片格式。 如果图片数量非常多&#xff0c;要如何实现批量转换呢…

<Windows>《Windows当前桌面壁纸的位置》

《Windows当前桌面壁纸的位置》 问题&#xff1a; 想找到当前桌面壁纸的位置&#xff0c;该怎么做&#xff1f; 解决&#xff1a; win7之后&#xff0c;windows壁纸以注册表存在。注册表位置为&#xff1a; HKEY_CURRENT_USER\Control Panel\Desktop\Wallpaper该值记录了位置…

JWT验证

JSON Web Token 入门教程 - 阮一峰的网络日志 (ruanyifeng.com) 补充上时间线&#xff1f;画图&#xff1f; 隐患是什么 为什么一开始不这么做 这个封面挺好做的&#xff0c;以后笔记我也做一个&#xff0c;&#xff0c;要是能自动生成就好了 一、认证 为了保存信息用的&#…

【深度学习】日常笔记3

如果分类问题具有预测这样带有自然顺序的问题&#xff0c;如{婴⼉, ⼉童, ⻘少年, ⻘年⼈, 中年⼈, ⽼年⼈}&#xff0c;那么可以把分类问题转变为回归问题了。不过可以使用独热编码one-hot encoding。 类别对应的分量设置为1&#xff0c;其他所有分量设置为0。在我们的例⼦中…

Cadence原理图快速查找元器件的方法

1.Cadence原理图快速查找元器件的方法 ①在红框中输入元器件编号&#xff0c;点击望远镜的图标在底下的状态栏可看到查找到的相关元器件&#xff0c;点击元器件可自动定位当前元器件的位置。 ②点击hierarchy&#xff08;层&#xff09;可自主查找&#xff0c;找到后点击序号即…

【项目实战】一、Spring boot整合JWT、Vue案例展示用户鉴权

前言 案例整合了Spring boot、Spring Cloud alibaba、Gateway、Nacos discovery、Nacos config、openFeign、JWT、Vue3、Router、Axios等&#xff1b;通过JWT和登录、查询&#xff08;带用户信息&#xff09;接口&#xff0c;验证了上述工具以及鉴权功能。 1、若无公共模块&a…

学好Java爬虫需要什么技巧

Java爬虫是一种利用Java编程语言编写的网络爬虫程序&#xff0c;它可以自动化地浏览和抓取互联网上的数据&#xff0c;并将数据进行处理和保存。Java爬虫通常使用HTTP协议模拟浏览器请求来获取网页内容&#xff0c;并通过解析HTML网页标签和属性等信息来提取有用的数据。Java爬…

PPT处理控件Aspose.Slides入门教程:在 C# 中加密和解密 PPT

Aspose API支持流行文件格式处理&#xff0c;控件覆盖 word、excel、PDF、条码、OCR、CAD、HTML、email、ppt、等各个文档管理领域 是一款 PowerPoint管理API&#xff0c;用于读取&#xff0c;编写&#xff0c;操作和转换PowerPoint幻灯片的独立API&#xff0c;可将PowerPoint…

【网页设计】第 2 课 - 网页设计规范

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01; 时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、网页规范 3、设计规范 4、banner 简介 4.1、Banner 的定义 4.2、Banner 的类型 4.3、Banner 构图 4.4、…

chatgpt赋能python:Python学习笔记:如何合并元组

Python学习笔记&#xff1a;如何合并元组 在Python中&#xff0c;元组是一种不可变的数据结构。当我们需要组合不同的元组时&#xff0c;我们可以使用元组合并的方法来实现。在本文中&#xff0c;我们将学习如何使用Python语言来合并元组。 什么是元组 在Python语言中&#…

windows 服务程序和桌面程序集成(六)集成安装、启动、卸载功能

系列文章目录链接&#xff1a; windows 服务程序和桌面程序集成&#xff08;一&#xff09;概念介绍windows 服务程序和桌面程序集成&#xff08;二&#xff09;服务程序windows 服务程序和桌面程序集成&#xff08;三&#xff09;UDP监控工具windows 服务程序和桌面程序集成&…

AntDesign——TableAPI学习

table表格用于展示数据 https://ant.design/components/table-cn#table 1.bordered false不显示每一个小表格的边框&#xff0c;true反之 2.columns 列名及列数据&#xff0c;接受columns数组 2.1 colums中必须声明的属性 title&#xff08;列标题&#xff09; dataInde…

为什么会被扣小红书品牌违规分,原因是什么

小红书在2022年经过一次较大点的规则变动&#xff0c;其中小红书品牌违规分就是其中亮点名词之一。很多人对此都不甚了解&#xff0c;今天为大家分享下为什么会被扣小红书品牌违规分&#xff0c;原因是什么&#xff1f; 一、什么是品牌违规分 品牌违规分是小红书在2022年4月20日…

工厂模式~

核心本质 ① 实例化对象不使用new&#xff0c;用工厂方法代替 ② 将选择实现类&#xff0c;创建对象统一管理和控制&#xff0c;从而将调用者跟我们的实现类解耦 简单工厂 public interface Car {void name(); }public class Tesla implements Car{Overridepublic void name()…

基于 opencv 的人脸识别上课考勤系统,附源码,可作为毕业设计

一、简介 这个人脸识别考勤签到系统是基于大佬的人脸识别陌生人报警系统二次开发的。 项目使用Python实现&#xff0c;基于OpenCV框架进行人脸识别和摄像头硬件调用&#xff0c;同时也用OpenCV工具包处理图片。交互界面使用pyqt5实现。 该系统实现了从学生信息输入、人脸数据…

ps复制图层警告 (不能从选区建立新图层,因为所选区域是空的。)解决方法

有时我们选完选区 按 CtrlJ 复制图层 会出现这种情况 问题出在你当前选的图层 因为 我选择的这块选区在第二个图层上 但很明显 选择的是一大个图层 简单说 你操作的选区必须在你当前选择的图层上才行 也就是 我现在要将选择区换成第二个图层才行 再按 CtrlJ 图层就出来了

AssetStudio工程导入VS各种报错解决

AssetStudio下载地址&#xff1a;https://github.com/Perfare/AssetStudio 工程导入&#xff0c;生成解决方案&#xff0c;然后报了一堆错。让我们来一个一个的解决 这个错误&#xff0c;是缺少System.Runtime.InteropServices.RuntimeInformation.dll文件&#xff0c;下载并添…

“爱心助考 为梦护航”雷锋志愿者在行动

为确保我市高考、学考工作顺利进行&#xff0c;为考生营造安全温馨的考试环境保驾护航&#xff0c;共青团怀化市委、市教育局、共青团鹤城区委、区教育局联合怀化市青少年关爱协会党支部&#xff0c;开展2023“爱心助考 为梦护航”雷锋志愿者服务活动。 6月7-9日高考三天&#…

开发新项目看过来,这3款基于 Vue 的免费开源的 admin 管理后台框架非常好用

三款 admin 框架&#xff0c;分别基于热门的前端 UI 组件库 ElementPlus / Ant Design / Naive UI 打造&#xff0c;开箱即用。 新项目的开始&#xff0c;一般是搭建 admin 系统&#xff0c;今天盘点一下3个好的选择。 Vue vben admin 了解详细&#xff1a;https://www.thos…