JMeter取样器深度解析:从HTTP到TCP,精准模拟协议的性能测试核心
2026/8/5 4:17:52 网站建设 项目流程

1. 项目概述:从“会用”到“精通”的取样器进阶

如果你已经跟着前面的系列文章,搭建好了Jmeter环境,录制或编写了几个简单的脚本,并且成功跑起来看到了聚合报告里的数据,那么恭喜你,你已经迈出了性能测试的第一步。但接下来,一个核心问题就会浮现出来:我的脚本真的能准确模拟用户行为吗?我发送的请求,和真实场景下的请求,到底有没有差别?

这个问题的答案,很大程度上就藏在“取样器”里。在Jmeter的世界里,取样器是脚本的“发动机”,是所有请求的发起者。很多人对取样器的理解,可能还停留在“哦,就是那个发HTTP请求的东西”,或者“我右键添加一个HTTP请求,填上URL和参数就行了”。这种认知,足以让你完成一些简单的测试任务,但一旦遇到复杂的业务场景、特殊的协议或者需要精准控制请求细节时,就会立刻捉襟见肘。

我见过太多测试脚本,因为取样器配置不当,导致测试结果完全失真。比如,一个需要保持长连接的WebSocket接口,却用了普通的HTTP请求取样器去压测,结果TPS(每秒事务数)高得离谱,但实际服务端可能早就因为连接数爆满而崩溃了。又比如,测试一个文件上传接口,没有正确设置multipart/form-data的编码和文件路径,导致请求根本发不出去,还一直报一些让人摸不着头脑的400错误。

所以,这篇“取样器详解”,目的就是帮你把Jmeter这个最核心的部件彻底拆开、揉碎了看。我们不只讲怎么“填框”,更要讲清楚每个配置项背后的网络原理和业务含义。我会结合我这些年踩过的坑和总结的经验,带你从“知道有这么个东西”,升级到“明白为什么这么配”,最终达到“能根据业务场景灵活选用和调优”的境界。无论你是刚入门的新手,还是想深化理解的进阶者,这篇文章都能帮你把Jmeter脚本的“发动机”调校得更精准、更有力。

2. 取样器核心原理与设计思路拆解

在深入每个具体取样器之前,我们必须先建立起一个顶层的认知框架:Jmeter的取样器到底是什么?它在整个性能测试模型中扮演什么角色?

2.1 取样器的本质:协议模拟器与数据发生器

你可以把Jmeter想象成一个高度可编程的“机器人集群”。每个线程(虚拟用户)都是一个机器人,而取样器,就是给这个机器人下达的“具体动作指令”。这个指令的核心是:“请按照某种特定的协议规则,向目标服务器发送一段数据,并等待并解析它的回应。”

因此,取样器的设计首要目标是精确模拟协议。HTTP、HTTPS、FTP、JDBC、TCP、Java请求……每一种协议都有其严格的数据包格式、连接建立方式、认证机制和状态管理逻辑。Jmeter内置的取样器,本质上就是对这些协议客户端行为的封装。一个设计良好的取样器,应该能让测试者无需关心底层Socket编程的细节,只需关注业务层面的参数(如URL、SQL语句、报文内容),就能生成符合协议规范的请求。

其次,取样器是测试数据的出口。我们参数化后的变量、前置处理器生成的动态数据、配置元件定义的默认值,最终都要通过取样器发送出去。取样器如何组装这些数据,是否进行编码转换,是否添加了必要的协议头,直接决定了服务器接收到的数据是否“正确”。

2.2 方案选型:为何Jmeter内置如此多的取样器?

你可能会问,既然HTTP这么通用,为什么Jmeter不做一个“万能取样器”,而是提供了几十种不同的取样器?这背后是性能测试领域的一个核心思想:专用化优于通用化

  1. 协议效率与准确性:一个专用的FTP取样器,可以更好地处理文件传输的被动/主动模式、二进制/ASCII模式切换,而用HTTP取样器去模拟FTP操作,不仅极其困难,而且根本无法准确衡量FTP服务器的真实性能。
  2. 资源管理:像“JDBC请求”取样器,它内部封装了数据库连接池的管理。你可以配置最大连接数、超时时间、验证查询等。如果让你用通用的“BeanShell取样器”去写JDBC调用,光是一个稳健的连接池实现就够你折腾半天,且极易出现资源泄漏,影响测试稳定性。
  3. 结果解析与度量:不同的协议,成功的标准不同。HTTP看状态码,JDBC看是否抛出SQL异常,TCP可能要看返回的特定字节。专用取样器内置了针对该协议的成功/失败判断逻辑,并能提取出对该协议有意义的度量数据(如SQL执行时间、响应字节数中的有效数据部分)。
  4. 易用性:为特定协议提供专用的GUI配置界面,大大降低了使用门槛。试想一下,如果让你在一个文本框里手动编写一个完整的SOAP XML信封并通过HTTP发送,出错概率有多高?而“SOAP/XML-RPC请求”取样器提供了结构化的输入框,降低了出错率。

因此,面对一个测试需求,我们的选型思路应该是:优先寻找与协议完全匹配的内置取样器。如果没有,再考虑用“JSR223取样器”或“BeanShell取样器”配合对应的语言库(如用Groovy写一个Redis客户端调用)来实现。最后,万不得已时,才使用最原始的“TCP取样器”或“HTTP请求”去手动拼装报文。

2.3 核心设计考量:面向性能与可维护性

在设计测试脚本时,对取样器的配置需要平衡以下几个点:

  • 真实性 vs. 简洁性:是否要模拟浏览器一样携带所有的Header(如Accept-Encoding: gzip)?对于压力测试,有时为了减少网络带宽对结果的影响,我们会省略一些非必要的Header。但对于功能或正确性验证,则必须保证请求的真实性。
  • 灵活性 vs. 可读性:大量使用${变量}引用能让脚本非常灵活,但过度使用也会让脚本难以阅读和维护。建议为变量起有意义的名称,并在“用户定义的变量”或CSV文件中做好注释。
  • 资源消耗:像“SMTP取样器”会创建邮件会话,“JDBC请求”会占用数据库连接。在线程组中设置合理的线程数、循环次数和ramp-up时间,避免瞬间创建过多资源把测试机或服务器拖垮。

注意:不要盲目追求使用“高级”或“万能”的取样器。用对的,比用贵的、用复杂的更重要。一个配置正确的HTTP请求取样器,远比一个错误配置的“JSR223取样器”脚本要可靠和高效。

3. 核心取样器深度解析与实操要点

Jmeter的取样器家族庞大,但常用的核心成员也就十来个。我们挑出最常用、也最容易配置出问题的几个,进行深度拆解。

3.1 HTTP请求:Web测试的基石

这是使用频率最高的取样器,没有之一。它的界面看似简单,但每个字段都有讲究。

1. 协议、服务器名称/IP、端口号这是最基本的三要素。常见错误是使用了http协议却访问443端口,或者服务器名填写了带http://前缀的完整URL。

  • 协议httphttps。如果是https,Jmeter会自动处理SSL/TLS握手,你通常不需要额外配置客户端证书,除非服务端有强制要求。
  • 服务器名称/IP:填写域名或IP地址,不要包含http://。例如api.example.com192.168.1.100
  • 端口号:HTTP默认80,HTTPS默认443。如果服务使用非标准端口,必须明确指定。

2. HTTP请求方法GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS等。选择错误会导致请求被服务器拒绝(如用GET请求一个需要提交body的API)。

  • GET:参数通常放在“路径”后面,或写在“参数”表中,会以?key1=value1&key2=value2的形式附加在URL后。GET请求不应有请求体
  • POST/PUT等:参数可以放在“参数”表(表单格式application/x-www-form-urlencoded),也可以放在“消息体数据”中(如JSON、XML)。两者不要混用。

3. 路径指的是URL中域名之后的部分。以https://api.example.com/v1/users/login为例,路径应填写/v1/users/login。这里经常需要拼接动态变量,如/v1/users/${user_id}/profile

4. 参数(Parameters) vs. 消息体数据(Body Data)这是最容易混淆的地方。

  • “参数”表:适用于application/x-www-form-urlencoded格式的表单提交。当你选择POST方法并在这里填参数时,Jmeter会自动将Content-Type头设置为application/x-www-form-urlencoded,并将参数编码为key=value&的形式放在请求体中。
  • “消息体数据”:一个纯文本区域,用于放置原始的请求体内容,如JSON字符串、XML文档或自定义格式。你需要手动在“HTTP信息头管理器”中添加正确的Content-Type,例如Content-Type: application/json

实操心得:99%的现代RESTful API都使用JSON格式。我的习惯是,对于这类请求,永远使用“消息体数据”,并配合“HTTP信息头管理器”设置Content-Type: application/json。这样最清晰,也最不容易出错。避免使用“参数”表来模拟JSON提交,那会导致格式错误。

5. 文件上传测试文件上传接口时,需要用到“文件上传”标签页。

  • 文件路径:可以是绝对路径,也可以是相对于JMeter启动目录的相对路径。建议使用绝对路径,或者使用${__P(project.dir,)}等属性来定义项目根目录,再拼接相对路径,以增强脚本的可移植性。
  • 参数名称:这个名称必须和服务器端接口期望的multipart表单字段名完全一致。通常由后端开发定义,比如file
  • MIME类型:如image/png,text/plain。填写正确有助于服务器解析。如果不确定,可以抓包查看浏览器上传时的值,或使用application/octet-stream(二进制流)作为通用类型。

3.2 JDBC请求:数据库性能的直接探针

当需要测试存储过程、复杂查询或直接验证数据库层性能时,JDBC请求取样器不可或缺。

1. 配置核心四要素它必须和“JDBC连接配置”元件(通常放在线程组开头)配合使用。

  • Variable Name:与“JDBC连接配置”元件中定义的变量名绑定。这是它们建立联系的桥梁。
  • SQL Query:填写你需要执行的SQL语句。可以是SELECT,INSERT,UPDATE,DELETE,也可以是调用存储过程的{call procedure_name(?,?)}
  • Parameter values:如果SQL中有占位符?,在这里按顺序填写值。支持变量,如${user_id}
  • Parameter types:必须与Parameter values一一对应,指定每个参数的数据类型,如VARCHAR,INTEGER。类型不匹配会导致执行错误。

2. 结果处理与变量提取

  • Variable names:这是一个非常强大但易错的功能。如果你执行的是SELECT语句,可以在这里填写一个变量名列表(用逗号分隔),Jmeter会将结果集第一行的各列值,分别赋值给这些变量。
    • 例如:SQL是SELECT id, name FROM users WHERE email = ?Variable names填写db_user_id, db_user_name
    • 执行后,就可以用${db_user_id}${db_user_name}来引用查询到的值了。
  • Result variable name:如果你需要处理多行结果集,可以指定一个变量名(如resultSet),结果集的所有行会以对象形式存储在这个变量中,后续可以通过BeanShell或JSR223脚本进行复杂处理。

注意事项:数据库性能测试要格外小心!

  1. 清理数据INSERT测试一定要有对应的清理机制(如用tearDown线程组执行DELETE),避免产生大量垃圾数据。
  2. 使用测试库:绝对不要在生产数据库上直接进行压测。
  3. 关注连接池:在“JDBC连接配置”中合理设置Max Number of Connections。设置过小会成为瓶颈,设置过大会压垮数据库。通常从与线程数相当的值开始调整。
  4. SQL本身要有代表性:测试的SQL应该是业务中最常用或最复杂的那些。

3.3 TCP取样器:测试自定义协议的神器

很多传统系统或物联网设备使用自定义的TCP协议进行通信(比如定长的二进制报文)。这时,HTTP取样器就无能为力了,TCP取样器是唯一选择。

1. 核心配置

  • TCPClient classname:这是TCP取样器的“大脑”,决定了如何序列化你输入的文本。最常用的是org.apache.jmeter.protocol.tcp.sampler.TCPClientImpl,它支持文本和16进制。
    • 如果你发送的是纯文本(如XML字符串),使用这个实现,并在“文本行结束符”处填写服务器期望的结束符(如\n)。
    • 如果你发送的是16进制原始数据,必须使用org.apache.jmeter.protocol.tcp.sampler.BinaryTCPClientImpl
  • 要发送的文本:输入你要发送的报文内容。如果使用BinaryTCPClientImpl,这里需要填写16进制字符串,不带0x前缀,且字节之间通常用空格分隔,例如01 02 AB CD
  • 连接超时、响应超时:根据网络状况和服务端处理能力设置。测试内网服务可以设短些(如2000ms),测试复杂业务或网络不佳时需加长。

2. 16进制报文实战假设服务器协议规定,报文头两个字节是长度,后面是JSON数据。

  1. 首先,你需要用代码(如一个前置JSR223处理器)计算出JSON字符串的字节长度。假设JSON是{"cmd": "ping"},长度是14字节(注意,中文字符占多个字节)。
  2. 将长度14转换为16进制的00 0E(假设是双字节大端序)。
  3. 将JSON字符串转换为16进制。{"cmd": "ping"}的16进制表示(UTF-8编码)大概是7b 22 63 6d 64 22 3a 20 22 70 69 6e 67 22 7d(可以通过在线工具或脚本获取)。
  4. 在TCP取样器的“要发送的文本”中,填入:00 0E 7b 22 63 6d 64 22 3a 20 22 70 69 6e 67 22 7d
  5. TCPClient classname 选择BinaryTCPClientImpl

踩坑记录:TCP测试最大的坑就是编解码和字节序。务必和开发人员确认清楚:

  • 报文是文本还是二进制?
  • 文本编码是UTF-8还是GBK?
  • 长度字段占几个字节?是大端序(Big-endian)还是小端序(Little-endian)?
  • 服务器期望的结束符是什么?(有的没有结束符,靠长度判断;有的以\n\r\n结束)。 一个字符的差异都可能导致整个请求被服务器拒绝。强烈建议先用Wireshark抓包,对比成功请求的原始16进制流,来验证你构造的报文是否正确。

3.4 JSR223取样器:终极灵活性的双刃剑

当内置取样器都无法满足需求时,JSR223取样器(或较旧的BeanShell取样器)提供了用编程语言(Groovy、Java、JavaScript等)编写任意逻辑的能力。它功能强大,但滥用也会导致脚本性能低下、难以维护。

1. 为何选择Groovy?在JSR223中,强烈推荐使用Groovy语言。因为Jmeter为Groovy提供了持续的优化和缓存支持,其执行效率远高于BeanShell和JavaScript。从Jmeter 3.1开始,Groovy就是默认的、也是性能最好的脚本语言。

2. 典型应用场景

  • 调用外部Java库:比如需要用到特定的加密算法、压缩库或SDK。
  • 实现复杂协议:例如,模拟一个Redis客户端发送GET/SET命令。
  • 处理复杂逻辑:根据前一个请求的响应,动态生成下一个请求的极其复杂的参数。
  • 直接进行系统调用(谨慎使用):比如执行一个shell命令并获取结果。

3. 一个简单的Groovy示例:生成时间戳签名假设某个API需要将当前时间戳作为签名参数。

// 获取当前时间戳(毫秒) long timestamp = System.currentTimeMillis(); // 假设签名算法是 MD5(secret_key + timestamp) import java.security.MessageDigest def secret = "my_secret_key"; def input = secret + timestamp; MessageDigest md = MessageDigest.getInstance("MD5"); byte[] digest = md.digest(input.getBytes("UTF-8")); // 将字节数组转换为16进制字符串 def signature = digest.encodeHex().toString(); // 将计算出的变量存入Jmeter变量中,供后续取样器使用 vars.put("timestamp", timestamp.toString()); vars.put("signature", signature); // 采样器成功 SampleResult.setSuccessful(true);

在脚本中,你可以通过${timestamp}${signature}来引用这些值。

4. 性能与资源警告JSR223取样器每次执行都会解释/编译脚本,即使有缓存,其开销也远大于原生Java实现的取样器。

重要原则能使用内置取样器实现的,绝不要用JSR223取样器。仅在确实没有其他选择时才使用它。对于需要复杂逻辑的情况,尽量将逻辑放在“JSR223前置处理器”中,计算好变量,再由一个轻量的HTTP取样器去发送请求。

4. 高级配置与性能调优要点

掌握了单个取样器的使用,我们还需要从全局视角看如何配置它们,才能发挥出最佳性能,获得准确的测试结果。

4.1 HTTP请求默认值:提升脚本可维护性

这是一个配置元件,通常放在线程组的最开始。它的作用是为你作用域内的所有HTTP请求取样器设置默认值

  • 用法:在“HTTP请求默认值”中填写协议、服务器、端口、路径前缀等公共部分。
  • 好处
    1. 可维护性:如果测试服务器地址变了,你只需要修改这一个地方,而不是成百上千个HTTP请求取样器。
    2. 简洁性:在具体的HTTP请求中,你只需要填写差异部分(如具体的API路径/login),公共部分会自动继承。
  • 注意:如果某个HTTP请求取样器自己填写了相同的字段(如服务器地址),则会覆盖默认值。这是符合直觉的。

4.2 连接管理与超时设置

这些设置藏在“高级”标签页或“HTTP请求默认值”中,但对性能影响巨大。

  • 实现(Implementation)
    • HttpClient4(默认):功能强大,支持连接池、认证等。性能测试首选
    • Java:旧实现,功能少,不稳定,不推荐使用
  • 连接(Connect Timeout):建立TCP连接的最大等待时间。网络不稳定或服务器连接池满时,这个值需要调大。默认值可能偏小,在压力测试下可适当增加至5000-10000ms。
  • 响应(Response Timeout):从发送请求完毕到接收完响应数据的最大等待时间。这是判断“请求超时”的依据。应根据接口的业务逻辑复杂度来设置。一个简单的查询接口可能2秒,一个生成报告的后台任务可能需要60秒以上。
  • 从资源池重用连接(Use KeepAlive)务必勾选。这允许Jmeter复用TCP连接发送多个HTTP请求,模拟浏览器行为,并大幅减少连接建立和断开的开销。不勾选会导致每次请求都进行TCP三次握手和四次挥手,性能会急剧下降,且不符合真实用户场景。

4.3 重定向与自动跳转

  • 自动重定向:如果勾选,当收到3xx状态码(如302)时,Jmeter会自动向Location头指定的新URL发起一个新的GET请求(即使原请求是POST)。这个新请求不会被记录为一个独立的取样器结果,其时间和数据会合并到原始请求中。这适用于你只关心最终结果的场景。
  • 跟随重定向:如果勾选,Jmeter也会自动跳转,但每次跳转都会被记录为一个独立的取样器结果。这让你能清楚地看到每次跳转的耗时,但也会使结果树中的样本数变多。

如何选择:在性能测试中,为了真实模拟用户,通常两者都勾选(“跟随重定向”包含了“自动重定向”的功能)。如果你需要分析链路上每一步的性能,就勾选“跟随重定向”。如果你只关心整个操作的最终耗时,可以只勾选“自动重定向”。

4.4 源地址绑定(Source Address)

这是一个高级功能,用于模拟来自不同IP地址的请求。在“高级”标签页的“源地址”中,你可以选择特定的IP或网卡。

  • 用途:测试负载均衡策略,或验证基于IP的防火墙/限流规则。
  • 实现:通常需要你的测试机有多个IP地址(虚拟IP或物理网卡)。你可以使用“IP欺骗”技术,或者更简单地,启动多个Jmeter实例,每个实例绑定不同的源地址。
  • 注意:滥用此功能可能导致网络配置复杂化。在大多数内部压测中,不需要设置。

5. 常见问题排查与调试技巧实录

无论配置多么仔细,在实际执行中总会遇到各种问题。下面是我总结的一些常见错误和排查思路。

5.1 请求发送失败类问题

问题现象可能原因排查步骤
Response code: Non HTTP response code: java.net.UnknownHostExceptionDNS解析失败。服务器地址写错,或测试机网络配置问题。1.ping一下你填写的服务器名或IP,看是否通。
2. 检查Jmeter所在机器的/etc/hosts文件或DNS设置。
Response code: Non HTTP response code: java.net.ConnectException: Connection refused (Connection refused)连接被拒绝。服务器没启动,或端口错误,或防火墙拦截。1. 用telnet IP 端口命令测试端口连通性。
2. 检查服务器进程是否在运行(netstat -tlnp | grep 端口)。
3. 检查服务器和客户端的防火墙规则。
Response code: 400错误的请求。请求格式不符合服务器要求。这是最高频的错误
1. 检查Content-Type请求头是否与消息体格式匹配(JSON、表单等)。
2. 检查请求体(Body Data)的JSON/XML格式是否正确(可用在线格式化工具验证)。
3. 检查URL路径和参数是否有非法字符(需URL编码)。
4.抓包对比:用Fiddler/Charles抓一个浏览器正常请求的包,与Jmeter的请求详情(在“查看结果树”中点击请求,看“请求”标签页的原始数据)逐字节对比。
Response code: 404资源未找到。1. 检查URL路径是否拼写错误。
2. 检查服务器上对应的API路由是否存在。
3. 如果是RESTful API,检查请求方法(GET/POST等)是否正确。
Response code: 500服务器内部错误。1. 查看响应数据,通常会有具体的错误栈信息。
2. 检查你发送的参数是否导致了服务器端业务逻辑异常(如查询了不存在的ID)。
3. 这可能是服务端bug,需要联系开发查看服务器日志。

5.2 性能结果异常类问题

问题现象可能原因排查步骤
TPS(每秒事务数)远低于预期,但服务器资源(CPU、内存)使用率很低。瓶颈在测试机本身或脚本逻辑1.监控测试机资源:用top或任务管理器看Jmeter进程的CPU、内存、网络IO是否已吃满。一台机器能发出的压力是有限的。
2.检查脚本:是否在取样器中或前后处理器里写了低效的、阻塞的代码(如循环等待、同步锁)?
3.检查断言:是否使用了耗时的“响应断言”或“XPath断言”处理大量数据?
4.简化脚本:先注释掉所有监听器(如“查看结果树”),用最简脚本(只发请求)测试,看TPS是否提升。
响应时间随着测试进行越来越长。服务器或数据库连接池耗尽、内存泄漏、或产生了资源竞争1.检查服务器监控:观察服务器连接数、线程数、数据库连接池使用率是否在持续增长。
2.检查Jmeter配置:是否没有使用HTTP连接复用(KeepAlive)?导致每次请求都新建连接。
3.检查测试逻辑:是否每个线程都在创建不可释放的资源(如打开了文件未关闭)?
出现大量SocketExceptionTimeout错误。网络不稳定,或服务器处理不过来,主动断开连接。1. 适当增加“连接超时”和“响应超时”时间。
2. 降低并发线程数,看错误是否消失。如果消失,说明服务器处理能力已达上限。
3. 检查网络链路是否有丢包(ping -t观察一段时间)。

5.3 调试技巧:让问题无所遁形

  1. 善用“查看结果树”:这是你最好的朋友。在调试阶段,务必添加它。

    • 请求标签页:查看Jmeter实际发送出去的原始请求(包括所有Header和Body)。与你预设的是否一致?这是排查400错误的关键。
    • 响应数据标签页:查看服务器返回的原始数据。对于非200的响应,这里常有错误信息。
    • 将“查看结果树”设置为“仅日志错误”:在正式压测时,这样既能捕获错误样本,又不会因为记录所有成功样本而产生巨大的内存和IO开销。
  2. 使用“Debug Sampler”和“Debug PostProcessor”:这两个元件可以输出所有Jmeter变量、属性、系统属性的值。当你不确定变量是否被正确赋值时,添加一个Debug Sampler,运行一下,在结果树里查看它的响应数据,一切一目了然。

  3. 分布式测试时,从一台机器开始:如果计划用多台机器分布式压测,务必先在一台机器上把脚本调试通过,确保逻辑正确,没有本地依赖(如写死的文件路径)。然后再扩展到多台机器,这样可以排除脚本本身错误和网络配置错误的干扰。

  4. 对比真实用户请求:始终使用Fiddler、Charles或浏览器开发者工具抓取一个真实的、成功的用户请求。用这个请求作为基准,来配置你的Jmeter取样器。对比两者的Header、Cookie、请求体,确保完全一致。

取样器是Jmeter脚本的基石,它的正确配置直接决定了性能测试的有效性和可信度。从简单的HTTP请求到复杂的TCP二进制报文,每一种取样器都有其特定的应用场景和配置陷阱。我希望通过这篇近万字的详解,不仅能让你知道每个输入框该怎么填,更能理解其背后的网络协议原理和性能影响。

记住,配置一个取样器不是终点,而是一个起点。真正的功夫在于,能根据业务场景,选择最合适的取样器,并配置出最贴近真实用户行为的请求。这需要不断地实践、踩坑和总结。当你下次再遇到一个陌生的协议或一个诡异的400错误时,希望这篇文章能成为你手边最可靠的排查指南。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询