为 FMW 拉伸群集配置其他优化
虽然并非所有拓扑都是强制性的,但它们可以提高性能并改善某些特性和场景的行为。
在 Oracle WebLogic Server (WLS) 中配置超时
对于数据库中的事务处理、事务处理分支、企业 JavaBean (EJB) 方法调用、Web 服务等,都指定了超时限制。Oracle Fusion Middleware 拉伸集群部署对超时设置特别敏感,因为多个操作需要访问其他位置中的数据库。配置超时,以便:
- 它们考虑了系统中的延迟。
由于所涉及的延迟,您可能需要增加这些类型的系统中的超时。在拉伸集群模型中,两个站点都共享域设置;因此,需要使用超时来应对最坏情况。
- 它们在不同层的调用链中正确失效。
必须在系统的不同层中配置超时,以便适当的包含层能够正常工作。例如,如果将数据库超时设置为低于全局 WLS 超时的值,则事务处理 ID 可能在完成其他分支的工作之前从数据库中“删除”。
这些是不同层中的主要超时参数:
- 全局事务处理超时间
Oracle WebLogic Server 全局事务处理超时决定了分布式事务处理(全局事务处理)在 Oracle WebLogic Server 自动回退之前允许保持活动状态的最长持续时间(秒)。通过在编辑树的服务部分中选择 JTA (Java Transaction API) 并指定超时秒数,在 WebLogic 远程控制台中配置全局事务处理超时。
- XA 事务处理超时间
Oracle WebLogic Server 中使用 XA 数据源中的 XA 事务处理超时来设置数据源的事务处理分支超时。默认情况下,此值设置为 0(零),因此使用 WebLogic 全局事务处理超时。但是,如果有长时间运行的事务处理超过了 XA 资源的默认超时值,可能需要设置该事务处理。此值在事务处理选项卡中为每个 XA 数据源配置。
- 分布式锁定超时
数据库中的分布式锁定超时指定分布式事务处理等待锁定资源所需的时间(秒)。可以使用相应的
SQL ALTER语句修改参数 (distributed_lock_timeout)。
考虑到站点之间的任何网络延迟,将数据库的分布式锁定超时设置为足够长的时间,以实现最慢的事务处理。之后,使用以下规则将“XA 数据源”和“全局事务处理超时”设置为较低的值:
distributed_lock_timeout >= XA DS Timeout >= Global Transaction Timeout应用程序可以使用其他超时参数。例如,Oracle SOA 和 BPEL 具有以下附加超时参数,您必须考虑:
- syncMaxWaitTime
syncMaxWaitTime 是同步客户机等待响应的最长时间。此设置定义请求和响应操作在超时之前可以花费多长时间。如果 BPEL 流程在此时间内未收到回复,则活动将失败。要在 Oracle Enterprise Manager Fusion Middleware Control 中更改此值:
- 右键单击 SOA-infra ,然后选择 SOA 管理。
- 选择 BPEL 属性。
- 选择更多 BPEL 配置属性。
- 更新 syncMaxWaitTime 值(以秒为单位)。
- EJB 的超时
当涉及 BPEL EJB 方法时,这将指定事务处理超时(以秒为单位)(对于所有 BPEL EJB,默认值为 300)。按如下方式修改超时:
- 在 WebLogic Remote Console 监视树中,选择部署,然后选择应用程序管理。
- 展开 soa_infra 应用程序,然后展开 Configuration 和 Subdeployment 。
- 展开模块并选择特定的 BPEL EJB。
Global Transaction Timeout > BPEL EJB's transaction timeout > syncMaxWaitTime - Web 服务客户机的超时
Web 服务客户机必须配置有足够宽松且延迟最差的超时。例如,如果呼叫通过站点 1 需要 3 秒,但通过站点 2 需要 10 秒,则应将超时设置为至少 10 秒才能处理较慢的站点。
- BPEL 处理超时
如果 BPEL 流程使用特定的请求回复(同步)和仅接收(异步)超时,则必须根据最坏情况(当调用进入数据库延迟最高的站点时)定义它们。这些超时设置是在 BPEL 流程中定义的,不能为每个站点进行不同的设置。有关在 BPEL 流程中配置事件和超时的详细信息,请参阅 Oracle Fusion Middleware Developer's Guide for Oracle SOA Suite 。请参阅“探索更多”部分。
配置会话复制
某些应用程序(Web 应用程序、控制台(例如 Oracle SOA 作曲器、BPM 作曲器、BPM 工作区等)会大量使用 HTTP 会话对象。
Oracle Fusion Middleware (FMW) 拉伸集群部署的优势之一是在站点之间提供无缝故障转移。但是,跨区域的会话复制可能会导致系统性能下降。Oracle 建议定义两个不同的复制组(每个区域一个),以最大程度地减少跨两个站点的复制。
要配置会话复制组,请执行以下操作:
- 在 WebLogic Remote Console 编辑树中,依次选择环境和服务器。
- 选择 Server Name(服务器名称),然后选择 Cluster(集群)选项卡。
- 对于区域 1 中的每个服务器,请输入相同的复制组名称(例如 Region1RepGroup )。
- 对区域 2 中的服务器重复这些步骤,对所有服务器使用通用名称,但与区域 1 中使用的名称不同(例如 Region2RepGroup )。
请注意,使用复制组是将状态仅复制到同一站点中的服务器的最好方法,但不是确定性的方法。如果单个服务器在一个站点中可用,而其他服务器在另一个站点中可用,则跨区域进行复制,即使服务器在同一站点中重新联机,该会话也将继续进行复制。
为 JMS 配置就地重新启动
持久性存储对于 Oracle WebLogic Server (WLS) 服务器的正常运行至关重要。在就地重新启动时,如果持久性存储遇到错误,JMS 服务将尝试在同一服务器上重新启动,然后再尝试迁移到其他服务器。此方法比将整个 JMS 服务迁移到其他服务器更快,并且通常可以快速解决问题。
要为 JMS 持久性存储配置就地重新启动,相关的 JMS 服务器和持久性存储必须定位到可迁移目标。此可迁移目标必须使用 Restart on Failure (默认情况下未启用)。要配置此属性,请执行以下步骤:
- 连接到 WebLogic Remote Console
- 在“编辑树”中,依次选择环境和可迁移目标。
- 选择可迁移目标并启用失败时重新启动。
- 选择保存并提交更改。
配置 Oracle FMW SOA Suite JMS 适配器
Oracle 建议使用群集语法(例如:cluster:t3s://cluster_name)来简化配置。此方法通过允许适配器动态检索集群中活动服务器的当前列表来简化配置,从而确保高效的 JNDI 上下文检索。
如果系统密集使用 JMS 适配器并具有大型有效负载,建议将 JNDI URL 配置为仅包括每个区域中的本地服务器。这意味着在区域 1 中为区域 1 中的配置指定服务器,在区域 2 中为区域 2 中的配置指定服务器。此设置可确保站点上下文关联性,优化性能并减少延迟。
配置 Oracle FMW SOA Suite 文件适配器
此机制可确保同一文件一次仅由一台服务器处理,并且两个适配器实例不会同时写入同一文件。
在 Oracle Fusion Middleware (FMW) 拉伸集群拓扑中,每个站点都独立运行,使用自己的专用共享存储处理文件。但是,默认情况下,两个站点使用相同的数据源、模式和表进行文件锁定和互斥机制。
在出站操作中,利用共享数据库表是合适的,因为使用唯一的序列作为互斥体,以防止并发写入操作覆盖文件。
但是,入站操作可能会出现“正在处理”情况。任何站点中的文件适配器实例都可以将文件标记为“已阻止”。如果两个站点中存在相同的文件名,则此机制可以在两个位置阻止其处理,但该文件将仅用于其中一个位置。为了避免这种情况,有多种选择:
- 实施特定于站点的文件命名约定。在基于站点的文件名中使用唯一标识符,从而降低名称冲突和后续阻塞的可能性。
- 为文件适配器锁和互斥表为每个区域配置单独的方案,以确保文件锁定和互斥机制独立运行,从而防止跨站点阻塞。
- 将单独的数据库用于文件适配器锁定和互斥表,以确保文件处理元数据是单独管理的。
要将文件适配器配置为在每个区域中使用不同的数据库或单独的方案,必须创建相应的方案所有者和表,并建立新的数据源。区域 1 中的服务器将继续使用原始数据源,只有区域 2 中的部署计划将被修改为使用新数据源。
区域 1 中的服务器将使用原始数据源,而区域 2 中的服务器将使用新数据源。
配置 Oracle Fusion Middleware Oracle SOA Suite 内存中 SOA
这提高了这些业务流程的性能和可伸缩性,因为读写操作是从高速缓存中执行的。
BPEL 状态信息存储在 Oracle Coherence 高速缓存中并从中提取。进程状态仅在发生故障时写入数据库,或者使用写后线程定期写入数据库。
Oracle Fusion Middleware 拉伸集群拓扑不支持内存中 SOA,其中 Coherence 高速缓存的使用量必须很小,因为它对延迟非常敏感。
配置优化 WebLogic 数据库租赁
数据库租赁是用于支持自动服务迁移的核心机制,尤其适用于集群单例服务,例如 JMS 服务器或 JTA 事务处理恢复服务。它用于管理和协调集群中多个服务器上的这些单例服务的所有权。此机制使用数据库作为中心点,以可靠地跟踪和控制集群中的哪个服务器在任何给定时间“拥有”或管理特定的单例服务。这是通过在数据库中存储租赁记录来实现的,该记录由所属服务器定期更新(续订)。请参阅《 Administering Clusters for Oracle WebLogic Server 》中的 Leasing for Migratable Services 。
本指南前面提供的 GridLink 数据源配置可确保在发生数据库故障转移或切换时自动重新连接。但是,配置有数据库租赁或 JDBC 持久性存储的所有服务器都可以在数据库中断、切换或故障转移期间关闭。当关键子系统(如 JTA 服务)发生故障时,服务器将设置为 "FAILED"(故障)状态,节点管理器将自动重新启动该子系统。
转到“FAILED(失败)”状态所用的时间是可变的;这取决于触发相关检查的时间,并且可能由于以下各种原因而发生:
- 如果服务器在重试总数之后无法更新租赁表。
- 如果服务器在多次重试并就地重新启动后无法访问 JTA JDBC 持久性存储。
数据库切换可能需要几分钟时间。由于丢失对 JTA JDBC 持久性存储的访问而自动重新启动 WLS 服务器需要更长的时间(大约 8-9 分钟),因此在典型的数据库切换或故障转移期间不会触发 WLS 服务器。但是,由于使用默认租赁配置在不到 2 分钟内丢失租约,服务器可能会转换为 "FAILED"(失败)状态。因此,如果 WebLogic 服务器正在使用数据库租赁,则可以在 Oracle Data Guard 切换或故障转移期间自动触发 Oracle WebLogic Server 重新启动。
有两个参数可用于提高使用数据库租赁的服务器的数据库中断弹性。这些参数为 database-leasing-basis-connection-retry-count(默认情况下为 1 次重试)和 database-leasing-basis-connection-retry-delay(默认情况下为 1 秒)。增加这些参数会延长发生丢失租约错误之前的时间。这允许 WebLogic 服务器在不自动重新启动的情况下容忍较长的数据库中断;一旦数据库再次可用,它们就会重新连接到数据库。尽管在数据库关闭时连接尝试将失败,但不会重新启动 WebLogic 服务器。
因此,在拉伸的集群中,建议递增“数据库租赁连接重试计数”和“超时”的值,以使 WebLogic 服务器对数据库停机更具弹性。要更改这些属性,请使用 WLST 命令。例如:
$ORACLE_COMMON_HOME/common/bin/wlst.sh
connect('weblogic','password','t3s://ADMINVHN:9002')
edit()
startEdit()
cd('/Clusters/' + 'My_Cluster')
cmo.setDatabaseLeasingBasisConnectionRetryCount(10)
cmo.setDatabaseLeasingBasisConnectionRetryDelay(10000L)
save()
activate()
disconnect()
exit()提示:
服务器进入 FAILED 状态时,默认情况下,节点管理器会尝试对服务器两次重新启动。如果服务器无法正确启动,则将其标记为 FAILED_NOT_RESTARTABLE。您可以在服务器的 Health 选项卡中优化重新启动次数。使用参数 Max Restarts Within Interval(间隔内的最大重新启动数)定义节点管理器可以在重新启动间隔中指定的间隔内重新启动服务器的次数。配置 Coherence
例如,Oracle SOA Suite 使用 Oracle Coherence 在集群中传播组合部署和元数据 (metadata,MDS) 更新。
Oracle Coherence 支持多播和单播通信,以实现集群成员搜索和消息传递。单点传送特别适用于无法使用或不支持多点传送的环境中,例如跨多个数据中心或云区域。使用众所周知的地址 (WKA) 功能,群集成员可以搜索并加入群集,而无需依赖多播。配置 WKA 时,将禁用所有多播通信。默认情况下,Oracle Fusion Middleware 产品使用单点传送和 Coherence 的预定义 WKA 列表。
Oracle Coherence 对集群形成期间和响应集群成员脉动期间的延迟很敏感。但是,最近的版本通过 allowable variance 等功能增强了对通信延迟的容忍度。allowable variance 定义 Coherence 集群中网络通信的可允许时间变化。此可配置参数 (maximum-time-variance) 默认为 16 毫秒,用于设置往返时间 (RTT) UDP 通信的最大允许延迟。Coherence 动态调整此值以响应观察到的网络延迟或不一致,通过在预期时间中适应更大的偏差来保持集群稳定性和性能。消息 Increasing allowable variance to XX 指示此类调整。请参阅使用 Oracle Coherence 开发应用程序中的操作配置元素。
随着 Oracle Coherence 的此改进,如果延迟仍然在 FMW 拉伸集群拓扑的建议限制内 (<10ms RTT),则不会报告集群形成错误。但是,集群心跳的长时间延迟可能会导致部署中的争用以及停机的不良反应时间。
如果在 Coherence 集群的形成或操作中遇到错误,则可以调整以下 Coherence 网络超时参数:
<multicast-listener><join-timeout-milliseconds>. 尽管最初是为多播配置设计的,但单播中的连接超时影响也是如此。它决定了初始节点形成集群需要多长时间,在此之后,每个节点在尝试形成自己的集群(如果它们在 WKA 列表中)之前将花费多长时间查找集群。默认值为 3000,在不可靠的网络上,您可能需要增加此值,以便在启动新群集之前尝试更长时间查找群集。<packet-publisher><packet-delivery><resend-milliseconds>. 数据包重新发送间隔指定数据包发布者在重新发送数据包之前等待相应 ACK 数据包的最短时间(毫秒)。这应该是 RTT 的几个倍数,10x 应该可以。默认值为 200。<packet-publisher><packet-delivery><timeout-milliseconds>. 对于需要确认的包,指定重新发送包的最长时间(以毫秒为单位)。在此超时到期后,Coherence 将确定收件人是否被视为已终止。默认值 5 分钟应该足够,但您可以增加默认值以避免在加入集群时超时。<packet-publisher><packet-delivery><heartbeat-milliseconds>此参数是 tcp 环死亡检测的脉动间隔。默认心跳值为 1 秒。您可以增加值以缓解网络流量,但这也会延长对失败成员的检测。<tcp-ring-listener><ip-timeout>和<ip-attempts>。这些是确定托管集群成员的计算机已无法访问之前的时间和尝试量。Ip-timeout 应位于 RTT 或更高版本的 10x 区域,且至少为 5s。<cluster-config><tcp-ring-listener><enabled>. 您甚至可以禁用 tcp 环死亡检测来缓解网络流量,但它也使检测失败的成员所需的时间更长。要禁用死亡检测,请将其设置为 false。如果禁用,群集成员将使用数据包发布者的重新发送超时间隔来确定其他成员已停止响应 UDP 数据包(默认情况下设置为 5 分钟)。
要修改默认配置设置,请使用 Coherence 覆盖文件。创建一个名为 custom-coherence-override-<name>.xml 的文件,并确保该文件一致且可供集群中的所有服务器访问。在 java 属性 tangosol.coherence.override 中指定此文件。可以在 setUserOverrides.sh 文件的 EXTRA_JAVA_PROPERTIES java 属性中设置该属性。例如:
EXTRA_JAVA_PROPERTIES="${EXTRA_JAVA_PROPERTIES} -Dtangosol.coherence.override=/u01/oracle/config/coherence_custom/custom-coherence-override.xml"用于优化参数的 Coherence 覆盖文件的示例:
<?xml version='1.0'?>
<!--
This is a custom operational configuration override
-->
<coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-operational-config coherence-operational-config.xsd"
>
<cluster-config>
<multicast-listener>
<join-timeout-milliseconds>5000</join-timeout-milliseconds>
</multicast-listener>
<tcp-ring-listener>
<ip-timeout>20s</ip-timeout>
<ip-attempts>3</ip-attempts>
</tcp-ring-listener>
<packet-publisher>
<packet-delivery>
<resend-milliseconds>200</resend-milliseconds>
<timeout-milliseconds>650000</timeout-milliseconds>
</packet-delivery>
</packet-publisher>
</cluster-config>
</coherence>
用于优化 tcp-ring 间隔的 Coherence 覆盖文件的示例:
<?xml version='1.0'?>
<coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-operational-config coherence-operational-config.xsd">
<cluster-config>
<packet-publisher>
<packet-delivery>
<heartbeat-milliseconds>5000</heartbeat-milliseconds>
</packet-delivery>
</packet-publisher>
</cluster-config>
</coherence>用于禁用 tcp-ring 死亡检测的 Coherence 覆盖文件的示例:
<?xml version='1.0'?>
<coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-operational-config coherence-operational-config.xsd">
<cluster-config>
<tcp-ring-listener>
<enabled>false</enabled>
</tcp-ring-listener>
</cluster-config>
</coherence>
配置网络服务性能
一些操作系统默认配置可能无法优化,因此调整一些参数以提高数据传输效率变得非常重要。当 JDBC 客户机与服务器之间存在高延迟时,这些调整变得尤为重要。数据库访问延迟最高的服务器应引导网络缓冲区和 Oracle Net Services 设置的配置,以优化性能。
确定最佳配置的关键指标之一是带宽延迟产品 (Bandwidth-delay product,BDP)。它表示在任何给定时间网络中可以传输的最大数据量。它通过将网络链路的容量(带宽)乘以其往返延迟时间(延迟)来计算:
BDP = Bandwidth × Round-Trip Time (RTT)- RTT:在 OCI 中,您可以从 OCI 控制台的区域间延迟页面中获取区域之间的平均 RTT。或者,可以使用命令(如在几分钟内从一台主机 ping 到另一台主机 ping)确定往返时间 (round-trip time,RTT),并使用返回的响应时间。
- 带宽:OCI 区域之间没有保证的带宽,OCI 不提供特定的 OCI 带宽测量工具。对于精确的带宽测量,您可以使用 iPerf 等工具进行测试。法兰克福和阿姆斯特丹之间经过测试的带宽约为 2-2.5 Gbps。
TCP 套接字缓冲区设置控制一次通过网络发送的包数。为了实现最佳吞吐量,建议将套接字缓冲区大小至少设置为 BDP。在许多情况下,将缓冲区大小设置为 BDP 的两倍可以进一步提高性能,特别是在高延迟网络中。但是,过大的缓冲区可能会导致内存使用量增加。因此,建议将 BDP 范围内的缓冲区大小设置为 BDP 的三倍:
BDP ≤ Socket Buffer Size ≤ 3 × BDP在数据库中配置 IO 缓冲区大小
SEND_BUF_SIZE 参数通常就足够了。
如果数据库服务器收到较大的请求,则还应设置 RECV_BUF_SIZE 参数。建议在数据库中的 Oracle Net Services 级别对其进行优化,而不是在操作系统级别进行优化,以便常规 TCP 会话(例如 SSH)不使用额外的内存。
要为数据库服务器配置这些参数,请在 listener.ora 或 sqlnet.ora 文件中设置缓冲区空间大小。
-
在
listener.ora文件中,指定特定协议地址或说明的缓冲区空间参数。以下是 Oracle Cloud Infrastructure (OCI) 中基本数据库系统中典型 Oracle RAC 侦听器配置的设置示例:LISTENER_SCAN2=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN2)))) LISTENER_SCAN1=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN1)))) LISTENER_SCAN3=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN3)))) (…) LISTENER=(DESCRIPTION=(SDU=65535)(SEND_BUF_SIZE=10485760)(RECV_BUF_SIZE=10485760)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))) -
如果在
sqlnet.ora中设置了参数,这些参数将全局应用于所有监听程序。下面是sqlnet.ora文件中的设置示例:RECV_BUF_SIZE=10485760 SEND_BUF_SIZE=10485760
在中间层节点中配置 IO 缓冲区大小
Linux 操作系统对接收缓冲区和发送器缓冲区都使用自动优化。
对于接收缓冲区,自动优化由 /proc/sys/net/ipv4/tcp_moderate_rcvbuf 参数确定。如果参数的值为 1,则启用自动优化。通过自动优化,将动态更新每个连接的接收器缓冲区大小(和 TCP 窗口大小),最大缓冲区大小为 4 MB。
对于发件人缓冲区,默认情况下也会启用自动优化。虽然可以通过 tcp_moderate_rcvbuf 参数控制接收缓冲区自动优化,但发送缓冲区自动优化没有直接切换。只需设置固定缓冲区大小即可禁用发送缓冲区自动优化。
这些自动优化进程由几个内核参数控制,这些参数管理用于发送和接收数据的内存分配:
- 每个连接缓冲区大小
每个 TCP 连接的内存分配由两个参数定义:
/proc/sys/net/ipv4/tcp_rmem,指定为 TCP 接收缓冲区保留的内存。/proc/sys/net/ipv4/tcp_wmem,指定为 TCP 发送缓冲区保留的内存。
两个参数都接受三个值:
- 最小缓冲区大小:为 TCP 套接字分配的最小缓冲区大小。
- 默认缓冲区大小:创建时分配给 TCP 套接字的初始缓冲区大小。
- 最大缓冲区大小:可自动为 TCP 套接字分配的最大缓冲区大小。
这些设置建立了自动调优机制的边界,有助于平衡内存使用情况,特别是在内存压力期间。
- 每个应用程序的缓冲区大小
应用程序可以请求特定的缓冲区大小,但这些请求受以下参数定义的限制:
/proc/sys/net/core/rmem_max是最大接收窗口,用于设置应用程序可以请求的接收缓冲区大小的上限。/proc/sys/net/core/wmem_max是最大发送窗口,用于设置应用程序可以请求的发送缓冲区大小的上限。
要调整 IO 缓冲区大小,请执行以下操作:
TCP 自动调优保持启用状态,为网络带宽延迟产品设置边界,从而提高吞吐量,而不会过度调整系统内存使用量。
配置会话数据单元大小
Oracle Net Services 将在通过网络发送这些单元之前等待这些单元进行填充。其中每个缓冲区都是一个会话数据单元 (session data unit,SDU)。将 SDU 的大小调整为提供给 Oracle Net Services 的数据量可以提高延迟高于 5 毫秒 RTT 的 Oracle Fusion Middleware 拉伸集群中的性能、网络利用率和内存消耗。
SDU 大小可以设置为 512 字节到 2 MB。在 Oracle Database 23ai 中,默认 SDU 大小为 64 KB(65,536 字节)。较早的数据库发行版将其默认 SDU 大小设置为 8 KB。
使用的实际 SDU 大小是连接时在客户机与服务器之间协商确定的,为两个值中的较小者。配置不同于缺省大小的 SDU 需要在客户机和服务器计算机上配置 SDU。Oracle 建议将 SDU 设置为可能的最大值 (64k)。
客户机与服务器在连接时协商 SDU;配置两端可确保使用预期的 SDU。