MQ的基本概念

本篇内容介绍了“MQ的基本概念”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

对象(objects)

       WebSphereMQ对象是一种由WebSphereMQ管理的具有可恢复能力的资源。

 队列管理器(Queue managers)

队列(Queues)

名字列表(Namelists)

分发列表(Distribution lists)

进程定义(Process definitions)

通道(Channels)

存储类(Storage classes)

 这些对象在异种平台上都是统一的。对于系统管理员来说,操纵对象的命令都是可用的。这些命令格式,对于不同平台是有区别的。当你创建队列管理器时,会自动地创建缺省对象。这些缺省对象可以帮助您来定义所需的对象。

      
每一个对象都有一个名字,以便通过命令和MQI调用可以引用它。通常在这些对象类型中的每一种对象的名字必须唯一。例如,一个队列和一个进程的名字可以相同,但是不可以有两个相同名字的队列。这意味着一个本地队列名不能和模板队列、远程队列或别名队列相同。但是也会有些特殊情况。另外在互连的队列管理器网络中,队列管理器名必须唯一。

       WebSphereMQ的对象名是大小写敏感的,因此在定义对象时,需要仔细选择好大小写字母。在 WebSphere MQ 中,除最多有 20 个字符的通道之外,名称最多可以有 48 个字符。

消息

消息的类型

       WebSphereMQ定义了四种基本类型的消息。应用程序可以定义其他类型的消息。四种基本类型是:

1.请求消息 Request message

请求消息需要应答。从客户端发往服务器的查询和更新信息往往是一条请求消息。请求消息中应该包含回复消息的路由信息,即回复消息发往什么地方。

2. 回复消息 Reply message

回复消息是对请求消息的回应。请求消息中的信息决定了回应消息的目的地。处理请求和回应的应用程序控制着消息间的关联,这种关联和队列管理器没有关系。消息自身带有足够的信息供应用程序实现这种关联。

3.报文消息 Datagram message

数据报消息是不需要回复的消息,报文消息只是一次单向的信息传送。

4.报告消息 Report message。

报告消息用于对一些系统故障的响应。有些报告消息是由应用程序创建的,有些报告消息是由队列管理器创建的。后一种情况是由于远程队列已经满或者远程队列不存在引起消息不能正确发送。最初发送者条消息的应用程序不能检测到这种错误,只有等远程队列管理器创建了这样一条报告消息并发往本地队列管理器之后,应用程序才能作相应的处理。

队列管理器把报告消息也用于其他目的,比如报告一些事件。消息可能有一个失效时间限制。如果一条消息在失效时间过后还没有被某个应用程序处理,该条消息将被队列管理器从系统中清除。当队列管理器清除一条失效消息之后,它将创建一条报告消息,这条报告消息的目的地址由失效消息提供。

报告消息的另一个用途是确保消息的到达。应用程序可以要求它们所发送的消息到达目的地后,他们收到一条报告消息,这叫做接收确认(Confirmation
of
arrival)。与此相类似,应用程序也可以要求当另外一个程序取走这条消息时它们收到一条报告消息,这被叫做交付确认(Confirmation
of delivery)。这两种情况,都是由队列管理器创建报告消息,并把报告消息发送到适当地目的地。

另外还一类特殊的消息叫触发消息。触发消息是由队列管理器创建的一类特殊消息。WebSphere MQ的队列管理器提供了一种当满足某一条件时,自动触发应用程序的机制,而触发消息是触发机制的重要组成部分。

应用程序也可以定义新的消息类型。队列管理器不能解释这些类型,应用程序设置的消息类型由一个范围。这些类型值可用来区分不同类型的应用程序在同一个输入队列中放入的消息。

消息长度

最大消息长度为 100 MB(其中 1 MB 等于 1 048 576 字节),缺省最大消息长度是 4 MB。实际上,消息长度受以下方面的影响:

  • 接收队列定义的最大消息长度

  • 队列管理器定义的最大消息长度

  • 传输队列定义的最大消息长度

  • 发送或接收应用程序定义的最大消息长度

  • 存储消息的可用空间

所以有时可能需要由多个消息组成的信息才能满足应用程序的要求。

应用程序如何发送和接收消息?

应用程序使用 MQI 调用来实现发送和接收消息。

例如,要将消息放入队列,应用程序:

  1. 通过发出 MQI  MQOPEN 调用打开所需的队列

  2. 发出 MQI  MQPUT 调用以将消息放入队列

另一个应用程序可以通过发出MQI MQGET 调用,从同一队列取出消息

队列

队列的类型

按创建方法分类

  • 预定义队列由管理员使用相应的 MQSC 或 PCF 命令创建。 预定义队列是永久的;它们的存在与应用程序是否实用它们无关,并且 WebSphere MQ 重新启动后继续存在。

  • 动态队列在应用程序发出设定模型队列名的MQOPEN调用时创建的。被创建的队列是基于一个模板队列。 您可以使用 MQSC 命令 DEFINE QMODEL 创建模板队列。动态队列继承了模板队列的属性。模板队列有一个属性可以说明动态队列是永久的还是临时的。永久队列在应用程序和队列管理器重新启动后继续存在;临时队列在重新启动后消失。

按功能分类

1.        本地队列(local queue):

一个本地队列是一个物理上位于本地队列管理器中的队列。本地队列实际上存在与本地系统的内存或磁盘存储终。本地队列管理器控制队列的访问。

       应用程序可以“PUT”消息到本地队列,也可以从本地队列“GET”消息,另外程序还可以查询或修改这些队列的某些属性。对队列属性的修改需要相应的权限。

2.        远程队列(remote queue):

       一个远程队列属于一个不与该应用程序直接相连的队列管理器。对这类队列的访问包含有本地队列管理器和远程队列管理器的通信过程。这种通信涉及到通道。

       应用程序可对远程队列进行某些操作,比如程序可以向一个远程队列放一条消息,但程序不能从远程队列中去消息。应用程序只能从本地队列读取消息。

     
应用程序有两种不同的方法可用来访问远程队列。第一种是当程序打开一个远程队列时同时提供队列管理器名和队列名两个参数。这要求程序知道目的队列属于哪个队列管理器。第二种方法是在本地队列管理器上存在一个远程队列的定义,这个定义包含有足够的信息让本地队列管理器确定该远程队列所在的队列管理器。

       远程队列定义中的目的队列不一定是远程队列管理器的本地队列,它也可以是一个远程队列定义

       应用程序放一条消息到Q1,Q1是本地队列管理器QM1上的一个远程队列定义:Q2at
QM2。QM2是远程队列管理器。Q2是QM2上的一个远程队列定义Q3 at
QM3。Q3是QM3的一个本地队列,经过两次传送,消息最终到达Q3这个QM3的本地队列。

      
有多种原因使这种多跳(Multihop)传送变得有意义。在一个TCP/IP网络内部,所有机器都有IP地址,IP协议本身处理节点间的路由选择。但假设消息需要穿过不同类型的网络,这就需要中间件参加路由选择。在图中,QM2位于一台连接TCP/IP网和SNA网的机器上,只需在QM2上提供一个远程队列定义Q2:Q3
at QM3,就可以实现消息的跨网络传输。

       因为对远程队列的访问总是涉及到队列管理器之间的通信,因而我们需要定义其他一些资源,比如通道、传输队列(Transmission queue)。

3.        传输队列(Transmission queue):

      
传输队列是临时存储目标为远程队列管理器的消息的队列。队列管理器利用传输队列把消息分阶段地发向远程队列。队列管理器和消息移动程序一起负责把数据传送到远程队列。当队列管理器收到把一条消息发往远程队列的要求后,它把消息发送到一个与目的队列管理器相关联的传输队列,传输队列位于本地队列管理器上。目的队列管理器的名称可能由应用程序提供,也可以从远程队列定义中得到。

      
一个传输队列是两个队列管理器之间的连接的一端。所有直接目的地是同一队列管理器的消息都可放在同一个传输队列上,这些消息的最终目的可能不一样。把消息从一个队列管理器传送到另一个队列管理器只需要一个传输队列,然而也有可能在两个队列管理器之间存在着多个连接以提供不同的传输服务,每个连接都带有一个不同的传输队列。

       传输队列是由MCA处理的,MCA负责在队列管理器之间可靠地传送消息。MCA实际上是处理传输队列上消息的MQI应用程序。

4.        动态队列和模板队列:

除了有固定定义的队列之外,WebSphere
MQ还为程序在它们执行时提供了动态地创建队列的能力。例如,一个应用程序作为某种服务的客户,它可能创建一个动态队列,并通知服务器把对服务要求的响应发送到该动态队列。当然,这种情况也可以使用具有永久定义的队列。为了简化在创建动态队列时所必需设置的许多参数,动态队列总是基于模板队列被创建的,模板队列定义了动态队列的所有属性。当应用程序试图打开一个模板队列时,WebSphere
MQ就创建一个动态队列。WebSphere MQ为应用提供了系统模板队列。

动态队列也可以分成两种,它们的生存周期和故障恢复特性不同。在创建临时动态队列(Temorary dynamic
queue)的应用程序关闭时,这些队列将被删除,队列上的消息将丢失。这类动态队列不支持消息的持久性。如果队列管理器发生故障重新启动,临时动态队列也不会被恢复。另一种动态队列是持久动态队列(Permanent
dynamic
queue)。只有当一个应用程序关闭持久动态队列时定义删除选项,持久动态队列才会被删除。删除持久动态队列的程序不一定是创建持久动态队列的程序,持久动态队列在队列管理器重启后会被恢复,并且支持具有持久性的消息。

5.        启动队列

启动队列是在触发中使用的队列。如果队列管理器将使用触发,则必须至少为此队列管理器定义一个启动队列。队列管理器在触发器事件发生时将触发器消息放入启动队列。触发器事件是由队列管理器检测的条件的逻辑组合。例如,当队列上的消息数达到预定义深度时,可能会生成触发器事件。此事件使队列管理器将触发器消息放入指定的启动队列。此触发器消息由触发器监视器(即监视启动队列的特殊应用程序)检索。然后触发器监视器启动在触发器消息中指定的应用程序。

6.        群集传输队列

每个在群集中的队列管理器有一个称为 SYSTEM.CLUSTER.TRANSMIT.QUEUE
的群集传输队列。当您定义队列管理器时,按缺省情况创建此队列的定义。作为群集一部分的队列管理器可以将群集传输队列上的消息发送到在同一群集中的任何其它队列管理器。
在路由解析期间,群集传输队列优先于缺省传输队列。 当队列管理器是群集的一部分时,缺省操作是使用
SYSTEM.CLUSTER.TRANSMIT.QUEUE,除非当目标队列管理器不是此群集的一部分。

7.        死信队列 (Dead letter queue)

死信(未传递的消息)队列是存储无法发送到其正确目的地的消息的队列。有时候会出现队列管理器不能把消息发送到目的地的情况,此时消息将被发送到某个死信队列中。死信队列中的消息常常暗示了系统可能出现的问题。例如当一条消息到达目的队列管理器之后却发现目的队列并不存在。或者目的队列出现不能接收信消息的情况,比如目的队列已经满了,或者它被设置成不允许再加入新的消息。并不是所有的放消息操作的失败都导致消息被放入死信队列,例如,由于本地队列出现错误造成应用程序不能“放”消息,此时MQI调用直接把错误码返回给应用程序。

 
有些错误只能由死信队列报告,例如,一条消息穿越网络之后到达目的队列管理器,却发现目的队列已满。发现错误的机器不同于最初“放”消息应用程序所在的机器,甚至可能放消息的应用程序已不在运行状态。此时目的队列管理器把这条消息发往它所拥有的死信队列,而不是简单地扔掉该条消息。这样使得这次错误是可见的,也给应用程序提供了一个改正错误的机会。

         死信队列是WebSphere MQ面对远端系统错误时的一种解决方案。应用程序可以利用WebSphere MQ提供的其他一些工具来监视并确保消息的可靠传送和接收。

         在队列管理器创建时,系统会缺省创建一个死信队列,队列名是SYSTEM.DEAD.LETTER.QUEUE。建议在生产系统上,需要独立创建一个死信队列,而不使用系统缺省的死信队列。

8.        命令队列

命令队列 SYSTEM.ADMIN.COMMAND.QUEUE 是用来存放由应用管理程序放的具有PCF(programcommand
format)的消息的队列。该队列主要用于编写管理程序时使用。具体的使用将在后续章节介绍。在创建队列管理器时将为每个队列管理器自动创建命令队列。

9.        回复队列

当应用程序发送请求消息时,接收消息的应用程序可以将回复消息发送给发送应用程序。此回复消息放入一个称为回复队列的队列中,它通常是发送应用程序的本地队列。回复队列的名称由作为消息描述符一部分的发送应用程序指定。

10.    别名队列

      
别名队列实际上是本地队列、远程队列定义或队列名表的另外一个名字。它是一种简单的名字到名字的映射,它允许应用程序用另外一个名字来访问队列。WebSphere
MQ已经为应用程序屏蔽了许多底层系统细节,特别是网络通信的细节,而别名队列允许在不修改应用程序的条件下访问其他名字的队列。

队列管理器

在WebSphere MQ中队列管理器是基本的软件系统,队列管理器可看成是队列和其他对象的容器。WebSphere MQ中的每一个队列都属于一个队列管理器,队列管理器是为应用程序和WebSphere MQ部件(一些管理工具)提供对队列管理中对象的访问。

一个队列管理器是WebSphere MQ中的一个基本的独立的执行单元。一台机器上可以运行一个或多个队列管理器。

任何需要访问WebSphere
MQ提供的服务的应用程序都必须先和队列管理器相连,和应用程序相连的队列管理器对该应用程序而言就叫“本地队列管理器”(Local Queue
Manager),本地队列管理器为程序提供MQI调用的支持。应用程序可以操作、管理本地队列管理器所拥有的各种资源,也可以向其他的队列管理器发送消息。

应用程序通过一种叫做MQI的编程接口向队列管理器申请服务。这些服务包括“放”一条消息到队列或从队列“取”一条消息等一些基本操作。队列管理器还使队列成为可靠的存储消息的地方,它也控制安全性管理,并提供一些特殊的队列功能,比如触发队列。

为了减少应用程序对于它所运行环境的依赖性,WebSphere
MQ的应用程序可以和一个它不知道名字的队列管理器相连,这个队列管理器就是一台机器上的缺省队列管理器。如果程序在调用MQCONN时,把队列管理器名参数设置为空,MQCONN将返回与缺省的队列管理器连接的句柄。

队列管理器拥有每个队列。队列管理器负责维护它所拥有的队列,以及将它接收到的所有消息存储到相应的队列。可以由应用程序或队列管理器将消息放入队列,这些是它的正常操作的一部分。

通道

消息通道(Messagechannels)

消息通道是一种提供从一个队列管理器到另一个队列管理器的通信路径。消息通道用在分布式的队列把消息从一个队列管理器发送到另一个队列管理器。它们使应用程序屏蔽了底层的通信协议。队列管理器可能存在同种或异种平台之间。为了实现队列管理器之间的通信,您必需在一个队列管理器中定义一个发送消息的通道对象,在另一个队列管理器中定义一个接收消息的通道对象。消息通道是一个单向链接。它通过消息通道代理(message
channel agents)把两个队列管理器连接起来。 

不要和MQI通道(MQI channel)通道混淆。MQI通道有两种类型,分别是服务器连接(server-connection)和客户器连接(client-connection)。

消息通道分类

消息通道的定义可以分为以下6种类型:

l  发送通道(Sender)

l  接收通道(Receiver)

l  服务器通道(Server)

l  请求器通道(Requester)

l  群集发送通道(Cluster sender)

l  群集接收通道(Cluster receiver)

消息通道的组合形式

如果要在队列管理之间实现消息传输,必须要在两个队列管理器上都要定义相应的通道。发送方和接收方通道的组合形式如下:

l  发送通道-接收通道(Sender-receiver )

l  请求器通道-服务器通道(Requester-server)

l  请求器通道-发送通道(Requester-sender (callback) )

l  服务器通道-接收通道(Server-receiver )

l  群集发送通道-群集接收通道(Cluster sender –cluster receiver)

注意:通道的组合形式有5种形式,每种组合方式是固定的,用户不能随意组合。每对通道的名称必需相同例如:在发送通道-接收通道组合中,发送通道名和接收通道名必须一致,否则通道将无法启动。

消息通道用法

发送通道-接收通道(Sender-receiver)

用法:由一个系统的发送通道来启动通道,以便它可以发送消息到另一个系统。发送通道向接收通道发送启动请求。发送通道从传输队列发送消息到接收通道。接收通道把消息放到目标队列。

请求器通道-服务器通道(Requester-server)

用法:

(1)由一个系统中的请求器通道来启动通道,以便它能从另一个系统接收到消息。 请求器通道向通道另一端的服务器通道发送请求来启动。服务器通道从传输队列把消息发送到请求器通道。

(2) 服务器通道也能启动通道,并发送消息到请求器, 但这仅应用于完全意义的服务器通道, 也即服务器通道定义中应含有对方的连接名。一个完全意义的服务器通道可以由请求器通道启动, 也可以发起和服务器通道的通讯。

(3) 最好不要手工去停止Server和Request通道,而是依靠Server通道的Discint的属性来停止通道。

请求器通道-发送通道(Requester-sender (callback))

用法:请求器通道启动通道,发送通道终止这个会话。发送通道然后依据它的通道定义中的信息(称为
callback)来重新启动会话。它把消息从传输队列发送给请求器通道。最好不要手工去停止Sender和Request通道,而是依靠Sender
通道的Discint属性来停止通道。

服务器通道-接收通道(Server-receiver)

用法:类似于发送通道-接收通道,但仅应用在完全意义的服务器通道。也即服务器通道定义应含有对方的连接名,通道的启动方是服务器通道。

群集发送通道(Cluster sender)

用法:在一个群集中,每个队列管理器都有一个群集发送通道,通过它可以把送群集信息发送到其中一个队列管理器资源管理器。队列管理器通过这个通道也可以把消息发送到其他的队列管理器。

群集接收通道(cluster receiver)

功能:在一个群集中,每一个队列管理器都有一个群集接收通道。通过这个通道可以接收数据消息和关于群集的消息。

MQI通道

       MQI通道是WebSphere MQ 客户端和服务器上的队列管理器的通信的通道。当客户端应用程序发出MQCONN或MQCONNX调用时,才开始建立连接。它是一个双向的通道,可以负责发送和接收,被用作MQI调用的传送和响应。

一个MQI通道可以把一个客户端连接到单个队列管理器,MQI通道有两种类型,它们定义了双向的MQI通道。

客户端连接通道(Client-connectionchannel)

这种类型为WebSphereMQ 的客户端所使用。

服务器连接通道(Server-connectionchannel)

这种类型为运行队列管理器的服务器端所使用,运行在WebSphere MQ 客户端的应用程序将使用这种通道进行通信。

比较消息通道和MQI通道

消息通道与MQI通道之间的区别可以从两方面进行比较:

l  MQI通道是双向的:一个MQI通道可以被用来发送请求,也可用来接收响应。而消息通道则只能单向数据通信。如果要在两个队列管理器之间实现双向通信,那么需要定义两个消息通道,一个用来实现数据的发送,另一个用来实现数据的接收。

l  MQI通道的通信是同步的:当一个MQI请求从客户端发送服务器端时,WebSphere
MQ的客户端在发送下一个请求之间必须要等待来自服务器端的响应。而消息通道,在通道中传输的消息是与时间无关的。大量的消息可以从一个队列管理器发送到另一个队列管理器,发送队列管理器不必等待来自接收队列管理器的任何响应。

进程

进程定义对象定义响应 WebSphere MQ 队列管理器上的触发器事件启动的应用程序。进程定义属性包含应用程序标识、应用程序类型和特定于应用程序的数据。

群集

在使用分布式排队的传统 WebSphere MQ 网络中,每个队列管理器是独立的。如果队列管理器需要将消息发送到另一个队列管理器,则它必须定义一个传输队列、一个到远程队列管理器的通道,以及它要将消息发送到的每个队列的远程队列定义。

群集是一组以队列管理器可以在不需要传输队列、通道和远程队列定义的情况下在单个网络上彼此直接通信的方法设置的队列管理器。

名称列表

名称列表是包含其它 WebSphere MQ 对象列表的 WebSphere MQ
对象。通常,应用程序(如触发器监视器)使用名称列表,它们用于标识一组队列。使用名称列表的优点是它独立于应用程序维护;可以在不停止任何使用它的应用程序的情况下更新它。并且,如果一个应用程序失败,则名称列表不受影响,其它应用程序可以继续使用它。

名称列表还与队列管理器群集一起使用,以维护多个 WebSphere MQ 对象引用的群集列表。

认证信息对象

队列管理器认证信息对象(AUTHINFO)组成安全套接字层(SSL)安全性的WebSphere MQ 支持的部件。它提供使用LDAP 服务器检查证书撤销列表(CRL)所需的定义。CRL 允许认证中心取消不再可信的证书。

本书描述对认证信息对象使用setmqautdspmqautdmpmqautrcrmqobjrcdmqimgdspmqfls 命令。有关 SSL 概述以及 AUTHINFO 的使用,请参阅 WebSphere MQ Security。

系统缺省对象

系统缺省对象是一组每次创建队列管理器时自动创建的对象定义。您可以复制和修改这些对象定义中的任何一个,以在安装时用于应用程序。

缺省对象名具有项 SYSTEM.DEFAULT;例如,缺省本地队列是 SYSTEM.DEFAULT.LOCAL.QUEUE,并且缺省接收方通道是 SYSTEM.DEFAULT.RECEIVER。您无法重命名这些对象;这些名称的缺省对象是必需的。

当您定义对象时,从相应的缺省对象复制您不明确指定的任何属性。例如,如果您定义本地队列,则从缺省队列 SYSTEM.DEFAULT.LOCAL.QUEUE 获取您未指定的那些属性。

请参阅附录1, "系统和缺省对象"以获取有关系统缺省的更多信息。

MQI(message queue interface)

MQI(消息队列接口)有下列组成部分:

l  函数接口:应用程序通过函数可以访问队列管理器和它的部件。

l  数据结构:应用程序使用提供的数据接口来是实现把数据传递给队列管理器,或从队列管理器中获得数据。

l  基本数据类型:也是用来实现从队列管理器传递数据,或从队列管理器中获得数据。

控制命令

       以下是每个 WebSphere MQ 控制命令的参考信息:

命令名

目的

amqmcert

管理 SSL 证书

amqmdain

配置或控制 WebSphere MQ 服务(仅 Windows 系统)

crtmqcvx

转换数据

crtmqm

创建本地队列管理器

dltmqm

删除队列管理器

dmpmqaut

转储打开对象的权限

dmpmqlog

转储日志

dspmq

显示队列管理器

dspmqaut

显示打开对象的权限

dmpmqcap

显示处理程序容量和处理程序数

dspmqcsv

显示命令服务器状态

dspmqfls

显示文件名

dspmqtrc

显示格式化跟踪输出(HP-UX、Linux 和 Solaris)

dspmqrtn

显示事务的详细信息

endmqcsv

停止队列管理器上的命令服务器

endmqlsr

停止队列管理器上的侦听器进程

endmqm

停止本地队列管理器

endmqtrc

停止对实体的跟踪(不用于 AIX)

rcdmqimg

向日志写对象的映象

rcrmqobj

根据它们在日志中的映象重新创建一个对象

rsvmqtrn

提交或逆序恢复事务

runmqchi

启动通道启动器进程

runmqchl

启动发送方或请求者通道

runmqdlq

启动死信队列处理程序

runmqlsr

启动侦听器进程

runmqsc

向队列管理器发出 MQSC 命令

runmqtmc

调用客户机的触发器监控器(仅 AIX 客户机)

runmqtrm

调用服务器的触发器监控器

setmqaut

更改打开对象的权限

setmqcap

设置处理程序容量

setmqcrl

设置证书撤销列表(CRL)服务器定义

setmqscp

设置服务连接点(仅 Windows 系统)

strmqcsv

启动队列管理器的命令服务器

strmqm

启动本地队列管理器

strmqtrc

启用跟踪(不用于 AIX)

举例
1.  此命令创建一个称为 Paint.queue.manager 的缺省队列管理器,创建系统和缺省对象,并请求两个主日志文件和三个次日志文件:

crtmqm -c"Paint shop" -ll -lp 2 -ls 3 -q Paint.queue.manager

2. 下列命令删除队列管理器 travel 并且也抑制任何由该命令发出的消息。

dltmqm -z travel

3. 此命令立即结束名为 saturn.queue.manager 的队列管理器。完成所有当前 MQI 调用,但不允许新的调用。

endmqm -isaturn.queue.manager

“MQ的基本概念”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

原创文章,作者:1402239773,如若转载,请注明出处:https://blog.ytso.com/230008.html

(0)
上一篇 2022年1月15日
下一篇 2022年1月15日

相关推荐

发表回复

登录后才能评论