基于SaaS模式的进销存实战架构分析

josh_zgq

贡献于2013-08-21

字数:4909 关键词: 分布式/云计算/大数据

 基于SaaS模式的进销存实战架构分析 作者:邢波涛 关于什么是SaaS (Software As a Service ) ,无论是各大媒体,包括网络媒体,还是《程序员》杂志本身,都已经讲了很多了(《程序员》杂志还分别在2007年第10期和2008年第8期,做了两期关于SaaS的专题),我也就不再重复。基于SaaS模式的应用还是很丰富的,但是对企业管理软件这个领域来讲,无论是美国的Salesforce , 还是国内的八百客,都是从CRM做起的。直至现在,基于SaaS模式的进销存,在技术架构上,都还是处于摸索阶段,甚至有人在我的Blog上留言,金蝶的友商网只是象征性的推出了用ASP.net技术编写的第一版,第二版要完全转向JAVA平台,从.NET平台转向JAVA平台,那就相当于把整个软件重新写了一遍。用友虽然推出了伟库网,但是至今尚未看到它的进销存应用,只是“网上订货”和“租户营销”两大功能模块。进销存对广大中小企业来讲,还是非常有市场的,但是各大软件厂商,迟迟未推出基于SaaS模式的稳定成熟的进销存软件,这说明什么呢?这说明它的确不好做,在技术架构上,的确有很难解决的问题。我做了很多年的MIS/ERP/进销存管理软件,关注SaaS模式也好几年了,所以我就做了一套基于SaaS模式的进销存软件,和大家一起探讨一下基于SaaS模式的进销存软件的技术架构,就当是抛砖引玉,无知者无畏吧。 一、 SaaS成熟度模型 《程序员》在第八期,刊登了阿里软件首席架构师赵进的文章《SaaS成熟度模型浅析》, 他借用Frederick和Gianpanolo Carraro的文章,把SaaS的成熟度,从低到高分成4个级别: 第一,每个租户使用一个独立的数据库实例和应用服务器实例,数据库中的数据结构和应用程序的代码根据租户需求,订制化修改。 第二,每个租户依然使用一个独立的数据库实例和应用服务器实例,但是应用程序已经考虑到了可扩展性,针对每个租户的可定制化通过配置的方式实现,它是一套应用程序。 第三,单实例,多租户,所有租户共享一个数据库实例和一个应用服务器实例,数据库通过增加Tenant表和TENANT_ID字段来解决识别租户的问题。这时也是一套应用程序。 第四,多实例,多租户,这时有多个应用服务器实例,最终租户通过负载均衡被分配到不同的应用服务器实例,并且该租户携带某个业务数据库实例信息,由应用服务器动态链接到相应得业务数据库。此时也是一套应用程序。 二、 技术架构设计目标 由上面分析可以看出,从理论上SaaS已经有了一套完整的成熟度模型,所以基于SaaS模式的应用,还是蛮丰富的。但是由于进销存软件的需求,完全不同于CRM软件和财务软件,相对于财务软件,国家有着明确的法律规范,而进销存系统是个性化非常强的一个系统,要求所有的租户采用同一个用户界面和同一个业务逻辑,是不现实的。对于进销存这块来说,租户有强烈的个性化需求的意愿。所以,本着这个思想,应用层的设计要求能够做到以下两点: (1)所有的租户理论上均可以自定义自己的页面 (2)所有的租户理论上均可以自定义自己的业务逻辑 这个目标和SaaS模型成熟度的第一类是类似的,但是我们要支持多实例,多租户,并且是一套程序,一个Framwork。也就是说我们既要实现SaaS模型成熟度第一类的目标,又要实现第四类的技术架构。下面我从数据库层到业务逻辑层,再到视图层,详细讲解我是如何做的,其系统架构图如图一所示。 (图一) 三、 数据库层的设计 数据库这一层的设计模式,无外乎只有3种方案: (1)每个租户独立一个数据库: 在应用服务器中配制不同的数据源,或者使用不同的连接池。这个方案的优点是不同租户的数据物理分离,安全性比较好。它的缺点是数据库连接的利用效率不高。性能问题会很大。它对应SaaS模型成熟度第一类和第一类。 (2)所有租户的数据都存放在一个数据库的同一套表中, 增加Tenant表和TENANT_ID字段,表明该业务数据是属于哪个租户的。它的优缺点在赵进的那篇文章《SaaS成熟度模型浅析》也已经讲了很清晰了。它对应SaaS模型成熟度第三类。 (3) 多Schema,单数据源。这个方案基本是方案(1)的变种。同一个数据库下可以有多个Schema。它的优点是除了方案(1)的优点以外,它共享数据源或连接池,效率更高。缺点是和方案(2)比较起来,数据库连接池开销会比较大 说实话,我不太确认这个模式是不是对应SaaS模型成熟度第(4)类, 如果是的话,那么数据库之间的负载均衡是没有意义的,因为每个数据库之间的数据根本不一样(不包括备份数据库)。如果不是的话,那么SaaS模型成熟度第(4)类数据库是如何划分的呢?赵进也没有讲清楚,或者是我自己没有看明白。 具体到我的设计,这里我选择方案(3),并结合了方案(2),对于登陆/验证/权限,所有的租户共享一个Schema,而对于业务数据,则每个租户的业务数据,是独立一个Schema。这样,每个租户的业务数据达到了物理分离,安全性比较好,导入导出也很方便。 四、 应用层的设计 前面咱们说过,进销存程序不同于别的应用程序,进销存应用程序有强烈的个性化需求,应用层的设计要求能够做到以下两点: (1)所有的租户理论上均可以自定义自己的页面 (2)所有的租户理论上均可以自定义自己的业务逻辑 下面我说说我是如何做到以上两点的: 要做到以上两点,只能有一套代码,一个Framework才算成功,如果针对不同的用户界面和用户逻辑需求,Framework也需要变动的话,那就是项目性质了,也就是SaaS模型成熟度第一类的目标。 (1)所有的租户理论上均可以自定义自己的页面 我这里也是采用了MVC的架构,参考了Struts 的源代码,并重新写了一个Web Framework,使之能适应SaaS架构的需求。上篇咱们说过,对数据库这一层,我采用的是方案3,每个租户有自己独立的一个Schema,但所有的租户,在菜单、角色、权限方面,他们采用了同一个公共的Schema,也就是说,用户的登陆验证和对应的菜单,是在这个公共的Schema里面实现的。缺省的,这些租户共享这些菜单,每个菜单对应一个Action,每个Action对应一个View, 这一点,是采用了Struts的思想。 对于租户的个性需求,如果有的租户的界面跟其余租户的界面不同,则新增一个菜单(登陆的时候,会覆盖掉原来的同一个menu_id的菜单),这个菜单当然有一个字段Compamy_ID,表明这个菜单是这个租户所独有的,在登陆的时候,把这个菜单加载到界面上,而这个菜单对应了一个新的Action,这个新的Action对应了一个新的View层,这样就实现了不同租户,可以有自己完全不同的界面的需求。 下面谈谈第2个目标: 所有的客户理论上均可以自定义自己的业务逻辑 在这里,我采用了Eclipse插件的思想(本人的现本职工作是Eclipse插件Tooling 工具开发),所有和业务层相关的业务逻辑代码,按照业务功能模块分类,我都放在配置文件里,动态加载,还是回到那个Menu--〉Action--〉View , 这个Action不仅对应一个View层,还对应一个业务逻辑,通过不同的租户,配置不同的菜单, 这些菜单又对应不同的Action,这些Action又对应不同的业务逻辑,并且是动态加载的,这样,就做到了业务逻辑和Framework的分离。 例如,有的客户的应付款和采购入库对应上,入库了,才会形成应付款,而有的客户,可能跟采购订单对应上,只要下了采购订单,就会形成应付款,等等这些,无论客户的需求怎么变化,这个Framework是不变的,当然,形成应收应付的业务逻辑代码还是要自己写的。 五、 视图层的选择 对于View这一层,我选择了Flex,我之所以没有采用JSP+Ajax,是因为加载Ajax框架,比如Ext,可能也是很浪费时间的,造成加载速度很慢。可扩展性和可持续发展性也没Flex好,而且,Flex天生长着一张惊艳的脸,会给用户带来很好的UI体验,借用别人的一句话:“乍一看,很唬人”。 在Flex框架选择上,我没有采用Flex流行的framewok, 比如modelglueflex/Cairngorm/Flex FDS/PureMVC/Blazeds等等Framework,我直接自己写了一个,感觉还是很好用的,增加、修改、查询、删除等等基本操作,基本上做到自动化了,不用写什么代码了。学习这些Framework的曲线都比较陡,要沉下心,不容易啊。如果FDS不要钱,我还是推荐FDS。 Flex最大的不方便是客户端的Flash容器和服务器端的Tomcat等容器,根本就是两码事,两者之间也可以说没有任何关系,就像IE跟tomcat 没有任何关系一样,所以在 Flash容器内,找到Session,还是不容易的,当然也有一些Framework,例如Blazeds似乎解决了这个问题,我没有仔细看,网上也有一些文章,说解决了这个问题,我看了看,都不是很方便的解决方案。拿不到Session,还是蛮不方便的。 对于菜单,我还是用了JSP。因为菜单要根据每个客户的不同权限,显示不同的菜单,我在Flex里面没有解决好Session的问题,所以没有用Flex做菜单。 六、关于O/R Mapping工具的的选择 关于O/R Mapping工具,我并没有采用流行的Hibernate。SaaS模式进销存的第一个目标是允许用户自定义自己的界面,界面的不同,也就意味着数据库字段的不同,而Hibernate要求数据库字段和Hibernate类严格一一对应,我个人觉得它不适合SaaS模式的业务架构。当然也许有Hibernate的高人能够解决这个问题,我对Hibernate仅仅是一知半解。我采用的是Apache Tuscany DAS(http://tuscany.apache.org/das-overview.html), DAS 虽然牺牲了OO特性,用了类似于HashMAP的东西,但是它的灵活架构,还是很适合SaaS这种模式的。不过,在缓存上,Tuscany DAS肯定没有Hibernate那么成熟,而且,Tuscany DAS还有一个问题是它更新比较慢,不像Tuscany SCA/SDO更新那么快,就好像不是一个娘生的。Tuscany DAS 目前的版本还有一个很大的bug,就是double数据类型存盘有问题,我看他们现在也没修改过来。我自己更改了它的SDODataTypeHelper类的源代码,修改了它的Bug。 七、关于SOA/SCA 关于SCA,在写这个进销存的第一版的时候,所有Service和Service之间的调用,我都是基于SCA实现的。后来出于性能的考虑,以及这些Source Codes和Service全是我自己控制的,就把所有有关SCA的调用全去掉了,Service和Service之间修改为直接调用。再后来,想想这些租户之间,很可能有很强的业务协同需求。而这些租户之间的Service,也可能分布在不同的机器上,所以再次更新版本的时候,又加入了一些Service和Service之间的动态调用,而这些动态调用的Service之间,就是用SCA来整合到一起了。 八、开发后记: 在开发过程当中,我参考了很多Framework,总是感觉和自己想要得差距很大,与其整合别人的Framework, 还不如自己写一个。于是,我参考了Struts,重新写了一个Web Framework,整合了Flex, JDBC,Apache Tuscany DAS和Apache Tuscany SCA,,还有那些插件开发思想,自我感觉还是非常好用的(本人有自恋倾向,大家不要学我)。 开发完这个基于SaaS模式的进销存后,我就把它放在了Internet上,大家可以通过 http://www.spluss.cn/saas/ 这个网址进行访问,可以通过邮件 spluss@163.com 或者我的blog http://blog.csdn.net/bjblues 跟我沟通,一起探讨基于SaaS模式的进销存的技术架构。

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享文档获得金币 ]
1 人已下载

下载文档

相关文档