Sentinel应用笔记

概念

正常情况
当A、B、G、H掉线,其他服务就没法通信了
异常情况

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应过载保护、热点流量防护等多个维度保护服务的稳定性。
imagepng

特性:

富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。
完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
imagepng
主要用途:围绕资源的实时状态设定规则,所有规则都可以进行动态实时调整。如服务降级熔断、系统流量控制、系统自适应过载保护等。
Sentinel熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出DegradeException)。
imagepng

熔断、降级、限流

熔断

服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的情况时,为了防止整个系统出现雪崩,暂时停止对该服务的调用。
停止是说,当前服务一旦对下游服务进行熔断,当请求到达时,当前服务不再对下游服务进行调用,而是使用设定好的策略(如构建默认值)直接返回。
暂时是说,熔断后,并不会一直不再调用下游服务,而是以一定的策略(如每分钟调用 10 次,若均返回成功,则增大调用量)试探调用下游服务,当下游服务恢复可用时,自动停止熔断。

降级

降级是指当自身服务压力增大时,采取一些手段,增强自身服务的处理能力,以保障服务的持续可用。比如,下线非核心服务以保证核心服务的稳定、降低实时性、降低数据一致性。
为了预防某些功能出现负荷过载或者响应慢的情况,在其内部暂时舍弃一些非核心接口和数据的请求(如评论、积分),而直接返回一个提前准备好的 fallback(退路) 错误处理信息。释放CPU和内存资源,以保证整个系统的稳定性和可用性。
所谓熔断降级就是为了解决微服务之间调用后产生的异常问题,如A调用了B,而B是微信支付或其他第三方的接口,由于当时的网络原因导致B的响应时长增加,从而造成调用方A的线程池被占用,极端情况下,A的线程池被耗尽,整个服务雪崩。
QPS是对请求的数量进行控制,而无法对于进入服务内的请求是否异常进行控制,熔断降级就是对进入服务之中的请求是否异常来进行控制,从而保护我们的服务。
所以当某个资源的响应时间的线程超过设定线程的阈值时,对于其可以进行熔断降级处理,暂时得关闭访问,熔断器open,当熔断时长到达之后,熔断器进入half-open状态,允许一个请求进入,无论该请求是否正常都会返回,然后如果这个请求正常则熔断器close,如果这个请求异常则熔断器继续open,继续熔断,反复上述步骤。

限流

限流是指上游服务对本服务请求 QPS 超过阙值时,通过一定的策略(如延迟处理、拒绝处理)对上游服务的请求量进行限制,以保证本服务不被压垮,从而持续提供稳定服务。常见的限流算法有滑动窗口、令牌桶、漏桶等。

docker安装Sentinel

docker pull bladex/sentinel-dashboard:1.8.0docker run --name sentinel --restart=always -d  -p 8858:8858  bladex/sentinel-dashboard:1.8.0账号/密码都是 sentinel

imagepng

项目中应用

注册到sentinel(服务监控)

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>2021.1</version>
</dependency>
spring:cloud:sentinel:transport:client-ip: 192.168.56.1dashboard: 192.168.56.10:8858    //sentinel  仪表盘地址port: 8719    //默认 sentinel api 端口

imagepng

实时监控

感觉不需要有这个也可以实时监控啊

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Actuator默认情况下,只有/info和/heath端点是启用的。因为Actuator本身没有保护,所以大多数端点默认是禁用的,需要我们来选择对外暴露哪些端点。通过这2个属性management.endpoints.web.exposure.include和management.endpoints.web.exposure.exclude(排除哪些)。通过management.endpoints.web.exposure.include属性,可以指定哪些端点想要暴露出来。
我理解的端点指的是需要监控的API接口

management:endpoints:web:exposure:include: '*'

imagepng

限流

流控规则

imagepng
流控规则主要分为QPS 和 线程数两大控制方向, 而其后的处理方式有: 直接,关联,链路三种方式,处理效果又分为:快速失败,Warm Up(冷启动),匀速排队。

  • QPS (Query per second) : 即每秒的请求数量

  • 线程数: 即服务中的并发量,值得注意的是,线程数就是并发量,而QPS不一定是并发量,如QPS为1000,而由于服务的耗时操作少,线程执行后归还到线程池的速度快,可能只需要10个线程即可完成,所以要明确QPS与线程数的区别

  • 直接: 顾名思义,即是直接进行接下来的操作,是对被保护的服务进行操作

  • 关联: 在关联资源触碰到阈值时对被保护资源进行操作

  • 链路: 在多个调用中,针对某一条调用链路进行操作,如果触碰到阈值,则该条链路无法访问请求的资源

  • 快速失败: 直接拒绝请求

  • Warm Up: 冷启动,如果启动需要耗时操作时可以如此设置,防止在刚开始进行耗时操作时过多的访问压垮服务,而给与一定的时间进行预热,之后达到处理峰值

  • 匀速排队: 是为了针对访问在不同的时间内,访问量不同,因此设置一个时间长度,来匀速的处理请求,实现削峰填谷,让程序平稳的进行,使用到了漏桶算法,值得注意的是该处理方式不支持QPS> 1000 的场景

    访问某个资源超过阈值时,该资源被保护不让访问
    
      我理解warm up 作用预防在于再短时间内一下子过多qps导致压垮服务在服务启动时,对该资源直接进行流控操作,在某段预热时长(单位秒)内,慢慢达到设定的阈值,期间超出的部分直接拒绝,如此达到保护目标资源的目的,Warm Up 的起始值为设定阈值的 1/3(如设定300,则起始阈值为100
    在访问目标资源时,由于访问在不同时间段内的访问量不同,设置此操作
    在设定的时间段内(单位:毫秒),处理 阈值 个数的请求 , 每一个请求的处理时间为: 设置的超时时间 / 阈值
    
    如果关联资源的QPS超过阈值,则被保护资源拒绝访问
    注意点: 关联资源之间不一定就是调用关系,可能并没有关系,而设置之后是控制关联资源的QPS阈值来限制目标资源的访问权限
    
    也是对关联资源在超过设定的QPS阈值时,对目标资源进行冷启动处理,初始阈值依然是设定阈值的 1/3
    而后在预热时长内达到设定阈值,预热时间内超出阈值的请求直接快速失败
    
    关联资源在超过设定阈值时,对于目标资源进行匀速排队的操作
    
    machine-root/       \/         \
    Entrance1     Entrance2/             \
    /               \
    DefaultNode(nodeA)   DefaultNode(nodeA)
    

针对同一个资源有两个入口,Entrance1 和Entrance2 ,他们都调用了同一个资源nodeA,那么这样就形成了一个链路,对此,我们可以设置入口资源为Entrance1 或 Entrance2 中的一个,表示在某一个入口的QPS值达到阈值之后,切断这条链路,使该入口无法被访问

```java
上述介绍的冷启动和匀速排队的策略相同,只是针对的是链路中的某一个入口达到QPS阈值之后的操作

线程数超过阈值的操作一致

降级规则

imagepng

最大 RTResponse Time) : 响应时间,就是在规定什么叫做 “慢” , 单个请求的响应时长大于我们设定的最大RT,那么这个请求就叫做 “慢请求”比例阈值: 响应时间大于设定RT的线程占总请求数的比例,取值0.0~1.0之间熔断时长: 达到阈值之后服务请求拒绝的时长(单位:秒)最小请求数: 1秒钟内发出的最少需要的请求的总数量
解读: 如果一秒钟内发送了5个请求,而其中 比例阈值 * 最小请求数 的个数的请求超过了最大RT 的时间,那么目标资源就会被熔断降级,熔断时长单位为秒。断路器的工作流程:
1、达到熔断的阈值之后,断路器的状态为open
2、熔断时长内所有的请求都被拒绝,无法进入
3、熔断时长之后,断路器的状态变为half-open,此时允许一个请求进来
4、若该请求没有异常,则断路器的状态为close,之后回归正常
5、若该请求依然异常,则断路器再次变为open状态,所有请求无法进入,等待下一次熔断时长之后

imagepng
imagepng

热点规则

imagepng

授权规则

imagepng

熔断降级fegin托底

@FeignClient(value = "mall-member", fallback = MemberFeginServiceFallBack.class)
@Component
public interface MemberFeginService {@PostMapping("/mallmember/member/register")public R register(@RequestBody UserRegisterVO userRegisterVO);@PostMapping("/mallmember/member/login")public R login(@RequestBody LoginVO loginVO);
}
/*** @author guanglin.ma* @date 2024-01-26 13:32*/
@Component
@Slf4j
public class MemberFeginServiceFallBack implements MemberFeginService {Logger logger = LoggerFactory.getLogger(MemberFeginServiceFallBack.class);@Overridepublic R register(UserRegisterVO userRegisterVO) {logger.error("注册失败哦");return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());}@Overridepublic R login(LoginVO loginVO) {logger.error("登录失败哦");return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());}
}
feign:sentinel:enabled: true

imagepng

限流

public class SentinelUrlBlockHandler implements BlockExceptionHandler {@Overridepublic void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {R r = R.error(500,"访问太快,稍后再试!");httpServletResponse.setContentType("application/json;charset=UTF-8");httpServletResponse.getWriter().write(JSON.toJSONString(r));}
}

设置流控规则
imagepng

自定义资源(不前测试没有成功)

// 1.5.0 版本开始可以利用 try-with-resources 特性(使用有限制)
// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
try (Entry entry = SphU.entry("resourceName")) {// 被保护的业务逻辑// do something here...
} catch (BlockException ex) {// 资源访问阻止,被限流或被降级// 在此处进行相应的处理操作
}
// 资源名可使用任意有业务语义的字符串
if (SphO.entry("自定义资源名")) {// 务必保证finally会被执行try {/*** 被保护的业务逻辑*/} finally {SphO.exit();}
} else {// 资源访问阻止,被限流或被降级// 进行相应的处理操作
}
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-annotation-aspectj</artifactId><version>1.8.0</version>
</dependency>@SentinelResource(value = "test1Resource",blockHandler = "test1BlockHandler")
@Override
public String test1() {// 1.5.0 版本开始可以利用 try-with-resources 特性(使用有限制)
// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
//        try (Entry entry = SphU.entry("test1Resource")) {// 被保护的业务逻辑// do something here...logger.error("正常访问");return "正常访问";
//        } catch (BlockException ex) {
//            // 资源访问阻止,被限流或被降级
//            // 在此处进行相应的处理操作
//            logger.error("限流中");
//            return "限流中";
//
//        }}public void test1BlockHandler(BlockException blockException){logger.error("限流中");
}

网关流控

imagepng

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId><version>2021.1</version>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>2021.1</version>
</dependency>
spring:cloud:sentinel:transport:dashboard: 192.168.56.10:8858port: 8719eager: truemanagement:endpoints:web:exposure:include: '*'

imagepng
控制仪表可能不显示网关的控制列表,我只这么解决的
imagepng

imagepng

持久化

<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId><version>1.8.0</version>
</dependency>
spring:cloud:nacos:discovery:server-addr: 192.168.56.10:8848 #nacos地址config:server-addr: 192.168.56.10:8848 #nacos地址 配置中心auto-refresh: true # 是否自动刷新,默认为 falsesentinel:transport:client-ip: 192.168.56.1dashboard: 192.168.56.10:8858port: 8719eager: true# Sentinel 规则持久化datasource:ds1:nacos:server-addr: 192.168.56.10:8848dataId: test11groupId: DEFAULT_GROUPdata-type: json
#            流控rule-type: flowdegrade:nacos:server-addr: localhost:8848dataId: ${spring.application.name}-degrade-rulesgroupId: SENTINEL_GROUP#            降级rule-type: degradesystem:nacos:server-addr: localhost:8848dataId: ${spring.application.name}-system-rulesgroupId: SENTINEL_GROUP#            系统rule-type: systemauthority:nacos:server-addr: localhost:8848dataId: ${spring.application.name}-authority-rulesgroupId: SENTINEL_GROUP#            授权rule-type: authorityparam-flow:nacos:server-addr: localhost:8848dataId: ${spring.application.name}-param-flow-rulesgroupId: SENTINEL_GROUP#            热点rule-type: param-flow

新建配置

[{// 资源名"resource": "/test",// 针对来源,若为 default 则不区分调用来源"limitApp": "default",// 限流阈值类型(1:QPS;0:并发线程数)"grade": 1,// 阈值"count": 1,// 是否是集群模式"clusterMode": false,// 流控效果(0:快速失败;1:Warm Up(预热模式);2:排队等待)"controlBehavior": 0,// 流控模式(0:直接;1:关联;2:链路)"strategy": 0,// 预热时间(秒,预热模式需要此参数)"warmUpPeriodSec": 10,// 超时时间(排队等待模式需要此参数)"maxQueueingTimeMs": 500,// 关联资源、入口资源(关联、链路模式)"refResource": "rrr"}
]
[{// 资源名"resource": "/test1","limitApp": "default",// 熔断策略(0:慢调用比例,1:异常比率,2:异常计数)"grade": 0,// 最大RT、比例阈值、异常数"count": 200,// 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)"slowRatioThreshold": 0.2,// 最小请求数"minRequestAmount": 5,// 当单位统计时长(类中默认1000)"statIntervalMs": 1000,// 熔断时长"timeWindow": 10}
]
[{// 资源名"resource": "/test1",// 限流模式(QPS 模式,不可更改)"grade": 1,// 参数索引"paramIdx": 0,// 单机阈值"count": 13,// 统计窗口时长"durationInSec": 6,// 是否集群 默认false"clusterMode": 默认false,// "burstCount": 0,// 集群模式配置"clusterConfig": {// "fallbackToLocalWhenFail": true,// "flowId": 2,// "sampleCount": 10,// "thresholdType": 0,// "windowIntervalMs": 1000},// 流控效果(支持快速失败和匀速排队模式)"controlBehavior": 0,// "limitApp": "default",// "maxQueueingTimeMs": 0,// 高级选项"paramFlowItemList": [{// 参数类型"classType": "int",// 限流阈值"count": 222,// 参数值"object": "2"}]}
]
[{// RT"avgRt": 1,// CPU 使用率"highestCpuUsage": -1,// LOAD"highestSystemLoad": -1,// 线程数"maxThread": -1,// 入口 QPS"qps": -1}
]
[{// 资源名"resource": "sentinel_spring_web_context",// 流控应用"limitApp": "/test",// 授权类型(0代表白名单;1代表黑名单。)"strategy": 0}
]

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

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

相关文章

Vue3.0(二):Vue组件化基础 - 脚手架

Vue组件化基础 - 脚手架 Vue的组件化 我们在处理一些任务量比较庞大的工作时候&#xff0c;会将工作内容进行拆分&#xff0c;分步骤完成 而组件化的思想正式如此&#xff0c;对于一个庞大的项目&#xff0c;我们可以将其拆分成一个个的小功能&#xff0c;分步骤进行实现 组…

MySQL数据库基础第二篇(函数)

文章目录 一、函数介绍二、字符串函数1.练习代码2.读出结果 三、数值函数1.练习代码2.读出结果 四、日期函数1.练习代码2.读出结果 五、流程控制函数1.练习代码2.读出结果 在当代技术世界中&#xff0c;掌握数据库设计和操作的知识和技能&#xff0c;尤其是对SQL的理解&#xf…

react 之 useInperativeHandle

useInperativeHandle是通过ref暴露子组件中的方法 1.场景说明-直接调用子组件内部的方法 import { forwardRef, useImperativeHandle, useRef } from "react"// 子组件const Son forwardRef((props, ref) > {// 实现聚焦逻辑const inputRef useRef(null)const …

【C++】C++入门 — 类和对象初步介绍

类和对象 1 类的作用域2 类的实例化3 类对象模型4 this指针介绍&#xff1a;特性&#xff1a; Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;下一篇文章见&#xff01;&#xff01;&#xff01; 1 类的作用域 类定义了一个新的作用域&#xff0c;类的…

openGauss学习笔记-213 openGauss 性能调优-总体调优思路

文章目录 openGauss学习笔记-213 openGauss 性能调优-总体调优思路213.1 调优思路概述213.2 调优流程 openGauss学习笔记-213 openGauss 性能调优-总体调优思路 213.1 调优思路概述 openGauss的总体性能调优思路为性能瓶颈点分析、关键参数调整以及SQL调优。在调优过程中&…

uniapp 高德地图显示

1. uniapp 高德地图显示 使用前需到**高德开放平台&#xff08;https://lbs.amap.com/&#xff09;**创建应用并申请Key   登录 高德开放平台&#xff0c;进入“控制台”&#xff0c;如果没有注册账号请先根据页面提示注册账号   打开 “应用管理” -> “我的应用”页面…

vue 渲染多列表格,拖动加载

vue在使用el-table渲染多列&#xff08;几千列&#xff09;表格时&#xff0c;页面会十分卡顿&#xff0c;使用html原生表格拖动滚动条加载列&#xff0c;可以解决这个问题 后端接口返回的数据格式如下&#xff1a; line_data中的数据title对应index_title里的内容 <temp…

Linux---yum命令详解

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1.概念2.yum的配置信…

【开源】WordPress一键崩溃宕机插件(整活娱乐)

插件介绍 可一键实现Wordpress崩溃宕机的整活向插件&#xff08;请勿用于非法途径&#xff0c;仅供整活娱乐&#xff09;。鼓励关注网站性能的提升&#xff0c;以提供更好的用户体验&#xff0c;提倡为用户提供良好体验和高效速度的原则。 介绍 长期以来&#xff0c;人们都在…

【Vue】3-1、Vue 3 简介

一、Vue 3 的优势 Vue 2 Options API 的缺陷&#xff1a; 一个功能往往需要在不同的 vue 配置项中定义属性和方法&#xff0c;比较分散&#xff0c;需求简单还好&#xff0c;清晰明了&#xff1b;但是需求复杂之后&#xff0c;就会多出 watch&#xff0c;computed&#xff0c;i…

两次NAT

两次NAT即Twice NAT&#xff0c;指源IP和目的IP同时转换&#xff0c;该技术应用于内部网络主机地址与外部网络上主机地址重叠的情况。 如图所示&#xff0c;两次NAT转换的过程如下: 内网Host A要访问地址重叠的外部网络Host B&#xff0c;Host A向位于外部网络的DNS服务器发送…

力扣面试150 只出现一次的数字Ⅱ 哈希 统计数位 DFA有穷自动机

Problem: 137. 只出现一次的数字 II 文章目录 思路&#x1f496; 哈希&#x1f496; 位数统计&#x1f496; DFA 状态机 思路 &#x1f468;‍&#x1f3eb; 参考 &#x1f496; 哈希 ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) cl…

【EVP】Explicit Visual Prompting for Low-Level Structure Segmentations

目录 &#x1f347;&#x1f347;0.简介 &#x1f337;&#x1f337;1.研究动机 &#x1f34b;&#x1f34b;2.主要贡献 &#x1f353;&#x1f353;3.网络结构 &#x1f36d;3.1整体结构 &#x1f36d;3.2高频分量计算 &#x1f36d;3.3显示视觉提示EVP &#x1f342;&…

【Java八股文面试系列】JVM-内存区域

目录 Java内存区域 运行时数据区域 线程独享区域 程序计数器 Java 虚拟机栈 StackFlowError&OOM 本地方法栈 线程共享区域 堆 GCR-分代回收算法 字符串常量池 方法区 运行时常量池 HotSpot 虚拟机对象探秘 对象的创建 对象的内存布局 句柄 Java内存区域 运…

2024年美赛数学建模F题思路分析 - 减少非法野生动物贸易

# 1 赛题 问题F&#xff1a;减少非法野生动物贸易 非法的野生动物贸易会对我们的环境产生负面影响&#xff0c;并威胁到全球的生物多样性。据估计&#xff0c;它每年涉及高达265亿美元&#xff0c;被认为是全球第四大非法交易。[1]你将开发一个由数据驱动的5年项目&#xff0c…

git命令远程仓库推送本地项目报错了,解决方案

如果你在使用git命令上传本地项目到远程仓库遇到了如下错误&#xff1a; Updates were rejected because the tip of your current branch is behind。n 别慌&#xff0c;肯定是你的远程仓库里面有原始文件&#xff0c;需要你提前进行一下合并操作&#xff0c;然后才能使用pu…

离线数仓-数据治理

目录 一、前言 1.1 数据治理概念 1.2 数据治理目标 1.3 数据治理要解决的问题 1.3.1 合规性 元数据合规性 数据质量合规性 数据安全合规性 1.3.2 成本 存储资源成本 计算资源成本 二、数据仓库发展阶段 2.1 初始期 2.2 扩张期 2.3 缓慢发展期 2.4 变革期 三、…

华为机考入门python3--(5)牛客5-进制转换

分类&#xff1a;数字 知识点&#xff1a; 十六进制转int num int(hex_num, 16) int转十六进制 hex_num hex(num) 题目来自【牛客】 hex_num input().strip() dec_num int(hex_num, 16) print(dec_num) by 软件工程小施同学

挖矿系列:细说Python、conda 和 pip 之间的关系

继续挖矿&#xff0c;挖金矿&#xff01; 1. Python、conda 和 pip Python、conda 和 pip 是在现代数据科学和软件开发中常用的工具&#xff0c;它们各自有不同的作用&#xff0c;但相互之间存在密切的关系&#xff1a; Python&#xff1a;是一种解释型、面向对象的高级程序设…