【2.3】Java微服务:sentinel服务哨兵
✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。
🍎个人主页:Meteors.的博客
💞当前专栏:Java微服务
✨特色专栏: 知识分享
🥭本文内容:【2.3】Java微服务:sentinel服务哨兵
📚 ** ps ** : 阅读这篇文章如果有问题或者疑惑,欢迎各位在评论区提问或指出!
---------------------------------------------------------- 目录 --------------------------------------------------------------
目录
一、内容
二、Sentinel介绍
1.背景
2. 介绍
3. 特性
三. Sentinel的历史
四. Sentinel与Hystrix的对比
五. Sentinel核心
六、Sentinel控制台
1. 介绍
2. 功能
3. 文档
4. 控制台安装
1)进入下载页面
2)下载jar包
3)将jar包移动到合适目录并启动
七. 客户端接入控制台
1. 添加依赖
1)父工程中添加编辑
2)子工程中添加
3)添加配置文件
4)重启服务并发送一次请求
2. 定义资源
ps:资源属性
3. 定义规则
1)流量控制规则
2)熔断降级规则
3)热点参数规则
4)授权规则
5)系统保护规则
6)动态规则扩展
1. 支持
2. 本地文件中设置方式Demo
八. RestTemplate支持
1. 配置异常类
2. RestTemplate的声明位置加上注解
3.注释掉之前在方法上的声明
4. 增加流控进行测试
九. OpenFeign支持
1. 添加依赖
2. 开启Sentinel
参考文献
---------------------------------------------------------------------------------------------------------------------------------
一、内容

二、Sentinel介绍
1.背景
Netflix中多项开源产品已进入维护阶段,不再开发新的版本,就目前来看是没有什么问题的。但是从长远角度出发,我们还是需要考虑是否有可替代产品使用。比如本文中介绍Alibaba Sentinel就是一款高性能且轻量级的流量控制、熔断降级可替代方案。是一款面向云原生微服务的高可用流控防护组件
(Hystrix目前状态:不在主动开发,当前处于维护模式 ——摘录自Hystrix官网)
2. 介绍
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。(摘录自Sentinel官网)
3. 特性
Sentinel 具有以下特征:
丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
三. Sentinel的历史
- 2012 年,Sentinel 诞生,主要功能为入口流量控制。
- 2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。
- 2018 年,Sentinel 开源,并持续演进。
- 2019 年,Sentinel 朝着多语言扩展的方向不断探索,推出 C++ 原生版本,同时针对 Service Mesh 场景也推出了 Envoy 集群流量控制支持,以解决 Service Mesh 架构下多语言限流的问题。
- 2020 年,推出 Sentinel Go 版本,继续朝着云原生方向演进。
- 2021 年,Sentinel 正在朝着 2.0 云原生高可用决策中心组件进行演进;同时推出了 Sentinel Rust 原生版本。同时我们也在 Rust 社区进行了 Envoy WASM extension 及 eBPF extension 等场景探索。
- 2022 年,Sentinel 品牌升级为流量治理,领域涵盖流量路由/调度、流量染色、流控降级、过载保护/实例摘除等;同时社区将流量治理相关标准抽出到 OpenSergo 标准中,Sentinel 作为流量治理标准实现。
四. Sentinel与Hystrix的对比
| Sentinel | Hystrix | |
|---|---|---|
| 隔离策略 | 信号量隔离(并发线程数限流) | 线程池隔离/信号量隔离 |
| 熔断降级策略 | 基于响应时间、异常比率、异常数 | 基于异常比率 |
| 实时指标实现 | 滑动窗口(LeapArray) | 滑动窗口(基于 RxJava) |
| 规则配置 | 支持多种数据源 | 支持多种数据源 |
| 扩展性 | 多个扩展点 | 插件的形式 |
| 基于注解的支持 | 支持 | 支持 |
| 调用链路信息 | 支持同步调用 | 不支持 |
| 限流 | 基于 QPS / 并发数,支持基于调用关系的限流 | 有限支持 |
| 流量整形 | 支持慢启动、匀速器模式 | 不支持 |
| 系统负载保护 | 支持 | 不支持 |
| 控制台 | 开箱即用,可配置规则、查看秒级监控、机器发现等 | 较为简单 |
| 常见框架的适配 | Servlet、Spring Cloud、Dubbo、gRPC 等 | Servlet、Spring Cloud Netflix |
五. Sentinel核心
Sentinel 的使用可以分为两个部分:
核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 7 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持(见 主流框架适配)。
控制台(Dashboard):控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等。
六、Sentinel控制台
1. 介绍
Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。这里,我们将会详细讲述如何通过简单的步骤就可以使用这些功能。
2. 功能
Sentinel 控制台包含如下功能:
- 查看机器列表以及健康情况:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。
- 监控 (单机和集群聚合):通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
- 规则管理和推送:统一管理推送规则。
- 鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。
3. 文档
控制台 · alibaba/Sentinel Wiki · GitHubA powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件) - 控制台 · alibaba/Sentinel Wiki
https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0
4. 控制台安装
1)进入下载页面
2)下载jar包
3)将jar包移动到合适目录并启动
执行命令(注意版本要改为自己的,可以使用tab键补全):
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.5.jar
七. 客户端接入控制台
1. 添加依赖
1)父工程中添加
<!-- 父工程添加如下依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.5.RELEASE</version></dependency>2)子工程中添加
<!-- 在子工程中导入依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>3)添加配置文件
sentinel:transport:port: 8719dashboard: localhost:80804)重启服务并发送一次请求
然后刷新控制台就有显示了
2. 定义资源
ps:资源属性
重启服务后,刷新控制台就有显示资源了
Field 说明 默认值 resource 资源名,资源名是限流规则的作用对象 count 限流阈值 grade 限流阈值类型,QPS 模式(1)或并发线程数模式(0) QPS 模式 limitApp 流控针对的调用来源 default,代表不区分调用来源strategy 调用关系限流策略:直接、链路、关联 根据资源本身(直接) controlBehavior 流控效果(直接拒绝 / 排队等待 / 慢启动模式),不支持按调用关系限流 直接拒绝 clusterMode 是否集群限流 否
3. 定义规则
1)流量控制规则
(不推荐和这一样在控制台进行设置,这里的设置重启服务后会消失,推荐使用动态规则)
请求超过设置,触发限流方法(上文的method1)
2)熔断降级规则
熔断降级规则是远程调用奔溃了,就会调用熔断降级触发方法(上文的method2)
3)热点参数规则
热点参数规则是一种更细粒度的流控规则,它允许将规则具体到参数上
4)授权规则
根据调用来源来判断该次请求是否被允许,这时可以调用Sentinel的来源访问控制的功能。来源访问根据资源的请求来源(origin)限制资源是否通过。
设置禁止访问的来源:
添加配置类:
/*** 自定义来源处理规则*/ @Component public class MyRequestOriginParser implements RequestOriginParser {@Overridepublic String parseOrigin(HttpServletRequest httpServletRequest) {return httpServletRequest.getParameter("userName");} }
5)系统保护规则
系统保护规则是从应用级别的入口流量进行控制,从单台机器的总体 Load、RT、入口 QPS 和线程数四个维度监控应用数据,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(
EntryType.IN),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。系统规则支持以下的阈值类型:
- Load(仅对 Linux/Unix-like 机器生效):当系统 load1 超过阈值,且系统当前的并发线程数超过系统容量时才会触发系统保护。系统容量由系统的
maxQps * minRt计算得出。设定参考值一般是CPU cores * 2.5。- CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0)。
- RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
- 线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
- 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
6)动态规则扩展
1. 支持
Sentinel 目前支持以下数据源扩展:
- Pull-based: 动态文件数据源、Consul, Eureka
- Push-based: ZooKeeper, Redis, Nacos, Apollo, etcd
2. 本地文件中设置方式Demo
在yml文件中进行配置
datasource:ds1:file:file: classpath:flowRule.jsondata-type: jsonrule-type: flow增加并配置JSON文件
重启项目后,调用接口
八. RestTemplate支持
Spring Cloud Alibaba Sentinel 支持对 RestTemplate 调用的服务进行服务保护。需要在构造 RestTemplate Bean 时添加
@SentinelRestTemplate注解。1. 配置异常类
/*** sentinel异常工具类*/ public class ExceptionUtil {// 服务流量控制处理public static ClientHttpResponse handleException(HttpRequest request,byte[] body,ClientHttpRequestExecution execution,BlockException exception) {exception.printStackTrace();return new SentinelClientHttpResponse(JSON.toJSONString(new Order(333L, 333L, "333", 333, 3L, new ArrayList<>())));}// 服务熔断降级处理public static ClientHttpResponse fallback(HttpRequest request,byte[] body,ClientHttpRequestExecution execution,BlockException exception) {exception.printStackTrace();return new SentinelClientHttpResponse(JSON.toJSONString(new Order(444L, 444L, "444", 444, 4L, new ArrayList<>())));} }2. RestTemplate的声明位置加上注解
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class,fallback = "fallback", fallbackClass = ExceptionUtil.class)
3.注释掉之前在方法上的声明
4. 增加流控进行测试
九. OpenFeign支持
1. 添加依赖
<!-- spring cloud openfeign 依赖 --> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- spring cloud alibaba sentinel 依赖 --> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>2. 开启Sentinel
yml文件中添加两处地方:
# feign 开启 sentinel 支持 feign:sentinel:enabled:truecloud:sentinel:transport:port:8719dashboard:localhost:8080创建异常注解
/*** 服务熔断降级处理可以捕获异常*/ @Component publicclass ProductServiceFallbackFactory implements FallbackFactory<ProductService> {// 获取日志,在需要捕获异常的方法中进行处理Logger logger = LoggerFactory.getLogger(ProductServiceFallbackFactory.class);@Overridepublic ProductService create(Throwable throwable) {returnnew ProductService() {@Overridepublic Product selectProductById(Integer id) {return new new Order(333L, 333L, "333", 333, 3L, new ArrayList<>());}};}}服务接口类中添加注解即可
@FeignClient(value = "user-service", fallbackFactory = ProductServiceFallbackFactory.class)
参考文献
home | Sentinelhome
https://sentinelguard.io/zh-cn/index.html微服务系列之Sentinel服务哨兵今日份视频来啦,通过视频学习可真是一点不累,快点进来 ~
https://mp.weixin.qq.com/s?__biz=MzA4MDEwNTI1NA==&mid=2459057627&idx=1&sn=2c4b1d9d98b6ea847face29de41d3872&chksm=88cfc792bfb84e84a792ffaa1dd464603297e99f3eccb28f379794875daf985f2835376501d5&cur_album_id=1337276895993430016&scene=189#wechat_redirect
最后,
相关内容会陆续更新,希望文章对你有所帮助!
相关文章:
【2.3】Java微服务:sentinel服务哨兵
✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。 🍎个人主页:Meteors.的博客 💞当前专栏:Java微服务 ✨特色专栏: 知识分享 &…...
【C++】开源:abseil-cpp基础组件库配置使用
😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍abseil-cpp基础组件库配置使用。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下&#…...
【GPT-3 】创建能写博客的AI工具
一、说明 如何使用OpenAI API,GPT-3和Python创建AI博客写作工具。 在本教程中,我们将从 OpenAI API 中断的地方继续,并创建我们自己的 AI 版权工具,我们可以使用它使用 GPT-3 人工智能 (AI) API 创建独特的…...
[保研/考研机试] KY35 最简真分数 北京大学复试上机题 C++实现
题目链接: 最简真分数https://www.nowcoder.com/share/jump/437195121691719749588 描述 给出n个正整数,任取两个数分别作为分子和分母组成最简真分数,编程求共有几个这样的组合。 输入描述: 每组包含n(n<600&…...
算法备案后,企业需要做什么?合规与执行挑战
随着技术的迅猛发展,算法已经成为多数企业核心竞争力的一部分。但在技术进步的同时,我们也面临了算法透明度、公平性以及安全性的问题。因此,许多国家已经开始实施算法备案制度,以确保算法的应用满足一定的标准和规范。但在完成算…...
云原生应用程序的自动化管理和编排
云原生应用程序是一种为云环境设计的应用程序,它采用了如微服务、容器、可伸缩性和自动化等特性,以最大限度地提高效率和响应速度。本文将深入探讨云原生应用如何实现自动化管理和编排。 容器化 容器技术,如Docker,是云原生应用程…...
Spring项目整合过滤链模式~实战应用
代码下载 设计模式代码全部在gitee上,下载链接: https://gitee.com/xiaozheng2019/desgin_mode.git 日常写代码遇到的囧 1.新建一个类,不知道该放哪个包下 2.方法名称叫A,干得却是A+B+C几件事情,随时隐藏着惊喜 3.想复用一个方法,但是里面嵌套了多余的逻辑,只能自己拆出来…...
FFmpeg常见命令行(五):FFmpeg滤镜使用
前言 在Android音视频开发中,网上知识点过于零碎,自学起来难度非常大,不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》,结合我自己的工作学习经历,我准备写一个音视频系列blog。本文是音视频系…...
网络编程 tcp udp http编程流程 网络基础知识
讲解 网络基础知识网络编程tcp编程流程图示理解bind和accept函数理解监视套接字和链接套接字理解linux和window下的编程实现tcp特点 udp编程流程图示理解udp特点 http编程流程图示理解编程实现-网站服务器 网络基础知识 OSI分层:应用层 表示层 会话层 传输层 网络层…...
LaTeX基础学习笔记
LaTeX是一个文本编辑器。其类似于markdown,使用特殊标记和代码来修改文本格式,创建特殊字符等。可以使用overleaf在线LaTex编辑器编写LaTeX并转换为pdf文件(https://www.overleaf.com/) 同时推荐一个网站http://detexify.kirelab…...
zookeeper和kafka
目录 一、zookeeper理论 1.1、zookeeper定义 1.2、zookeeper工作机制 1.3、zookeeper特点 1.4、zookeeper的数据结构 1.5、zookeeper应用场景 1.6、zookeeper的选举机制 二、部署Zookeeper 集群 2.1、环境准备 2.2、安装 Zookeeper 2.3、修改配置文件 2.4、配置…...
服务器无法加载海康sdk依赖的问题
首先遇到的jna.jar和examples.jar无法加载的问题,尝试了很多方法无效,以下方法实测有效 其次是动态链接库无法加载的问题,而且是播放库,我的方法比较简单,netsdk加载出来就行了,播放库用不到,删…...
brew+nginx配置静态文件服务器
背景 一下子闲下来了,了解的我的人都知道我闲不下来。于是,我在思考COS之后,决定自己整一个本地的OSS,实现静态文件的访问。那么,首屈一指的就是我很熟的nginx。也算是个小复习吧,复习一下nginx代理静态文…...
JavaFx异常: Not on FX application thread; currentThread = Timer-0
我的定时器任务中有两个控件: FXML TextArea Display; FXML Label Label_Display; 执行下方代码会抛出:Exception in thread "Timer-0" java.lang.IllegalStateException: Not on FX application thread; currentThread Timer-0 Timer_tas…...
【Django】无法从“django.utils.encoding”导入名称“force_text”
整晚处理 Django 的导入错误。 我将把它作为提醒,希望处于相同情况的人数会减少。 原因 某些软件包版本不支持Django 4 请看下表并决定Django和Python的版本 方案 如果出现难以响应,或者更改环境麻烦,请尝试以下操作 例如出现以下错误 …...
docker-compose redis 一直启动失败
环境: centos 8.x 背景 使用docker-compose 来启动redis docker-compose.yml 如下: version: 3.3 services:redis:image: redis:latestrestart: alwayscontainer_name: redisports:- 6379:6379volumes:- ./data:/redis/data- ./redis.conf:/redis/re…...
使用GUI Guider工具在MCU上开发嵌入式GUI应用 (1) - GUI Guider简介及安装
使用GUI Guider工具在MCU上开发嵌入式GUI应用 (1) - GUI Guider简介及安装 受限于每篇文章最多只能贴9张图的限制,这个教程被拆分成了多篇文章连载发布,完整目录结构如下图x所示。后续会发布完整教程的pdf文件,敬请期待。 图x 完整教程文档…...
解决:django设置DEBUG=false时出现的问题
首先,我用的是django4.2,python3.10版本 本来,如果在settings.py中使用 DEBUG True,那么什么问题也没有,当然,这属于调试模式。 DEBUG True TEMPLATE_DEBUG DEBUGSTATIC_URL /static/ STATICFILES_DI…...
2023-08-10力扣每日一题
链接: 1289. 下降路径最小和 II 题意: 每一行选择一个数字,相邻行选择不能是同一列,求选择的数字和最小是多少 解: 每一行选择最小的次小的,下一行能加最小的(列坐标不冲突)就加…...
C#与halcon联合 缩放移动自适应图像
读取图片 //获取文件路径下的图片public HObject GetImgFromPath(string imgPath){HObject L_Img;HOperatorSet.GenEmptyObj(out L_Img);//清空图片L_Img.Dispose();//释放HOperatorSet.ReadImage(out L_Img, imgPath);//读取图片存入到l_imgreturn L_Img;}拉伸显示 //图片拉…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...





























