从 MVC 到微服务,技术演变的必经之路

标签: mvc 微服务 技术 | 发表时间:2016-11-07 23:32 | 作者:u010646653
出处:http://blog.csdn.net

编者按:近两年很火的微服务是什么?它的发展经历了什么?为什么微服务突然变得很火?本文将为大家介绍微服务的来龙去脉。

一、架构模式演进

CGI 模式

这里写图片描述
图 1

CGI 出现于 1993 年,图 1 是 CGI 模式比较简单的结构图。

MVC 模式

开源电商软件等都是采用 MVC 模式,MVC 模式是做软件开发必学和必经历的一个阶段。

这里写图片描述
图 2

1970 年提出了 MVC 的概念,当时的主机和客户端早已凸显了这个概念。如图 2 所示,这是一个 MVC 模式的标准框架,做一个电商网站时,会把订单、用户、物流信息整合起来,做一个单体服务。

90 年代正是 Java 的时代,MVC 模式在这个时期开始变火。开发者把 MVC 的实践引入 Java 世界。这个模式大放异彩后,各种语言都在借鉴。

SOA 模式

这里写图片描述

图 3

单体服务之后是 SOA 标准化(图 3 ),在 SOA 里面比较重要的是 Service bus。在企业架构里它起到很关键的作用,主要用来沟通各个服务组件,就像高速公路一样,用来连接所有的村庄。

经过 MVC 模式后,单体模式开发速度很快,网民的速度增长也很快,服务器接收的请求越来越多,慢慢需要做拆分才出现了 SOA 概念。虽然 1983 年提出了 SOA 的概念,但国内绝大部分企业至少是在 2000 年之后才开始 SOA 化。

Microservices 模式

这里写图片描述
图 4

图 4 是 Microservices 的架构图,每个 Host 里面都有一个服务,它是独立的。Microservices 于 2005 年出现,到现在仍备受关注和讨论。一个概念由提出到落地,有很深层次的原因,具体后文分析。

二、何时使用微服务?

这里写图片描述
图 5

微服务并不能解决所有问题,所以一定要慎重考虑何时采用微服务。这张图(图 5 )很常见,单体服务的开发速度、代价都是比较低的,只有业务复杂到一定程度的时候才适合采用微服务。微服务其实是一个理念和框架,它对团队的要求比较高,首先团队所有成员都要认可这个事情,认可微服务的理念和治理框架,否则执行过程中会有很多问题。

这里写图片描述
图 6

单体服务是把所有东西都部署在一块,如图 6 所示,这是最简单的单体服务。在一定阶段下,简单代表高效,所有东西部署在一起时,整个过程的沟通效率会提高。

提到微服务时首先会提到康威定律,即当开发一个新的架构时,组织架构图跟软件架构图是极其相似的。举例说明,一个最简单的 APP 开发架构包括移动端和服务端,如果把后台服务的人进行角色分层,会有运维、前端、做中间商业逻辑的后台开发者,就会发现软件架构跟组织架构很相似。对微服务进行的拆分,其实也是对人员组织架构和角色职能的拆分。这两者是很相似的。

三、为什么 API 很重要?

微服务里面最重要的是 API ,API 是服务公开化的方法,它是服务价值的精华体现。API 一定要可靠、可用、可读,前两点大部分人都能做到,但是可读性,很多团队却做得很差。许多国内开发出来的开发系统文档可读性很差,看完之后可能还需要跟对方人员沟通。然而,无论是给内部开发,还是给外部用户提供服务,都不希望产生更多的沟通。

出现这种情况的原因在于程序员本身的特性,程序员是写程序的。很多程序员认为写文档不如写程序有快感,这对于很多人来说是一种挑战,也是一件很枯燥的事情。可是,对于公众来说,文档却很重要,就像要成为一个好的架构师就要有良好的沟通能力,要做好微服务,API 可读性很重要。

API 的设计永远只有一次机会,特别是像七牛这类做对外服务的云服务厂商。API 设计完之后,一直都会有人调用,由于无法知道谁正在调用 API ,就无法让对方停用,从而无法升级。所以 API 只有一次机会,发布后就定了型。例如京东的部门不算多,但是 API 发布之后有很多部门在调用。团队做升级时,会通知所有部门停用 API 并且要升级的事情。但在升级完成之后,还是会有部门询问 API 为什么不通了?所以要符合可靠可用这两点,只有一次机会。

API Gateway

通常在企业里用的是 API Gateway ,因为它们可以直连。用这个方式有几个优点:

  • 一些通用的事情可以在 Gateway 上面做,包括所有API的请求调用量、请求响应时间、4xx 和 5xx 等错误出错数,这些东西可以通过日志或者其它方式很实时展现出来。
  • 所有的服务其实都需要负载均衡,可以在 API Gateway 统一做一些规则、限流。

API 的设计要素

  • 版本号

永远要清楚谁调了哪一个版本的 API 。虽然 API 发布只有一次机会,但有版本号之后能有所防备,做版本升级或版本兼容性的时候会更容易。

  • RequstID

RequstID 可以有效地提高效率,并在后台加快 Bug 复查和定位问题。给客户端的请求都有ID ,客户端发现有问题或者返回失败时,直接把 RequstID 给服务器端,服务器端拿 RequstID 到后台日志里查,就可以定义到问题。实际上从客户端发过来的一个请求,在后台经过了十几个微服务。而这十几个微服务调用的上下文串联和跟踪的工作,都需要一个 RequstID ,能够从请求端开始,往后去传递,每个人都要记录 RequstID ,出现问题时,把微服务的日志拉出来,就可以很快定位问题的来源。

  • 安全认证和 Signature

要知道谁调了什么东西,并且保证被调的东西不被篡改。外部调动 API 时都会做安全认证,但是内部调用时不一定会做安全认证。但往往很多时候事情的发展都是出乎意料的,有可能因为老板的决定或者业务的变化,API 需要对外开放,如果前期做了安全认证,就可以避免很多麻烦。

  • 文档可读性

一定要写好文档,不论是对客户、领导还是外部用户,文档写得漂亮更能彰显性能的优点。

  • Error Code 和 Message 的问题

以前有两个流派的 Error Code 和 Message 的展现方式。第一种是调用一个请求,对方把错误码写在 HTTP 的 Code 里面,可能用 400、404、409。第二种调法是客户端给服务端发了一个请求,返回 200,在 Body 里面有一个真正的 Code ,通过观察这个 Code 来判断调用是否成功,不成功就会通知 Error Message 。经过几年的实践后推荐使用第二种,因为在微服务相互调用时,它的协议不仅仅局限于 HTTP ,可能是其它方式的调用,直接用这个协议表示这种方式的调用状态并不合适,相反在里面表示一个状态会更好。

这里写图片描述
图 7

这里写图片描述
图 8

做一个案例分析,如图 7 所示是一家公司的架构图,野蛮生长的时候更注意的是功能的效率。架构很简单,没有服务需要进行小拆分,都是放在一起形成一个大块整体。前期功能性开发很快,但到了一定阶段后,不管是调用效率还是开发效率都会显现出不足之处。所以进行一个拆分,把大块的拆成十几个、二十几个(如图 8 所示)。基本上每家在做架构升级时,都会把一堆大的东西拆成小的,即微服务;而把四个变六个,就是微服务的架构升级。

然而在升级的过程中,也会存在一些「战争」,如下:

  1. 列表内容
  2. 效率与规则的战争
  3. 习惯与规范的战争
  4. 迭代与优化的战争
  5. 产品与开发的战争
  6. 业务爆发与服务能力的战争

业务爆发有两种:

一种是用户量、请求量上来了,服务却跟不上;

其次是是业务模式增加,需要开发更多的功能,但是开发更多功能时,却会导致服务能力和服务质量的下降。

四、微服务变火的原因

十年前的技术到近几年才开始变得很火的原因,需要从微服务的优劣势进行分析,主要是以下几个原因:

第一,微服务有按需伸缩的特点。按需伸缩是微服务的优点也是它的缺点。它的缺点是会带来部署与监控运维的成本,每个部署都要监控要运维,每个微服务后面都包含一个缺点。

第二,每个微服务都可以独立部署,但它的缺点是增加机器数量与部署成本。

第三,业务独立。微服务的业务很独立,但有服务依赖、治理、版本管理、事务处理的缺点。

第四,技术多样性。它带来的成本是环境部署成本,因为每个语言环境不同。以及约定成本,和跨语言如何调,都是成本。

五、微服务如何治理?

当了解微服务的优缺点之后,自然会考虑到如何治理微服务,可以通过以下几点进行治理:

第一,运行状态治理。监控、限流、SLA 、LB 、日志分析,都有一些成熟的开发组件,现在有开源版本的也有云端服务,比如做性能监控的 APM SaaS 等。限流不需要做多么复杂的东西,SLA 自己有日志分析就可以。

第二,服务注册与发现,现在已有一些比较完善的解决方案。

第三,部署。部署和布置上的成本大部分被解决了,不管是用容器还是虚拟机,都可以快速部署、快速复制镜像,再进行扩容。当本机上的线上环境所有服务都布好了,在本地开发是最方便的,且不依赖于其他同事提供服务软件。

第四,调用。注重安全、容错、服务降级、调用延迟。

六、服务注册

服务注册有两种方案:第一种是客户端发现,第二种是服务端发现。这两种方案是很主流的方案,都有各自的优缺点。下面就是对这两种方案的介绍。

客户端发现

首先分析客户端发现。所有的路由表信息存在客户端,客户端知道应该调用哪台机器设备的哪个微服务后,再去做相应的 Load Balance ,比如微服务有四个服务,每个服务的权重都推送到客户端里,客户端再决定调用哪个服务。客户端拥有所有微服务的服务器列表和端口,每个客户端和 Service Registry 都会保持一个长连接,常见做法是每个客户端和 Service Registry 建立一个连接,当微服务后台增加或减少一个微服务,都可以实时地通知客户端。但是这个方案也存在优缺点。下面就是对其优缺点的分析。

优点:快,可以直接跟微服务直连。

缺点:

  • Service Registry 很多时候会成为一个瓶颈,当客户端越多瓶颈越明显,任何一个微服务有更新,都必须通知所有客户端,对实时性的要求比较高。
  • 升级痛苦。因为微服务嵌在客户端,很难知道哪些内部用户是用哪个版本的 API ,同时也很难约定大家在同一个时间升级。
  • 维护成本高。

服务端发现

服务端发现,通常的服务范围是,所有对外提供服务的接口,七牛用的也是这个方式,因为有成千上万个客户端,不可能把路由表写在七牛的客户端上面。当然这种方式也存在优缺点。

优点是:所有的服务可控。增加或删除一个服务时,不需要通知客户端,所有客户端可以脱离管控范围。

缺点:

  • 治理效率和瓶颈是一个很难的问题。
  • 标准的 HTTP 协议问题不大,如果是自定义协议会很麻烦,需要做的工作会很多。

七、微服务的部署

平台

微服务的部署和治理跟云平台没有必然的联系,用微服务并不意味着只能用容器,仍然可以用 IaaS 、 PaaS 、老的数据中心等平台,这个跟基础设施并没有多大的关系,但使用容器可以更好的解决某些方面的问题。

手段

部署方式一般分为手动部署和使用脚本来自动化部署。大公司有基础设施自动化、应用部署自动化平台,一点按钮就可以完成测试、打包、上线、监控、部署,但是小公司基本上没有这种基础设施建设。目前还没有公司把基础设施建设进行开源,因为每个公司的基础设施自动化测试不同,业务场景不同,所以不一定适用。

应用的自动化部署。 2010 年 PaaS 很火,很多人想把这个部署做成自动化。因为当部署应用特别方便的时,大家才愿意做拆分。管理一台机器,部署一件事情、一个服务,跟部署十个是有明显的时间成本的,如果时间成本降低,大家更愿意进行拆分。

还有一种方式是 Image 的部署。把虚拟机打包成一个镜像(它的扩展很迅速),常见做法是镜像里面不放代码而是放脚本。每次部署一个新的用户服务时,需要到上面取一个最新的包来部署新的工作,而不是把代码放上去。因为镜像的制作成本比较高,更新麻烦。

八、容器和微服务

近几年微服务突然变火,其实跟容器有很大的关系。

第一容器够小,可以解决微服务独立部署的问题,解决微服务对机器数量的诉求。

第二容器独立,可以解决多语言的问题。

第三是开发环境与生产环境相同,针对非 Windows 开发者,如果使用容器技术,就比较容易使本机的开发环境与生产环境相同。Windows 开发者需要自己部署一台服务器,保持服务器跟线上相同。当一个公司里面有多语言时,有一个镜像就容易解决这个问题。

第四是容器效率高,省钱。

第五是代码和 image 一体化。简网以前以服务为核心,每个服务的管理体系比较难做,现在用 Docker 后可以把 image 做完,再把服务和 image 做一一对应后,管理就可以实现一体化。

第六是容器的横向扩展。容器很容易横向扩展,但纵向扩展对公司来说更有意义。从整个公司的层面来看,机器利用率并不好,这是一个客观存在的问题,当时的技术无法解决问题,因为要多少机器是业务决定的,运维并没有决策权。此时,可以把内存和 CPU 做一个动态调整,最初,可以调低一点,当增上来之后再进行扩容。

但是这样做仍然存在一些问题。

第一是 Image 管理问题,有很多服务做,但是谁真正有资格做 Image 管理呢?Image 镜像越来越多,如果开放给所有人,每发布一个升级就多一个镜像,那这是需要治理的。

第二是系统安全管理问题,在 KVM 里面套一个 Docker ,用 KVM 做隔离,这样做,不仅加强了安全性,又利用了 Docker 快速部署、快速开发微服务管理的体系,系统安全上,短期内无解,但在公司内部运用还可以。

第三是授权管理问题,授权管理很多时候是特指数据库,如果服务是有状态的,扩容的时候需要做数据库授权,这个授权的操作和管理是有难度的,特别是发布后发现系统有漏洞,管理的难度很高。

第四是系统成熟度问题,虽然现在 Docker 很火,但整体来说系统成熟度没有达到理想的状态,运用过程中多少会出现一些问题。

第五是社区成熟度问题,Docker 在两三年的时间内突然变热,但社区成熟度是需要时间沉淀的。

作者:郭理靖@简网 CTO,更多云行业技术洞见请访问 七牛云博客

作者:u010646653 发表于2016/11/7 15:32:59 原文链接
阅读:16 评论:0 查看评论

相关 [mvc 微服务 技术] 推荐:

从 MVC 到微服务,技术演变的必经之路

- - CSDN博客推荐文章
编者按:近两年很火的微服务是什么. 本文将为大家介绍微服务的来龙去脉. CGI 出现于 1993 年,图 1 是 CGI 模式比较简单的结构图. 开源电商软件等都是采用 MVC 模式,MVC 模式是做软件开发必学和必经历的一个阶段. 1970 年提出了 MVC 的概念,当时的主机和客户端早已凸显了这个概念.

MVC演化史

- huige - 火丁笔记
Martin Fowler在他所写的《企业应用架构模式》一书中感慨道:MVC已经成为我们最常误用的模式. 人们之所以常常误用MVC,很大程度上是因为混淆了不同的MVC变体. 大概上世纪七十年代,Xerox PARC的Trygve提出了MVC的概念,并应用在Smalltalk系统中,为了和其它类型的MVC加以区分,历史上习惯的称之为Classic MVC.

Spring MVC 和 Struts2

- - CSDN博客架构设计推荐文章
Web层面的框架学习了三个Struts1和2,SpringMVC,那他们之间肯定存在一个优劣和适用的环境,Struts1和2的异同点我已经做过对比《 Struts1和Struts2》,这篇将对比下Struts2和SpringMVC的异同,下面数据基本来源于网络,本人是搜集整理所得,供大家参考. 一个项目使用什么样的技术,决定的因素很多,我所能想到的有:对系统的性能、开发的效率、团队学习的成本、业务场景等,下面尽量从这几个方面入手,来分析比较下他们之间存在的优劣.

最佳MVC实践

- - CSDN博客架构设计推荐文章
原文地址 http://www.yiiframework.com/doc/guide/1.1/zh_cn/basics.best-practices 最佳MVC实践(Best MVC Practices). Although Model-View-Controller (MVC) is known by nearly every Web developer, how to properly use MVC in real application development still eludes many people.

srping mvc RequestMapping实现

- - CSDN博客推荐文章
spring mvc中定义请求的url只需要在方法上添加注解: @RequestMapping("aa.mvc")即可定义访问的url地址,但是你是否有考虑过为什么添加这个注解就可以实现url访问地址的定义了呢. 首先定义注解RequestMapping. mvc中常需要对输入值进行合法性校验,所以也定义了校验的注解MyValid.

MVC就是个选择题

- Dash - Becomin' Charles
由于采用了Web开发框架来开发项目,所以我首次在真正的项目中采用MVC的开发模式. 随着项目的不断深入,我也在不断反思,MVC设计模式到底给项目带来了什么. 听起来都很难听对吗,但是确实如此. 清晰的代码结构,易于维护,易于扩展. 当然,我不是在批判MVC,只是觉得,在使用MVC过程中,还是需要投入更深入的思考,到底怎样才能用好这个设计模式.

表现层模式-MVC

- - 博客园_首页
       在前面简述了从服务层到数据层参见 架构设计目录. 剩下了表现层,一个再好的中间层表现也必须有一个用户界面,提供和用户交互,将用户行为输入转化为系统操作,进入后台逻辑. 在当下RAD(快速应用开发)工具的支持下,我们可以比较快速的完成UI设计,RAD追求所见即所得的快速反馈,快速应用.

三层架构与MVC

- - CSDN博客推荐文章
MVC是Model View Controller , 是模型-视图-控制器的缩写,一种软件设计典范.用于组织代码用 一种业务逻辑和数据显示分离的方法,这个方法的假设挑剔是如果业务逻辑被聚集到一个部件里面,而且界面和用户围绕数据的交互能被改进和个性化指定而不需要重新编写业务逻辑.. 三层架构是最基本的项目分层结果,而MVC则是三层架构的一个变体,MVC是一种好的开发模式.

Spring MVC 3 深入总结

- - 企业架构 - ITeye博客
大家好,Spring3 MVC是非常优秀的MVC框架,由其是在3.0版本发布后,现在有越来越多的团队选择了Spring3 MVC了. Spring3 MVC结构简单,应了那句话简单就是美,而且他强大不失灵活,性能也很优秀. 官方的下载网址是: http://www.springsource.org/download   (本文使用是的Spring 3.0.5版本).

Spring MVC 与 web开发

- - 码蜂笔记
项目组用了 Spring MVC 进行开发,觉得对里面的使用方式不是很满意,就想,如果是我来搭建开发环境,我会怎么做. 下面就是我的想法,只关注于 MVC 的 View 层. 现在基本上都是用 ajax 来调用后台接口,拿到 json格式的数据再展示,有的人直接返回数据,却没有考虑异常的情况,我觉得返回的报文里必须包含表示可能的异常信息的数据和业务响应数据.