企业服务总线相关理论和技术的研究

企业服务总线相关理论和技术的研究

 随着社会信息化进程的进一步加快和信息化技术的不断进步,很多企业发现在引进新的应用和系统的同时,如何保证公司旧有的应用和系统不被全部抛弃或替换是节省公司运作成本,有效利用公司资源的重要手段。但由于旧的应用和系统所采用的体系结构与新的系统存在及大的差异,往往使这些应用集成到新的系统中并不容易。阻碍企业将新旧应用系统集成在一起的问题显而易见,不外乎有以下两点所组成:

·所采用的体系结构不同;

·所使用的技术不同;

要完全跨越企业应用集成的这两条鸿沟确实存在巨大困难。为了解决这些问题,业界已经出现了许多相关的技术及方案,典型的有企业应用集成(EAI)等。但是传统面向组件的EAI实现方式存在许多明显的局限性,例如:复用度差、紧耦合、配置文件过多导致应用复杂以及报文格式的转换缺少标准支持等缺点,所以业界正在广泛寻求解决传统EAI实施方式所存在问题的方案。

SOA的提出在很大程度上就是为了更好的满足企业应用集成的需求。SOA强调复用和松耦合,注重接口及其标准化描述,这些都为企业应用集成规划了非常好的框架体系结构。基于SOA的应用集成系统具有更好的可扩展性和灵活性,用户可以在对已有系统影响最小的情况下开发应用新的业务模块(服务)或修改已有模块,从而快速满足业务需求的变化。SOA的体系结构一般来说也需要企业服务总线(ESB)的支撑,只是它对总线上的服务和总线本身的作用和位置有着更加明确的要求。

如何把SOA架构下的企业服务总线应用到企业自身的EAI建设之中,已经成为当前的一个研究热点。

本文首先介绍传统企业应用集成(EAI)所存在的问题,然后阐述面向服务架构(SOA)的特点和对软件架构设计的影响,其次介绍ESBSOA的关系,最后重点对用企业服务总线(ESB) 实施EAI的方式进行分析研究。

关键词: EAI(企业应用整合);SOA(面向服务架构);ESB(企业服务总线);


 

 


 


 

1 绪论

1.1 企业应用集成的概念及重要性

随着计算机软件技术的发展和企业信息化的不断发展,企业使用的软件,如:ERP、财务管理,MISCRM等应用和管理系统也越来越多。虽然这些系统是应用在不同的领域,管理着不同的对象,但是它们之间也有很多相互交叉,甚至重复的信息和数据。而各个应用系统又是相互独立运行,因此企业内部的这些系统相当于一个个信息孤岛,相互之间没有畅通的信息交流与共享。这样的后果是在企业中经常会出现信息和数据的更新不同步甚至不一致,从而造成各个部门之间的矛盾,给企业中不同部门的人员在进行交流时带来很多问题,给客户也经常提供一些前后不一致的信息,使客户无所适从,严重影响企业的形象和信誉。另一方面是企业间的交流与合作的日益增加,协同商务和各种新的制造模式(如:敏捷制造,虚拟企业,信贷物流管理等)的需要和建立自己的企业信息门户等要求企业的应用系统是一个基于B/S应用模式的开放式系统,以便利用INTERNET这个世界上最方便的通信和信息载体获得竞争优势。

企业要解决这些矛盾,一种办法是对现有系统推倒重来:将企业的各个信息系统全部更新成一个统一的管理系统,各个部门都在这个统一的系统上工作,但考虑到成本、实施周期和难度因素,这不是一种切实可行的解决方案。另一种办法是企业从整体来考虑企业的整个信息系统,根据实际需要,对各个应用系统进行总体规划,选择一个合适的集成平台,把企业的各个信息孤岛有机的集成起来。这种解决方案不管是从实施难度,还是从实施成本、周期和技术上考虑都是切实可行的。

EAI (enterprise application integration)就是将基于各种不同平台、用不同方案建立的异构应用集成的一种方法和技术。EAI通过建立底层结构,来联系横贯整个企业的异构系统、应用、数据源等,完成在企业内部的 ERPCRMSCM、数据库、数据仓库,以及其他重要的内部系统之间无缝地共享和交换数据的需要。有了 EAI,企业就可以将企业核心应用和新的Internet解决方案结合在一起。[1]

 

1.2 国内外研究现状

在企业应用集成(Enterprise Application IntegrationEAI)领域,企业一直面临着削减成本和最大限度地利用现有技术的难题,在当前激烈竞争的环境下,一个成功的企业在IT构建上需要解决下列问题:

如何让已有的多种应用系统无缝的集成起来,实现应用系统的快速构建,迁移和伸缩,以满足不断变化的市场需求。

与此相对应,EAI技术也在不断的向前发展。EAI技术的发展历史,可以从EAI产品的体系结构来说明。

定制连接,两两互连

最早期的EAI解决方案就是将企业中需要互通信息,共享数据的系统两两桥接起来。桥接的技术也是为两个特定系统专门定制通讯链路来转换这两个系统的接口,协议以及数据格式等差异,使用硬编码来实现系统之间的点对点连接。这种方式,在有些特定情况下(比如很小规模的集成系统)可能会得到相对较高的性能。但集成规模稍复杂,这种方式代码量大,不可靠,无法维护等缺点就会显露无疑。 另外,全部使用专门为两个特定系统定制的连接,在企业系统众多的情况下连接急剧增加,难以开发,后期维护更加困难。由于这些专用连接完全互相独立,其只能满足系统两两互连通讯的需求,无法实现涉及多个应用系统的复杂业务流程。

中心——辐条(hub-spoke)式体系结构

中心——辐条(hub-spoke)式体系结构如图1.1所示,该方式提供一个应用集成中心(hub),这个中心具有自己的连接协议,所有需要集成的系统(spoke)都和该中心相连。原来用户每集成一个系统,都要考虑改系统和其他所有系统的点对点连接的协议,数据结构的转换,而在中心——辐条结构下,用户只需要考虑系统和集成中心的点对点连接上转换。这样,原来n个系统之间的nx(n-1)/2个点对点连接减少为n个连接。

一般集成中心和各个系统的连接及相应的转换使用集成中心中适配器来完成。同时,这种方式也使的集中管理以及流程集成成为可能。另外,体系结构中开始出现集中式的资源中心(Repository)。资源中心将原来分散的各种资源(适配器,组件,运行信息等)集中管理起来,这为用户设计,开发,部署和维护管理EAI系统提供了很大的便利。 但是集中式的结构容易造成效率瓶颈,同时存在单点失效的问题。

 

1.1中心——辐条(hub-spoke)式体系结构

随着IT技术的发展,企业服务总线(Enterprise Service Bus)的体系结构逐渐浮出水面。这种体系结构继承了中心——辐条(hub-spoke)式体系结构将各个系统点对点连接转化为多个系统对中心的连接的理念。但在这种体系结构中,集成中心被扩展成可以分布在多个物理节点上的总线,从而有效解决了中心——辐条模式的单点失效和效率问题。 

1.2 企业服务总线体系结构

ESB技术并不仅仅是简单的将集成中心被扩展成总线。企业服务总线本身提供各种消息路由,数据转换等各种EAI模式的支持。这种总线一般以成熟的消息中间件作为其物理消息传递背板,保证消息在分布式环境下可靠高效的传输。同时,企业服务总线作为应用集成系统的基础框架,大多数采用面向组件的技术,这实际上是SOA的雏形。

1.3Gartner Group2002年对EAI技术趋势的预测[2]

1.3 EAI技术趋势预测

1.3 本课题研究的价值及现实意义

面向服务的体系架构(Service Oriented Architecture)是目前EAI领域最先进的体系结构。实际上,SOA的提出在很大程度上就是为了更好的满足企业应用集成的需求。SOA强调复用和松偶合,注重接口及其标准化描述,这些都为企业应用集成规划了非常好的框架体系结构。除了具有前面ESB结构的优点之外,基于SOA的应用集成系统具有更好的可扩展性和灵活性,用户可以在对已有系统影响最小的情况下开发应用新的业务模块(服务)或修改已有模块,从而快速满足业务需求的变化。SOA的体系结构一般来说也需要企业服务总线的支撑,只是它对总线上的服务和总线本身的作用和位置有着更加明确的要求。

如何把SOA应用到企业自身的EAI建设之中,已经成为当前的一个研究热点。

本课题介绍了目前业界比较流行的企业服务总线产品,研究了如何使用SOA架构下的企业服务总线来替代传统的EAI方式实现企业应用的整合,并结合实际项目开发,给出了成功的案例,使得本课题的提出具备相当的理论意义和实用价值。

1.4 本文的主要内容及组织

本文主要内容包括对国内外多种ESB产品的研究,深入介绍了ESB产品概念、特点以及各个功能模块的作用

第一章介绍EAI的背景,概念和国内外研究现状;然后,提出用面向服务架构下的EAI替代传统的EAI,从而指出了本课题研究的价值和现实意义。

第二章 介绍企业服务总线的支撑平台和理论基础,包括面向服务架构(SOA)、企业服务总线(ESB)、WEB服务、可扩展样式转换语言(XSLT)和系统开发的基础平台、框架及其工具简介。

第三章 介绍企业服务总线的相关技术,包括服务注册和发现、JAXRJNDIJMSDigesterlog4j


2 企业服务总线系统的支撑平台与理论基础

2.1 面向服务架构(SOA)

2.1.1 SOA概念

面向服务的体系结构(Service-Oriented ArchitectureSOA,也叫面向服务架构)是指为了解决在Internet环境下业务集成的需要,通过连接能完成特定任务的独立功能实体实现的一种软件系统架构。SOA是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种这样的系统中的服务可以以一种统一和通用的方式进行交互。

传统的WebHTML/HTTP)技术有效的解决了人与信息系统的交互和沟通问题,极大的促进了B2C模式的发展。WEB服务(XML/SOAP/WSDL)技术则是要有效的解决信息系统之间的交互和沟通问题,促进B2B/EAI/CB2C的发展。SOA则是采用面向服务的商业建模技术和WEB服务技术,实现系统之间的松耦合,实现系统之间的整合与协同。WEB服务和SOA的本质思路在于使得信息系统个体在能够沟通的基础上形成协同工作。

对于面向同步和异步应用的,基于请求/响应模式的分布式计算来说,SOA是一场革命。一个应用程序的业务逻辑(Business Logic)或某些单独的功能被模块化并作为服务呈现给消费者或客户端。这些服务的关键是他们的松耦合特性。例如,服务的接口和实现相独立。应用开发人员或者系统集成者可以通过组合一个或多个服务来构建应用,而无须理解服务的底层实现。举例来说,一个服务可以用.NETJ2EE来实现,而使用该服务的应用程序可以在不同的平台之上,使用的语言也可以不同。[3]

2.1.2 SOA特征

l  独立的功能实体

Internet这样松散的使用环境中,任何访问请求都有可能出错,因此任何企图通过Internet进行控制的结构都会面临严重的稳定性问题。SOA非常强调架构中提供服务的功能实体的完全独立自主的能力。传统的组件技术,如.NET Remoting EJBCOM或者CORBA,都需要有一个宿主(Host或者Server)来存放和管理这些功能实体;当这些宿主运行结束时这些组件的寿命也随之结束。这样当宿主本身或者其它功能部分出现问题的时候,在该宿主上运行的其它应用服务就会受到影响。

SOA架构中非常强调实体自我管理和恢复能力。常见的用来进行自我恢复的技术,比如事务处理(Transaction),消息队列(Message Queue),冗余部署(Redundant Deployment)和集群系统(Cluster)SOA中都起到至关重要的作用。

l  大数据量低频率访问

对于.NET RemotingEJB或者XML-RPC这些传统的分布式计算模型而言,他们的服务提供都是通过函数调用的方式进行的,一个功能的完成往往需要通过客户端和服务器来回很多次函数调用才能完成。在Intranet的环境下,这些调用给系统的响应速度和稳定性带来的影响都可以忽略不计,但是在Internet环境下这些因素往往是决定整个系统是否能正常工作的一个关键决定因素。因此SOA系统推荐采用大数据量的方式一次性进行信息交换。

l  基于文本的消息传递

由于Internet中大量异构系统的存在决定了SOA系统必须采用基于文本而非二进制的消息传递方式。在COMCORBA这些传统的组件模型中,从服务器端传往客户端的是一个二进制编码的对象,在客户端通过调用这个对象的方法来完成某些功能;但是在Internet环境下,不同语言,不同平台对数据、甚至是一些基本数据类型定义不同,给不同的服务之间传递对象带来的很大困难。由于基于文本的消息本身是不包含任何处理逻辑和数据类型的,因此服务间只传递文本,对数据的处理依赖于接收端的方式可以帮忙绕过兼容性这个的大泥坑。

此外,对于一个服务来说,Internet与局域网最大的一个区别就是在Internet上的版本管理极其困难,传统软件采用的升级方式在这种松散的分布式环境中几乎无法进行。采用基于文本的消息传递方式,数据处理端可以只选择性的处理自己理解的那部分数据,而忽略其它的数据,从而得到的非常理想的兼容性。[4]

2.1.3 SOAWeb服务

Web服务是技术规范,而SOA是设计原则。特别是Web服务中的WSDL,是一个SOA配套的接口定义标准:这是 Web服务和SOA的根本联系.下面让我们看看Web Service中的各种协议是如何互相工作来满足SOA所需的特点的:

·独立的功能实体:通过UDDI的目录查找,我们可以动态改变一个服务的提供方而无需影响客户端的应用程序配置。所有的访问都通过SOAP访问进行,只要WSDL接口封装良好,外界客户端是根本没有办法直接访问服务器端的数据的。

·大数据量低频率访问:通过使用WSDL和基于文本(Literal)SOAP请求,我们可以实现能一次性接收大量数据的接口。这里需要着重指出的是SOAP请求分文本方式和远程调用(RPC)两种方式,正如上文已经提到的,采用远程调用方式的SOAP请求并不符合这点要求。但是令人遗憾的是现有的大多数SOAP请求采用的仍然是远程调用(RPC)方式,在某些平台上,例如IBM WebSphere的早期版本,甚至没有提供文本方式的SOAP支持。

·基于文本的消息传递:Web Service所有的通讯是通过SOAP进行的,而SOAP是基于XML的,不同版本之间可以使用不同的DTD或者XML Schema加以辨别和区分。因此只需要我们为不同的版本提供不同的处理就可以轻松实现版本控制的目标。[5]

2.1.4 SOA对软件架构设计的影响

复杂性降低:基于标准的兼容性,与点到点的集成相比降低了复杂性。重用增加:通过重用以前开发和部署的共享服务,实现了更有效的应用程序 / 项目开发和交付。遗留集成:用作可重用服务的遗留应用程序降低了维护和集成的成本。如今的服务驱动型企业都在体验着开发的高效率,服务的高可靠性和服务的高质量,以最大限度获得业务机会所带来的这些好处。[6]

2.2 企业服务总线(ESB)

2.2.1传统EAI

Integrator产品利用传统的EAI技术开发的EAI整合平台。它屏蔽了所有银行渠道的差异性以及后台服务系统的差异性。提供更高级的服务访问接口,向分行提供功能更强大的业务整合能力。从业务上解决了复杂的外围系统,快速变化的业务逻辑以及巨大的业务量的压力。从技术上又提供了灵活及高性能的架构,快速的开发测试和部署平台。图2.1Integrator的体系结构图,图2.2Integrator的功能模型图。[7]

2.1 Integrator体系结构图

通讯模块

1 利用系统层通讯协议和系统进行通讯,包括TCP/IP,SNA/LUO,TUXEDO等通讯方式

2 外部系统约定的通讯方式的实现,包括如何进行通讯连接,如何进行通讯应答,如何进行数据传输,如何约定通讯报文的大小,如何确定数据传输是否完毕,如何处理通讯错误,如何关闭通讯连接,如何处理通讯层数据完整性校验等。

3 识别外部系统类型

4 多通讯连接的并发处理

 

2.2 Integrator功能模型图

数据交换模块

从功能上讲,数据交换要解决的是两个问题,一是定义数据标准的问题,二是解决非标准数据和标准数据之间的转换问题。

服务整合模块:

1 完成对原子服务的调用。

2 完成对服务调用流程的控制

3 实现了对服务执行过程中数据一致性的保证。

4 实现对不同类型服务的服务总量控制。

5 完成对服务的动态加载和动态起停。

产品关键特性

1 兼容新老系统

2 分层设计、层次之间接口明确,耦合度小

3 各个关键部分使用接口设计,提供了各个层次扩展系统的机制

4 配置驱动方式,辅以少量的代码,保证对业务变化的快速反应。

5 核心模块(数据交换,流程管理)使用底层JAVA代码实现,以确保系统的性能。

缺点:

1 面向组件开发,没有真正的面向服务,复用度差;

2 服务请求者和服务提供者之间位置不透明;

3 所有组件的实现基于静态配置文件, 复杂度高,缺乏灵活性;

4 报文处理缺少标准技术的支持;

2.2.2 ESB概念

在企业基于SOA实施EAIB2BBMP的过程中,如果采用点对点的集成方式存在着复杂度高,可管理性差,复用度差、系统脆弱等问题。企业服务总线(Enterprise Service Bus,简称ESB)技术在这种背景下产生,其思想是提供一种标准的软件底层架构,各种程序组件能够以服务单元的方式插入到该平台上运行,并且组件之间能够以标准的消息通信方式来进行交互。它的定义通常如下:企业服务总线是由中间件技术实现的支持面向服务架构的基础软件平台,支持异构环境中的服务以基于消息和事件驱动模式的交互,并且具有适当的服务质量(Qos)和可管理性。

2.3 ESB示意图

如图2.3所示ESB本质上是以中间件形式支持服务单元之间进行交互的软件平台。各种程序组件以标准的方式连接在该总线上,并组件之间能够以格式统一的消息通信的方式来进行交互。一个典型的在ESB环境中组件之间的交互过程是:首先由服务请求者触发一次交互过程,产生一个服务请求消息,并将该消息按照ESB的要求标准化,然后标准化的消息被发送给服务总线。ESB根据请求消息中的服务名或者接口名进行目的组件查找,将消息转发至目的组件,并最终将处理结果逆向返回给服务请求者。这种交互过程不再是点对点的直接交互模式,而是由事件驱动的消息交互模式。通过这种方式,ESB最大限度上解耦了组件之间的依赖关系,降低了软件系统互连的复杂性。连接在总线上的组件无需了解其他组件和应用系统的位置和交互协议,只需要向服务总线发出请求消息即可获得所需服务。服务总线事实上实现了组件和应用系统的位置透明和协议透明。技术人员可以通过开发符合ESB标准的组件(适配器)将外部应用连接至服务总线,实现与其他系统的互操作。同时,ESB以中间件的方式,提供服务容错、负载均衡、Qos保障和可管理功能。[8]

2.2.3 ESB功能

ESB的核心功能包括:1)提供位置透明性的消息路由和寻址服务 2)提供服务注册和命名的管理功能 3)支持多种的消息传递范型(例如,请求/响应、发布/订阅等等) 4)支持多种可以广泛使用的传输协议5)支持多种数据格式及其相互转换6)提供日志和监控功能。

2.2.4 ESB优点

由于采用了基于标准的互连技术,ESB使得企业内部以及外部系统之间可以很容易地进行异步或同步交互。它采用的面向服务的架构为系统提供了易扩展性和灵活性,在提高集成应用的开发效率的同时降低了成本。ESB技术克服了传统应用集成技术的缺陷,能够对各种技术和应用系统提供支持,具有很强的灵活性和可扩展性,可以说是目前理想的EAIB2B应用系统集成支撑平台。

ESB本身为EAI提供了良好的支持平台。但是,作为最终的企业用户需要的则是包含业务集成软件基础平台、各种预制服务组件、集成应用开发、部署、管理和监控工具为一体的EAI环境。因此,作为软件厂商则是以ESB中间件为基础软件平台,为用户提供整套立体的完善的企业应用软件集成平台。[9]

2.2.5 ESB实施EAI

ESB是特定环境下(SOA架构中)实施EAI的方式:首先,在ESB系统中,被集成的对象被明确定义为服务,而不是传统EAI中各种各样的中间件平台,这样就极大简化了在集成异构性上的考虑,因为不管有怎样的应用底层实现,只要是SOA架构中的服务,它就一定是基于标准的。

其次,ESB明确强调消息(Message)处理在集成过程中的作用,这里的消息指的是应用环境中被集成对象之间的沟通。以往传统的EAI实施中碰到的最大的问题就是被集成者都有自己的方言,即各自的消息格式。作为基础架构的EAI系统,必须能够对系统范畴内的任何一种消息进行解析。传统的EAI系统中的消息处理大多是被动的,消息的处理需要各自中间件的私有方式支持,例如API的方式。因此尽管消息处理本身很重要,但消息的直接处理不会是传统EAI系统的核心。ESB系统由于集成对象统一到服务,消息在应用服务之间传递时格式是标准的,直接面向消息的处理方式成为可能。如果ESB能够在底层支持现有的各种通讯协议,那么对消息的处理就完全不考虑底层的传输细节,而直接通过消息的标准格式定义来进行。这样,在ESB中,对消息的处理就会成为ESB的核心,因为通过消息处理来集成服务是最简单可行的方式。这也是ESB中总线(Bus)功能的体现。其实,总线的概念并不新鲜,传统的EAI系统中,也曾经提出过信息总线的概念,通过某种中间件平台,如CORBA来连接企业信息孤岛,但是,ESB的概念不仅仅是提供消息交互的通道,更重要的是提供服务的智能化集成基础架构。

最后,事件驱动成为ESB的重要特征。通常服务之间传递的消息有两种形式,一种是调用(Call),即请求/回应方式,这是常见的同步模式。还有一种我们称之为单路消息(One-way),它的目的往往是触发异步的事件,发送者不需要马上得到回复。考虑到有些应用服务是长时间运行的,因此,这种异步服务之间的消息交互也是ESB必须支持的。除此之外,ESB的很多功能都可以利用这种机制来实现,例如,SOA中服务的性能监控等基础架构功能,需要通过ESB来提供数据,当服务的请求通过ESB中转的时候,ESB很容易通过事件驱动机制向SOA的基础架构服务传递信息。[10]

2.2.6 JBossESB 基本信息[11-15]

2.1 JbossESB 产品信息表

 

JBossESB

版本

4.2GA

License

GNU Lesser General Public License, v. 2.1

ESB标准

JBI/SCA(目前还不支持)

单独运行于java SE

jdk1.5(java 1.5.0_09-b03)

自带AS

tomcat5.5.20

路由

JBossRules 3.0.4

报文转换

Smooks 0.8-SNAPSHOT/XSLT/ActionProcessor Data Transformation

服务注册

juddi trunk as of September 2006/Scout-v0.7RC3

消息中间件

JBossMQ/ActiveMQ

组件加载和组件容器

基于JBoss Microkernel/Apache XmlBeans

业务流程管理

JBoss jBPM 3.2

IDE

JBossIDE-2.0.0 Beta2

控制台

版本升级速度

3个月一个里程碑版本(最新4.2MR3

文档

少(正式文档需付费)

JbossESB架构图:

2.4 JBossESB产品架构图

2.4 本章小结

本章介绍了企业服务总线系统的支撑平台和相关理论基础,主要包括面向服务架构(SOA)的概念、特征、与WEB服务的关系以及SOA对软件架构设计的影响;然后重点介绍企业服务总线ESB,它作为面向服务类型EAI的实施方式和传统的EAI相比有着强大的功能和优点,它也是本课题研究的重点;最后介绍了系统的j2ee开发平台、struts框架、企业服务总线基础平台和相关的开发工具Eclipse等。


 

3 企业服务总线相关技术

3.1 服务注册和发现

3.1.1 UDDI

UDDI Universal Description, Discovery and Integration 的缩写,目的是为电子商务建立标准;UDDI 是一套基于Web 的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的Web Service 注册,以使别的企业能够发现的访问协议的实现标准。通过UDDI,企业可以注册.发布,以及寻找相应的Web Services.

1 UDDI 的信息类型

UDDI 注册中心使用的核心信息模型是由XML Schema 定义的。UDDI XML Schema 定义了四种主要的信息类型,它们是技术人员在需要使用合作伙伴所提供的Web 服务时必须了解的技术信息。它们是:商业实体信息(businessEntity 结构) 、服务信息(businessService 结构)、绑定信息(bindingTemplate 结构)和技术规范信息(tModel 结构)。在UDDI 的数据模型中,tModel 是一个很特殊的数据项。tModel 描述了一切技术信息, tModel 的全体组成了UDDI 中的所有技术注册信息。

商业实体信息: businessEntity 元素

在商业领域内,合作伙伴和潜在的合作伙伴都期望能准确地定位到商业实体所能提供的服务或产品的相关信息,并把这些信息作为了解你们企业的开始。而在技术领域,技术人员、程序员或应用程序都

期望能知道他们需要集成的商业实体的名称和一些关键性的标识,以及该商业实体是属于那个具体工业分类之类的分类信息,以及联络方法(包括Email、电话、URL)等。支持对UDDI 商业注册的商业信息发布和发现的核心XML 元素都包含在“businessEntity”结构中。这个结构是商业实体专属信息集的最高层的数据容器,位于整个信息结构的最上层。

商业服务信息:businessService 元素

businessService 结构将一系列有关商业流程或分类目录的Web 服务的描述组合到一起。businessService 和下面要提到的bindingTemplate 一起构成了绿页信息。其中,一个可能的商业流程的例子是一组相关的Web 服务信息,包括采购服务、运输服务和其它的高层商业流程。这些服务都将是提供这些商业流程服务的商业实体所需要注册的Web 服务。

这些businessService 的信息集合可以再次加以分类,使Web 应用服务的描述可以按不同的行业、产品、服务类型或是地域划分来进行。分类的方法的机制与businessEntity 是类似的。

技术绑定信息:bindingTemplate 元素

对于每一个businessService,存在一个或多个Web 服务的技术描述bindingTemplate。这些技术描述包括应用程序连接远程Web 服务并与之通讯所必

须的信息。这些信息包括Web 应用服务的地址、应用服务宿主和调用服务前必须调用的附加应用服务等。另外,通过附加的特性还可以实现一些复杂的路由选择,诸如负载平衡等。

元技术信息:tModel 元素

调用一个服务所需要的信息是在bindingTemplate 的结构中定义的,这在前面一节中已经阐述了。不过一般来说,仅知道Web 服务所在的地址是不够的。例如,如果我知道我的合作伙伴提供一个Web 服务来让我下订单,同时也知道这个服务的URL,不过如果不知道一些具体的信息,如订单的具体格式,应该使用的协议,需要采用的安全机制,调用返回的响应格式等,那样的话,通过Web 服务将两个系统集成起来仍然是非常困难的。

当一个程序或是程序员需要调用某个特定的Web 服务时,必须根据应用要求得到了足够充分的调用规范等相关信息,以使调用被正确地执行。因此,每一个bindingTemplate 元素都包含一个特殊的元素,该元素包含了一个列表,列表的每个子元素分别是一个调用规范的引用。这些引用作为一个标识符的杂凑集合,组成了类似指纹的技术标识,用来查找、识别实现了给定行为或编程接口的Web 服务。

2UDDI API

程序员API

Uddi 规范包括了web 服务的接口定义,使得能通过编程实现对UDDI 注册中心的信息访问.程序员的API 规范文档详细定义了程序员API.API 分为两类:查询API 和发布API

查询API 包含两类调用,使程序能快速地定位候选商业实体、Web 服务及其调用规范,然后在最初调用获得的初始信息的基础上,获得进一步的相关信息的细节。这类以find_xx 命名的API 提供了多种搜索标准,从而能对注册中心中的数据进行广泛地搜索。发布API 包括四个save_xx 函数和四个delete_xx 函数,每个对应于一个UDDI 主要结构(businessEntitybinsinessServicebindingTemplatetModel)[21]

3.1.2 JUDDI

jUDDI 是一个开源的UDDI 服务器软件,采用java 语言编写。jUDDI 的主页是:http://ws.apache.org/juddi/ 。目前jUDDI 的最新版本是1.0

JUDDI特点:

1 开源:你可以查看它的代码。这在我们通过jsp 构建注册中心的时候,尤其重要。

2 平台独立:你可以部署在win 或者Linux 下,我们是部署在RH 7.3 上。

3 支持JDK1.3.1 以及后继版本;

4 实现了UDDI 2.0 版本;

5 后台的数据库没有特定的要求,只要支持ANSI 标准的SQL 语言操作的关系型数据库系统即可。

6 可以部署在任何一个java 应用程序服务器上,只有这个服务器支持servlet2.3 标注。主要有Jakarta Tomcat, JonAS WebSphere WebLogicBorland Enterprise Service, JRun 等。

7 jUDDI 注册支持集群式的分布配置;

8 可以很方便的和现有的认证系统相结合。做到对注册web 服务的用户的认证。[22]

 

 

3.2 JAXR

3.2.1 概述

Web服务核心的部分就是服务的发布和发现,目的就是服务的标准化和集成化,特别是动态集成服务的发现和使用。

大多数B2B的业务是两个交易双方以伙伴关系的紧密协同合作,这些合作伙伴共享一个注册,通常是以基于Web的服务形式存在。一个注册功能就像电子黄页,在那里你就可以发布和发现有关商业、产品和所提供的服务的信息。注册中心也可以当作数据库,或者存储共享信息库,或者有关某些事情的资料。注册中心也可以作为电子公告板,合作伙伴就可以动态、时尚地共享信息。

注册服务的客户端进行的典型操作是什么呢?提交和保存共享信息是比较重要的注册操作,客户端需要完成注册管理操作,比如标识、命名、描述、分类、关联、分组和标注注册元数据等。最后,客户端还必须能够从注册中心完成查询、发现和得到共享的信息等操作,并且期望一个典型的注册中心能支持这其中的大多数的操作。

通过注册中心,可以允许一个组织发布和发现其Web服务。目前,占有支配地位的有两个注册标准:UDDIebXML,使用两者之中的任何一个,商业公司就可以发布一套Web服务,内部的或者外部的商业伙伴就可以发现它们。然而,要集成和注册Web服务而不考虑对注册标准的支持,对商业行为来说,是一件具有挑战性的事情。

JAXR提供了一套标准的API来通过现有的注册体系发布和发现Web服务。目前,JAXR包含在JAVA Web服务开发包(JWSDP1.0和最近发布的JAVA XML包之内,此外,JAXR将在J2EEJAVA 2 平台企业版)1.4中占据重要作用。

3.2.2 JAXR概念

Java API for XML RegistriesJAXR)提供一个统一的、标准的 Java API,用于访问不同类型的 XML RegistriesXML 注册项是构建、部署和发现 Web 服务的基础设施。

JAXR并不是定义一个新的注册标准,相反,这个标准的JAVA API对不同的注册服务进行操作,并定义了用来描述注册内容的统一信息模型。不考虑要访问的注册服务提供者,你的程序可以使用通用的API和通用的信息模型。JAXR定义了一套通用的API,允许任何一个客户端通过JAXR提供者对任何一个商业注册中心进行访问和互操作。从这种意义上讲,JAXR提供的是一次编写,处处运行的注册操作API,这样可以大大简化Web服务的开发和集成。

JAXR专家组希望API能够同时支持UDDIebXML的最突出、最好的那部分特性,而不是一些普通的特性。就像标准中阐述的那样,JAXR至少不是一种普通意义上的API

3.2.3 JAXR结构

JAXR定义了三个重要的结构:

1)注册提供者实现了现存的注册标准,如OASISOrganization for the Advancement of Structured Information/ebXML注册服务标准2.0

2JAXR提供者实现了Java Community Process (JCP)20025月批准的JAXR规范。

3JAXR客户端是一个JAVA程序,通过JAXR提供者使用JAXR访问注册提供者。JAXR客户端既可以是独立的J2EE应用程序,也可以是J2EE的组件,比如:EJBEnterprise JavaBeans),JAVA Servlets,或JSP页面(JavaServer Pages),JAXR实现部分的手册里也提供了一个基于Swing的注册浏览的JAXR客户端应用程序。

3.1说明了不同的JAXR客户端上如何利用JAXR与不同的注册中心进行交互操作的。在结构上,JAXR客户端利用API执行注册操作,而JAXR提供者实现这个API的功能。由于JAXR提供了一个标准的API来访问不同的注册提供者和描述注册内容的统一信息模型,无论是HTML浏览器、J2EE组件或独立的J2SE应用程序的JAXR客户端,都能够统一地对不同的注册提供者执行注册操作。[23]

3.1 JAXR客户端与注册中心的交互

 

3.3 JNDI

JNDI(The Java Naming and Directory InterfaceJava命名和目录接口)是一组在Java应用中访问命名和目录服务的API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象。目录服务是一种命名服务,在这种服务里,对象不但有名称,还有属性。JNDI规定了命名服务和目录服务之间的差别,命名服务将一个名称映射到一个对象。

命名或目录服务使你可以集中存储共有信息,这一点在网络应用中是重要的,因为这使得这样的应用更协调、更容易管理。例如,可以将打印机设置存储在目录服务中,以便被与打印机有关的应用使用。

目录服务是命名服务的自然扩展。两者之间的关键差别是目录服务中对象可以有属性(例如,用户有email地址),而命名服务中对象没有属性。因此,在目录服务中,你可以根据属性搜索对象。JNDI允许你访问文件系统中的文件,定位远程RMI注册的对象,访问像LDAP这样的目录服务,定位网络上的EJB组件。 

对于像LDAP 客户端、应用launcher、类浏览器、网络管理实用程序,甚至地址薄这样的应用来说,JNDI是一个很好的选择。 

JNDI架构提供了一组标准的独立于命名系统的API,这些API构建在与命名系统有关的驱动之上。这一层有助于将应用与实际数据源分离,因此不管应用访问的是LDAPRMIDNS、还是其他的目录服务。换句话说,JNDI独立于目录服务的具体实现,只要你有目录的服务提供接口(或驱动),你就可以使用目录。

关于JNDI要注意的重要一点是,它提供了应用编程接口 (application programming interface,API)和服务提供者接口 (service provider interface,SPI)。这一点的真正含义是,要让你的应用与命名服务或目录服务交互,必须有这个服务的 JNDI服务提供者,这正是JNDI SPI发挥作用的地方。服务提供者基本上是一组类,这些类为各种具体的命名和目录服务实现了JNDI接口—很像JDBC驱动为各种具体的数据库系统实现了JDBC接口一样。作为一个应用开发者,你不必操心JNDI SPI。你只需要确认你要使用的每一个命名或目录服务都有服务提供者。[24] 

3.4 JMS和消息中间件

企业消息传递系统通常又称为面向消息的中间件(Message Oriented Middle Ware,简称MOM),它使用松散耦合的、非常灵活的方式来集成应用程序,在存储和转发的基础上支持应用程序间数据的异步传递;每个应用程序都只与作为中介的MOM通信。

JMS就是用于和企业消息传递系统相互通信的应用程序接口(图3.2简单描述了这一通信模型)。在JMS出现之前,每个MOM供应商都提供专有的API以供客户程序访问它们的产品;而JMSjava客户程序通过MOM产品收发消息提供了一种标准可移植的方法——用JMS编写的程序能够在任何实现了JMS标准的MOM上运行。[25]

 

3.2 JMS通信模型

JMS体系由客户端(Messaging Clinet)和MOMMessage-Oriented Middleware)构成。

原理是:发送者将消息发送给消息服务器(MOM),消息服务器将消息存放在若干队列中,在合适的时候再将消息转发给接受者。在这种模式下,发送和接受是异步的,发送者只要把消息发送出去,程序将继续执行而无需等待。两者的生命周期可以不同:发送消息的时候,接受者不一定运行,接受消息的时候发送者也不一定运行。

基于消息的异步处理模型采用非阻塞的调用特性,发送者将消息发送给消息服务器,消息服务器在合适的时候再将消息转发给接收者;发送和接收是异步的,发送者无需等待,二者的生命周期也可以不必相同,而且发送者可以将消息间接传给多个接收者,大大提高了程序的性能、可扩展性及健壮性,这使得异步处理模型在分布式应用上比起同步处理模型更具有吸引力。这种模式下,发送和接收是异步的,发送者无需等待;并且发送消息的时候接收者不一定运行,接收消息的时候发送者也不一定运行;另外实现了一对多通信:对于一个消息可以有多个接收者。

JMS支持两种消息传递模式――点对点模式(P2P)和发布/订阅模式(Publish/Subscribe)。这两种都是人们熟知的push模式,消息的发送者是活动的发起人,而接收者则是被动的接收消息。在JMS中,这些消息传递模式被称为消息域(message domain)。

JMS点对点消息域:

在点对点模式中,发送者和接收者对消息传送的目的地址达成一致,即所谓的队列(queue)。消息队列位于JMS提供者中,消息发送者向一个消息队列发送消息,消息接收者可以在消息发送后的任何时刻从这个队列中(被动地)接收消息,在接收者确认之前消息一直保存在消息队列中直到过期。点对点模式的结构图如图3.1所示:

3.3 点对点模式

JMS点对点消息域具有以下特点:

ü  每条消息能而且只能被一个接收者接收。

ü  每条消息或者被接收者从队列中取走,或者被 JMS提供者在超时的情况下删除。

ü  消息产生的时候接收者不一定要存在,接收者可以在消息产生后的任何时间里取走消息。

ü  接收者不能请求一个消息。

ü  接收者必须在收到消息后发出确认信息。

JMS发布/订阅消息域

在发布/订阅模式下,发送者被称为发布者(publisher),一个消息可已有很多接收者,这些接收者被称为订阅者(subscriber)。发布/订阅模式采用与点对点模式完全不同的消息发送模式。在发布/订阅模式下,发布者给一个主题(topic)发送消息,多个订阅者在订阅的时候可以订阅他们感兴趣的主题。一个主题可以被多个订阅者订阅,一个订阅者也可以订阅多个主题。一个主题的消息只被发给该主题的所有订阅者。订阅者只能接收它订阅的主题中的消息,并且,在默认情况下,订阅者在消息发送的时候必须是活动的,并随时准备接收消息,否则它将错过该消息。为了避免这种时间依赖性JMS API允许订阅者创建持久订阅。发布/订阅模式的结构图如图3.2所示:

3.4 发布/订阅模式

JMS发布/订阅消息域具有以下特点:

ü  每一条消息由一个发布者创建而由0个或多个订阅者接收它。

ü  消息立刻被分发给现有的订阅者。

ü  订阅者必须在消息发送的时候存在以接收消息。

ü  持久订阅允许订阅者接收它处于非活动状态时由发布者向主题发送的消息。

ü  订阅者必须在接收到消息后发出确认信息。

Java 消息服务(Java Message ServiceJMSAPI J2EE 平台的构成元素。JMS 1.0.2 定义了两种类型的消息传递域(它们是相互独立的),即点对点和发布/订阅。JMS 的最新版本,即版本 1.1,将成为 J2EE 1.4 的一部分,EJB 2.1 也将会需要它,JMS 统一了这两个域。有了 JMS 1.1,客户机就不再必须专门针对这个或那个域进行实现了。相反,JMS 客户机可以实现为能与来自任一域的目标一起工作。这极大地简化了 JMS API,并为开发者创建更通用、重用性更好的消息传递代码提供了机会。一旦有实现 JMS 1.1 JMS 提供程序和 J2EE 容器可供使用,JMS 客户机代码的开发者就应该可以开始在他们的新代码中使用版本 1.1 API,并且也可以从将他们现有的 JMS 1.0.2 代码移植到新的 API 中受益。

3.1 JMSAPI列表

JMS 公共

PTP

Pub/Sub

ConnectionFactory

QueueConnectionFactory

TopicConnectionFactory

Connection

QueueConnection

TopicConnection

Destination

Queue

Topic

Session

QueueSession

TopicSession

MessageProducer

QueueSender

TopicPublisher

MessageConsumer

QueueReceiver

TopicSubscriber

由于企业服务总线系统发布在weblogic9.1.0应用服务器上,所以消息中间件使用weblogic9.1容器自带的JMS

同时提供对其他消息中间件的使用接口的支持。例如:ActiveMQJBossMQWebsphere MQ

3.5 Digester框架

3.5.1 概述

Windows下开发程序,用M$提供的接口处理.ini文件或管理注册表的键值是非常方便的。在java平台上开发程序,则习惯于以xml格式的文件来存放系统的配置信息,对这种文件的解析和处理可以使用Digester框架,

JavaXML开发中,一个常见的任务是把XML文档转换成对应的Java Bean对象的层次结构。人们经常用标准的SAXDOM API来完成这个任务。虽然这两种API都很强大和灵活,但对于某些简单的任务来说,它们显得操作层次太低,也就是说,涉及了太多的细节问题。Jakarta Digester框架能够很好地满足这类场合的需要。 

Digester框架属于Jakarta Commons,它以规则和模式为基础处理XML文档。与SAXDOM之类的标准API相比,Digester不涉及太多的细节问题,非常适合于对XML文档进行简单的处理, 它具有把XML文件映射到Java对象的能力.

总的来说,XML文件解析有2种基本方法。一种是DOM(Document Object Model)方法。采用DOM方法进行解析时,XML解析器读取整个XML文件并生成一个树状表达方式。另一个是使用SAX,它的特点是不需要遍历整个文件而是用事件驱动来解析文件。虽然DOM方法有时实现起来比较容易,但是与SAX方法相比速度更慢而且更耗资源。Digester构件通过为SAX事件提供高级的接口大大简化了SAX方法的解析过程。该接口隐含了大量XML文件处理的复杂的技术细节。使开发人员得以集中精力处理XML数据而不是花太多的时间在如何解析文件本身上。

3.5.2 Digester中的概念

为了更好地应用Digester,需要深入理解三个重要概念:元素匹配模式,处理规则以及对象栈。

(1) 元素匹配模式

为了简化使用,Digester通过元素匹配模式来定位要解析的XML元素标签。如果将XML文件结构看作为一颗树,那么每个标签的匹配模式就是从根元素到这个元素的路径。下面是一个XML层次结构的元素匹配模式的例子:

<?xml version="1.0"?>

<teachers>

<teacher>

<name>Jim</name>

<course>C</course>

</teacher>

<teacher>

<name>Mary</name>

<course > Java </course>

</teacher>

</teachers>

每个标签与相应的匹配模式对应如表3.1所示。

3.1

标签

匹配模式

<teachers>

teachers

<teacher>

   teachers/teacher

<name>

teachers/teacher/name

<course>

teachers/teacher/course

(2) 处理规则

元素匹配模式用以识别什么时候采取行动,处理规则用以定义行动的内容。Digester预定了很多处理规则,并允许用户进行自定义,自定义的处理规则是通过扩展org.apache.commons.digester.Rule类来实现。

从形式上讲,一个处理规则是一个java类,它扩展了org. apache. commons. digester. Rule类。每个处理规则实现下列的一个或几个事件处理方法(event method),当相应的模板匹配成功后,在已定义的某个时刻,这些事件方法会被触发。

ü  begin( ),在一个匹配元素被识别出后的“开始”时刻被调用,这个元素的所有属性放在一个数据结构中,并传递给begin()

ü  body(),当元素的嵌套内容(如子元素)被识别出时被调用。在解析的过程中,前后的空白被去掉

ü  end(),匹配元素的“结束”时刻被调用。如果子元素也需要匹配相关的规则,则这些规则的方法需都执行毕,才能达到该元素的“结束”时刻。

ü  finish( ),解析结束时被调用,以提供给各个规则以清理临时数据的机会。

(3) 对象栈

Digester技术最普通的应用,是用来动态创建一个由Java对象构成的树结构。各对象的属性以及对象间的关系,是基于XML文档的内容来设置的(XML文档就是一棵树)。为实现这种应用,Digester提供一个对象栈,在匹配模式识别后激活处理规则操作。对象栈的基本操作包括:

ü  clear(),清空栈的内容。

ü  peek(),返回对栈顶对象的引用。

ü  pop(),将栈顶对象弹出并返回。

ü  push(),将一个新的对象压入栈顶。

 对象栈的运行过程如下:当识别出一个XML元素的“开始”时,将相关对象生成并压入栈顶,这个对象在处理该元素的子元素过程中一直在栈中,当所有子元素都处理完后,解析器遇到这个元素的“结束”时,则弹出此对象,并进行相关的处理。对象可以由处理规则或Digester中的相应方法压入和弹出对象栈。

尽管Digester最初是为了简化对XML配置文件的解析而开发的。但是它也可以用在把XML文件映射到java对象的场合。[26]

3.6 log4j

Log4jApache组织的一个开源项目,它是一个日志操作包,通过使用Log4j可以指定日志信息输出的目的地,如控制台,文件,GUI组件,NT的时间记录器,还可以控制每一条日志输出的格式,此外通过定义日志的级别,能够非常细致的控制日志的输出,最好的地方是这些功能可以通过一个配置文件来灵活的进行配置,而不需要修改程序代码.在应用程序中输出日志有三个目的:

1) 监视代码变量的变化情况,把详细信息记录到文件中,进行统计分析;

2) 跟踪代码运行轨迹,作为日后审计的依据;

3) 担当集成开发环境中的调试器的作用,向文件和控制器打印代码的调试信息。

Log4j最重要的是首先要了解两个常用的接口:LogLogFactory.首先说一说Log接口.通用日志包把日志消息分为6个级别:

1) fatal致命的

2) error错误

3) warn警告

4) info信息

5) debug调试

6) trace细节

其中级别按照以上的顺序,org.apache.commons.logging.Log接口代表日志器,它提供一组输出日志的方法.例如fatal(Object message)参数都是一个对象,要注意的是只有当它输出日志的级别大于或者等于为日志配置的级别的时候,这个方法才会被执行.Log接口还提供了一组判断是否允许输出特定级别日志信息的方法,很简单例如isFatalEnabled()在程序输出某种级别的日志消息之前,提倡先调用以上的方法来判断该级别的日志是否允许输出,这有助于提高应用的性能.这种判断主要是为了提高性能,避免执行多余的操作。

以上阐述了重要的Log接口,下面简单说明一下LogFactory接口,这个接口也和Log接口一样在logging包中,接口提供了获得日志器实例的两个静态方法如下:

public static Log getLog(String name)throws LogConfigurationException;

public static Log getLog(Class class)throws LogConfigurationException;

第一个getLog()方法name参数作为日志器的名字,第二个getLog()方法以class参数指定的类的名字作为日志器的名字。

在强调可重用组件的今天,除了自己从头到尾开发一个可重用的日志操作类以外,还有一个Apache为我们提供的一个强有力的现成的日志操作包Log4j.主要由三大组件构成:

1) Logger:负责生成日志,并能够对日志信息进行分类筛选;

2) Appender:定义了日志信息输出的目的地,指定日志信息应该被输出到什么地方;

3) Layout:指定日志信息的输出格式。

以上的三个组件协同工作,使得开发者能够依据日志信息类别记录信息,并能够在程序运行期间,控制日志信息的输出格式以及日志的存放地点.Log4jAppender组件决定日志输出到什么地方,目前Log4jAppender支持将日志信息输出到控制台Console,文件,GUI组件.一个Logger可以同时对应多个Appender也就是说一个Logger的日志信息可以同时输出在多个目的地上.例如可以为rootLogger配置两个Appender,一个是file一个是console可以这样写:log4j.rootLogger=warn.file.console然后可以用appender.console或者是appender.file来指定具体的控制台或者文件.当以上的都设置好了以后还需要配置Layout组件,主要是解决日志的输出格式,它的类型有:HTMLLayout(html格式),PattemLayout(可以灵活的指定布局模式),SimpleLayout(包含日志信息级别和信息的字符串)TTCCLayout(包含日志生产时间,线程和类别等信息).通过如上的研究已经可以配置Log4j,然后就可以通过Log4jAPI来操作日志了.如果要在Web应用中使用Log4j,需要创建一个配置文件配置Log4j的环境,然后就可以在其他的Web组件中获取Logger对象并输出日志.下面展示一个局部的Log4j,这里只是举例Log4j的配置文件和在具体的Action中进行调用,如下:[27]

1)Log4jjar文件copyWEB-INFlib目录下;

2)创建Log4j的配置文件log4j.properties存放在classes目录下。

Log4j.rootLogger=INFO,console,file

Log4j.appender.console=org.apache.log4j.ConsoleAppender

Log4j.appender.file=org.apache.log4j.RollingFileAppender

Log4j.appender.file=e:/log/log.txt

Log4j.appender.console.layout=org.apache.log4j.PattemLayout

Log4j.appender.console.layout.ConversionPattrm=%t%p-%m%n

Log4j.appender.file.layout=rog.appache.log4j.HTMLLayout

Log4j.appender.file.layout.ConversionPattem=%t%p-%m%n

 

3.7 本章小结

本章着重介绍了在开发企业服务总线系统过程中所要用到的关键技术,总结为以下几种:UDDI标准以及它的java实现Juddi用于访问不同类型的 XML Registries技术JAXRjava名字和目录接口(jndi)、java消息服务(JMS)、Digester框架和日志工具包等。通过对这些相关技术的深入研究和理解,才能将这些技术应用到企业服务总线系统的各个模块的设计和开发过程中,为企业服务总线系统的各个模块的设计和开发工作做好技术准备工作。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值