1. 系统集成的基础设施
RPC (Remote Procedure Call)
RPC是现代C/S和分布式程序的基础概念之一,通常由具体的技术来实现。以下是远程通信通常遵循的模式:
客户程序 <-> 桩(残根)函数接口 <-> Channel(协议栈通信通路) <-> 桩(残根)函数接口 <-> 服务程序
优点: 隐藏传输细节; 简化; 透明
桩函数接口的作用: 程序参数和通信栈上数据之间的转化、组织和传递。
CORBA (COmmon Request Broker Architecture)
CORBA曾经非常流行的一种RPC模式。其基本概念包括:
物件Object -- 可接受客户请求可位于远端的实体;
服务Servant -- 物件的功能实现;
IDL(Interface Definition Language) -- 接口定义语言,一种协议,类似COM的IDL,WSDL等的作用;用于保证CORBA语言无关。
ORB(Object Request Broker) -- 直接位于通信栈上用于处理请求的机构
通信模式:
客户程序(使用) <-> 物件对象(引用) | 桩函数接口(根据IDL生成) <-> ORB
|
通信链路
|
服务程序(创建和维护) <-> 物件对象(实现) | Skeleton函数接口 <-> ORB
RMI (Remote Method Invocation)
是Java程序之间RPC通信的方式。如果JAVA要和其他语言程序通信,则采用CORBA;因此rmic工具为特定桩对象生成Java方法以支持通信。
在两个Java虚拟机之间则用JRMP(Java Remote Method Protocol)通信。
Server侧接口需继承:java.rmi.Remote,异常:java.rmi.RemoteException。
首先System.get/setSecurityManager()设置安全管理对象,java.rmi.registry.*设置Registry;对象创建,然后绑定到Java的命名系统中:Naming.bind("路径", obj); 客户端查询则通过Naming.lookup("路径");
.NET Remoting(已被WCF取代)
仅仅是上课提到,非上课重点,且为更新技术取代,不再赘述。
2. JEE (J2EE) 系统集成技术发展
1.2 (初始版): Servelets, JSP, EJB, JMS, Mail, JDBC, Transactions, JNDI
1.3:Connector Architecture, JAAS, XML for Web Services, JSP Tag Libraries
1.4:Management (JMX), 安全扩展(Security Extensions)
1.5:(主发布版本) 原部署标记(XML)可以用Annotation取代,Dependency Injection,JPA
1.6:(最近版本) Profile概念(功能子集),REST的Web Service(JAS-RS),Managed Beans,Bean Validation, EJB Lite, Servlet(支持Annotations, 异步asynchronous,可插卸性pluggability),Faces(Annotations, facelets, AJAX, implicit navigation)
3. JDBC
JDBC
目的:使Java接入关系数据库系统Relational Dababase Management System (RDMS);
驱动Driver:适应特定数据库的JDBC API;
注册:v4以后的驱动不需要
结构: Java应用 | JDBC API | JDBC SPI | JDBC驱动(数据库提供商提供) <-> 数据库
步骤:
1. 驱动注册: Class.forName("驱动名称").newInstance(); // need to catch Exception e
2. 建立连接: Connecton conn = DriverManager.getConnection(url); // need to catch SQLException
2'. 含参连接: Properties props = new Propertis(); props.setProperty("user", "Peter"); props... conn = DriverManager.getConnection(url, props); 或: conn = DriverManager.getConnection(url, name, passwd);
2''. DS连接:Context ctx = new InitialContext(); /*JNDI*/ DataSource ds = (DataSource)ctx.Lookup("路径"); conn = ds.getConnection([user, passwd]); (DataSource是一个Factory产生普通/Pooled/Distributed Transaction的连接)
3. 使用后关闭连接: conn.close();
JDBC中使用SQL语句
Statement:执行SQL查询和更新:
Statement stmt = conn.createStatement(); int res = stmt.executeUpdate("SQL更新语句");ResultSet rs = stmt.executeQuery("SQL查询语句" [, resultSetType concurency, holdability]); ... stmt.close();
PreparedStatement:允许java变量作为参数:安全性(防止SQL代码注入);效率(驱动可优化执行代码)
PreparedStatement ps = conn.prepareStatement("..?..?..?.."); ps.setInt(1,...); ps.setString(2,...); ...; ps.executeUpdate(); ps.close();
JDBC中执行事务(Transaction)控制
自动控制:conn.setAutoCommit(true/false); /*默认true,每执行一SQL即commit*/
手动控制:conn.commit(); 或 conn.rollback();
conn.setTransactionIsolationLevel(int level); /*Connection.TRANSACTION_NONE, READ_COMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE */
CURSOR
使得一组从Query返回的数据行可被结构化/OO语言访问。
4. Hibernate技术
Hibernate
一种自动连接到RDBMS的技术,与JavaBean属性对应(Mapping)。
规定:JDBC属性和数据列的对应;设置映射关系(Mapping);跨数据库支持;DDL生成;同时支持XML或Java Annotation
配置:连接到DB;映射的类;Caching;Transaction管理
Hibernate API
使用HQL完成数据获取并存入到映射的物件中。
Query q = session.createQuery("from Product");
List products = q.list();
HQL
例如:
from Product p where p.name = '...'
5. JPA
JPA
标准化的Java物件向关系数据库的映射(Java Object Relational Mapping)
提供者:ORM实现支持:如Hibernate, OpenJPA, EclipseLink等
因此JPA在概念上是比Hibernate相对更抽象和标准化的架构。
JPA常用Annotations
@Entity 定义一个数据保持对象,修饰类
@Table 定义表性质,修饰类(Table通常和一个类对应)
@Basic 定义数据保持属性,修饰变量
@Column 定义对应RDBMS列的性质,修饰变量(Column通常和一个变量对应)
@Id 定义实体(entity,即类实例)对应的主键,修饰变量,通常是int型
@GeneratedValue 定义如何生成主键值(如IDENTITY),修饰变量
@NamedQuery 定义一个命名查询,修饰类
JPA过程
(java.persistence.)EntityManagerFactory emf = EntityManagerFactory.createEntityManagerFactory();
java.persistence.EntityManager em = emf.getEntityManager(); // emf是EntityManager的类厂
em.getTransaction().begin();
... obj ...
em.persistent(obj); //数据实例本身保存,和数据库同步(数据实例更改反映到数据库)
em.getTransaction().commit();
em.remove(obj);
em.merge(obj); //数据实例备份被保存,故数据实例后续更改不反映到数据库
em.close(); emf.close();
参考: http://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge
6. EJB技术
EJB
简化分布式应用开发; 应用组件开发的框架; 作为一个容器,包含: 保持Persistence,事务Transaction Integrity;并发控制;目录服务(Directory Services);部署服务(Deployment Services);安全
Entity Beans
一个应用实体,例如:顾客、订单等。
Session Beans
业务逻辑的封装;代表一个单独的客户端交互单元;分成Stateful和Stateless
层次结构
Web Browser
----------------
Web Container: JSP Pages / Servlets
----------------
EJB Container: EJBs
----------------
Database
组件通信结构
Local接口 EJBLocalHome派生接口作为工厂创建EJBLocalObject派生接口的实例
Remote接口 EJBHome派生接口作为工厂创建EJBObject派生接口的实例;Remote之不同在于可跨JVM访问
而实际的业务逻辑由SessionBean的派生类实例完成
参考: http://stackoverflow.com/questions/913267/ejb-confused-about-home-remote-localhome-local-interfaces
状态转换
Stateful: [doesn't exist] <-remove | create/setSessionContext-> Ready <-passivate | activate-> Passive
Stateless: [doesn't exist] <-remove | create/setSessionContext-> Ready
EJB使用
Context ini = new InitialContext();
Context env = ini.lookup("env路径");
Object objref = env.lookup("ejb路径");
<Home类型> home = (<Home类型>)PortableRemoteObject.narrow(objref, <Home类型>.class);
<Object实例> foo = home.create();
foo.SomeMethod();
EJBQL
用于定义Entity Bean的finder和select方法。
Select(私有)返回保持字段(Persistent fields)和相关Entity Bean;
Finder返回整个Remote Interface对象。
7. 设计模式
Singleton
单一实例全局使用,首次创建。
Factory
一个实例能够创建出其创建对象实例。
Facade
统辖和整合子项(物件)功能,提供结构化的方法操作这些物件。
Proxy
根据一组协定的接口将远程抽象到本地,由本地和远程的基础实现和通信架构完成具体的传递。
Adaptor
功能适配,使得两方的功能协调
Observer
事件通知。
Builder
用诸方法收集参数,并最后根据参数创建一个对象。
8. 企业级设计模式
Design Patterns
在给定语境下对特定问题解决方案高级抽象
Patterns(模式): 高级抽象
Strategy(实现策略): 对一个Pattern的实现层详情或具体策略
Business Delegate
隐藏远程业务服务(Business Service)复杂通信细节和实现细节,封装。用Service Locator定位服务并使用SF中的接口方法。
Client-side Artifact,有业务层实现者实现,需要理解业务服务;取出客户端对业务服务变化的依赖;可以从暂时的错误中恢复,Cache结果提速;转换远程异常到应用异常。
策略:Proxy方式,BD作为Proxy将调用转发到BS,可实现Caching和Validating,通常不处理异常;
Adapter方式,通常用于异质环境,如JEE与.NET用XML RPC通信,可以根据现有功能定义新的方法适配相应环境。
Session Facade
向远端提供业务组件和服务,中心化业务逻辑到远端,防止客户端直接访问业务层;隐藏业务物件依赖性和互动。
Session Facade可以用EJB Session Bean实现与业务组件的交互;Session Facade少含或不含业务逻辑(AS包含)。
Service Locator
统一定位业务组件;隐藏JNDI查询,类型转换,异常抛出等的具体信息和复杂性。
方案:Singleton提供定位服务;Cache提升效率;JNDI使用InitialContext;易扩展至其他。
策略:EJB (home接口, cache);JDBC(lookup Datasource,cache); JPA Entity Manager(no cache needed);Hibernate Session (no cache needed)。
范式:检查cache,如无按照一般方式获取加入cache并返回。
Application Service
中心化/抽象化业务逻辑,跨物件作用域业务层组件和服务,业务实现所需的所有结构化(Procedural)业务逻辑;在Service Facade中实现跨物件业务逻辑可能会导致Facade之间冗余。比Service Facade粗,但比BO细。更复杂的交互可由多个AS协调完成。
Business Objects (业务层 Business-tier)
在物件模型(Object Model)中分离业务数据和逻辑;物件为可重用的一层描述业务域(Business Domain)的业务实体;
统一业务行为和状态,避免业务逻辑冗余。
包含:内部的业务逻辑和规则,作用于本BO;
不包含:外部的业务逻辑和规则,作用于多个BO(由AS完成)。
客户信息的验证(Validation)。
策略:POJO+保持策略(或更好地用DAO);EJB+Bean/Container Managed Persistence;
Data Access Objects
数据访问和数据处理(Manipulation)分离,故而将应用逻辑和数据保持和访问逻辑(persistence/data access logic)分开。
封装/抽象化到数据存储的访问;处理到数据存储的连接;没有详情和信息的泄漏,例如没有java.sql.SQLException,ResultSet的抛出等;统一抽象的客户端API;使用TO进行数据返回和用户更改。
Transfer Objects
用于传送多个数据元素,跨越应用各层(App. Tiers);如果用Entity Bean的属性getter和setter来完成则由于数量多而低效。
它们只是简单的Java类,可用字段直接访问或getter/setter或仅getter可读访问。
策略:一个App中使用不同的TO; 可更新,客户端可修改并返回更改;Entity(Business Object)继承了TO的实现策略减少代码冗余。
9. 其他方式
消息队列
安全;负载平衡,可增加请求接受数量;消息驱动架构,到达后自动触发程序处理,队列路由消息;容错,收到的消息必会传递。
程序到程序,从队列中读写消息;无需专有通信连接
Websphere MQ
Message Descriptor:ID, Type, Expiry Time, Priority, QueueNameForReply
Message Data: 消息数据主体
消息类型:Datagram,请求无回复;Request,请求需回复;Reply,为回复;Report,事件报告,如错误。
Persistent:记录(log)到二级存储,重启后可恢复; Non-persistent,不可恢复。
MQEnvironment
定义一系列不同的连接属性,用于和MQManager连接时提供环境信息。
MQManager
维护一些队列MQQueue
方法:
begin开始一个事务
backout撤销一个变化
commit提交一个事务
MQQueue
方法:
void get(MQMessage message[, MQGetMessageOptions getMessageOptions, int maxMsgSize]) throws MQException;
void set(MQMessage message[, MQPutMessageOptions putMessageOptions]) throws MQException;
JMS (Javs Message Service)
方式:
1. 点对点(Point-to-point)队列: 一个Producer对应一个Consumer,无Consumer表示消息挂起。
2. 发布订阅(Publish-subscribe): 可被任意个Consumers获得,Consumer注册定于一个topic,当无对应topic的Consumer,消息丢弃。
JMS消息
消息体(可选),类型:空消息;流(一串Java基本类型);Map(名/值对);Text(字符串信息,如XML);Object(例如Java对象);字节串
消息头:用于路由及辨识的消息
属性:值只能是Java基本类型,只能在消息创建时设置
JMS框架和流程
ConnectionFactory为连接类厂,创建连接Connection
Connection创建后是Stop状态,用start()/stop()管理消息流动;它也是Session类厂
JMS Destination:源或目的,是实现(如MQQueue)的抽象,或类似于WCF中的Endpoint
Session创建Message,也创建Producer和Consumer,分别从或向对应Destination中获取或发送消息。
异步获取,可以Consumer.setMessageListener(一个MessageListener对象)
IMS (IBM Information Management System)
和Java, JDBC和Web Servces交互
数据模型(Data Model):分成多个Segments,由数据库组织Segment的Hierarchical Structure。
事务模型(Transaction Model):从终端(如Web Client等)获得事务,队列成消息,Schedulers启动业务应用来处理事务。
IMS的两个Java程序的执行环境
Java Batch Processing (JBP) regions:
1. 创建IMSDataSource对象并设置参数,包括数据存储名称,数据类型,Metadata的URL
2. 创建Application对象,在尤其创建获得Transaction对象tran
3. 从IMSDataSource对象获取连接Connection对象conn, 在conn上可以用JDBC的接口方式执行Query Statements
4. 由PSBFactory.createPSB()创建PSB对象,再由其上的getPCB获得PCB,再由PCB上getSSAList获得SSAList ssa
5. PathSet pathSet = pcb.batchRetrieve(ssa); pathSet.hasNext() Path path = pathSet.next()可遍历树状路径。
6. tran.commit(),psb.close()
Java Message Processing (JMP) regions,与JBP流程不同在不用PSB而用:
1. 创建IMSFieldMessage派生类用于封装一组DLITypeInfo
2. 从Application对象中获得MessageQueue
3. IOMessage ioMessage = app.getIOMessage("到1定义的类的路径");
4. 循环中从MessageQueue中获得更新ioMessage,进行处理,并最后将ioMessage insert到MessageQueue中
IMS访问
2型JDBC驱动:借助JNI并在同一个z/Series逻辑分区
4型JDBC驱动:可以通过TCP/IP访问
JDBC驱动基于IMS结构虚拟一个关系数据库,功能包括Aggregate函数(SUM, MIN, MAX, ...),ORDER BY和GROUP BY
IMS Universal DL/I驱动:本地访问IMS的API,Java实现调用接口,以比JDBC更低级方式接入IMS;创建Search Segment Arugments;
Program Communication Block物件用于读写和执行批处理和segments;完整的segment hierarchy的浏览
IMS元数据(Metadata)
描述IMS Program Specifiation Blocks, Database(DBDs),segments,字段,关系,键/非键,和数据类型等;
IMS Universal驱动用之创建和审核查询;保证所有相关的DBDs都可用;DLIModel工具将会生成合适的Java代码。
10. Web Services
Service:抽象的功能集合;
Agent:Service的具体实现;
Provider:提供Agent的实体;
Requester:需要使用Agent的实体。
SOAP - 交换结构化信息的协议,W3C标准XML应用通常使用HTTP和其他协议用于消息传输
消息结构: Envelope { Header(可选); Body; Fault(可选); }
WSDL - Web Service Description Language, XML应用,描述服务,语言和平台无关,XML Schema用于数据类型
格式:definitions, types, messages, portType, binding, service
工具:wsgen, wsimport
REST - REpresentational State Transfer,相对轻量级的WS。限制:
C/S,两侧可分别演化; Server不保留状态,所有信息在请求中包含; 可Cache; Layered System客户无法获知对方身份; Code on demand (可选,返回给客户Javascript或Java Applets);统一接口;
操作:基于HTTP操作,组(collection)URI和element URI;GET获取成员/PUT更改或创建成员/POST新建项/DELETE删除组或成员
JSON (原JavaScript Object Notation,现在语言无关)
序列化和传送数据
11. 后续发展
SOA (Service Oriented Architecture,但事实上并不能称为Architecture,
SOA是一种模式,而Web Services则对应地是一种具体的策略。基于SOA的系统应该将功能用一组可互操作的服务实现,而这些服务可以被位于多个业务域的不同系统使用。
SOA服务
用IT方式实现业务功能;一个单独的动作,如创建一个顾客,或更改顾客名称,支付等;隐藏技术细节;可被商务/管理人员理解
Producer提供服务的实体,Consumer访问服务的实体。
送耦合
防止组件间依赖;考虑异步通信问题;异质数据类型;大系统中,最小的可提供共识必须保证;系统越大,耦合需要越松。
一些问题
数据类型协调(Data Type Harmonisation): CRM和ERP对Customer的定义不会一样。
Mediators:Consumer寻找Producer的方法:Name service,搜寻Provider然后调用;路由(由基础设施实现)。
Validation:尽量早;尽量不用底层执行该验证;不同的情形不同方式
数据类型:考虑能最大化交互
双步提交(Two-step Commit):较高的资源需求;较高的编程要求;不是所有系统支持;需要所有系统在线
补偿提交(Commit with Compensation):保证总体一致性;顺序更改,可回退;混入人工
服务分类
基础服务(Basic Services):原子性;数据(业务数据处理,事务)/逻辑服务(如验证信息);自治自包含;可能有重复
组合服务(Composed Services):组合;短时(Short-running);无状态;例如,转账
处理服务(Process Services):表示业务过程(Business Process);长时(Long-running);通常有状态以跟踪业务流进程;例如买保险网购等
SOA层次
基础层(Fundamental)——通常只有基础服务
联合层(Federated)——基础和组合服务,组织内增值
处理使能层(Process-enabled)——包含处理服务,或需要人工介入
服务的其他特性
公共和内部服务:安全性;可用性;稳定性;部署
读服务:较简单,脚步稳定,可能需要审查(Auditing);写服务:可能需要补偿,审查和跟踪更新
关键要素
基础设施;架构;处理过程(包含管理支配(Governance))
ESB (Enterprise Service Bus)
允许Consumer访问Provider的服务
互操作性
解决服务之间的阻抗性失配(impedance mismatch)
Facilities of ESB:
Connectivity, Data transformation, Routing, Security, Reliability, Service Management, Monitoring/Logging, 等
异质ESB,通过路由等连接
Mediation
BPEL (Business Process Execution Language)
Business Process Management: 技术使能的,对长期的和多步的跨系统和人员的过程获得可见性和控制
Business Process Modelling: 描述所有或部分业务过程的一组实践
自下而上设计:可能会导致过于复杂繁难的技术
自下而上设计:可能会导致冗余或缺漏
实践上可以采取综合的设计方法
BPEL: 一种集成Web Services的技术,用于定义包含启动Web Services的BP,本身作为WS触发,OASIS维护,XML应用,可执行的规则
基本活动:
receive(接受请求), invoke(调用Web Services), assign(处理变量), validate(验证保存的XML), reply(回复消息)
throw(产生错误),rethrow(转发错误),exit(退出一个过程),compensate(调用补偿活动),compensateScope(在子作用域补偿),
wait(等一段时间),empty(无操作),extensionActivity(语言扩展包装)
结构化活动:
flow(并行执行),sequence(顺序执行),while(条件循环),repeat(循环直到),pick(阻塞到消息到达),forEach(顺序/并行),
if/elseif/else(分支),scope(创建子作用域)