`
timeson
  • 浏览: 146452 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

从项目开发到云端架构(03)

 
阅读更多

2.2 项目架构

       架构师把握2个中心点:业务的可扩展和能力的可扩展。系统的健壮性和扩展性是系统架构的考虑的事情,云平台不是系统健壮和可扩展的银弹,IaaS只是解决了物理存储和系统搭建的工作;PaaS只是解决了服务和软件部署和维护的工作。系统的可扩展性依赖于:拆分;异步;分发。

 

  • 业务的扩展:系统分层,分模块,表拆分
  • 能力的扩展:负载均衡,分布式部署,无状态模式,路由转发,数据库拆分

 

 

       系统的架构根据业务的需求不同而有所不一样,一般来说,越是大型系统,架构就越复杂,所以在本章节中,分布举3个实例,分别阐述面对大中小应用的架构应对模式。其中有些组件可能还没有完全实现,但作为架构是需要的,那作为架构中也会被说明。

 

2.2.1            普通系统

2.2.1.1    特点

       面向普通项目需求,从逻辑上看项目分解为:1个应用服务器,1个数据库,程序部署的时候,统一打成war包部署在应用服务器下。借助应用服务器本身集群能力进行业务扩展。总的来说,扩展能力有限。

2.2.1.2    架构



 

22-01普通系统架构

 

       看上去虽然有些复杂,但其实很简单,总体架构采取servcie+dao+orm模式,至于该种模式的优劣后续的《开发》章节有详细阐述。后端的组件对外采用统一接口来暴露(openapi)。数据源为单一来源。

2.2.1.3    开发

2.2.1.3.1  开发方式



 

22-02:开发结构

 

       不过总体为前端采取mvc模式展现,中间逻辑采取springbean装配方式,以及事务申明,后台采取hibernate/ ibatis /jdbc作为持久层,加上其他一些辅助支撑组件,组成了service+dao+orm的方式,前后台通过POJO传递数据(现在也与时俱进了,有用xmljson方式传递数据的)。Serivce采取的是贫血模式,把组件提供的功能当作dao的功能来使用,所以在组件这层面就得考虑组件自身的数据如何与上层业务数据的集成,当只有组件是充血模型方式,才能保证上层业务数据的提交一致性;否则自身组件不维护信息状态,全部持久化到表中,在事务回滚的时刻,就不能保证组件的信息数据也能同步回滚。

 

Service Dao

       Dao完成连接数据库修改删除添加等的实现细节,书写SQL语句的地方。Service层是面向功能的,多个Dao层中API的排列组合调用。

     在有些项目中,看上去dao层和service的方法会有雷同,是因为service的需求简单能和dao层一一对应,这是为了将来系统扩展或者迭作的预留铺垫;也可以采用Service+BaseDao的模式,提供一个具有初步功能的增删改查的通用Dao,来辅助servcie实现数据的处理,并减少代码量。在曾经开发过的工作流引擎项目,因为涉及到业务的复杂程度,所以servcie层和dao层泾渭分明,各司其职,在复杂项目中能充分提现2者拆分的优势。

在高并发业务系统中,涉及到事务传播的特性,servcie层和dao层的设计亦有讲究,但不在这里阐述,这里的场景是war都在一个jvm中的模式。

 

单例和多例

       单例模式的意思就是只有一个实例,确保一个类只有一个实例。单例模式适合建模无状态的服务类,DAO本身是属于无状态的,所以适合使用单例模式,而每次得到Connection时都是使用DriverManager.getConnection()来得到的话就是使用新的Connection,所以两个事物之间没有使用相同的Connection,事务的安全性是能够保证的。如果需要使用之前的connect,可以借助ThreadLocal,这种模式在spring中提供了直接的支持。

       一个类能够以单实例的方式运行的前提是“无状态”:即一个类不能拥有状态化的成员变量。我们知道,在传统的编程中,DAO 必须执有一个 Connection,而 Connection 即是状态化的对象。所以传统的 DAO 不能做成单实例的,每次要用时都必须 new 一个新的实例。传统的 Service 由于将有状态的 DAO 作为成员变量,所以传统的 Service 本身也是有状态的。

  但是在 Spring 中,DAO Service 都以单实例的方式存在。Spring 是通过 ThreadLocal 将有状态的变量( Connection )本地线程化,达到另一个层面上的“线程无关”,从而实现线程安全。Spring 不遗余力地将状态化的对象无状态化,就是要达到单实例化 Bean 的目的。

由于 Spring 已经通过 ThreadLocal 的设施将 Bean 无状态化,所以 Spring 中单实例 Bean 对线程安全问题拥有了一种天生的免疫能力。不但单实例的 Service 可以成功运行于多线程环境中,Service 本身还可以自由地启动独立线程以执行其它的 Service。所以如果我们的系统基于Spring来构建,servciedao层创建单例模式即可。

 

贫血和充血

       贫血模式和充血模式其实是领域建模中的范畴,在面向对象语言开发中常引起争论,这里不讨论2者的优劣,各有优缺点,置于采用哪种模式,根据项目成员的掌握程度以及底层支撑软件的特性来选择。一个典型的场景:某些核心组件采取的是充血模式,而整个大的业务系统采取的是贫血模式。下面是示意图:在充血POJO处,具有状态的数据在内部处理,但和数据库交互的部分在service处统一处理,形成充血模式和贫血模式相结合的方式。



 

22-03:充血和贫血结合

 

       所谓贫血模型就是模型对象之间存在完整的关联,但是对象除了getset方外外几乎就没有其它的方法,整个对象充当的就是一个数据容器,所有的业务方法都在一个无状态的Service类中实现,因为无状态,才有可能在多线程环境下安全。Service类仅仅包含一些行为。基于Spring提供了对这种模式很好的支撑,所以如果基于spring开发的项目,建议在总体上采用贫血模式。基于贫血模式的分层结构为:

 

  • dao:负责持久化逻辑
  • model:包含数据对象,是service操纵的对象
  • service:放置所有的服务类,其中包含了所有的业务逻辑
  • facade:提供对UI层访问的入口

 

 

       贫血模式的优点:

 

  • 简单,容易掌握,被Spring支持。
  • 事务边界清楚,缺省每个servcie就是事务的起点,可以参与或则独立启动一个事务。如果service层和dao层在事务声明上进行技巧性声明,对于提升整体系统性能有帮助。

 

       缺点:

 

  • 所有的业务都在service中处理,当业越复杂时,service会变得越庞大,变得理解和维护。
  • 将所有的业务放在无状态的service中实际上是一个过程化的设计,它在组织复杂的业务存在天然的劣势,随着业务的复杂,业务会在service中多个方法间重复。
  • 当添加一个新的UI时,很多业务逻辑得重新写。例如,当要提供Web Service的接口时,原先为Web界面提供的service就很难重用,导致重复的业务逻辑(在贫血模型的分层图中可以看得更清楚),如何保持业务逻辑一致是很大的挑战。

 

       领域驱动模型,与贫血模型相反,领域模型要承担关键业务逻辑,业务逻辑在多个领域对象之间分配,而Service只是完成一些不适合放在模型中的业务逻辑,它是非常薄的一层,它指挥多个模型对象来完成业务功能。基于充血模式的分层结构为:

 

  • infrastructure: 代表基础设施层,一般负责对象的持久化。
  • domain:代表领域层。domain包中包括两个子包,分别是modelservicemodel中包含模型对象,RepositoryDAO)接口。它负责关键业务逻辑。service包为一系列的领域服务,之所以需要service,按照DDD的观点,是因为领域中的某些概念本质是一些行为,并且不便放入某个模型对象中。
  • application: 代表应用层,它的主要提供对UI层的统一访问接口,并作为事务界限。

 

       其优点是:

 

  • 领域模型采用OO设计,通过将职责分配到相应的模型对象或Service,可以很好的组织业务逻辑,当业务变得复杂时,领域模型显出巨大的优势。
  • 当需要多个UI接口时,领域模型可以重用,并且业务逻辑只在领域层中出现,这使得很容易对多个UI接口保持业务逻辑的一致。

 

       其缺点是:

 

  • 对程序员的要求较高。初学者对这种将职责分配到多个协作对象中的方式感到极不适应。
  • 领域驱动建模要求对领域模型完整而透彻的了解,只给出一个用例的实现步骤是无法得到领域模型的,这需要和领域专家的充分讨论。错误的领域模型对项目的危害非常之大,而实现一个好的领域模型非常困难。

 



 

22-04:具体实例(工作流引擎)

 

左边是贫血模式,右边流程推进部分是充血模式,在流程引擎内部流转中业务相当复杂,内部维护3层结构的状态机并基于观察者模式,所以基于状态的业务模块采取了充血模式。在围绕flowDataNodeData类中维护了很多的状态数据,但从数据库的增删改查都从flowRunner进行调用,事务的边界在flowService处,这样基于充血模式和贫血模式的数据一致性就有了保障。

2.2.1.3.2  异常体系

 

       在项目中的异常体系,采取ExceptionErrorCode的混合模式。从java异常体系的初衷来看,这种方式并不美学,但是在具体的项目实践中得来迭代经验:

 

  • 架构师在设计的时候,不可能把所有的情况都考虑清楚,比如在票拉拉项目,想到了前面30个异常,但在具体项目开发的时候,程序员又开发了40个异常,并直接从baseException继承,打乱了整个体系的规范,因为程序员设计的时候,架构师不可能在身边盯着。
  • Java异常推崇异常的体系,有层次感,但程序员麻烦或者其他考虑,直接捕获Exception,导致精心设计的异常体系没有应有的作用
  • Spring体系推崇运行时异常,程序员不需要捕获直接往上抛,程序干净整洁,这点我们需要借鉴,但不能一葫芦画瓢,因为我们的开发者来自五湖四海,可能有众多公司的人来参与,没有spring开发团队这样整体划一,所以按照service+dao+orm的模式,我们把运行时异常限制在dao+ormservice对外暴露,需要check exception

 

 

由以上考虑,所以异常体系定义如下:

 

  1. 在整个项目中的异常体系中采取Exception/RunTimeException + ErrorCode模式
  2. 整个项目结构有service+dao+orm+db实现,其中runtime异常在dao层和orm层流转,service层出定义exception异常,提供上层业务使用
  3. 异常结构分为2层:baseExceptionà业务exception,以下不再派生,而由ErrorCode实现。
  4. 设计者大体为每个service模块定义唯一的异常信息,比如pay模块定义payExceptionorder模块定义orderException异常,该业务异常直接从baseException异常继承而来,该模块开发的程序员在具体定义ErrorCode
  5. ErrorCode由程序员和架构师共同确定,用接口方式来实现

 



 

22-05:异常体系

 

2.2.1.3.3  数据处理

       这里有个缺省的假设环境,即逻辑处理都在同一个JVM中,同一的数据源,相对分布式系统而言,数据一致性的问题相对简单,理解事务的传播模型已经理解悲观锁,乐观锁即可

 

事务处理

              Java 平台支持六种事务属性,假想 methodA() 方法是事务的边界:

 

  • methodA() 指定Required 事务属性,并且在已有事务作用域内调用了 methodA(),那么将使用已有的事务作用域。否则,methodA() 将启动一个新的事务。如果事务是由 methodA() 启动的,则它也必须由 methodA() 来终止(提交或回滚)。
  • methodA() 指定Mandatory 事务属性,并且在已有事务作用域内调用了 methodA(),那么将使用已有的事务作用域。但是,如果调用 methodA() 时没有事务上下文,则会抛出一个 TransactionRequiredException,指示必须在调用 methodA() 之前呈现事务。
  • methodA() 指定RequiresNew 属性,并且在有或没有事务上下文的情况下调用了 methodA(),那么新事务将始终由 methodA() 启动(和终止)。这意味着,如果在另一个事务(比如说 Transaction1)的上下文中调用了 methodA(),那么 Transaction1 将暂停,同时会启动一个新的事务(Transaction2)。当 methodA() 结束时,Transaction2 将提交或回滚,并且 Transaction1 将恢复,所有数据库更新都不再包含在一个单一的工作单元中。这个事务属性仅用于独立于底层事务的数据库操作(审计或记录)。
  • methodA() 指定Supports 事务属性,并且在已有事务的作用域中调用了 methodA(),则 methodA() 将在该事务的作用域中执行。但是,如果在没有事务上下文的情况下调用了 methodA(),则不会启动任何事务。此属性主要用于针对数据库的只读操作。在已有事务的上下文中调用查询操作会导致从数据库事务日志中读取数据(已更新的数据,同一个事务中的数据脏读),而不在事务作用域(NotSupported)中运行会导致查询从表中读取未修改的数据(读已提交数据,数据库一般会设定为读已提交模式)。
    • 在使用Support属性情况下,插入一个新的交易订单信息到订单表中,然后(在相同的事务中)获取所有交易订单的列表,则未提交的交易将出现在列表中;
    • 在使用NotSupported属性情况下,那么它会造成数据库查询从表中而不是从事务日志中读取数据。因此将不会看到未提交的交易。
  • methodA() 指定NotSupported 事务属性,并在某个事务的上下文中调用methodA(),则该事务将暂停直到 methodA() 结束。当 methodA() 结束时,原始事务将被恢复。这个事务属性用在主要涉及数据库存储过程的场景中。
  • Never 行为类似于 NotSupported 事务属性,但不同的是:如果使用 Never 事务属性调用方法时已经存在某个事务上下文,则会抛出一个异常,指示您在调用该方法时不允许使用这个事务。

 

 

数据锁定

       为了得到最大的性能,数据库都有并发机制,不过带来的问题就是数据访问的冲突。为了解决这个问题,大多数数据库用的方法就是数据的锁定。数据的锁定分为两种方法:

 

  • 第一种叫做悲观锁:悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住。
  • 第二种叫做乐观锁:乐观锁就是认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让用户返回错误的信息,让用户决定如何去做

 

      

       悲观锁。在SqlServer等其余很多数据库中,数据的锁定通常采用页级锁的方式,并在某些情况下会上升为表锁,当对一张表进行频繁操作时,数据库响应效率很低,可能会处于一种假死状态;而Oracle用的是行级锁,只是对想锁定的数据才进行锁定,不对其他数据影响,锁纪录的同时不会阻塞数据库的读取(非阻塞读),相比之下Oracle表中并发性能要高于其他数据库系统。

       悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,而乐观锁机制在一定程度上解决了这个问题。

       乐观锁,大多是基于数据版本记录机制实现,读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

 

       前面系统阐述了事务传播模式的特点,看上去很多内容,其实如果系统不是针对系统争用模式(订票模式/抢礼物模式:资源有限,并被争抢),一般来说采用Required模式+乐观锁即可。下面给出一个常规项目的事务处理模式,项目基于Spring,采取贫血模式,整个业务处理模式采用servcie + dao + orm模式。基于项目的约定的配置,和人员变化带来的技术层次的波动,对事务的边界和声明以及处理作如下假设:

 

  1. 事务声明采取xml配置方式,而不是注解方式
  2. 事务边界在service处定义,而不是在web端声明
  3. 只有包含在应用程序架构的ServcieAPI层中的公共方法包含事务逻辑。其他方法、类或组件都不应包含事务逻辑(包括事务注释、编程式事务逻辑和回滚逻辑)。
  4. ServcieAPI层的所有公共写方法(增删改)使用事务属性 REQUIRED 标记。
  5. ServcieAPI层的所有公共写方法(增删改)都应当包含回滚逻辑,以标记对检查出的异常执行回滚的事务。
  6. ServcieAPI层的所有公共读方法默认情况下都应使用事务属性 SUPPORTS 加以标记。这将确保在一个事务范围的上下文内调用读方法时,该方法被包括在事务范围内。

 

 

2.2.1.3.4  数据建模

 

       数据建模有3种方式:表驱动,页面驱动,以及pojo驱动方式。在我们的系统中,无论大中小项目,都采用POJO模式(贫血模式)。从页面驱动来说是需求人员的视角,从表驱动来说是业务人员的视角,从POJO来说,是架构师的视角。因为项目的主体采用的是基于service+dao+orm模式,基于贫血模式,采用POJO建模方式就顺理成章。

      

       之前有过用什么数据类型作为数据的载体的争论,争论的焦点是数据的载体是否在设计的时候就需要确定。以前有一种做法,就是把map作为通用数据载体,并加以适当的封装,需要存放什么数据,就put,需要什么数据,就get,好处就是在设计的时候用map数据结构能包罗万象,具体的数据承载需要在实现的时候才能实现,在对数据项进行严谨处理的情况下,系统具有一定的灵活性;还有一种方式就是在设计的时候需要把数据确定下来,利用java的强类型检查,这就要求在设计阶段的就把工作做夯实,明晰主要的数据项,况且POJO的设计,对于表结构的设计具有指导作用。所以在项目开发中,我们要求:

 

  1. 采取POJO作为数据载体的实现
  2. POJO以参考界面原形为基础,以跑通主要业务逻辑流程所需数据信息为依据。
  3. POJO设计完毕,作为表实现的重要依据。POJOTable不是一一对应:POJO有继承,Table是个平直的二维结构,数据库的类型和Java类型需要合理对应。

 

 

 

步骤:POJO à Table



   
   22-06apojo设计



 

                      22-06b:映射为表结构

 

表设计时建议遵循如下约束:

 

  • 表名定义规则
    • 打头为数据对象类型,"T-表示为表","V-表示为视图"
    • 2个栏目为模块定义,2~3个字符,比如t_biz_xxx(为业务模块表)t_sys_xxx(为系统管理表) 
  • 字段定义
    • 每个表定义主键,用number(20)java中用long对应
    • 表名和字段名定义全部大写
    • 表名和字段名定义长度,不超过15个字符为宜
    • 表名和字段名分割符用"_"来实现
    • 表中定义的字段长度,够用即可,不必定义过大(在计算存储规模时有规划) 
  • 外键和索引
    • 外键的利弊:
      • 强化数据的完整性;表建模时能清晰表之间关联关系;
      • 数据迁移和割接会有些困难
      • 建议是在设计的时候需要的外键可以设计,但在创建createSQL时,不生成外键。
    • 每个表对应的外建字段必须建立index
    • 没有外键,但在查询中多次作为查询的因子,并且数据重复率不高的,也需要创建index 

 

 

 

 

 

2.2.1.4    部署



 

22-07:普通系统的部署

 

负载均衡层

 

  1. 采取nginx+keepalived,主从模式,
  2. 在主机上安装流量监控软件,在从机上安装系统监控系统。
  3. nginx开启ip_hash来启用会话保持机制。

 

 

Web

 

  1. 所有的代码在逻辑上分层,部署上打成1war包,分别部署在不同的tomcat实例上,
  2. 因为没有启用文件共享模式,代码需要在各个web主机上同步
  3. Nginx开启proxy_cache,缓存web资源

 

 

数据库层

启用mysql Replication,作主从模式,主11,主机针对写,从机针对读。

 

 

 

上一篇 从项目开发到云端架构(02)  :http://timeson.iteye.com/blog/1683585
下一篇 从项目开发到云端架构(04)  :http://timeson.iteye.com/blog/1685746

  • 大小: 50.9 KB
  • 大小: 27.1 KB
  • 大小: 11 KB
  • 大小: 29.8 KB
  • 大小: 61.3 KB
  • 大小: 85.2 KB
  • 大小: 71.4 KB
  • 大小: 38.1 KB
0
0
分享到:
评论
1 楼 iilover 2014-01-29  
你好,写得很好,学习了,请问能将《云端平台的设计和实现》《云端平台的运营和管理》《云端平台的资源虚拟化》这三篇分享一下吗?发到我的邮箱:happyboy090909@163.com,大家多多交流,谢谢!

相关推荐

    模拟云端系统项目

    【模拟云端系统项目】是一个综合性的IT项目,它结合了前端和后端技术,旨在构建一个功能完善的云端应用。...这样的项目实践能帮助开发者深入理解云端应用的开发流程和架构设计,提升在分布式系统中的实战能力。

    云端第三代系统开发

    在当前数字化时代,"云端第三代系统开发"是一个重要的议题,它涉及到如何利用先进的技术构建高效、易用且灵活的云服务平台。在这个系统开发过程中,Java作为主要编程语言扮演着核心角色。下面我们将深入探讨这个话题...

    SRA2021-G03-项目开发计划1.81

    总结,SRA2021-G03-项目开发计划1.81是一个旨在构建云端知识库APP的详尽蓝图,涵盖了项目从需求分析到实施、测试、上线及后续维护的全过程。通过这个计划,团队能够有序地进行开发工作,确保知识库应用能高效、安全...

    SRA2021-G03-项目开发计划1.71

    【SRA2021-G03-项目开发计划1.71】是关于一...总之,"SRA2021-G03-项目开发计划1.71"是一个全面的项目管理文档,它涵盖了项目从启动到完成的所有关键环节,旨在确保团队高效协作,成功开发出满足需求的云端知识库APP。

    云端系统源码第二版

    云端系统源码第二版是一个...综上所述,云端系统源码第二版是一个涉及多方面技术和实践的综合项目,涵盖了从底层基础设施到上层应用服务的全方位设计。深入理解和掌握这些知识点对于开发、运维和管理云端系统至关重要。

    android基于webservice云端运用最新代码EasyEnglish

    在Android开发中,结合Web服务(Webservice)可以实现丰富的云端功能,比如数据同步、远程API调用等。"android基于webservice云端运用最新代码EasyEnglish"是一个示例项目,展示了如何在Android应用中集成Webservice...

    wiki云端知识库平台项目

    以上内容仅是对“wiki云端知识库平台项目”可能涉及的技术栈和概念的一个概述,具体实现可能根据开发团队的选择和技术栈有所不同。对于学习者来说,深入理解并掌握这些知识点,将对个人的技能提升和未来职业发展...

    鸿蒙Linux+项目文档+开发工具+harmonyOS+在线开发地址.rar

    综上所述,这个压缩包是鸿蒙OS开发者的一站式资源库,涵盖了从系统底层到应用开发的各个环节,对于想要涉足鸿蒙OS领域的开发者而言,是一个宝贵的资料集合。通过深入学习和实践,开发者可以更好地掌握鸿蒙OS的开发...

    自制云端脚本获取器

    “云端”意味着它涉及到云存储或云计算的服务。“脚本”指的是可执行的代码文件,如JavaScript、Python等,可能是网页脚本或者其他类型的程序。“获取器”和“下载器”则说明了工具的功能,即获取并下载云端的脚本...

    C#项目开发全程实录-源代码

    通过研究这些源代码,初学者可以学习到实际项目开发中的最佳实践,而有经验的开发者则可以借鉴其中的设计模式和问题解决策略。无论是独立学习还是团队协作,这个资源都能提供宝贵的经验和洞察。

    悟空项目管理-基于Spring Cloud Alibaba微服务架构 +vue ElementUI的前后端分离项目管.zip

    9. **部署与运维**: 项目可能还包含了部署和运维相关的文档,例如Dockerfile或者Kubernetes配置,帮助开发者将应用部署到云端或本地环境。 这个项目不仅提供了实际的代码实现,还可以作为学习微服务架构、前后端...

    云计算系统架构文档 汇总上

    DevOps 从云端到地面 熊节 pdf DevOps 让持续交付成为可能 乔梁 pdf eBay技术平台:掌控十亿级交易数据 Tony Ng pdf Facebook大数据实时分析案例分享 Uri pdf Java EE 7 平台:应云而生 Tyler Jewell pdf JS ...

    JSP+SSM项目-云端学习系统的Java毕业设计.rar

    JSP+SSM项目-云端学习系统的Java毕业设计.rar 【项目技术】 开发语言:Java 框架:ssm+jsp 架构:B/S 数据库:mysql 【演示视频-编号:345】 https://pan.quark.cn/s/b3a97032fae7 【实现功能】 端学习系统在...

    构筑大语言模型应用:应用开发与架构设计.zip

    《构筑大语言模型应用:应用开发与架构设计》是一份深度探讨大语言模型在实际应用中的开发和架构设计的资源集合。这份资料来源于GitHub上的开源项目phodal/aigc,旨在帮助开发者理解和利用大语言模型的技术,提升...

    SAAS架构设计模式SAAS架构设计模式

    它的出现是为了解决软件开发和维护的成本问题,通过将软件部署到云端,提供基于互联网的软件服务,用户可以通过互联网访问和使用软件。 SAAS 架构设计模式的优势包括: 1. 用户方面:拿来即用,无须维护,按需使用...

    Android-物联网环境监测数据中心-物联网项目开发

    在物联网项目开发中,可能还需要特定的物联网协议解析或设备模拟插件。 3. **物联网架构**: 物联网环境监测系统通常包含传感器节点、网关和云端平台三个部分。传感器节点负责采集环境数据,如温度、湿度、光照等...

    Android项目开发报告 (2).pdf

    总结,本Android项目开发报告全面展示了项目开发的各个方面,从底层的平台架构到上层的功能实现,再到数据库和项目组织,为开发者提供了清晰的开发指南。通过这样的报告,不仅可以评估项目的成熟度,也便于团队协作...

    微信小程序项目源码云开发cloudtest.zip

    9. **版本控制**:在项目开发过程中,版本控制非常重要。微信开发者工具允许开发者进行代码版本管理,便于团队协作和回滚更改。 10. **发布与更新**:完成开发后,开发者可以在微信开放平台上提交审核,待审核通过...

    springboot集成netty,使用protobuf作为数据交换格式,可以用于智能终端云端服务脚手架

    本项目“springboot-netty-protobuf-master”旨在提供一个基础架构,它利用了Spring Boot的便捷性以及Netty的高效网络通信能力,同时采用Google的Protocol Buffers(protobuf)作为数据交换格式,确保数据传输的高效...

Global site tag (gtag.js) - Google Analytics