跟着小程来学微服务--微服务思想

前言

一直对微服务非常感兴趣,因为公司的架构改造正好有机会能够接触微服务,买来一些书,请教了很多微服务大牛同时自己也做了很多总结,写成了80页ppt,算是我对微服务的一个认识吧,微服务本身不同的人有不同的理解,而我就从我自己的角度来谈谈微服务是什么。

目前市面上的不少书或者不少相关文章写的都是框架的使用,或者架构的介绍,其实对于刚入门不久的同学来说很容易造成微服务就是一堆框架和组件的堆砌,于是今天我将从理论和实践的角度来说说微服务。

现代互联网的方向是当企业发展到一定规模后,一定是大规模、云计算和大数据的三者的结合,从而形成平台,那么微服务就是基于此而提出的。

一、什么是微服务

1、常见的系统架构

目前我们经常接触的网络架构主要有三种,如下图:

从图中可以看到,共有三种模式,第一种是集中式架构也是单块应用最常使用的架构模式。第二种是分布式架构,最常见的应用是将一个大的任务拆分到不同的机器中进行计算,最终有一台服务器合并计算结果就是分布式架构的一个好的体现。第三种就是微服务架构。

2、现实遇到的挑战

  • 扩容困难

    我们之前开发项目用的是虚拟机,每次上线项目需要加机器总会遇到资源不足的情况,还要走非常复杂工单审批流程,还要与运维人员不断PK,才能申请下来资源,整个流程冗长,机器受限于资源申请困难。

  • 部署困难

    每次上线采用专门的人进行布署,上线之前需要与上线人员沟通上线的环境,防止上线出错。

  • 发布回滚困难

    每次上线发现问题后,需要重新从svn主干上面进行代码编译,但是有时候会因为各种问题回滚失败,而且重新编译很耗时导致回滚缓慢。

  • 适配新技术困难

    如果打算在不同的模块采用不同的语言开发,或者想在架构中做技术升级都很困难或者不支持。

  • 快速开发困难

    项目中采用单体应用,里面集成了太多功能模块,无法快速进行功能开发并且很容易牵一发动全身。

  • 测试困难

    测试人员没有自动化测试框架,或者Mock系统,导致只能采用简单的人工测试流程,而且还经常发生功能覆盖不全面等问题。

  • 学习困难

于是我们把项目中遇到上述问题的项目称为单体应用。

3、微服务的定义

The microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services , which may be written in different programming languages and use different data storage technologies.

– James Lewis and Martin Fowler

原文:http://martinfowler.com/articles/microservices.html

翻译文:http://blog.csdn.net/u013970991/article/details/53333921

总结了一下共有四点特性:

  • 一些列的独立的服务共同组成系统
  • 单独部署,跑在自己的进程里
  • 每个服务为独立的业务开发
  • 分布式的管理

4、微服务和SOA的区别

  • 微服务只是一种为经过良好架构设计的SOA解决方案,是面向服务的交付方案。
  • 微服务更趋向于以自治的方式产生价值。
  • 微服务与敏捷开发的思想高度结合在一起,服务的定义更加清晰,同时减少了企业ESB开发的复杂性。
  • 微服务是soa思想的一种提炼!
  • SOA是重ESB,微服务是轻网关。

5、微服务定义小结

二、关于微服务的建模

我们在谈建模,首先想到的是领域驱动设计的内容,没错,微服务的建模思想也是基于建模的思想,下面我将给简单给与介绍什么样的服务才算是好服务。

1、松耦合和高内聚

松耦合:修改一个服务不需要同时修改另一个,每个微服务都可以单独修改和布署。

高内聚:把相关的事务放在一起,把不相关的排除出去,聚集在一起的事务只能干同一件事。

用如下图可以清晰的表示:

2、限界上下文

限界:就是划分、规定,界限、边界。

上下文:是业务的整个流程。

当我们检查已有的系统时,经常会发现系统中存在混杂在一起的模型,他们之间的边界是非常模糊的。此时你应该为整个系统绘制一个边界,然后将其归纳在大泥球范围之内。往往在我们所在的项目中,经常是项目版本的迭代的时候出现这样的情况,导致后期维护代码越来越困难。

3、逐步上下文

  • 划分方法:一开始识别粗粒度的限界上下文、这些粗粒度的上下文可能包括一些套嵌的限界上下文,这些套嵌的上下文不直接对外可见。
  • 暴露原则:使用粗粒度上下文还是套嵌上下文暴露服务,哪个更合理,应该有组织结构来决定的。

正如上面二个图的示例所示,左边的订单处理,货物接收和库存管理三个模块在项目研发初期被归集到了仓库服务中,财务服务获取库存管理的数据,直接访问仓库服务的库存管理接口就可以了。随着这三个模块的不断演进和壮大,单个服务已经不能满足业务和团队发展的需求,这时候将这三个模块分别拆分演变成右边的结构图,这时候订单管理,货物接收和库存管理分别以服务的形式对应不同的团队,财务服务只需请求库存管理服务就可以得到相应的数据。

三、关于微服务的集成

1、集成原则

微服务的集成做到好,可以保持自治性、可以独立发布修改和发布。

  • 避免破坏性修改

    服务的一些修改不能导致该服务的消费方发生改变。

  • 保证API与技术的无关性
  • 保证API的易用性
  • 隐藏内部实现细节

2、编排与协同

编排:同步调用一组服务,等待各个服务的返回结果。优点知道业务流程中每一步跨服务调用结果,缺点容易承担太多的调用,太耗时,导致调用方的不稳定性。

协同:异步调用一组服务或服务调用加入队列中,降低服务之间的耦合度,带来的额外工作业务流程跨服务的监控,不过可通过消费方处理完成后,回调服务方告知处理结果。

(编排)

(协同)

3、版本管理

  • 尽可能推迟破坏性修改

    宽进严出的原则

  • 尽早发现破坏性的修改

    按照契约,通过测试及早发现是服务方还是消费方破坏性的修改

  • 不同的接口版本共存

    最好共存两个版本

4、案例分析

案例一:如何拆分单块系统结构

当我们看到一个单块系统时,往往首先要从数据库入手进行拆分,规划好哪些是财务代码的表,哪些是客户代码的表,将二者进行分离,这时候单块系统的应用结构并没有拆分,这还需要我们在进行设计单块系统的时候,客户代表和财务代码的表字段不能混在一起,还是要设计成不同的表才能方便我们将来拆分,虽然系统是在一起的,但是却为未来做了拆分准备,最后将应用系统拆分独立布署,这个过程就结束了。

案例二:如何跨系统访问数据表

有二个服务,分别是产品目录和财务,左图的场景是财务服务直接调用产品目录的数据表进行数据获取,这种跨服务的数据获取方式是有问题的,首先我们无法把控财务服务是如何获取数据的,是否对我们的数据表造成影响,其次从设计的角度来说无疑又增长了系统之间调用的耦合度,系统之间的依赖又增强了。于是演变成右图这样,左图只需提供服务接口给右图调用即可。

案例三:服务设计中的坏味道

在这样的系统中,ABCD四个系统进行了串联,这样也就要求这四个系统分别都是高可用,如果其中任何一个系统挂了或者发生问题,都会直接影响其他所有系统,所以我们设计微服务架构的时候要尽量避免这种集中式的架构。

四、如何大规模的使用微服务

我们真正使用微服务的时候,有很多需要注意和关注的点:

1、故障无所不在

网络是不可靠,只能尽力限制引起故障的因数,达到一定规模后,故障不可避免。

2、跨功能需求

服务吞吐量、可用性和数据持久性等这些需求需要持续测量,并保证服务满足可接受的目标。

3、功能降级

构建弹性系统,因微服务功能分散,在有可能down机的微服务上,能够安全的降级以保证弹性

4、反服务脆弱

为了不会引起严重级联影响,需要正确的设置超时、实现舱壁隔离或断路层等以避免在第一时间调用一个不健康的服务。

  • 超时

    设置超时时间对于调用下游服务十分重要,超时时间设置太长有可能把下游系统拖慢,设置太短可能下游服务未处理完成。最好设置一个默认的超时时间,当超时发生时后,记录到日志里看看发生了什么,并且做响应的调整。

  • 断路器

    使用断路器,当请求下游服务发生一定数量的失败后,短路器打开,接下来的请求快速失败。一断时间后,查看下游服务是否已服务,重置断路器。

  • 舱壁

    为每个下游服务建立单独的连接池。超时和断路器资源受限时释放资源,舱壁第一时间确保它不成为限制。还有一个拒绝请求的舱壁,用以避免资源饱和,称之为减载。

  • 隔离

    当下游服务离线,上游服务不受影响。设置成为服务间隔离。

5、幂等

幂等操作,多次执行所产生的影响,均与一次执行影响相同。可以把某些特定业务操作设计成幂等的,比如客户下单送积分。

6、扩展

增加负载、减少延迟。

  • 更强大的主机:垂直扩展,更好的机器。
  • 拆分负载:按业务拆分成不同的微服务
  • 分散风险:数据跨机房,异地备份等
  • 负载均衡:避免服务单点故障
  • 作业分离:Job独立服务执行
  • 重新设计:一般设计系统需要考虑10倍容量增长。重新设计系统应对规模化,是成功的标志。

7、扩展数据库

  • 服务的可用性
  • 服务的持久性:多副本
  • 读取数据扩展:读写分离
  • 写操作扩展:分表分库
  • 共享数据库设施:容易形成单点故障
  • CQRS:命令查询职责分离

8、缓存的使用

通过存储之前的操作结果,以便后续请求使用这个结果,而无需花重新计算或查询。

  • 客户端缓存

    客户端缓存获取的结果,客户端决定何时获取新副本。一般是有下游服务提供缓冲的过期时间。客户端缓存可以减少网络调用次数,并且减少下游服务负载的最快方法之一,客户端缓存数据,让数据失效需要做额外的工作。

  • 服务端缓存

    服务端来负责处理缓存,容易跟踪和优化缓存的命中率。

  • 代理服务器缓存

    缓存在服务的和客户端之间,比如方向代理或CDN等。对一切客户端和服务端不透明

  • HTTP缓存
  • 为写使用缓存

    先写入本地缓存,之后某个时刻将数据写入下游的,可能更规范化的数据源中。

  • 为弹性使用缓存

    下游服务不可用,客户端可以缓存可能失效的数据。

  • 隐藏源服务

    保护源服务,不直接暴露源服务。如果缓存不命中,立即失败,异步重建缓存。

  • 保持简单

    避免太多地方使用缓存,缓存越多,数据越可能失效,就越难保证数据的新鲜程度。

9、自动伸缩

响应型伸缩、预测型伸缩

10、CAP定理

在分布式系统中有三方面需要彼此权衡:一致性、可用性和分区容忍性。这个定理告之我们最多只能能保证三个中的两个。CA系统在分布式系统中根本不存在。

六、阶段总结:

在第一部分我们重点介绍了涉及微服务的一些思想,总结了如何设计一个相对好的服务,并且也介绍了一些微服务和领域驱动的相关概念帮助大家学习掌握。

那么在第二部分介绍中,我将在如何在微服务中使用事务,自动化测试怎么做,Devops是什么,如何利用康威定律管理团队,以及重点介绍实战项目,如何基于Spring boot/netflix来构建微服务项目。

时间: 2024-10-10 02:41:28

跟着小程来学微服务--微服务思想的相关文章

跟着小程学微服务-自己动手扩展分布式调用链

一.说在前面 微服务是当下最火的词语,现在很多公司都在推广微服务,当服务越来越多的时候,我们是否会纠结以下几个问题: 面对一笔超时的订单,究竟是哪一步处理时间超长呢? 数据由于并发莫名篡改,到底都谁有重大嫌疑呢? 处理遗漏了一笔订单,曾经是哪个环节出错把它落下了? 系统莫名的报错,究竟是哪一个服务报的错误? 每个服务那么多实例服务器,如何快速定位到是哪一个实例服务器报错的呢? 现在很多系统都要求可用性达到99.9%以上,那么我们除了增加系统健壮性减少故障的同时,我们又如何在真正发生故障的时候,快

【一起学源码-微服务】Nexflix Eureka 源码十:服务下线及实例摘除,一个client下线到底多久才会被其他实例感知?

前言 前情回顾 上一讲我们讲了 client端向server端发送心跳检查,也是默认每30钟发送一次,server端接收后会更新注册表的一个时间戳属性,然后一次心跳(续约)也就完成了. 本讲目录 这一篇有两个知识点及一个疑问,这个疑问是在工作中真真实实遇到过的. 例如我有服务A.服务B,A.B都注册在同一个注册中心,当B下线后,A多久能感知到B已经下线了呢? 不知道大家有没有这个困惑,这篇文章最后会对此问题答疑,如果能够看到文章的结尾,或许你就知道答案了,当然答案也会在结尾揭晓. 目录如下: C

【一起学源码-微服务】Nexflix Eureka 源码十三:Eureka源码解读完结撒花篇~!

前言 想说的话 [一起学源码-微服务-Netflix Eureka]专栏到这里就已经全部结束了. 实话实说,从最开始Eureka Server和Eureka Client初始化的流程还是一脸闷逼,到现在Eureka各种操作都了然于心了. 本专栏从12.17开始写,一直到今天12.30(文章在平台是延后发布的),这将近半个月的时间确实收获很多.每天都会保持一定的时间学习,只要肯下功夫,没有学不会的东西. 2020年将继续保持学习的节奏,自己定的目标是把spring cloud几个重要的组件都学一遍

微服务化之服务拆分与服务发现

本文章为<互联网高并发微服务化架构实践>系列课程的第六篇 前五篇为: 微服务化的基石--持续集成 微服务的接入层设计与动静资源隔离 微服务化的数据库设计与读写分离 微服务化之无状态化与容器化 微服务化之缓存的设计 一.服务拆分的前提 说到微服务,服务拆分是绕不过去的话题,但是微服务不是说拆就能拆的,有很多的前提条件,需要完成前面几节所论述的部分. 首先要有一个持续集成的平台,使得服务在拆分的过程中,功能的一致性,这种一致性不能通过人的经验来,而需要经过大量的回归测试集,并且持续的拆分,持续的演

微服务 | 微服务网站性能测试

开发者们在工作中经常会遇到过这样的情况:在接手实际项目时,在传统的单体架构下,一个同事负责的功能模块出现故障后,会导致整个系统瘫痪.那么有什么办法才能解决这种问题呢?云上有一种服务--微服务,可以对业务流程进行独立开发和部署,满足新业务快速创新和敏捷交付的需求. 基于Devops的微服务架构是云时代部署应用的一项热门技术,它把庞大的单个应用程序分解为数十个微服务,每个服务独立开发.更新和部署,使业务更快速地响应市场变化. 单体架构无力支撑大型系统 新ICT时代,数字化转型已成为全球各大企业的战略

初见微服务之服务注册与发现

什么是服务注册与发现 微服务将传统的"巨石"应用拆分成一个一个的组件应用,每个组件应用提供特定的服务,可以是一个,也可以是多个,并且组件所含服务应该是可以动态扩展的,随着时间推移.系统进化,可任意拆分.合并. 组件化应用和颗粒化的服务,遍布在系统的各个角落,由不同的项目成员进行维护,微服务的核心是化整为零.各司其职,这就要求开发人员不得操作其业务或服务范围以外的数据模型等资源,只能通过接口的访问,使用某一服务. 由于服务的跨度很大(公司很大的情况下).数量很多(数以百计甚至更多),为保

微服务的服务拆分

一.服务拆分的三个维度 三个维度拆分后,微服务的架构图就如下图所示: API GATEWAY服务网关: 身份认证.权限管理.服务动态路由.数据的聚合(比如房产详情页就有详情.评论.推荐,这些都属于不同的服务,这些我们就需要在服务网关中去做) Service Register:注册中心 服务的注册与发现 注册与发现:如果是在单体架构中,添加一个实例,一般是在前端反向代理中如Nginx中添加一个实例服务器ip端口. 而在微服务中这种方式就很难满足多服务的架构,一方面频繁的修改Nginx配置文件极易出

Spring Cloud构建微服务架构服务注册与发现

Spring Cloud简介Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁.决策竞选.分布式会话和集群状态管理等操作提供了一种简单的开发方式. Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Spring Cloud Config.Spring Cloud Netflix.Spring Cloud0 CloudFoundry.S

Spring Cloud微服务架构—服务注册与发现

Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁.决策竞选.分布式会话和集群状态管理等操作提供了一种简单的开发方式. Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Spring Cloud Config.Spring Cloud Netflix.Spring Cloud0 CloudFoundry.