【Kubernetes知识点】 解读 Service 和 EndpointSlice 之间的关系

【Kubernetes知识点】 解读 Service 和 EndpointSlice 之间的关系

目录

  • 1 概念
    • 1.1 Service的概念
    • 1.2 Endpoint 的概念
    • 1.3 EndpointSlice 的引入
      • 1.3.1 EndpointSlice支持的地址
      • 1.3.2 EndpointSlice的状态
      • 1.3.3 EndpointSlice的拓扑信息
    • 1.4 Service 、Endpoint和 EndpointSlice 的关系
    • 1.5 Endpoint 和 EndpointSlice 的对比
    • 1.6 无选择器 Service 的场景
    • 1.7 自定义EndpointSlice 要求
  • 2 实验设计:验证Service 和 EndpointSlice关联
    • 2.1 创建测试应用:
    • 2.2 观察Service和EndpointSlice
    • 2.3 模拟 Pod 变化: 扩容和缩容Pod
    • 2.4 无选择器 Service 实验:
  • 3 结论
  • 4 参考文献

❤️ 摘要:在 Kubernetes 中,Service 和 EndpointSlice 是实现负载均衡和服务发现的重要组件。 EndpointSlice让Service更好地处理大量后端,并允许集群有效地更新其健康后端列表。本文将深入探讨它们之间的关系,并设计实验来验证这一关系。


💯 本文关联好文:

  • 《一文读懂Service以及实践攻略》

1 概念

1.1 Service的概念

❔说明:想深入了解Service,请提前看前文《一文读懂Service以及实践攻略》

Kubernetes 中的 Service 是一种网络抽象层,旨在为一组 Pod 提供稳定的访问入口。通过 Service,用户可以不必关心 Pod 的变化,而是通过统一的 IP 地址和端口来访问这些 Pod。

1.2 Endpoint 的概念

Endpoints 是 Kubernetes 中用于跟踪服务网络端点的原始 API。每个 Service 都有一个对应的 Endpoints 对象,存储该服务的所有网络端点。然而,随着 Kubernetes 集群和服务的扩展,原有的 Endpoints API 逐渐暴露出其局限性,特别是在处理大量网络端点的时候。

Kubernetes 限制单个 Endpoints 对象中可以容纳的端点数量。当服务有超过 1000 个支持端点时,Kubernetes 会截断 Endpoints 对象中的数据, 并在 Endpoints 上设置注释: endpoints.kubernetes.io/over-capacity: truncated

1.3 EndpointSlice 的引入

❔ 说明: Kubernetes v1.21之后, EndpointSlice特性是stable

为了更有效地管理服务的端点,Kubernetes 引入了 EndpointSlice。与传统的 Endpoints 资源相比,EndpointSlice 提供了更好的扩展性,尤其是在处理大规模集群时。它将多个端点组织成切片,减少 API 调用次数,提高效率。

如果某个服务的端点数量达到阈值,那么 Kubernetes 将添加另一个空的 EndpointSlice 并在其中存储新的端点信息。默认情况下,一旦现有 EndpointSlice 全部包含至少 100 个端点,Kubernetes 就会创建一个新的 EndpointSlice。

1.3.1 EndpointSlice支持的地址

EndpointSlices 支持三种地址类型,设置addressType字段:

  • IPv4
  • IPv6
  • FQDN (Fully Qualified Domain Name)

❔ 说明: 每个 EndpointSlice 对象代表一个特定的IP地址类型。如果您有一项可通过 IPv4 和 IPv6 使用的服务,则至少有两个 EndpointSlice 对象。

1.3.2 EndpointSlice的状态

EndpointSlice API有三个状态条件, 说明以下:

条件说明
ready正在运行的Pod将Ready 条件设置为 True 时,同时将 EndpointSlice 条件也设置为 true。
servingserving 条件几乎与 ready 条件相同。不同之处在于,如果用户在 pod 终止时关心 pod是否还运行,则应检查 serving 条件。
TerminatingTerminating 是指示端点是否正在终止的条件。对于 Pod,这是设置了删除时间戳的任何 Pod。

1.3.3 EndpointSlice的拓扑信息

EndpointSlice 中的每个端点都可以包含相关的拓扑信息。拓扑信息包括端点的位置以及对应的Node和Zone的信息。字段说明以下:

  • nodeName - 此端点所在节点的名称。
  • zone - 此端点所在的区域。

1.4 Service 、Endpoint和 EndpointSlice 的关系

打个比喻:在一个大型活动中,K8s中的Service作为活动入口的前台人员,他为所有来宾提供入口进入指示。每个来宾Endpoint在活动中有自己的身份标识,比如知道他们的座位号。

现在这个活动区,划分了多个小区域,EndpointSlice就像是一个拿着分区名单的组长,名单记录了一组来宾的身份信息和他们的座位分布。通过EndpointSlice,你可以更高效地管理和查找来宾的位置信息,尤其是在活动人数众多时。这种分片的方式让协调工作变得更加灵活和高效。

Kubernetes中,Service与EndpointSlice实现以下机制:

  1. 选择器机制:Service 使用标签选择器来确定哪些 Pod 作为其后端。EndpointSlice 则维护与这些 Pod 相关联的网络端点信息。
  2. 动态更新:当 Pod 的状态变化时,Service 控制器会自动更新 EndpointSlice,确保服务始终指向活跃的 Pod。
  3. 负载均衡:EndpointSlice 的分组机制使得负载均衡变得更加高效,能够快速响应 Pod 的变化。

1.5 Endpoint 和 EndpointSlice 的对比

作为新的替代方案,EndpointSlice与Endpoint有以下不同点:

资源对象EndpointsEndpointSlice
数据结构所有网络端点信息存储在一个单一的 Endpoints 对象中。随着后端 Pod 数量的增加,这些对象可能会变得非常庞大。将网络端点组织为多个切片,使得每个切片只包含一部分端点信息,从而减小单个对象的大小。
性能在更新过程中,Endpoints 的每次变更都会引发大量的流量,这在高频更新的场景下尤其明显。EndpointSlices 的设计使得添加或删除单个 Pod 只需触发相同数量的更新,但更新消息的大小要小得多,从而降低了 CPU 使用率和网络流量。
新特性支持N/AEndpointSlices 支持新的网络功能,如双栈网络和拓扑感知路由,使得 Kubernetes 在网络管理上更加灵活和高效。

1.6 无选择器 Service 的场景

在某些情况下,用户可能希望定义一个没有选择器的 Service。这种情况通常用于以下场景:

  • 外部数据库:在生产环境中使用外部数据库集群,而在测试环境中使用内部数据库。
  • 跨命名空间或集群访问:需要将 Service 指向不同命名空间或其他集群中的 Service。
  • 迁移工作负载:在评估迁移至 Kubernetes 的过程中,可能只在 Kubernetes 中运行部分后端。

在这些场景中,可以定义一个不带选择器的 Service。由于没有选择器,Kubernetes 不会自动创建对应的 EndpointSlice(和旧版的 Endpoints)对象。用户可以手动添加 EndpointSlice 对象,将 Service 映射到实际运行的网络地址和端口。

1.7 自定义EndpointSlice 要求

对于用户手动创建的 EndpointSlice,建议选择合适的标签值,例如 endpointslice.kubernetes.io/managed-by。对于直接使用 kubectl 管理 EndpointSlices 的用户,建议使用描述此手动管理的名称,例如 “staff” 或 “cluster-admins”,应避免使用保留值 “controller”,因为它表示由 Kubernetes 自身控制平面管理的 EndpointSlices。

⚠️ 注意: Kubernetes API 服务器不允许代理未映射到 Pods 的端点。由于这一限制,诸如 kubectl port-forward service/<service-name> 的操作在 Service 没有选择器时会失败。

2 实验设计:验证Service 和 EndpointSlice关联

为验证 Service 和 EndpointSlice 之间的关系,我们可以进行以下实验:

2.1 创建测试应用:

沿用《一文读懂Service以及实践攻略》案例,创建一个简单的 Web 应用,定义一个 Deployment 和对应的 Service。

Deployment 示例

apiVersion: apps/v1
kind: Deployment
metadata:
# 定义Deployment的名字name: nginx-deploymentlabels:app: nginx
spec:# 定义副本数replicas: 1# 选择器指定label与pod模板的label匹配selector:matchLabels:app: nginxtemplate:metadata:# 与选择器指定label匹配labels:app: nginxspec:containers:# pod名字,可自定义- name: nginx# 镜像源, 这里设置私有镜像源image: harbor.zx/hcie/nginx:1.26.1# pod暴露端口号ports:- containerPort: 80name: httpprotocol: TCP

Service 示例

---
apiVersion: v1
kind: Service
metadata:name: my-clusterip-service
spec:selector:app: nginxports:- protocol: TCPport: 80targetPort: 80type: ClusterIP

部署Service和Deployment

kubectl apply -f nginx-deployment.yaml
kubectl apply -f clusterip-service.yaml

2.2 观察Service和EndpointSlice

查看service详细信息

kubectl describe svc my-clusterip-service

输出如下:

Name:              my-clusterip-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.245.81.75
IPs:               10.245.81.75
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         172.16.194.102:80
Session Affinity:  None
Events:            <none>

查看endpointslice

kubectl describe endpointslices.discovery.k8s.io my-clusterip-service-xvl7k

输出如下:

Name:         my-clusterip-service-xvl7k
Namespace:    default
Labels:       endpointslice.kubernetes.io/managed-by=endpointslice-controller.k8s.io
# 通过label,自动关联my-clusterip-servicekubernetes.io/service-name=my-clusterip-service
Annotations:  endpoints.kubernetes.io/last-change-trigger-time: 2024-09-28T09:43:42Z
AddressType:  IPv4
Ports:Name     Port  Protocol----     ----  --------<unset>  80    TCP
# 自动关联Endpoint,对应pod
Endpoints:- Addresses:  172.16.194.102# pod状态是Ready时, EndpointSlice状态自动设置为ReadyConditions:Ready:    trueHostname:   <unset># 关联某个Deployment下podTargetRef:  Pod/nginx-deployment-64db67d8bc-zblx6# 描述pod在当前的节点NodeName:   k8s-worker1# 描述pod在当前的域Zone:       <unset>
Events:         <none>

❔ 说明:

  • 通过创建上述 Deployment 和 Service,Kubernetes 会自动生成 EndpointSlice。

2.3 模拟 Pod 变化: 扩容和缩容Pod

扩容Deployment的副本数到3,观察EndpointSlice的变化:

kubectl scale deployment/nginx-deployment --replicas=3

观察Endpointslice,执行以下命令

kubectl describe endpointslices.discovery.k8s.io my-clusterip-service-xvl7k

输出如下:

erip-service-xvl7k
Name:         my-clusterip-service-xvl7k
Namespace:    default
Labels:       endpointslice.kubernetes.io/managed-by=endpointslice-controller.k8s.iokubernetes.io/service-name=my-clusterip-service
Annotations:  endpoints.kubernetes.io/last-change-trigger-time: 2024-09-28T09:57:26Z
AddressType:  IPv4
Ports:Name     Port  Protocol----     ----  --------<unset>  80    TCP
# 新增两个Endpoint,并分配到不同的节点
Endpoints:- Addresses:  172.16.194.102Conditions:Ready:    trueHostname:   <unset>TargetRef:  Pod/nginx-deployment-64db67d8bc-zblx6NodeName:   k8s-worker1Zone:       <unset>- Addresses:  172.16.135.200Conditions:Ready:    trueHostname:   <unset>TargetRef:  Pod/nginx-deployment-64db67d8bc-qbmvdNodeName:   k8s-master3Zone:       <unset>- Addresses:  172.16.126.43Conditions:Ready:    trueHostname:   <unset>TargetRef:  Pod/nginx-deployment-64db67d8bc-p7xqjNodeName:   k8s-worker2Zone:       <unset>
Events:         <none>

手动删除一个 Pod,并观察 EndpointSlice 的变化:

kubectl delete pod nginx-deployment-64db67d8bc-zblx6 

观察Endpointslice,执行以下命令

kubectl describe endpointslices.discovery.k8s.io my-clusterip-service-xvl7k

输出如下:

# Endpoint列表会剔除被删除的pod
Endpoints:- Addresses:  172.16.135.200Conditions:Ready:    trueHostname:   <unset>TargetRef:  Pod/nginx-deployment-64db67d8bc-qbmvdNodeName:   k8s-master3Zone:       <unset>- Addresses:  172.16.126.43Conditions:Ready:    trueHostname:   <unset>TargetRef:  Pod/nginx-deployment-64db67d8bc-p7xqjNodeName:   k8s-worker2Zone:       <unset>
Events:         <none>
---
Endpoints:- Addresses:  172.16.135.200Conditions:Ready:    trueHostname:   <unset>TargetRef:  Pod/nginx-deployment-64db67d8bc-qbmvdNodeName:   k8s-master3Zone:       <unset>- Addresses:  172.16.126.43Conditions:Ready:    trueHostname:   <unset>TargetRef:  Pod/nginx-deployment-64db67d8bc-p7xqjNodeName:   k8s-worker2Zone:       <unset>- Addresses:  172.16.194.101Conditions:Ready:    false                                   -> Ready状态从false转为true Hostname:   <unset>TargetRef:  Pod/nginx-deployment-64db67d8bc-v86vr   -> 添加新的pod NodeName:   k8s-worker1Zone:       <unset>
Events:         <none>

❔步骤说明:

  1. EndpointSlice监听到Pod被删除的事件;
  2. 更新Endpoint列表,剔除被删除的Pod;
  3. EndpointSlice监听到新的Pod被创建;
  4. 更新Endpoint列表,新增新创建的Pod;
  5. 监听Pod的状态,如果Pod状态转为Ready, 则设置Endpoint的状态为Ready。

❔ 总结:

  1. 动态更新:当 Pod 的状态变化时,Service 控制器会自动更新 EndpointSlice,确保服务始终指向活跃的 Pod。
  2. 负载均衡:EndpointSlice 的分组机制使得负载均衡变得更加高效,能够快速响应 Pod 的变化。

2.4 无选择器 Service 实验:

如果是Service需要代理外部的应用,或者应用的部署在Service之后的, 可能会采用无选择器的Service这种方式部署Service资源。

创建一个不带选择器的 Service:

apiVersion: v1
kind: Service
metadata:name: external-service
spec:ports:- port: 8080targetPort: 8080

然后手动创建 EndpointSlice:

apiVersion: discovery.k8s.io/v1
addressType: IPv4
endpoints:
# 外部应用的IP地址- addresses:- 192.168.1.100conditions:ready: true
kind: EndpointSlice
metadata:labels:endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io# 关联没有选择器的servicekubernetes.io/service-name: external-servicename: external-service-endpointsnamespace: default
# 指定映射的端口
ports:
- name: ""port: 8080protocol: TCP

创建service和endpointslice

kubectl apply -f external-service.yaml
kubectl apply -f external-service-endpoints.yaml

观察service状态

[root@k8s-master1 hcie]# kubectl describe svc external-service
Name:              external-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
# 确实没有selector
Selector:          <none>
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.245.23.244
IPs:               10.245.23.244
Port:              <unset>  8080/TCP
TargetPort:        8080/TCP
# 没有Endpoint
Endpoints:         <none>
Session Affinity:  None
Events:            <none>

观察Endpointslice状态

[root@k8s-master1 hcie]# kubectl describe endpointslices.discovery.k8s.io external-service-endpoints
Name:         external-service-endpoints
Namespace:    default
Labels:       endpointslice.kubernetes.io/managed-by=endpointslice-controller.k8s.iokubernetes.io/service-name=external-service
Annotations:  <none>
AddressType:  IPv4
Ports:Name     Port  Protocol----     ----  --------<unset>  8080  TCP
Endpoints:- Addresses:  192.168.1.100Conditions:Ready:   trueHostname:  <unset>NodeName:  <unset>Zone:      <unset>
Events:        <none>

成功创建并关联。

3 结论

通过以上实验,我们可以验证 Service 和 EndpointSlice 之间的密切关系。EndpointSlices 的引入解决了原有 Endpoints 的性能瓶颈,使 Kubernetes 在网络管理上更加高效和灵活。在实验中,验证了Service 通过标签选择器关联 Pod,而 EndpointSlice 则负责维护这些 Pod 的网络信息。无选择器的 Service 也能够与外部后端进行整合,提供更大的灵活性。希望本文可以帮助你更深入了解它们间的关系。

4 参考文献

[1]Kubernetes 官方文档-service

[2]EndpointSlices

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

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

相关文章

自动驾驶TPM技术杂谈 ———— 高精度地图

文章目录 概述高精度地图分层架构价值体现 关键技术道路元素图像处理激光点云处理点云特征提取点云法向量点云配准点云分割 同步定位与地图构建高精度地图云端服务体系 解决方案高精度地图采集数据模型 高精度地图制作和编译数据处理编译及格式规范NDSOpenDRIVE 高精度地图质量…

入职2年的程序员,被劝退了!年纪大了,感觉好绝望!

入职2年的程序员&#xff0c;今天被劝退了&#xff01;年纪大了&#xff0c;感觉好绝望&#xff01; 我的朋友是一位程序员&#xff0c;毕业后去了BAT企业&#xff0c;前2年去了一家国企&#xff0c;至今刚满2年&#xff0c;刚进去绩效领导给打了C&#xff0c;现在被边缘化&…

可视化是工业互联网的核心技术之一,都有哪些应用场景?

一、工业互联网是什么&#xff0c;发展的来胧去脉 工业互联网是指利用互联网技术和物联网技术&#xff0c;将工业生产中的各种设备、机器、传感器等进行互联互通&#xff0c;实现信息的实时采集、传输和分析&#xff0c;从而实现生产过程的智能化、自动化和高效化。 工业互联网…

echarts实现3D柱状图(视觉层面)根据博主改编

https://blog.csdn.net/weixin_57798646/article/details/131067725 这是原贴 在这个基础上我需要实现 一根柱子 代码如下 <!DOCTYPE html> <html lang"en" style"height: 100%"><head><meta charset"utf8"> </hea…

Python画笔案例-069 绘制调皮田彩格

1、绘制调皮田彩格 通过 python 的turtle 库绘制 调皮田彩格,如下图: 2、实现代码 绘制 调皮田彩格,以下为实现代码: """调皮田彩格.py本程序需要coloradd模块支持,安装方法:pip install coloradd =""" import turtle from coloradd import…

AIGC实践|AI助力文旅短视频创作全流程

前言&#xff1a; 受到央视《AI我中华》及各地文旅AI宣传片的启发&#xff0c;本次我将尝试使用AI辅助进行城市宣传片的创作探索。我将尽可能详细的展示使用AI辅助创作城市宣传片的全过程&#xff0c;从灵感捕捉到最终成品呈现。现在&#xff0c;让我们一同踏上这段充满创意的探…

工作日志:el-table在无数据情况下,出现横向滚动条。

1、遇到一个警告。 原因&#xff1a;中的组件不能呈现动画的非元素根节点。 也就是说&#xff0c;Transition包裹的必须是一个单根的组件。 2、el-table在无数据情况下&#xff0c;出现横向滚动条&#xff0c;大概跟边框的设置有关系。 开始排查。 给.el-scrollbar加了一个…

ChatGPT+R语言强强联合,数据分析不再难!回归与混合效应模型、多元统计分析、结构方程模型(SEM)(lavaan)、Meta分析、贝叶斯回归等应用

目录 第一章 生态环境数据统计概述及基础 第二章 GPT&R&#xff1a;回归与混合效应模型 第三章 GPT&R&#xff1a;多元统计分析 第四章 GPT&R&#xff1a;结构方程模型&#xff08;SEM&#xff09;&#xff08;lavaan&#xff09; 第五章 GPT&R&#xff1…

C++ STL容器(四) —— vector底层剖析

这篇讲解vector&#xff0c;不说废话&#xff0c;直接开始&#xff01; 文章目录 原理UML类图代码实现构造函数插入元素删除元素清空容器析构函数赋值运算符 案例分析 原理 这里简单说一下 vector 的大致思想&#xff0c;动态数组&#xff0c;即它的长度会随着我们插入元素而产…

安全帽识别摄像机

安全帽识别摄像机 是一种结合了监控摄像技术和智能分析技术的先进设备&#xff0c;旨在通过实时监测和分析人员头部是否佩戴安全帽&#xff0c;识别出未佩戴安全帽的情况&#xff0c;并及时发出警报通知相关人员。这种摄像机在建筑工地、工厂车间、交通运输等领域有着广泛的应用…

本省第一所!新大学,揭牌!

9月26日&#xff0c;海南艺术职业学院举行揭牌仪式&#xff0c;标志着海南省第一所公办艺术类高等职业院校正式揭牌成立。海南省旅文厅党组成员、副厅长刘成出席揭牌仪式&#xff0c;省教育厅党组成员、副厅长邢孔政在揭牌仪式上宣读省人民政府同意设立海南艺术职业学院的批复。…

jmeter进行性能测试实践

设置场景接口 一、通过抓取一个场景的接口&#xff08;抓包&#xff09; 自己抓取需要的接口&#xff0c;进行依赖 流程&#xff1a;1.在网页上F12抓取登录页面和登出页面的URL。2.在jemeter设置线程组&#xff0c;添加http请求输入URL等。3.查看结果数 二、通过boday录制 …

Linux之实战命令20:split应用实例(五十四)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

猫咪增肥大作战!福派斯牛肉高脂乳鸽猫粮测评

产品背景 福派斯宠物食品有限公司近期推出了其爆款产品——福派斯牛肉高脂乳鸽全价通用猫粮。这款猫粮以其高肉低敏配方、精选食材以及全面的营养补充&#xff0c;赢得了众多宠物主人和专业猫舍的青睐。经过全面配方和包装升级后&#xff0c;它不仅在口感和营养上有所提升&…

taobao.item_get_appAPI接口原app数据测试指南

在电商竞争日益激烈的当下&#xff0c;数据成为了商家们争夺市场的重要武器。淘宝&#xff0c;作为中国最大的在线零售平台&#xff0c;其庞大的商品库和用户群体为商家提供了巨大的商机。为了帮助商家更好地了解市场动态&#xff0c;优化库存和营销策略&#xff0c;淘宝推出了…

基于SpringBoot实现QQ邮箱发送短信功能 | 免费短信服务

开发学习过程中有个短信发送功能&#xff0c;阿里云腾讯云等等都要money&#xff0c;听说qq邮箱可以实现免费发送邮箱的功能&#xff08;短信发送的平替&#xff09;&#xff0c;就用这个来实现&#xff01;&#xff01;&#xff01;【找了好多好多方法才成功的啊啊啊啊&#x…

时序预测:多头注意力+宽度学习

本文所涉及所有资源均在 传知代码 平台可获取。 目录 概述 文章的主要贡献点 Multi-Attn整体架构 混沌时序数据预处理&#xff1a;基于相空间重构理论的混沌系统恢复 基于BLS随机映射的非线性动态特征重新激活 利用多头注意力机制进行多层语义信息提取 核心代码复现 代码优…

Golang | Leetcode Golang题解之第447题回旋镖的数量

题目&#xff1a; 题解&#xff1a; func numberOfBoomerangs(points [][]int) (ans int) {for _, p : range points {cnt : map[int]int{}for _, q : range points {dis : (p[0]-q[0])*(p[0]-q[0]) (p[1]-q[1])*(p[1]-q[1])cnt[dis]}for _, m : range cnt {ans m * (m - 1)…

Vue3 + Vite 开发环境下解决跨域问题:配置代理服务器

一、介绍 在 Vue3 结合 Vite 的前端开发中&#xff0c;跨域问题是常见的挑战之一。特别是在开发阶段&#xff0c;当后端 API 尚未配置好 CORS 支持时&#xff0c;使用代理服务器来绕过浏览器的同源策略&#xff08;Same-origin policy&#xff09;就显得尤为重要。本文将介绍如…

Word办公自动化的一些方法

1.Word部分内容介绍 word本身是带有格式的一种文档&#xff0c;有人说它本质是XML&#xff0c;所以一定要充分利用标记了【样式】的特性来迅速调整【格式】&#xff0c;从而专心编辑文档内容本身。 样式&#xff08;集&#xff09; 编号&#xff08;多级关联样式编号&#xff…