单体应用和微服务浅析

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

    最近两年,微服务架构盛行,出现了一些优秀的微服务框架,如SpringCloud等。近来工作需要,接触了部分微服务的内容,和之前的传统开发模式不相同,进行对比,有所感。

    首先是看一张简单总结画的图:

单体应用和微服务浅析_第1张图片

一.单体应用

    单体应用 - 一个war文件包含所有功能的应用程序包。这种很常见,在电信CRM开发团队待过一段时间,像CRM系统,包含复杂的业务逻辑/自服务接口/定时任务/集团接口等等,都在一个war文件里面。每次发布,都是版本管理员拿到一个大war包,上传到WebSphere,再往几十台服务器上推送。好处是All In One,部署测试比较容易,版本管控比较简单。但是随着时间的推移,越来越多的需求被加到war包中,慢慢地,单体应用变得越来越臃肿,上线后运行五六年,war包就有几百兆,可维护性和灵活性低。参考了《SpringCloud与Docker微服务架构实战》一书,结合实际工作项目经历,下面列出单体应用存在的问题:

    1.复杂性高

    拿上面的CRM系统举例,首先本身包含复杂的业务逻辑,电信的三户模型,各种套餐受理规则,服务接口,定时任务,都在一个项目里面。导致的问题是模块之间变得强耦合,边界模糊,依赖关系不清晰,代码质量参差不齐,最后使得项目变得十分复杂。而且容易有Bug的隐患,如果测试错过一个问题点,上线后可能产生生产故障,影响业务办理。

    2.技术债务

    “为了短期的利益,而做了欠考虑的决定所导致的后果。” 随着时间的推移,需求频繁的变更以及开发人员的更迭,会慢慢形成应用程序的技术债务。作为一个开发人员,也确实做过这样的事情:为了赶紧上线,少做一些测试,简单测试没问题后就匆忙上线。上线之后铁定出问题,因为“出来混,迟早要还的”。出问题后,就会有紧急补丁,这个补丁就是之前的欠下的“债务”。此外,紧急补丁多了后,会影响系统的原有设计,可能导致后面开发的时候很难修改。

    3.部署频率低

    单体应用一般是全量部署,每次需求和功能的上线都是重新部署发布整个应用。相比增量发布,全量部署的方式耗时长,影响范围大同时风险高。在此方式下,部署频率不太可能高。上面举例的CRM系统基本是一个月一个版本。同时部署频率低又会导致存在的Bug可能不会很及时的修复,系统的迭代变更可能跟不上快速变化的市场和需求的变更。

    4.可靠性差

    单体应用,当出现稍微大一点的Bug时候,如内存溢出,死循环,可能导致整个应用崩溃。可能客户正在提交订单,突然当前请求所在的服务器崩溃掉,界面得不到响应,影响客户体验。另外,假如通过F5或者负载均衡通过IP或者其他方式负载的情况下,很有可能出现,即使重新登录,客户的请求最后还是会被路由到宕掉的服务器上面,导致业务不能受理。

    5.扩展能力受限

    单体应用只能作为一个整体扩展,要么是增加单台服务器的内存,要么是增加服务器的数量。所有的模块部署在一起,不能根据业务模块进行伸缩。这样可能会造成不必要的资源浪费。

    6.技术创新难

    单体应用往往使用统一的技术平台或方案解决所有的问题。也就是说,对于开发人员来说,项目的技术选型和开发套路都已经规定好了,圈定在一个范围内。每个成员都必须使用相同的开发语言和框架,要想引入新框架或新技术会非常困难。如一个系统使用的是SSH的有一百多万行代码的单体应用,如果想换成SpringMVC或者SpringBoot,这种切换的成本是很高的。

 

二.微服务

    什么是微服务?2014年,Martin Fowler与James Lewis共同提出了微服务的概念 - 以开发一组小型服务的方式来开发一个独立的应用系统,每个服务都以一个独立进程的方式运行,每个服务与其他服务使用轻量级(通常是HTTP API)的通信机制。这些服务是围绕业务功能构建的,可以通过全自动部署机制独立部署,同时服务会使用最小规模的集中管理(例如Docker)能力,也可以采用不同的编程语言和数据库。

    微服务与单体应用相比,能够更好的满足互联网时代业务快速变化的需要。下面对比单体应用,列出微服务的部分特性:

    1.业务拆分

    业务拆分,即把一个复杂庞大的业务系统划分为若干模块,拆分出各种服务和中心。《企业IT架构转型之道》的介绍,阿里巴巴中台战略中,把复杂的业务拆分出了几大中心:用户中心,商品中心,交易中心,评价中心等等。不同的中心由不同的团队负责开发维护各自的服务,服务之间的交互定义好,内部想要怎样变更都不会影响外部的使用。前面举例的CRM系统在去年也完成了服务拆分改造,由一个单体应用拆分出了用户中心,订单中心等。

    2.持续试错

    听过一个原则 - 演进式设计原则。在系统开发的过程中,可能会遇到各种问题,加上频繁变更的业务需求。在微服务的架构下,可以采用快速迭代的方式进行架构的演进,在这个过程中可能会出现各种问题,但在微服务的架构下,即使是某个服务遇到问题,发版修复,也不会导致这个应用系统不可用。腾讯有一条重要发展原则就是“小步快跑”。

    3.持续集成部署

    相比之前的单体应用,在微服务的架构在,可能被拆分出来几个模块,如前端模块,系统模块,网关模块,权限模块等。不同的模块由不同的团队开发负责,模块化后,更利于使用一些持续集成的工具来简化和提高我们的系统开发运维效率。常用的有Jenkins,关联到Gitlab,可以实现测试人员一键部署,及时测试和发布修复问题。

    4.分布式高可用

    在微服务架构之前,单体应用往往是中心化的,几十台服务器应用通过集中的Oracle数据库来协同工作。中心化模式存在一个隐患,当位于中心的数据库服务器宕机的时候,整片应用服务器都将不可用,后果将是不可想象的。还有另外一种总线ESB模式也存在这种隐患。在微服务架构下,不同模块服务都是独立运行在不同的服务器上,使用的数据库是分布式数据库,以前的一个数据库,现在可能按照服务划分被拆分成多个分布式数据库,每个数据库还能有主备。此外,加上分布式缓存,分布式消息队列等中间件的使用,大大提高了应用系统的可用性。

    5.独立进程

    前面讲到单体应用的扩展性受限,相反,在微服务下,独立进程的方式灵活性很高。拿现在项目中使用到的SpringCloud举例,每个服务模块都是单独的进程(jar包),有系统服务,网关服务,订单服务,假如在某一时刻,发现某个服务的请求比较大,可以通过临时追加进程数量实例,注册到服务中心,分散请求。这种方式下,相比之前整体扩展,进程级别的伸缩对于服务器系统资源能更好的利用。

    6.结合容器技术

    不像单体应用很难实现创新,在微服务的架构下,团队完全可以结合不同成员的优势,不限开发语言和数据库,在找到更优的解决方案时,可以使用容器部署的方式来屏蔽这种差异,这种方式需要定义约定好不同模块服务直接的交互方式。通过容器封装环境,开发人员可以直接将所有软件和依赖直接封装到容器中,打包成镜像,生产环境直接部署镜像,通过容器实现开发测试生产环境的一致。通过容器调度平台管理容器,资源利用率更高。

 

    想到的就是这些,有点晚了,准备休息。有不对的地方,还望大家指正。

转载于:https://my.oschina.net/javamaster/blog/2966387

你可能感兴趣的:(数据库,运维,python)