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

使用istio实现权重路由

istio概述

**概述:**Istio 是一个开源的 服务网格(Service Mesh)解决方案,主要用于管理、保护和监控微服务架构中的服务通信。它为微服务提供了基础设施层的控制功能,不需要更改应用程序的代码,从而解决服务之间的安全性、流量管理、可观察性等问题

**工作机制:**通过在每个服务的旁边部署一个 Sidecar Proxy(通常是 Envoy)。这个代理会拦截所有进出该服务的流量,并将其发送到 Istio 的控制平面进行管理和监控。应用程序本身不需要进行修改,所有的功能都通过配置管理

K8S版本要求:https://istio.io/latest/zh/docs/releases/supported-releases/#support-status-of-istio-releases

VersionCurrently SupportedRelease DateEnd of LifeSupported Kubernetes VersionsTested, but not supported
masterNo, development only1.29, 1.30, 1.31, 1.321.23, 1.24, 1.25, 1.26, 1.27, 1.28
1.24YesNovember 7, 2024~Aug 2025 (Expected)1.28, 1.29, 1.30, 1.311.23, 1.24, 1.25, 1.26, 1.27
1.23YesAug 14, 2024~May 2025 (Expected)1.27, 1.28, 1.29, 1.301.23, 1.24, 1.25, 1.26
1.22YesMay 13, 2024~Jan 2025 (Expected)1.27, 1.28, 1.29, 1.301.23, 1.24, 1.25, 1.26
1.21YesMar 13, 2024Sept 27, 20241.26, 1.27, 1.28, 1.291.23, 1.24, 1.25
1.20NoNov 14, 2023Jun 25, 20241.25, 1.26, 1.27, 1.28, 1.291.23, 1.24
1.19NoSept 5, 2023Apr 24, 20241.25, 1.26, 1.27, 1.281.21, 1.22, 1.23, 1.24
1.18NoJun 3, 2023Jan 4, 20241.24, 1.25, 1.26, 1.271.20, 1.21, 1.22, 1.23
1.17NoFeb 14, 2023Oct 27, 20231.23, 1.24, 1.25, 1.261.16, 1.17, 1.18, 1.19, 1.20, 1.21, 1.22
1.16NoNov 15, 2022Jul 25, 20231.22, 1.23, 1.24, 1.251.16, 1.17, 1.18, 1.19, 1.20, 1.21
1.15NoAug 31, 2022Apr 4, 20231.22, 1.23, 1.24, 1.251.16, 1.17, 1.18, 1.19, 1.20, 1.21
1.14NoMay 24, 2022Dec 27, 20221.21, 1.22, 1.23, 1.241.16, 1.17, 1.18, 1.19, 1.20
1.13NoFeb 11, 2022Oct 12, 20221.20, 1.21, 1.22, 1.231.16, 1.17, 1.18, 1.19

安装istio

参考链接:https://istio.io/v1.17/zh/docs/setup/getting-started/#download

1.下载指定版本的Istio,以K8S1.23版本为例安装istio1.17.8
[root@master231 06-istio]# curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.17.8 TARGET_ARCH=x86_64 sh -2.配置Istioctl工具的环境变量
[root@master231 06-istio]# tar xf istio-1.17.8-linux-amd64.tar.gz 
[root@master231 06-istio]# 
[root@master231 06-istio]# ll
total 26504
drwxr-xr-x 3 root root     4096 Aug 14 11:30 ./
drwxr-xr-x 8 root root     4096 Aug 14 11:24 ../
drwxr-x--- 6 root root     4096 Oct 11  2023 istio-1.17.8/
-rw-r--r-- 1 root root 27127663 Jun 21 17:39 istio-1.17.8-linux-amd64.tar.gz[root@master231 06-istio]# echo 'export PATH="$PATH:`pwd`/istio-1.17.8/bin"' > /etc/profile.d/istio.sh
[root@master231 06-istio]# source /etc/profile.d/istio.sh
[root@master231 06-istio]# istioctl --help3.安装Istio
[root@master241 ~]# istioctl install --set profile=demo -y  # 安装demo的配置[root@master241 ~]# istioctl profile dump demo|default|minimal|... # 查看你想要查看的配置即可。在安装 Istio 时所能够使用的内置配置文件。这些配置文件提供了对Istio控制平面和Istio数据平面Sidecar的定制内容。
可以从Istio内置配置文件的其中一个开始入手,然后根据您的特定需求进一步自定义配置文件。当前提供以下几种内置配置文件:- default:根据 IstioOperator API 的默认设置启动组件。 建议用于生产部署和 Multicluster Mesh 中的 Primary Cluster。您可以运行 istioctl profile dump 命令来查看默认设置。- demo:这一配置具有适度的资源需求,旨在展示 Istio 的功能。 它适合运行 Bookinfo 应用程序和相关任务。 这是通过快速开始指导安装的配置。此配置文件启用了高级别的追踪和访问日志,因此不适合进行性能测试。- minimal:与默认配置文件相同,但只安装了控制平面组件。 它允许您使用 Separate Profile 配置控制平面和数据平面组件(例如 Gateway)。- remote:配置 Multicluster Mesh 的 Remote Cluster。- empty:不部署任何东西。可以作为自定义配置的基本配置文件。- preview:预览文件包含的功能都是实验性。这是为了探索 Istio 的新功能。不确保稳定性、安全性和性能(使用风险需自负)。参考链接:https://istio.io/v1.17/zh/docs/setup/additional-setup/config-profiles/https://istio.io/v1.17/zh/docs/setup/getting-started/#download 温馨提示:此环节可能下载镜像失败,需要手动解决。成功的输出如下:
[root@master231 06-istio]# istioctl install --set profile=demo -y
✔ Istio core installed                                                                                                                 
✔ Istiod installed                                                                                                                     
✔ Egress gateways installed                                                                                                            
✔ Ingress gateways installed                                                                                                           
✔ Installation complete                                                                                                                Making this installation the default for injection and validation.Thank you for installing Istio 1.17.  Please take a few minutes to tell us about your install/upgrade experience!  https://forms.gle/hMHGiwZHPU7UQRWe9
[root@master231 06-istio]# 6.查看istio的版本号
[root@master231 06-istio]# istioctl version
client version: 1.17.8
control plane version: 1.17.8
data plane version: 1.17.8 (2 proxies)7.添加自动补全 
[root@master231 06-istio]# source istio-1.17.8/tools/istioctl.bash l 

手动注入pod

在安装完毕istio组件后,创建一些业务pod,然后在注入istiopod

cat > 00-test_istio.yaml <<eof
apiVersion: v1
kind: Namespace
metadata:name: wzyluckyboy
---apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-appsnamespace: wzyluckyboy
spec:replicas: 3selector:matchLabels:app: v1template:metadata:labels:app: v1spec:containers:- name: c1image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1ports:- containerPort: 80
eof

2.待pod创建完毕后再手动注入

istioctl kube-inject -f 00-test_istio.yaml | kubectl -n wzyluckyboy apply -f -

3.可以查看到带有istio标签的pod

[root@master23101-istio]# kubectl -n wzyluckyboy get pods --show-labels 
NAME                           READY   STATUS    RESTARTS   AGE   LABELS
deploy-apps-858765cd5c-pmbpm   2/2     Running   0          29s   app=v1,pod-template-hash=858765cd5c,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=v1,service.istio.io/canonical-revision=latest
deploy-apps-858765cd5c-w8gxf   2/2     Running   0          54s   app=v1,pod-template-hash=858765cd5c,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=v1,service.istio.io/canonical-revision=latest
deploy-apps-858765cd5c-zkbfk   2/2     Running   0          51s   app=v1,pod-template-hash=858765cd5c,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=v1,service.istio.io/canonical-revision=latest

查看pod的init容器:kubectl -n wzyluckyboy get pods -o yaml

istio实现权重路由

istio实现灰度发布

# 相关配置文件说明
01-deploy-apps.yaml       # 部署了2个pod,对应要灰度发布的应用
02-svc-apps.yaml          # 2个svc,关联到2个pod
03-deploy-client.yaml     # 仅用于业务访问测试
04-vs-apps-svc-all.yaml   # 虚拟服务,影响权重的操作在这个文件

1.流量管理之路由(权重路由模拟灰度发布)

cat > 01-deploy-apps.yaml <<EOF
apiVersion: v1
kind: Namespace
metadata:name: wzyluckyboy
---apiVersion: apps/v1
# 注意,创建pod建议使用deploy资源,不要使用rc资源,否则istioctl可能无法手动注入。
kind: Deployment
metadata:name: apps-v1namespace: wzyluckyboy
spec:replicas: 1selector:matchLabels:app: xiuxian01version: v1auther: wzyluckyboytemplate:metadata:labels:app: xiuxian01version: v1auther: wzyluckyboyspec:containers:- name: c1ports:- containerPort: 80image: busybox:1.36.1command: ["/bin/sh","-c","echo 'c1' > /var/www/index.html;httpd -f -p 80 -h /var/www"]
---apiVersion: apps/v1
kind: Deployment
metadata:name: apps-v2namespace: wzyluckyboy
spec:replicas: 1selector:matchLabels:app: xiuxian02version: v2auther: wzyluckyboytemplate:metadata:labels:app: xiuxian02version: v2auther: wzyluckyboyspec:containers:- name: c2ports:- containerPort: 80image: busybox:1.36.1command: ["/bin/sh","-c","echo 'c2' > /var/www/index.html;httpd -f -p 80 -h /var/www"]
EOF

2.创建3个service,分别关联不同的pod,其中一个svc管理之前创建的所有pod

cat > 02-svc-apps.yaml <<EOF
apiVersion: v1
kind: Service
metadata:name: apps-svc-v1namespace: wzyluckyboy
spec:selector:version: v1ports:- protocol: TCPport: 80targetPort: 80name: http---apiVersion: v1
kind: Service
metadata:name: apps-svc-v2namespace: wzyluckyboy
spec:selector:version: v2ports:- protocol: TCPport: 80targetPort: 80name: http---apiVersion: v1
kind: Service
metadata:name: apps-svc-allnamespace: wzyluckyboy
spec:selector:auther: wzyluckyboyports:- protocol: TCPport: 80targetPort: 80name: http
EOF

3.创建一个客户端用户业务测试

cat > 03-deploy-client.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: apps-clientnamespace: wzyluckyboy
spec:replicas: 1selector:matchLabels:app: client-testtemplate:metadata:labels:app: client-testspec:containers:- name: c1image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 command:- tail- -f- /etc/hosts
EOF

4.注入影响路由权重

cat > 04-vs-apps-svc-all.yaml <<eof
apiVersion: networking.istio.io/v1beta1
# apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: apps-svc-all-vsnamespace: wzyluckyboy
spec:# 指定vs关联的后端svc名称hosts:- apps-svc-all# 配置http配置http:# 定义路由信息- route:# 定义目标- destination:host: apps-svc-v1# 指定权重weight: 90- destination:host: apps-svc-v2weight: 10
eof
	3.手动注入Istio-proxy1.注入前
[root@master241 yinzhengjie]# kubectl get pods -n wzyluckyboy 
NAME                          READY   STATUS    RESTARTS   AGE
apps-client-f84c89565-kmqkv   1/1     Running   0          31s
apps-v1-9bff7546c-fsnmn       1/1     Running   0          32s
apps-v2-6c957bf64b-lz65z      1/1     Running   0          32s
[root@master241 yinzhengjie]# 
	2.开始手动注入
[root@master241 yinzhengjie]# istioctl kube-inject -f 03-deploy-client.yaml | kubectl -n wzyluckyboy apply -f -
deployment.apps/apps-client configured
[root@master241 yinzhengjie]# 
[root@master241 yinzhengjie]# istioctl kube-inject -f 01-deploy-apps.yaml | kubectl -n wzyluckyboy apply -f -
namespace/yinzhengjie unchanged
deployment.apps/apps-v1 configured
deployment.apps/apps-v2 configured
[root@master241 yinzhengjie]# 
	3.注入后
[root@master241 yinzhengjie]# kubectl get pods -n wzyluckyboy 
NAME                          READY   STATUS        RESTARTS   AGE
apps-client-5cc67d864-g2r2v   2/2     Running       0          41s
apps-v1-85c976498b-5qp59      2/2     Running       0          30s
apps-v2-5bb84548fc-65r7x      2/2     Running       0          30s
[root@master241 yinzhengjie]# 
5.4.开始测试
[root@master231 ~]# kubectl -n wzyluckyboy exec -it apps-client-5f579696d5-s7nvc   -- sh
/ # while true; do curl http://apps-svc-all;sleep 0.1;done
c1
c1
c1
c1
c1
c1
c1
c1
c1
c1
c1
c1
c1
c1
c2

相关文章:

使用istio实现权重路由

istio概述 **概述&#xff1a;**Istio 是一个开源的 服务网格&#xff08;Service Mesh&#xff09;解决方案&#xff0c;主要用于管理、保护和监控微服务架构中的服务通信。它为微服务提供了基础设施层的控制功能&#xff0c;不需要更改应用程序的代码&#xff0c;从而解决服…...

小程序项目-购物-首页与准备

前言 这一节讲一个购物项目 1. 项目介绍与项目文档 我们这里可以打开一个网址 https://applet-base-api-t.itheima.net/docs-uni-shop/index.htm 就可以查看对应的文档 2. 配置uni-app的开发环境 可以先打开这个的官网 https://uniapp.dcloud.net.cn/ 使用这个就可以发布到…...

基于 NodeJs 一个后端接口的创建过程及其规范 -- 【elpis全栈项目】

基于 NodeJs 一个后端接口的创建过程及其规范 一个接口的诞生&#xff1a; #mermaid-svg-46HXZKI3fdnO0rKV {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-46HXZKI3fdnO0rKV .error-icon{fill:#552222;}#mermaid-sv…...

【hot100】刷题记录(8)-矩阵置零

题目描述&#xff1a; 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]示例 2…...

C语言教学第三课:运算符与表达式

一、课程导入 同学们&#xff0c;上节课我们学习了变量和数据类型&#xff0c;这些是C语言的基础。今天&#xff0c;我们将继续深入学习C语言中的运算符与表达式。运算符是C语言中用于执行各种操作的符号&#xff0c;而表达式则是由变量、常量和运算符组成的有意义的组合。通过…...

一文讲解Spring中应用的设计模式

我们都知道Spring 框架中用了蛮多设计模式的&#xff1a; 工厂模式呢&#xff0c;就是用来创建对象的&#xff0c;把对象的创建和使用分开&#xff0c;这样代码更灵活。代理模式呢&#xff0c;是用一个代理对象来控制对真实对象的访问&#xff0c;可以在访问前后做一些处理。单…...

springboot集成钉钉,发送钉钉日报

目录 1.说明 2.示例 3.总结 1.说明 学习地图 - 钉钉开放平台 在钉钉开放文档中可以查看有关日志相关的api&#xff0c;主要用到以下几个api&#xff1a; ①获取模板详情 ②获取用户发送日志的概要信息 ③获取日志接收人员列表 ④创建日志 发送日志时需要根据模板规定日志…...

优选算法的灵动之章:双指针专题(一)

个人主页&#xff1a;手握风云 专栏&#xff1a;算法 目录 一、双指针算法思想 二、算法题精讲 2.1. 查找总价格为目标值的两个商品 2.2. 盛最多水的容器 ​编辑 2.3. 移动零 2.4. 有效的三角形个数 一、双指针算法思想 双指针算法主要用于处理数组、链表等线性数据结构…...

PyQt4学习笔记1】使用QWidget创建窗口

目录 一、创建一个简单的 QWidget 窗口 二、设置窗口属性 1. 设置窗口标题 2. 设置背景颜色 3. 设置窗口大小和位置 4. 设置窗口模式 5. 关闭窗口 6. QWidget 及其子控件的样式 三、添加控件到 QWidget 1. 添加按钮 2. 添加标签 3. 添加文本框 4. 控件布局管理 四、自定义样式 …...

pycharm 中的 Mark Directory As 的作用是什么?

文章目录 Mark Directory As 的作用PYTHONPATH 是什么PYTHONPATH 作用注意事项 Mark Directory As 的作用 可以查看官网&#xff1a;https://www.jetbrains.com/help/pycharm/project-structure-dialog.html#-9p9rve_3 我们这里以 Mark Directory As Sources 为例进行介绍。 这…...

【C++】string类(上):string类的常用接口介绍

文章目录 前言一、C中设计string类的意义二、string类的常用接口说明1. string类对象的常见构造2. string类对象的容量操作2.1 size、capacity 和 empty的使用2.2 clear的使用2.3 reserve的使用2.4 resize的使用 3. string类对象的访问及遍历操作3.1 下标[ ] 和 at3.2 迭代器it…...

CSS关系选择器详解

CSS关系选择器详解 学习前提什么是关系选择器&#xff1f;后代选择器&#xff08;Descendant Combinator&#xff09;语法示例注意事项 子代选择器&#xff08;Child Combinator&#xff09;语法示例注意事项 邻接兄弟选择器&#xff08;Adjacent Sibling Combinator&#xff0…...

C语言中的信号量

信号是操作系统中用来传递特定消息的机制。操作系统可以使用这种方式将程序运行过程中发生的各类特殊情况发送给程序&#xff0c;并按照其指定的逻辑进行处理。信号名称都以 “SIG” 作为前缀&#xff0c;如程序访问非法内存时&#xff0c;会产生名为 SIGSEGV 的信号。 程序需…...

求一个数的数根(高精度)

上一期我们讲的是求一个数的数根&#xff0c;和本期唯一不同的是&#xff0c;数据范围不同了&#xff0c;上一期这个数是小于等于10的18次方的&#xff0c;这一期是小于等于10的1000次方的&#xff0c;开一个变量&#xff1f;肯定不行&#xff0c;我们需要再开一个数组&#xf…...

从理论到实践:Linux 进程替换与 exec 系列函数

个人主页&#xff1a;chian-ocean 文章专栏-Linux 前言&#xff1a; 在Linux中&#xff0c;进程替换&#xff08;Process Substitution&#xff09;是一个非常强大的特性&#xff0c;它允许将一个进程的输出直接当作一个文件来处理。这种技术通常用于Shell脚本和命令行操作中…...

3 卷积神经网络CNN

1 Image Classification (Neuron Version) – 1.1 Observation 1 1.2 Observation 2 如果不同的receptive field需要相同功能的neuron&#xff0c;可以使这些neuron共享参数 1.3 Benefit of Convolutional Layer 2 Image Classification (Filter Version) 不用担心filter大小…...

详解Linux系统的终端(Terminal)以及分类(各种tty开头的设备文件)

目录 终端(Terminal)的概念和作用终端(Terminal)在Linux中被视为设备,每个终端有自己的设备文件tty三个字母的来源(tty名字的来源)如何查看当前终端的设备文件常见终端的分类1-串口终端02-虚拟控制台终端&#xff08;Virtual Console&#xff09;03-伪终端&#xff08;Pseudo T…...

强化学习数学原理(五)——随机近似与随机

一、Motivating example 首先有个random variable(随机变量)X&#xff0c;我们的目标就是求出他的expectation E(x)&#xff0c;我们有一些iid的采样&#xff0c;xi&#xff0c;从1到n&#xff0c;求出均值 但是如果有很多数据&#xff0c;我需要等很久&#xff0c;把所有数据都…...

图书管理系统 Axios 源码__获取图书列表

目录 核心功能 源码介绍 1. 获取图书列表 技术要点 适用人群 本项目是一个基于 HTML Bootstrap JavaScript Axios 开发的图书管理系统&#xff0c;可用于 添加、编辑、删除和管理图书信息&#xff0c;适合前端开发者学习 前端交互设计、Axios 数据请求 以及 Bootstrap 样…...

线性数据结构:单向链表

放弃眼高手低&#xff0c;你真正投入学习&#xff0c;会因为找到一个新方法产生成就感&#xff0c;学习不仅是片面的记单词、学高数......只要是提升自己的过程&#xff0c;探索到了未知&#xff0c;就是学习。 考虑到可能有小白在合并代码时出现各种细节问题&#xff0c;本文…...

线程互斥同步

前言&#xff1a; 简单回顾一下上文所学&#xff0c;上文我们最重要核心的工作就是介绍了我们线程自己的LWP和tid究竟是个什么&#xff0c;总结一句话&#xff0c;就是tid是用户视角下所认为的概念&#xff0c;因为在Linux系统中&#xff0c;从来没有线程这一说法&#xff0c;…...

《苍穹外卖》项目学习记录-Day11订单统计

根据起始时间和结束时间&#xff0c;先把begin放入集合中用while循环当begin不等于end的时候&#xff0c;让begin加一天&#xff0c;这样就把这个区间内的时间放到List集合。 查询每天的订单总数也就是查询的时间段是大于当天的开始时间&#xff08;0点0分0秒&#xff09;小于…...

SAP HCM 回溯分析

最近总有人问回溯问题&#xff0c;今天把12年总结的笔记在这共享下&#xff1a; 12年开这个图的时候总是不明白是什么原理&#xff0c;教程看N次&#xff0c;网上资料找一大堆&#xff0c;就是不明白原理&#xff0c;后来为搞明白逻辑&#xff0c;按照教材的数据一样做&#xf…...

JavaScript原型链与继承:优化与扩展的深度探索

在 JavaScript 的世界里&#xff0c;万物皆对象&#xff0c;而每个对象都有一个与之关联的原型对象&#xff0c;这就构成了原型链的基础。原型链&#xff0c;简单来说&#xff0c;是一个由对象的原型相互连接形成的链式结构 。每个对象都有一个内部属性[[Prototype]]&#xff0…...

五子棋对弈

问题描述 "在五子棋的对弈中&#xff0c;友谊的小船说翻就翻&#xff1f;" 不&#xff01;对小蓝和小桥来说&#xff0c;五子棋不仅是棋盘上的较量&#xff0c;更是心与心之间的沟通。这两位挚友秉承着"友谊第一&#xff0c;比赛第二"的宗旨&#xff0c;决…...

vue vscode插件推荐安装

在 VSCode 中开发 Vue&#xff0c;推荐安装以下插件&#xff1a; 核心插件 1. Volar&#xff08;Vue Language Features&#xff09; - Vue 3 官方推荐的开发工具&#xff0c;替代 Vetur。 This extension is deprecated. Use the Vue - Official extension instead. 1.Vue …...

Med-R2:基于循证医学的检索推理框架:提升大语言模型医疗问答能力的新方法

Med-R2 : Crafting Trustworthy LLM Physicians through Retrieval and Reasoning of Evidence-Based Medicine Med-R2框架Why - 这个研究要解决什么现实问题What - 核心发现或论点是什么How - 1. 前人研究的局限性How - 2. 你的创新方法/视角How - 3. 关键数据支持How - 4. 可…...

P7497 四方喝彩 Solution

Description 给定序列 a ( a 1 , a 2 , ⋯ , a n ) a(a_1,a_2,\cdots,a_n) a(a1​,a2​,⋯,an​)&#xff0c;有 m m m 个操作&#xff0c;分四种&#xff1a; add ⁡ ( l , r , v ) \operatorname{add}(l,r,v) add(l,r,v)&#xff1a;对于所有 i ∈ [ l , r ] i \in [l,r…...

EtherCAT主站IGH-- 29 -- IGH之mailbox.h/c文件解析

EtherCAT主站IGH-- 29 -- IGH之mailbox.h/c文件解析 0 预览一 该文件功能`mailbox.c` 文件功能函数预览二 函数功能介绍`mailbox.c` 中主要函数的作用1. `ec_slave_mbox_prepare_send`2. `ec_slave_mbox_prepare_check`3. `ec_slave_mbox_check`4. `ec_slave_mbox_prepare_fetc…...

UI线程用到COM只能选单线程模型

无论用不用UI库&#xff0c;哪怕是用Win32 API手搓UI&#xff0c;UI线程要用COM的话&#xff0c;必须初始化为单线程单元(STA)&#xff0c;即CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);&#xff0c;不能用MULTITHREADTHREADED。 实际上&#xff0c;很多(WPF等)UI库若…...