架构设计
版本号 : v1.0
作者 : hjl
2014年3月27日星期四
1. 目的
本说明书的编写目的是描述系统的架构设计方案,包括系统的软件总体架构设计及使用框架说明,以及基于该架构的开发流程,并作为指导开发人员、测试人员进行系统开发以及测试的依据。
2. 总体结构
总体图
平台主要功能如下:
资源管理:主要包括OpenStack的所需功能,来完成平台的基本功能。功能如:虚拟化、存储、网络等;
用户管理:主要是创建用户、分配用户访问权限、管理用户给子用户分配权限等;
设备管理:主要管理机房环境基础设施,如:UPS、空调等;
监控管理:主要对设施的监控告警、服务器的性能监控等;
统计分析:主要对用户访问的次数统计、流量统计;
计费账单:对计费的统计,做报表账单;
系统管理:系统功能的配置等;
3. Base与其他系统关系
Base层主要是做统一的Restful接口,这样Client端可以做相应设备的SDK来请求统一的Restful接口来实现方法,Kernel端是不同的资源池,有OpenStack、cloudstack等等,来实现Infrastructure端的能力如:计算资源、存储资源、网络资源、动环资源等,Base层做统一的接口来对应Kernel层资源的能力。
4. 架构设计
项目管理
本项目采用Maven做项目管理,其负责的开发过程中几乎所有东西:
1.版本
maven有自己的版本定义和规则
2.构建
maven支持许多种的应用程序类型,对于每一种支持的应用程序类型都定义好了一组构建规则和工具集。
3.输出物管理
maven可以管理项目构建的产物,并将其加入到用户库中。这个功能可以用于项目组和其他部门之间的交付行为。
4.依赖关系
maven对依赖关系的特性进行细致的分析和划分,避免开发过程中的依赖混乱和相互污染行为。
5.文档和构建结果
maven的site命令支持各种文档信息的发布,包括构建过程的各种输出,javadoc,产品文档等。
6.项目关系
一个大型的项目通常有几个小项目或者模块组成,用maven可以很方便地管理。
7.移植性管理
maven可以针对不同的开发场景,输出不同种类的输出结果。
架构层次
通过成熟的开源产品实现各层,同自己编写代码实现,相比之下能缩短开发周期,且架构所用到的开源产品均有很广泛的用户群,经受过实践的考验,质量和性能更有保障。 层与层之间松散耦合,增加代码重用率, 各层分工明确,这样也利于团队的明确分工。
层请求图:
1. Rest层
Rest层使用的架构和各个版本,如图所示:
REST风格Web Services架构
REST(Representational State Transfer表述性状态转移)是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。
REST提出了一些设计概念和准则:网络上的所有事物都被抽象为资源(resource);每个资源对应一个唯一的资源标识(resource identifier);通过通用的连接器接口(generic connector interface)对资源进行操作;对资源的各种操作不会改变资源标识;所有的操作都是无状态的(stateless)。
结合Jersey,可以很方便的相应的类前,标注@Path来定义生成的URI名称,在HTTP的GET、POST、PUT、DELETE响应方法前标注@GET、@POST、@PUT、@DELETE,并可附加以@Consumes和@Produces指定方法所提供的MIME类型,如application/xml、application/json或image/png等类型。
Jersey是一个REST风格服务的开发框架,是JAX-RS的参考实现。Jersey采用了Annotation机制,所有的HTTP相关的参数设置都采用标注实现,因此,在编程的时候针对的仍然是POJO,避免了分布式或Java EE编程带来的诸多麻烦。Jersey是一个开发的平台,可以扩展需求,比如在消息格式上,Jersey已经提供了Java基本数据类型、JSON、XML等类型,可以很容易的扩展自己的格式。
Spring框架
Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。
Spring是一个轻量级的实现了控制反转(IoC)和面向切面(AOP)的容器框架,其组件包括:
1.Core包 Core包是框架的最基础部分,它提供依赖注入(Dependency Injection)特性来管理Bean容器功能。
2.Context包 Context包提供了框架的资源访问方式,如JNDI、资源装载等的接口。
3.DAO包 DAO包提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商的特有代码。该包也提供了实现编程性和声明性事务管理的方法。
4.ORM包 ORM包为流行的关系-对象映射APIs提供了集成层,包括JDO,Hibernate和iBatis。
5.AOP包 AOP包提供与AOP联盟兼容的面向方面编程实现,允许用户定义,如方法拦截器和切点,来从逻辑上把应该被分离的功能实现代码解耦。
SpringSecurity 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。很好的处理了资源请求的权限限制,做到细粒度的控制。
Spring和Jersey、Hibernate可以无缝的融合在一起。
Hibernate框架
Hibernate是一个实现了以ORM模式实现了持久层的框架,由于数据库的读写是一个很耗费时间和资源的操作,当大量用户同时直接访问数据库的时候,效率将非常低,如果将数据持久化就不需要每次从数据库读取数据,直接在内存中对数据进行操作,这样就节约了数据库资源,而且加快了系统的反映速度。
Hibernate 提供的接口可以分为以下几类:
1. 提供访问数据库的操作的接口,包括session、Transaction、Query接口;
2. 用于配置Hibernate的接口,Configuration;
3. 间接接口,使应用程序接受Hibernate内部发生的事件,并作出相关的回应,包括:Interceptor、Lifecycle、Validatable;
4. 用于扩展Hibernate功能的接口,如UserType、CompositeUserType、IdentifierGenerator接口。
Hibernate内部还封装了JDBC、JTA(Java Transaction API)和JNDI(Java Naming And Directory Interface)。其中,JDBC提供底层的数据访问操作,只要用户提供了相应的JDBC驱动程序,Hibernate可以访问任何一个数据库系统。JTA和JNDI使Hibernate能够和J2EE应用服务器集成。
连接池
由于Hibernate默认的连接池(dbcp)有一个问题,不会自动检测数据库连接是否断开,MYSQL数据库一段时间(大约8小时)没有访问就会断开连接,连接池里的连接却还是存在,下次访问hibernate会继续使用这个连接,导致数据库连接异常。由于该问题需要在服务器长时间运行时才会出现,所以在平时测试很难发现,所有整合Driud连接池。
Druid是一个JDBC组件,它包括三部分:
1. DruidDriver 代理Driver,能够提供基于Filter-Chain模式的插件体系;
2. DruidDataSource 高效可管理的数据库连接池;
3. SQLParser 。
Druid可以做什么?
1) 可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。
2) 替换DBCP和C3P0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。
3) 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。
4) SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。
扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter-Chain机制,很方便编写JDBC层的扩展插件。
日志处理
规范合理的日志记录能让开发人员和维护人员事半功倍,在记录日志时还应该考虑不同的角色对日志内容可能会有 不同的需求。比如,软件正常情况下提供给用户的日志应该简洁明了,调试时提供给程序员的日志应该详细明确。
LOG4J作为一个开源的日志管理组件,提供了强大的日志管理功能,可以把日志输出到控制台、文件或其他地方,支持包括Fatal、Error、Warn、Info、Debug多级日志输入。并可以通过配置来控制日志的格式、输出级别。
本架构要求在每个函数的开始、结束位置、异常的初次抛出位置均要求输出到日志记录文件,并把用户的系统操作记录存入到数据库日志表。
数据库
MySQL是一个小型关系型数据库管理系统,其体积小、速度快、总体拥有成本低、开放源码,支持多线程,充分利用CPU资源,优化的SQL查询算法,有效地提高查询速度,提供用于管理、检查、优化数据库操作的管理工具。
2. 接口层
接口层用户Rest层和Jclouds API层连接,在接口定义Entity,创建Rest层和Jclouds层关联的方法,减少对Jclouds API层的依赖,同时可以扩展其他API功能,如:监控等功能。
3. Jclouds API 层
采用开源的Jclouds 1.7.1,其中包含openStackSDK进行访问OpenStack池。把接口层定义的方法在此进行实现,完成Openstack基本功能和可扩展功能。
技术细节介绍
Signature
通过对访问API的每个请求进行签名,使得每次请求都是可信的,而且是不可伪造的,他的大致流程如下图所示:
- API Signature,每次Client端请求时都进行签名,并将签名信息放入Request Headers一同发送到Server;
- Check Signature,Server段收到请求后,使用同样的签名策略生成签名信息,并与Client发来的进行比对;
- 比对签名成功,Server正常处理该请求,否则response相关错误信息到Client;
- Client得到reponse content,并展现相关信息。
Signature的过程是重中之重了,它的生成总共分为三步:
相关说明:
· HTTP verb:该请求的方法;
· URL:Restful请求地址;
· Query String:有Body时是body体的内容,无body时为空字符;
· TimeStamp:采用ISO8601标准,Client与Server都是用Header中Date的值进行转换使用;
· SigningKey:这个key相当于签名的钥匙,可以考虑使用md5(password),更安全的作法是使用Hash算法独立生成;
· HMAC-SHA256:一种签名算法,使用它主要是参考aws;
· X-Neunn-UUID:用户唯一标示,Server端用来反查SigningKey;
· X-Neunn-Sign:Client生成的签名信息,传入Server用于比对签名;
· X-PoolName:请求哪个池的名称;
· X-Zone:请求的是哪个zone下的资源。
Spring security
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inverse of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
SpringSecurity3对(用户注入)验证和(安全资源)授权的基本流程如下图:
租户管理
注册用户首先会选择资源池,注册信息首先在Base层保留,然后在到所对应的资源池创建用户信息,如果开通别的资源池也会再此资源池注册用户信息。一个Admin用户可以创建多个子用户,并且可以为他们分配不同的权限来管理其资源。
架构流程图
对于每个Rest 请求,都先进行签名验证(SignatureOauth),首先判断是否有时间戳,如果有时间戳,再进行判断时间是否是有效时间(比对服务器时间 -5~+5分钟),再判断签名是否一致,然后在数据提取该用户是否有访问该资源的权限,如果这些都符合了才可以进行Rest请求方法,否则直接返回验证失败信息。
时序图:
5. 开发流程
1.开发工具
1. eclipse-jee-kepler
2. jdk-7u51
3. apache-tomcat-7.0.52
4. Maven-3.0.5
开发工具自取地址ftp://192.168.1.125/软件/新文件夹,其中还有maven下载的Jar包(MavenRepository.rar),解压放到D盘根目录。
2.代码管理
本项目采用git来管理代码,Eclipse可以安装git插件egit, 安装地址http://download.eclipse.org/egit/updates,如图所示:
代码取得,URL地址ssh://git@192.168.1.25/home/git/ncloud-base.git, 用户名为git,密码为Neunn@123,如图所示:
然后取得ncloud-base工程中的所有工程,导入本地工程中,如图所示:
首先选中工程
接下来导入
3.开发步骤
首先在ncloud-base工程中创建Rest请求方法,此请求接口按照接口文档定义开发并完善此文档,其中具体开发可以参照com.neunn.jcloud.rest.NeunnServerRest方法进行开发。此类中包含了,GET和POST方法。如图所示:
然后再接口层工程ncloud-base-rp-impl,创建要使用的方法和涉及到的Entity,方法一定在接口里,Entity定义在domain中。如图所示:
然后所有和资源池打交道的具体方法实现都在ncloud-base-rp-api工程中实现,如图所示:
所有的方法都写好之后,就可以进行测试,试试自己写的方法是否有问题,调用此方法的工程是ncloud-sdk-java,此工程为以后做外部调用所有,所以也要把自己调用方法的具体实现写好,可以参照ServerResource进行开发,然后用com.neunn.sdk.TestClient进行调用。工程图如下: