您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 市场营销 > 基于SaaS模式的进销存实战架构分析
模式的进销存实战架构分析作者:邢波涛关于什么是SaaS(SoftwareAsaService),无论是各大媒体,包括网络媒体,还是《程序员》杂志本身,都已经讲了很多了(《程序员》杂志还分别在2007年第10期和2008年第8期,做了两期关于SaaS的专题),我也就不再重复。基于SaaS模式的应用还是很丰富的,但是对企业管理软件这个领域来讲,无论是美国的Salesforce,还是国内的八百客,都是从CRM做起的。直至现在,基于SaaS模式的进销存,在技术架构上,都还是处于摸索阶段,甚至有人在我的Blog上留言,金蝶的友商网只是象征性的推出了用ASP.net技术编写的第一版,第二版要完全转向JAVA平台,从.NET平台转向JAVA平台,那就相当于把整个软件重新写了一遍。用友虽然推出了伟库网,但是至今尚未看到它的进销存应用,只是“网上订货”和“租户营销”两大功能模块。进销存对广大中小企业来讲,还是非常有市场的,但是各大软件厂商,迟迟未推出基于SaaS模式的稳定成熟的进销存软件,这说明什么呢?这说明它的确不好做,在技术架构上,的确有很难解决的问题。我做了很多年的MIS/ERP/进销存管理软件,关注SaaS模式也好几年了,所以我就做了一套基于SaaS模式的进销存软件,和大家一起探讨一下基于SaaS模式的进销存软件的技术架构,就当是抛砖引玉,无知者无畏吧。一、SaaS成熟度模型《程序员》在第八期,刊登了阿里软件首席架构师赵进的文章《SaaS成熟度模型浅析》,他借用Frederick和GianpanoloCarraro的文章,把SaaS的成熟度,从低到高分成4个级别:第一,每个租户使用一个独立的数据库实例和应用服务器实例,数据库中的数据结构和应用程序的代码根据租户需求,订制化修改。第二,每个租户依然使用一个独立的数据库实例和应用服务器实例,但是应用程序已经考虑到了可扩展性,针对每个租户的可定制化通过配置的方式实现,它是一套应用程序。第三,单实例,多租户,所有租户共享一个数据库实例和一个应用服务器实例,数据库通过增加Tenant表和TENANT_ID字段来解决识别租户的问题。这时也是一套应用程序。第四,多实例,多租户,这时有多个应用服务器实例,最终租户通过负载均衡被分配到不同的应用服务器实例,并且该租户携带某个业务数据库实例信息,由应用服务器动态链接到相应得业务数据库。此时也是一套应用程序。二、技术架构设计目标由上面分析可以看出,从理论上SaaS已经有了一套完整的成熟度模型,所以基于SaaS模式的应用,还是蛮丰富的。但是由于进销存软件的需求,完全不同于CRM软件和财务软件,相对于财务软件,国家有着明确的法律规范,而进销存系统是个性化非常强的一个系统,要求所有的租户采用同一个用户界面和同一个业务逻辑,是不现实的。对于进销存这块来说,租户有强烈的个性化需求的意愿。所以,本着这个思想,应用层的设计要求能够做到以下两点:(1)所有的租户理论上均可以自定义自己的页面(2)所有的租户理论上均可以自定义自己的业务逻辑模型成熟度的第一类是类似的,但是我们要支持多实例,多租户,并且是一套程序,一个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的源代码,并重新写了一个WebFramework,使之能适应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/FlexFDS/PureMVC/Blazeds等等Framework,我直接自己写了一个,感觉还是很好用的,增加、修改、查询、删除等等基本操作,基本上做到自动化了,不用写什么代码了。学习这些Framework的曲线都比较陡,要沉下心,不容易啊。如果FDS不要钱,我还是推荐FDS。Flex最大的不方便是客户端的Flash容器和服务器端的Tomcat等容器,根本就是两码事,两者之间也可以说没有任何关系,就像IE跟tomcat没有任何关系一样,所以在Flash容器内,找到Session,还是不容易的,当然也有一些Framework,例如Blazeds似乎解决了这个问题,我没有仔细看,网上也有一些文章,说解决了这个问题,我看了看,都不是很方便的解决方案。拿不到Session,还是蛮不方便的。对于菜单,我还是用了JSP。因为菜单要根据每个客户的不同权限,显示不同的菜单,我在Flex里面没有解决好Session的问题,所以没有用Flex做菜单。六、关于O/RMapping工具的的选择关于O/RMapping工具,我并没有采用流行的Hibernate。SaaS模式进销存的第一个目标是允许用户自定义自己的界面,界面的不同,也就意味着数据库字段的不同,而Hibernate要求数据库字段和Hibernate类严格一一对应,我个人觉得它不适合SaaS模式的业务架构。当然也许有Hibernate的高人能够解决这个问题,我对Hibernate仅仅是一知半解。我采用的是ApacheTuscanyDAS(),DAS虽然牺牲了OO特性,用了类似于HashMAP的东西,但是它的灵活架构,还是很适合SaaS这种模式的。不过,在缓存上,TuscanyDAS肯定没有Hibernate那么成熟,而且,TuscanyDAS还有一个问题是它更新比较慢,不像TuscanySCA/SDO更新那么快,就好像不是一个娘生的。TuscanyDAS目前的版本还有一个很大的bug,就是double数据类型存盘有问题,我看他们现在也没修改过来。我自己更改了它的SDODataTypeHelper类的源代码,修改了它的Bug。七、关于SOA/SCA关于SCA,在写这个进销存的第一版的时候,所有Service和Service之间的调用,我都是基于SCA实现的。后来出于性能的考虑,以及这些SourceCodes和Service全是我自己控制的,就把所有有关SCA的调用全去掉了,Service和Service之间修改为直接调用。再后来,想想这些租户之间,很可能有很强的业务协同需求。而这些租户之间的Service,也可能分布在不同的机器上,所以再次更新版本的时候,又加入了一些Service和Service之间的动态调用,而这些动态调用的Service之间,就是用SCA来整合到一起了。八、开发后记:在开发过程当中,我参考了很多Framework,总是感觉和自己想要得差距很大,与其整合别人的Framework,还不如自己写一个。于是,我参考了Struts,重新写了一个WebFramework,整合了Flex,JDBC,ApacheTuscanyDAS和ApacheTuscanySCA,,还有那些插件开发思想,自我感觉还是非常好用的(本人有自恋倾向,大家不要学我)。
本文标题:基于SaaS模式的进销存实战架构分析
链接地址:https://www.777doc.com/doc-1704360 .html