Istio入门体验系列——基于Istio的灰度发布实践
导言:灰度发布是指在项目迭代的过程中用平滑过渡的方式进行发布。灰度发布可以保证整体系统的稳定性,在初始发布的时候就可以发现、调整问题,以保证其影响度。作为Istio体验系列的第一站,本文基于Istio的流量治理机制,针对最简单的几种业务场景进行了实践,为后续的探索学习提供了一个思路和实践案例。
文章目录
- 一、背景介绍
- 1.1 灰度发布概述
- 1.2 基于kubernetes的灰度发布
- 1.3 基于Istio的灰度发布
- 二、前置条件
- 2.1 实验环境搭建
- 2.2 服务网格监控组件的安装与配置
- 2.2.1 Kiali的安装
- 2.2.2 配置Kiali控制面板对外访问
- 2.3 实验项目部署
- 2.3.1 项目简介
- 2.3.2 Weather Forecast 部署
- 三、实验过程
- 3.1 初始状态部署
- 3.2 基于流量比例的路由
- 3.3 基于请求内容的发布
- 3.4 多服务同时发布
- 3.5 自动化部署
- 四、总结
一、背景介绍
1.1 灰度发布概述
在新版本上线时,不管是在技术上考虑产品的稳定性等因素,还是在商业上考虑新版本被用户接受的程度,直接将老版本全部升级是非常有风险的。所以一般的做法是,新老版本同时在线,新版本只切分少量流量出来,在确认新版本没有问题后,再逐步加大流量比例。这正是灰度发布要解决的问题。其核心是能配置一定的流量策略,将用户在同一个访问入口的流量导到不同的版本上。有如下几种典型场景。
- 蓝绿发布
蓝绿发布是指不停止老版本,部署新版本,然后进行测试,确认没有问题之后,再将流量全量切到新版本,然后老版本同时也升级到新版本。这样做的好处是无需停机,并且风险较小。

其发布的步骤大致如下:
- 部署版本1的应用(一开始的状态),所有外部请求的流量都打到这个版本上;
- 部署版本2的应用,版本2的代码与版本1不同(新功能、Bug修复等);
- 将流量从版本1切换到版本2,即流量从v1:v2为100:0,切换为0:100;
-
如果版本2存在问题,需要回滚到版本1,进行流量切换回v1:v2为100:0。
- A/B测试
A/B测试的场景比较明确,就是同时在线上部署A和B两个对等的版本来接收流量,按一定的目标选取策略让一部分用户使用A版本,让一部分用户使用B版本,收集这两部分用户的使用反馈,即对用户采样后做相关比较,通过分析数据来最终决定采用哪个版本。蓝绿发布则主要用于安全稳定地发布新版本应用,而A/B测试则是用来测试应用功能表现的一种方法。 - 金丝雀发布
金丝雀发布是指通过让一小部分用户流量引入的新版本进行测试,就像把一个金丝雀塞到瓦斯井里面一样,探测这个新版本在环境中是否可用,在观察到新版本没有问题后再增加切换的比例,直到全部切换完成,是一个渐变、尝试的过程。如在过程中出现任何问题,则可以中止并回滚到旧版本。最简单的方式是随机选择百分比请求到金丝雀版本,但在更复杂的方案下,则可以基于请求的内容、特定范围的用户或其他属性等。
![在这里插入图片描述][Image 1]
- A/B测试
1.2 基于kubernetes的灰度发布
在Kubernetes环境下可以基于Pod的数量比例分配流量。如下图所示,B服务的两个版本v2和v1分别有2个和3个实例,当流量被均衡地分发到每个实例上时,前者可以得到40%的流量,后者可以得到60%的流量,从而达到流量在两个版本间分配的效果。

给v1和v2版本设置对应比例的Pod数量,依靠Kube-proxy把流量均衡地分发到目标后端,可以解决一个服务的多个版本分配流量的问题,但是限制非常明显:首先,要求分配的流量比例必须和Pod数量成比例,试想,基于这种方式支持 3:97 比例的流量基本上是不可能的;另外,这种方式不支持根据请求的内容来分配流量,比如要求Chrome浏览器发来的请求和IE浏览器发来的请求分别访问不同的版本。有没有一种更细粒度的分流方式?答案当然是有,Istio就可以。Istio叠加在Kubernetes之上,从机制上可以提供比Kubernetes更细的服务控制粒度及更强的服务管理能力。
1.3 基于Istio的灰度发布
Istio本身并没有关于灰度发布的规则定义,灰度发布只是流量治理规则的一种典型应用,在进行灰度发布时,只要写个简单的流量规则配置即可。Istio在每个Pod里都注入了一个Envoy,因而只要在控制面配置分流策略,对目标服务发起访问的每个Envoy便都可以执行流量策略,完成灰度发布功能。
在使用Istio实现灰度发布的情况下,流量路由和副本部署是两个完全独立的功能。服务的pod数量可以根据流量负载灵活伸缩,与版本流量路由的控制完全无关。这在自动缩放的情况下能够更加简单地管理金丝雀版本。Istio的路由规则非常灵活,可以支持细粒度控制流量百分比(例如,路由1%的流量而不需要100个pod),也可以使用其他规则来控制流量(例如,将特定用户的流量路由到金丝雀版本)。
为了更加直观的验证和说明,接下来我们就通过搭建实验环境来模拟各种业务场景下的灰度发布。
二、前置条件
2.1 实验环境搭建
由于个人电脑的网络和内存限制,本人是直接选择了在腾讯云服务器上安装Minikube和Kubectl,然后下载最新版本的Istio1.9,最后通过istioctl工具进行安装。安装过程不再赘述,具体可参考:
http://km.oa.com/group/34294/articles/show/410837
不过安装较新版本Istio的同学需要注意一下的是Istio 1.9 支持的kubernets版本要求不能低于v1.17,所以在用minikube启动kubernetes集群时必须指定好版本:
$ minikube start --vm-driver=none --kubernetes-version v1.18.15
具体环境和版本清单如下:
- 64位Cenos7.6:2核4G(最低配置要求)
- Minikube == v1.17.1
- Docker == v1.13.1
- Kubernetes == v1.18.15
- Istio == v1.9.0
2.2 服务网格监控组件的安装与配置
2.2.1 Kiali的安装
Kiali 是一个为 Istio 提供图形化界面和丰富观测功能的 Dashboard 的开源项目,其名称源于希腊语,意思是望远镜。用户利用 Kiali 可以监测网格内服务的实时工作状态,管理Istio的网络配置,快速识别网络问题。但是从Istio 1.7开始,默认不安装控制面板Kiali等组件,所以需要用户自行单独安装控制面板Kiali及相关的组件。
首先进入到Istio的安装包解压目录下,然后通过以下命令安装:
[root@chon istio-1.9.0]# kubectl apply -f samples/addons[root@chon istio-1.9.0]# kubectl apply -f samples/addons/extras
安装时,由于网络原因,可能会报错,重试几次就好了。安装完成后,通过kubectl 命令查询相关pod的运行状态:
[root@chon istio-1.9.0]# kubectl get pod -n istio-systemNAME READY STATUS RESTARTS AGEgrafana-94f5bf75b-fvlrt 1/1 Running 0 7h14mistio-egressgateway-5b475b9856-lzwwm 1/1 Running 0 24histio-ingressgateway-648778567c-4gddl 1/1 Running 0 24histiod-7cccc657f6-ng9r2 1/1 Running 0 24hjaeger-5c7675974-fmw4n 1/1 Running 0 7h14mkiali-d4fdb9cdb-wdj2v 1/1 Running 0 7h14mprometheus-7d76687994-p6whv 2/2 Running 0 7h14mzipkin-679599ffd8-xxb8l 1/1 Running 0 7h1m
2.2.2 配置Kiali控制面板对外访问
查看kiali服务,发现其类型为ClusterIP,没有对外暴露端口,无法从外部访问:
[root@chon istio-1.9.0]# kubectl get service kiali -n istio-systemNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)kiali ClusterIP 10.105.136.82 <none> 20001:/TCP,9090/TCP
所以此时需要通过NodePort的方式对外暴露控制面板,我们将原来的ClusterIP类型的service导出yaml文件,通过删除注解、创建信息、状态字段及ClusterIP等信息将类型改NodePort,然后使用kubectl apply -f 创建:
[root@chon istio-1.9.0]# kubectl get svc -n istio-system kiali -o yaml > kiali-nodeport.yaml[root@chon istio-1.9.0]# vi kiali-nodeport.yaml#主要删除metadata下的annotation, resourceVersion,seflFlink, uid; 以及spec下的ClusterIP,修改类型为NodePort, 同时删除status状态字段即可。[root@chon istio-1.9.0]# kubectl apply -f kiali-nodeport.yaml
此时再查看kiali的service,可以看到已经可以端口已经暴露出来:
[root@chon istio-1.9.0]# kubectl get service kiali -n istio-systemNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkiali NodePort 10.105.136.82 <none> 20001:32662/TCP,9090:31692/TCP 7h44m
然后在浏览器中输入“http://<ip address>:32662/kiali”打开Kiali的登录页面,登录成功后,Kiali的总览视图如下所示:

2.3 实验项目部署
2.3.1 项目简介
下面通过经典的 Weather Forecast 进行部署实践,它是一款查询城市天气信息的应用实例,一共包含4个微服务,它们之间的调用关系如下:

- frontend:前台服务,会调用 advertisement 和 forecast 这两个服务,展示整个应用的页面;
- advertisement:广告服务,返回的静态的广告图片;
- forecast:添加预报服务,返回相应城市的天气数据;
- recommendation:推荐服务,根据天气情况向用户推荐穿衣和运行等信息。
其中,frontend 服务的有两个版本: - v1 版本的界面按钮为绿色。
- v2 版本的界面按钮为蓝色。
forecast 服务有两个版本: - v1 版本会直接返回天气信息;
- v2 版本会请求 recommendation 服务,获取推荐信息,并结合天气信息一起返回数据。
2.3.2 Weather Forecast 部署
Step1: 下载项目源码。由于官方代码的 Kubernetes api 版本未及时更新肯能会导致报错问题,所以这里不建议使用官,本文提供一个较新的源码:
$ git clone https://github.com/slzcc/cloud-native-istio.git
Step2: 添加 v1 版本的服务
$ kubectl create ns weather$ kubectl label namespace weather istio-injection=enabled$ kubectl apply -f install/weather-v1.yaml -n weather
等待服务安装成功:

Step3: 添加网关资源 Gateway。
$ kubectl apply -f install/weather-gateway.yaml
Step4: 验证访问页面。添加网关资源 Gateway 创建完成后访问 istio-ingressgateway 地址即可访问,或者访问其 NodePort 端口:
[root@chon ~]# kubectl get svc -n istio-system istio-ingressgatewayNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEistio-ingressgateway LoadBalancer 10.102.172.210 <pending> 15021:32492/TCP,80:31844/TCP,443:32460/TCP,31400:30568/TCP,15443:31743/TCP 25h

点击查询:

至此,初始实验环境就全部搭建部署完成,接下来就正式开启Istio灰度发布功能的体验之旅。
三、实验过程
实验中有两个核心配置文件贯穿始终,有必要先提前认识和区分一下:
- VirtualService:路由规则配置(虚拟服务),定义路由规则,可以将满足条件的流量都转发到对应的服务后端;
- DestinationRule:目标规则配置,定义发生路由后应用于服务流量的策略,描述到达目标的请求怎么处理。
目标规则是配合虚拟服务来使用的,主要用来定义子集,子集实际上就是具体的目标地址,除此以外,它主要描述的是到达目标请求后如何去处理,所谓的目标就是子集,而如何处理就是指具体的策略。
3.1 初始状态部署
在开始实验前,首先对每个服务都创建各自的 VirtualService 和 DestinationRule 资源,将访问请求路由到所有服务的 v1 版本:
$ kubectl apply -f install/destination-rule-v1.yaml -n weather$ kubectl apply -f install/virtual-service-v1.yaml -n weather
查看配置的路由规则,以 forecast 服务为例:
[root@chon ~]# kubectl get vs -n weather forecast-route -o yamlapiVersion: networking.istio.io/v1beta1kind: VirtualService...name: forecast-routenamespace: weather...spec:hosts:- forecasthttp:- route:- destination:host: forecastsubset: v1
在浏览器中多次加载前台页面,并查询城市的天气信息,确认显示正常。然后打开Kiali控制台,查看各个服务之间的调用关系,如下图所示:

3.2 基于流量比例的路由
场景一:用户需要软件能够根据不同的天气情况推荐合适的穿衣和运动信息。于是开发的同学增加了 recommendation 新服务,并升级 forecast 服务到 v2 版本来调用 recommendation 服务。在新特性上线时,运维的同学首先部署 forecast 服务的 v2 版本和 recommendation 服务,并对 forecast 服务的 v2 版本进行灰度发布。
Step1: 部署 recommendation 服务和 forecast 服务的 v2 版本。
[root@chon cloud-native-istio]# kubectl apply -f install/recommendation-service/recommendation-all.yaml -f install/forecast-service/forecast-v2-deployment.yaml -n weather
查看服务状态:

Step2: 更新 forecast 服务 v2 版本的 DestinationRule。
[root@chon cloud-native-istio]# kubectl apply -f install/forecast-service/forecast-v2-destination.yaml -n weather
查看下发成功的配置,可以看到增加了 v2 版本 subset 的定义:
[root@chon cloud-native-istio]# kubectl get dr forecast-dr -o yaml -n weather...host: forecastsubsets:- labels:version: v1name: v1- labels:version: v2name: v2
这时去浏览器中查询天气,显然还不会出现推荐信息,因为所有流量依然都被路由到 forecast 服务的 v1 版本,不会调用 recommendation 服务。
Step3: 配置 forecast 服务的 VirtualService 配置,其中的 weight 字段显示了相应服务的流量占比,可以看到此时为 v1:v2 = 1:1。

[root@chon cloud-native-istio]# kubectl apply -f chapter-files/canary-release/vs-forecast-weight-based-50.yaml -n weather
Step4: 在浏览器中查看配置后的效果。多次刷新查询天气页面,可以发现大概约 50% 的情况下不显示推荐服务,表示调用了 forecast 服务的 v1 版本;在另外 50% 的情况下表示推荐服务,调用了 forecast 服务的 v2 版本(刷新页面基本上是两个版本交替着来)。


Step5: 继续增加 forecast 服务的 v2 版本的流量比例,直到流量全部被路由到 v2 版本。

[root@chon cloud-native-istio]# kubectl apply -f chapter-files/canary-release/vs-forecast-weight-based-v2.yaml -n weather
Step6: 在浏览器中查看配置后的效果。多次刷新页面查询天气,每次都会出现推荐信息,说明访问请求都被路由到了 forecast 服务 v2 版本。
查看Kiali控制台:

Step7: 保留 forecast 服务的老版本 v1 一段时间,再确认 v2 版本的各性能指标稳定后,删除老版本 v1 的所有资源,完成灰度发布。
3.3 基于请求内容的发布
场景二:在生产环境中同时上线了 forecast 服务的 v1 和 v2 版本,运维同学期望让不同的终端用户访问不同的版本,例如:让使用 Chrome 浏览器的用户看到推荐信息,但让使用其他浏览器的用户看不到推荐信息。
有了上面场景一的经验,依葫芦画瓢,只需要修改 forecast 服务 v2 版本的 DestinationRule中的 match 条件,使来自Chrome浏览器的请求路由到 v2 版本,其余的不变即可:

在浏览器中查看配置后的效果:用 Chrome 浏览器多次查询天气信息,发现始终显示推荐信息,说明访问到 forecast 服务的 v2 版本;用 360 或 Firefox 浏览器多次查询天气信息,发现始终不显示推荐信息,说明访问到 forecast 服务的 v1 版本。
谷歌浏览器查询访问结果:

360浏览器查询访问结果:

现在已经掌握了两种路由规则的配置和应用之后,感兴趣的同学可以自己动手试一试,模拟将两种路由规则组合在一起的场景,比如:在生产环境中同时上线了 frontend 服务的 v1 和 v2 版本(v1 版本的按钮颜色是绿色的,v2 版本的按钮颜色是蓝色的),运维同学期望使用 Android 操作系统的一半用户看到的是 v1 版本,另一半用户看到的是 v2 版本;使用其他操作系统的用户看到的总是 v1 版本。
3.4 多服务同时发布
场景三:运维同学为 frontend 和 forecast 两个服务同时进行灰度发布,frontend 服务新增 v2 版本(界面的按钮为蓝色);forecast 服务新增 v2 版本(增加了推荐信息)。测试人员在用账户 tester 访问天气应用时会看到这两个服务的 v2 版本,其他用户只能看到两个服务的 v1 版本,要求不会出现服务版本交叉调用的情况。
在场景一中我们已经部署过了非入口服务 recommendation 和 forecast 的 v2 版本,并更新了 forecast 服务的 DestinationRule。现在我们在集群中来部署入口服务 frontend 的 v2 版本,并更新其 DestinationRule。
Step1: 部署入口服务 frontend 的 v2 版本。
[root@chon cloud-native-istio]# vi install/frontend-service/frontend-v2-deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: frontend-v2labels:app: frontendversion: v2spec:replicas: 1selector:matchLabels:app: frontendtemplate:metadata:labels:app: frontendversion: v2spec:containers:- name: frontendimage: istioweather/frontend:v2imagePullPolicy: IfNotPresentports:- containerPort: 3000[root@chon cloud-native-istio]# kubectl apply -f install/frontend-service/frontend-v2-deployment.yaml -n weather
查看部署情况:

Step2: 更新 frontend 服务的 DestinationRule,增加对 v2 版本 subset 的定义:
[root@chon cloud-native-istio]# vi frontend-service/frontend-v2-destination.yamlapiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:name: frontend-drspec:host: frontendsubsets:- name: v1labels:version: v1- name: v2labels:version: v2[root@chon cloud-native-istio]# kubectl apply -f install/frontend-service/frontend-v2-destination.yaml -n weather
Step3: 配置 frontend 服务的基于访问内容的路由规则,将测试账户(Cookie 带有 “user=tester”)信息的请求流量导入到 frontend 服务的 v2 版本的 Pod 实例。
apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: frontend-routespec:hosts:- "*"gateways:- istio-system/weather-gatewayhttp:- match:- headers:cookie:regex: ^(.*?;)?(user=tester)(;.*)?$route:- destination:host: frontendsubset: v2- route:- destination:host: frontendsubset: v1[root@chon cloud-native-istio]# kubectl apply -f chapter-files/canary-release/vs-frontend-multiservice-release.yaml -n weather
Step4: 配置非入口服务 forecast 的路由规则,使得只有带“version:v2”标签的 Pod 实例的流量,才能进入 forecast 服务的新版本 v2 实例:
[root@chon canary-release]# vi chapter-files/canary-release/vs-forecast-multiservice-release.yamlapiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: forecast-routespec:hosts:- forecasthttp:- match:- sourceLabels:version: v2route:- destination:host: forecastsubset: v2- route:- destination:host: forecastsubset: v1[root@chon cloud-native-istio]# kubectl apply -f chapter-files/canary-release/vs-forecast-multiservice-release.yaml -n weather
Step5: 查看配置后的效果。
用 tester 账户登录并访问前台页面,界面的按钮是蓝色的,表示访问到的是 frontend 服务的 v2 版本。在查询天气时会显示推荐信息,表示可以访问到 forecast 服务的 v2 版本:

不登入或者使用其他用户则访问的是 v1 版本看不到推荐信息:

可视化视图查看服务间调用关系:

3.5 自动化部署
前面介绍的灰度发布的策略配置都需要人工干预。在持续交付过程中,为了解决部署和管理的复杂性,往往需要通过自动化工具实现基于权重的灰度发布。
Flagger 是一个基于 Kubernetes 和 Istio 提供灰度发布、监控和告警等功能的开源软件,通过使用 Istio 的流量路由和 Prometheus 指标来分析应用程序的行为,从而实现灰度版本的自动部署,可以使用 Webhook 扩展 Canary 分析,已运行集成测试、压力测试或其他自定义测试。

其部署流程如上图所示,由于篇幅有限,这里就不再进行赘述,有兴趣的同学可以进一步进行实践体验。
四、总结
作为Istio入门体验系列的第一篇文章,关于灰度发布的实践暂时就先到这里了。对于一名刚接触Istio的小白,通过基于流量比例、基于请求内容以及多服务场景下的灰度发布的实践,Get到了它区别于Kubernetes的部署方式,也切身感受到了Istio在各种规则业务场景下的灵活性。当然,作为系列文章,接下来我也将继续学习探索,持续输出,还望各位同学多多关注,提出宝贵建议!
[
相关文章:
Istio入门体验系列——基于Istio的灰度发布实践
导言:灰度发布是指在项目迭代的过程中用平滑过渡的方式进行发布。灰度发布可以保证整体系统的稳定性,在初始发布的时候就可以发现、调整问题,以保证其影响度。作为Istio体验系列的第一站,本文基于Istio的流量治理机制,…...
CSS行内,内部,外部以及优先级
1.内联样式表: 将样式编写到style标签里 <style>.context {color: red;} </style> 2. 行内样式: 在 HTML 标签中使用 style 属性设置 CSS 样式 <div style"font-size: 18px;">行内样式</div> 3.外联样式࿱…...
LCA——最近公共祖先
LCA问题是指在一棵树中找到两个节点的最近公共祖先。最近公共祖先是指两个节点在树中的最近的共同祖先节点。例如,在下面这棵树中,节点 6 6 6和节点7的最近公共祖先是节点 3 3 3。 1/ \2 3/ \ / \4 5 6 7解决LCA问题的方法有很多种ÿ…...
游戏开发与硬件结合,开启全新游戏体验!
游戏与硬件的结合可以通过多种方式实现,从改善游戏体验到创造全新的游戏玩法。以下是一些常见的游戏与硬件结合的方式: 虚拟现实(VR)和增强现实(AR)技术:VR和AR技术使玩家能够沉浸式地体验游戏…...
测试框架pytest教程(4)运行测试
运行测试文件 $ pytest -q test_example.py 会运行该文件内test_开头的测试方法 该-q/--quiet标志使输出保持简短 测试类 pytest的测试用例可以不写在类中,但如果写在类中,类名需要是Test开头,非Test开头的类下的test_方法不会被搜集为用…...
Linux 上 离线部署GeoScene Server Py3 运行时环境
默认安装ArcGIS Pro的时候,会自动部署上Python3环境,所以在windows上不需要考虑这个问题,但是linux默认并不部署Py3,因此需要单独部署,具体部署可以参考Linux 上 ArcGIS Server 的 Python 3 运行时—ArcGIS Server | A…...
Python+request+unittest实现接口测试框架集成实例
这篇文章主要介绍了Pythonrequestunittest实现接口测试框架集成实例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 1、为什么要写代码实现接口自动化 大家知道很多接口测试工具可以实现对接口的测试…...
django/flask+python+vue汽车租赁管理系统_1ma2x
开发语言:Python 框架:django/flask Python版本:python3.7.7 数据库:mysql 数据库工具:Navicat 开发软件:PyCharm . 课题主要分为三大模块:即管理员模块、用户模块和普通管理员模块࿰…...
胜者打仗,就像高山上决开积水,势不可挡
胜者打仗,就像高山上决开积水,势不可挡 【安志强趣讲《孙子兵法》16讲】 【原文】 是故胜兵先胜而后求战,败兵先战而后求胜。善用兵者,修道而保法,故能为胜败之政。 【注释】 修道:指从各方面修治“先立于不…...
stm32的命令规则
stm32型号的说明:以STM32F103RBT6这个型号的芯片为例,该型号的组成为7个部分,其命名规则如下:...
1. HBase中文学习手册之揭开Hbase的神秘面纱
揭开Hbase的神秘面纱 1.1 欢迎使用 Apache Hbase1.1.1 什么是 Hbase?1.1.2 Hbase的前世今生1.1.3 HBase的技术选型?1.1.3.1 不适合使用 HBase的场景1.1.3.2 适合使用 HBase的场景 1.1.4 HBase的特点1.1.4.1 HBase的优点1.1.4.2 HBase的缺点 1.1.5 HBase设计架构 1.…...
[线程/C++]线程同(异)步和原子变量
文章目录 1.线程的使用1.1 函数构造1.2 公共成员函数1.2.1 get_id()1.2.2 join()2.2.3 detach()2.2.5 joinable()2.2.6 operator 1.3 静态函数1.4 call_once 2. this_thread 命名空间2.1 get_id()2.2 sleep_for()2.3 sleep_until()2.4 yield() 3. 线程同步之互斥锁3.1 std:mute…...
全球网络加速器GA和内容分发网络CDN,哪个更适合您的组织使用?
对互联网用户来说,提供最佳的用户体验至关重要:网页加载时间过长、视频播放断断续续以及服务忽然中断等问题都足以在瞬间失去客户。因此可以帮助提高您的网站或APP提高加载性能的解决方案就至关重要:全球网络加速器和CDN就是其中的两种解决方…...
蓝凌OA custom.jsp 任意文件读取
曾子曰:“慎终追远,民德归厚矣。” 漏洞复现 访问漏洞url: 出现漏洞的文件为 custom.jsp,构造payload: /sys/ui/extend/varkind/custom.jsp var{"body":{"file":"file:///etc/passwd&q…...
(二)结构型模式:7、享元模式(Flyweight Pattern)(C++实例)
目录 1、享元模式(Flyweight Pattern)含义 2、享元模式的UML图学习 3、享元模式的应用场景 4、享元模式的优缺点 5、C实现享元模式的简单实例 1、享元模式(Flyweight Pattern)含义 享元模式(Flyweight)…...
laravel 多次查询请求,下次请求清除上次请求的where 条件
在Laravel中,可以使用where方法来添加查询条件,但是每次添加where条件时,都会在查询构造器中持久化这些条件,直到你手动重置它们。所以,如果你想在下一次查询中清除上次查询的where条件,有以下几种选择&…...
C++根据如下使用类MyDate的程序,写出类MyDate的定义,MyDate中有三个数据成员:年year,月month,日day完成以下要求
题目: 根据如下使用类MyDate的程序,写出类MyDate的定义,MyDate中有三个数据成员: 年year,月month,日day int year,month,day; void main() { MyDate d1, d2; d1.set(2015, 12, 31); d2.set(d1); d1.…...
微盟集团中报增长稳健 重点发力智慧零售AI赛道
零售数字化进程已从渠道构建走向了用户的深度运营。粗放式用户运营体系无法适应“基于用户增长所需配套的精细化运营能力”,所以需要有个体、群体、个性化、自动化运营——即在对的时候、以对的方式、把对的内容推给用户。 出品|产业家 2023年已经过半,经济复苏成为…...
设计模式(7)模板方法模式
一、定义: 定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。 //模板方法抽象类 public abstract class AbstractClass {//模板方法publ…...
2308C++协程流程9
参考 #include <协程> #include "简异中.cpp" //用来中文定义的.元<类 T>构 P;元<类 T>构 任务{用 承诺型P<T>;任务()默认;动 符号 协待()常 无异{构 等待器{极 直接协()常 无异{中 p.是准备好();}协柄 挂起协(协柄<>o)常 无异{p.连续…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
