行业资讯

我看到的Web应用架构进化论(1)

我看到的Web应用架构进化论(1)

本人在IT行业已十年有余,一直从事技术开发的工作,从一个小鲜肉,变成了油腻的老油条。加班是家常便饭,所幸头发没有掉太多,真是谢天谢地。早些年,主要从事企业级的应用开发,近些年,从事互联网应用的架构工作。根据自己的工作经验,以我个人的视角,审视应用架构的演进路径。

单体应用的时代

1、基于指令码的应用架构

在上学那会儿,ASP.NET还是很流行的,自学了JSP和PHP。这些和“P”相关的技术,都是做网站的,这就是当年最朴素的认知。为学校开发过几个小的网站,不仅增长了技术水平,还赚了一点点的生活费,真是相当满足。

这种模式,和高可用高并发无关,与开发效率无关,与优良设计无关,只是根据使用者请求,动态的显示使用者资料,完成一定的功能而已。这种基于指令码的服务应用,似乎和高大上的 “架构”一次扯不上关系,但却是很好的启蒙,从此开始了应用架构的演进。就暂且命名其为“基于指令码的应用架构”吧。

2、分层设计的服务应用

使用简单的jsp、asp只能给学校做做小网站,工作中,显然不能满足需求。在企业级的开发中,逐渐应用了分层的设计理念。View层、控制层、业务层、DAO,大体都是这几种分层方法。

View层好一些的使用JSTL、FreeMarker标签语言,差一点的还是用HTML和Java程式码混用。控制层是用原生Servlet的也比较少,Struts、Struts2、Spring MVC都是可用的选择。业务层就是写业务程式码,实现界面。DAO层Hibernate是使用最广泛的,当然,后来都慢慢转向了MyBatis。

这种分层的设计理念,是基于Java的Web应用开发的最佳实践。即使后来的微服务,服务本身也是采用这种分层理念设计和开发的。

3、前后端分离

在使用Jsp的日子里,后端工程师往往还要掌握一定的JavaScript、HTML、CSS等,有些团队甚至没有专职的前端工程师。

这种模式存在着天然的缺陷,每次呼叫都重新整理页面,使用者体验较差。而随着互联网的普及,使用者越来越关注使用者体验,扁平化的设计理念深入人心,前端的开发技术日新月异。Bootstrap、Vue、Anglarjs、Rectjs等等新技术的出现,前端开发工程师的专业性更强,后端工程师不能做到全栈了。前后端分离的开发方式,越来越受欢迎。

在这种模式下,简化了后端研发中互动的复杂度,输出的只有json资料结构,这样,后端工程师把主要的精力,专注与业务逻辑的实现。

单体应用的时代,主要是解决的是研发过程问题,让逻辑更清晰、维护更容易、合作更有效。随着业务的增长,为更多的使用者提供服务,不允许停机升级程式,这样的需求,单体应用已经无法满足需求,就要过渡到丛集应用的时代。

丛集应用的时代

1、服务的水平扩充套件

支援更高的并发,支援7*24小时的高可用,最典型的解决方案,莫过于水平扩充套件:由1个应用服务,扩充套件成多个以提升并发能力;通过交替关闭/部署,实现不停机升级。

这个架构也还是有问题的,Nginx宕机会导致整个服务不可用,要考虑Nginx的高可用。如果采用了云供应商的服务,可以用负载均衡代替Nginx,负载均衡器已经考虑了高可用的问题。

另一个问题是两个应用服务共享使用者的登入资讯。假设使用者A登入了应用服务1,但是某次请求被分配到应用服务2,使用者验证失败。一般有四种解决方案:

利用Tomcat应服务器的广播机制,使session相互同步。系统开支大,占用更多的内存和IO流量。Nginx的黏着会话,Nginx转发使用者的请求时,同一个使用者的请求始终转发到同一个应用服务。如果应用服务宕机,登入在此应用服务的所有使用者登入状态失效。会话储存到统一的快取服务器。放弃使用java的session机制,登入成功给客户种下cookie,并且在快取服务器中记录使用者资讯。校验使用者时,从快取读取使用者资讯就可以了。上述的4种方案,a和b有先天的不足,不建议采用。推荐使用d方案,效率更高。c方案也可选择,优点就是很简单,对应用开发没有侵入性。

为了支援高并发,有很多的点可以去优化,例如:数据库的读写分离,引入快取机制等等,就不展开介绍了。

2、伪服务化

随着业务的扩充套件,发现把业务写在一起导致应用越来越臃肿,对开发和测试都是巨大的挑战。频繁的业务修改,带来频繁的上线释出,虽然已经做到了不停机上线,但还是带来了更多上线失败的风险。

这时候就会把一些业务拆分开来,开发新的应用服务独立部署,服务之间通过远端界面呼叫的方式通讯。在很多的业务实践中,因为没有提前规划,这时候的拆分往往并不科学,应用服务的呼叫也不是那么的讲究。

架构可能变成了这个样子:

服务是抽象出来了,但是他们之间的呼叫关系非常复杂,随着服务的增多,这个网变的越来越复杂。针对这个问题,有两种解决方案:

参考计算机的总线,提出了服务总线概念,有很多商业化的产品,例如:Oracle ESB,SAP XI。首先,将生产者的服务界面注册到服务总线,服务总线提供一个对外暴露的界面。需要注意的是,在服务总线是手动配置的,而不是生产者自动注册的。消费者呼叫服务总线提供的界面,然后服务总线呼叫到生产者。在呼叫过程中,服务总线是一个代理的角色。这种方案是有“中心”的,瓶颈就在于服务总线的吞吐量,在大并发场景下并不合适。另一种解决方案是在服务丛集中,引入注册中心的概念。生产者将服务的信注册到注册中心;消费者呼叫界面,首先去注册中心查询服务列表,然后在本地直接呼叫界面。这种方案的呼叫,就是没有中心的了,丛集的处理能力,不受制于注册中心的处理能力。有必要聊一下SOA,服务总线的概念,实在SOA如日中天的年代提出的;注册中心,则是微服务架构里的概念。SOA和微服务有什么关系呢?个人理解,讲述的是同一件事情,把一个复杂的系统,尽可能的模组化是最终目的。只不过呢,SOA更加的官方,强调面向企业级应用的,有不少的大厂提供站台和解决方案;微服务呢,来自民间,面向互联网,最近几年随着互联网的飞速发展,渐渐深入人心。微服务继承了SAO的衣钵而发扬光大。

谈到这里,脱离了伪服务化,已经演进到微服务化了。今天就写到这里了,明天更新微服务化的内容

我是咔咔,持续分享IT互联网相关技术,欢迎关注我。