微服务架构与实践及云原生等相关概念

微服务架构与实践

笔记:《微服务架构与实践》 王磊 著html

一 单块架构

  1 定义:对于这种功能集中、代码和数据中心化、一个发布包、部署后运行在同一进程的应用程序,咱们一般称之为单块架构应用,并不是物理上的分层。前端

  2 单层架构:数据 逻辑 页面 混合java

  3 三层架构:ios

    1)表示层:数据显示和用户交互git

    2)业务逻辑层:业务逻辑处理算法

    3)数据访问层:数据存储访问数据库

  4 优点: 比较适合小项目json

    易于开发:开发简单直接,集中式管理,基本不会重复开发,集成工具适合后端

    易于测试:单进程浏览器

    易于部署:单项目包,功能都在本地,没有分布式的管理开销和调用开销

    易于水平伸缩:发布相同的项目包,部署多个运行环境,使用负载均衡器分发,克隆

  5 挑战:

    开发效率低:全部的开发在一个项目改代码,递交代码相互等待,代码冲突不断

    代码维护难:代码功能耦合在一块儿,新人不知道何从下手

    部署不灵活:构建时间长,任何小修改必须从新构建整个项目,这个过程每每很长

    稳定性不高:一个微不足道的小问题,能够致使整个应用挂掉

    维护成本增长:功能多,团队大,管理复杂,缺陷修复容易致使新的缺陷问题

    持续交付周期长:

    技术选型成本高:采用统一的技术平台或方案开发,当尝试引入新的框架、技术或对技术站升级会面临不小的风险。技术变化快,平滑完成替代较难。

    可扩展性差:没法知足高并发状况下的业务需求

    构建全功能团队难:单块架构每每以技能为单位进行分组,如前端、业务层、数据库团队等。

二 微服务架构

  微服务架构是一种架构模式,它提倡将单一应用程序划分红一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每一个服务运行在其独立的进程中,服务与服务间采用轻量级的通讯机制互相沟通(一般是基于HTTP的RESTful API)。每一个服务都围绕着具体业务进行构建,而且可以被独立地部署到生产环境、类生产环境等。另外,应尽可能避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

                                                        ——摘自马丁· 福勒先生的博客

  1 特色:

    1)微

    微服务架构经过对特定业务领域的分析与建模,将复杂的应用分解成小而专、低耦合而且高度自治的一组服务。微的定义最好符合项目的敏捷开发周期。

    2)单一职责

    业务逻辑单一,高内聚低耦合,不一样服务经过管道等方式灵活组合。

      注:面向对象设计之SOLID原则

SRP

The Single Responsibility Principle 

单一责任原则

一个对象/类应该只有一个发生变化的缘由,若是一个对象/类被多个缘由改变,则说明该对象/类承担了多个职责

OCP

The Open Closed Principle

开放封闭原则

软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。

LSP

The Liskov Substitution Principle

里氏替换原则

当一个子类的实例应该可以替换任何其超类的实例时,它们之间才具备is-A关系(is-a 指的是类的父子继承关系)

DIP

The Dependency Inversion Principle

依赖倒置原则

1. 高层模块不该该依赖于低层模块,两者都应该依赖于抽象

2. 抽象不该该依赖于细节,细节应该依赖于抽象

ISP

The Interface Segregation Principle

接口分离原则

不能强迫用户去依赖那些他们不使用的接口。换句话说,使用多个专门的接口比使用单一的总接口总要好。

     3)轻量级通讯

    轻量级通讯机制一般指语言无关、平台无关的交互方式。通讯消息格式,如xml、json等,他们的解析和使用基本与语言、平台无关。通讯协议,一般基于HTTP,能让服务间的通讯标准化、无状态化。REST是实现服务之间互相协做的轻量级通讯机制之一。

    4)独立性

    开发测试部署的独立。每一个服务都是一个独立单元,有独立的代码库。服务与服务隔离。

    5)进程隔离

    每一个服务都运行在不一样的进程中,能够部署在不一样节点。组件通常指独立升级 独立替换掉的部分。

  2 背景技术

    1)互联网时代的产品一般有两类特色:需求变化快和用户群体庞大。在这种状况下,如何从系统架构的角度出发,构建灵活、易扩展的系统,快速应对需求       的变化;同时,随着用户量的增长,如何保证系统的可伸缩性、高可用性,成为系统架构面临的挑战。

    2)敏捷、精益方法论、DevOps的深刻人心

    精益创业(Lean Startup)帮助组织分析并创建最小可实行产品(Minimum Viable Product),经过迭代持续改进;敏捷方法帮助组织消除浪费,经过反       馈不断找到正确的方向;持续交付帮助组织构建更快、更可靠、可频繁发布的交付机制。DevOps文化的推行打破了传统开发与运维之间的壁垒,帮助组织造成         更高效的、开发与运维高度协做的交付团队。

    3)虚拟化技术和容器化技术

    虚拟化技术和基础设施自动化(Infrastructure As Code)的快速发展极大的简化了基础设施的建立、配置以及系统的安装和部署。譬如云平台的成熟以及像         Chef、Puppet、Ansible等工具的使用,让更多的基础设施可以经过自动化的方式动态建立。

      容器化技术的发展以及Docker的出现,更是将虚拟化技术推向了一个前所未有的高潮。 

  3 SOA面向服务架构

  SOA阐述了“对于复杂的企业IT系统,应按照不一样的、可重用的粒度划分,将功能相关的一组功能提供者组织在一块儿为消费者提供服务”,其目的是为了解决企业内部不一样IT资源之间没法互联而致使的信息孤岛问题。直到2000年左右,ESB(Enterprise Service Bus)、WebService、SOAP等这类技术的出现,才使得SOA渐渐落地。

  实际上, SOA的概念和微服务思想几乎一致。主要区别以下表所示:

                 SOA实现

微服务架构实现

企业级,自顶向下开展实施

团队级,自底向上开展实施

服务由多个子系统组成,粒度大

一个系统被拆分红多个服务,粒度细

企业服务总线,集中式的服务架构

无集中式总线,松散的服务架构

集成方式复杂(ESB/WS/SOAP)

集成方式简单(HTTP/REST/JSON)

单块架构系统,相互依赖,部署复杂

服务都能独立部署

  相比传统SOA的服务实现方式,微服务更具备灵活性、可实施性以及可扩展性,其强调的是一种独立测试、独立部署、独立运行的软件架构模式。

  4 微服务本质

    服务做为组件

      传统实现组件方式是隔离独立的部分或抽出公用的部分,构建共享库,从而达到解耦和复用的效果。服务之间定义清晰、语言无关、平台无关的接口。

    围绕业务组织团队

    关注产品而非项目

    技术多样性

    业务数据独立

      提供业务数据接口,而非公用数据库

    基础设施自动化

      每一个服务需分别部署,则部署 运维的成本增长,对持续交付和部署流水线要求高。实现基础设施的自动化促进微服务构建。

    演进式架构

      敏捷开发 版本更新

  5 微服务实施因素

    分布式系统的复杂度

      微服务架构师一种基于分布式的系统。

      性能:多服务之间响应延迟及协做

      可靠性:单点故障率增大

      异步:

      数据一致性:分布式事务管理 或保证数据的瞬时一致性

      工具:IDE对微服务的支持不太好

    运维成本

      配置信息:

      部署

      监控与告警

      日志收集

    部署自动化

      构建有效的自动化部署流水线

    DevOps与组织架构

      微服务不只是一种架构模型,也表现出一种组织模型(开发者将承担部署运维监控)

    服务间依赖测试

    服务间依赖管理 

三 微服务实践/项目开发流程

  敏捷开发 自动化工具

  1 API实现(REST)

    选择合适的开发语言及开发框架

    选择合适的代码仓库,svn、git

  2 代码检查

    1)代码自动化测试工具

    2)单元测试覆盖率统计

    3)代码静态检查,如代码的可读性、命名风格及统一的格式等

    4)代码复杂度检查

    可集成,如自动化测试的同时进行代码的静态检查

  3 代码构建

    代码构建工具及构建所生成文件类型,如war、jar、镜像等

  4 项目部署

    基础设施自动化(Puppet Ambari等)

    自动化部署,如部署脚本deploy.sh,可包括基础设施环境准备 

  5 持续交付流水线

    持续集成环境,如jenkins

    持续交付:小批量价值流动  频繁可发布  快速反馈

    1 提交阶段

      代码编译 静态检查 单元测试等等

      持续集成工具可经过WebHook的方式检测到代码仓库的提交并触发相应的处理机制,能够轮询的方式按期检测代码库(提交版本时间)的变化。

    2 构建阶段

      构建部署包,提交阶段完成后触发构建,注意部署包的版本定义    

    3 部署阶段

      测试环境

      生产环境

      基础环境搭建,如tomcat等,执行部署脚本deploy.sh等

  6 日志聚合

    日志聚合工具 splunk kafka flume

    数据采集  数据存储 高效索引 数据搜索 数据分析

  7 监控与告警 

    主机监控 基础设施 Nagios zabbix

    应用监控 项目相关的状态

    告警 服务出现异常通知相关人员修复

  8 功能迭代

    服务描述文件:服务介绍 (名称 功能) 服务维护者 服务级信息 运行环境(地址) 开发(搭建 运行) 测试 构建 部署 运维(日志URL 监控URL)

四 微服务进阶

  1 轻量级通讯机制

    定义:平台无关、语言无关的消息通讯协议

    同步通讯:请求->等待->响应->处理

      1)远程过程调用RPC:

        典型的分布式节点间同步通讯

        语言依赖

        传输格式为二进制  一端变化另外一端也许对应修改

      2)表述性状态传递REST

        以资源为核心、以HTTP为操做方式 HTTP通讯是同步的

        核心:资源:信息实体的抽象

           表述:对资源某一特定时刻的状态描述,如json格式等,URI仅表明资源的实体,HTTP请求头Accept、Content-Type字段才是表述

           状态转移:客户端同服务器端交互的过程当中,客户端能经过资源的表述来实现操做资源的目的。

           统一接口:GET获取资源 POST新建资源 PUT更新资源 DELETE销毁资源

      3)超文本应用语言HAL

        轻量级超文本应用描述协议,基于REST,并解决REST中资源结构标准化和定义资源连接的问题。可以使用HAL浏览器可视化资源信息。

        HAL又将资源分为:状态 连接 子资源

          状态:资源自己固有的属性

          连接Links:与当前资源相关的一组资源的连接的集合

          子资源:描述 在当前资源内部 其嵌套资源的定义

    异步通讯:

      1)消息队列

        核心:持久性(消息保持在内存、磁盘、或数据库中)  排队标准(消息队列的标准及算法)安全策略 清理策略 处理通知

        访问方式:

          拉模式pull:消费者按期检查队列上的消息,通常存在一个发布者和一个消费者

          推模式push:每当发布者将消息添加到队列中时,会经过某种机制通知消费者,通常存在多个消费者,也叫订阅者。

      2)后台任务处理系统

        相对简单的异步场景中使用消息队列略微复杂。常见的后台任务处理系统有Resque、Sidekiq、Delayed_job等

        核心:任务 队列 执行器 定时器

        服务回调:保持任务的轻量级 不在任务中定义过多逻辑 尽可能作到由任务回调具体的服务来完成交互。

          

   2 微服务与测试

            微服务的组成部分及测试内容

      

 

     在微服务场景下,这个层次能够被扩展为5层(若是将UI测试单独抽取出来,能够分为六层):

      单元测试:

        针对程序单元的正确性进行的检验。被测单元依赖于模拟部分和被测单元依赖于真实部分。工具如java中的JUnit

      接口/契约 测试

        针对服务接口进行的测试,验证提供者提供的契约/接口是否知足消费者的指望。对于微服务,建议使用基于消费者驱动的契约测试。

        工具如Pact、Pacto、Janus

      集成测试

        将不一样的单元按照指望组合起来,对其接口进行正确性检验的测试工做,如数据库访问模块与数据库的集成、对外部service依赖的测试。

        自顶向下集成(从应用的入口开始,把不一样部分组合起来,进行验证,并向底层移动)自底向上集成(传统瀑布模型经常使用)。

        工具如WireMock、mountebank

      组件测试

        对组件提供的功能进行正确性检验。进程内测试和进程外测试。

        工具如WireMock、mountebank、moco

      端到端测试

        从用户使用系统的角度出发,对系统的行为进行正确性检验。在端到端测试中,最重要的反而不是测试自己,而是环境的自动化能力。

        采用BDD方式描述测试用例,工具如Jbehave,Cucumber

    参考:微服务场景下的自动化测试

微服务实践 

摘自:微服务(Microservice)那点事

一 客户端如何访问这些服务?

  后台有N个服务,前台就须要记住管理N个服务,一个服务下线/更新/升级,前台就要从新部署,这明显不服务咱们 拆分的理念,特别当前台是移动应用的时候,一般业务变化的节奏更快。另外,N个小服务的调用也是一个不小的网络开销。还有通常微服务在系统内部,一般是无状态的,用户登陆信息和权限管理最好有一个统一的地方维护管理(OAuth)。因此,通常在后台N个服务和UI之间通常会一个代理或者叫API Gateway: 

  1)提供统一服务入口,让微服务对前台透明

  2)聚合后台的服务,节省流量,提高性能

  3)提供安全,过滤,流控等API管理功能 

  API Gateway能够是一个软硬一体的盒子,也能够是一个简单的MVC框架,甚至是一个Node.js的服务端。他们最重要的做 用是为前台(一般是移动应用)提供后台服务的聚合,提供一个统一的服务出口,解除他们之间的耦合,不过API Gateway也有可能成为单点故障点或者性能的瓶颈。

 二 服务之间如何通讯?

   由于全部的微服务都是独立的Java进程跑在独立的虚拟机上,因此服务间的通行就是IPC(inter process communication),如今基本最通用的有两种方式。

    1)同步调用:

      REST(JAX-RS,Spring Boot)

      RPC(Thrift, Dubbo)

    2)异步消息调用:(Kafka, Notify, MetaQ)

  通常同步调用比较简单,一致性强,可是容易出调用问题,性能体验上也会差些,特别是调用层次多的时候。RESTful和RPC的比较也是一个颇有意思的话题。通常REST基于HTTP,更容易实现,更容易被接受,服务端实现技术也更灵活些,各个语言都能支持,同时能跨客户端,对客户端没有特殊的要 求,只要封装了HTTP的SDK就能调用,因此相对使用的广一些。RPC也有本身的优势,传输协议更高效,安全更可控,特别在一个公司内部,若是有统一个 的开发规范和统一的服务框架时,他的开发效率优点更明显些。

  异步消息的方式在分布式系统中有特别普遍的应用,他既能减低调用服务之间的耦合,又能成为调用之间的缓冲,确保消息积压不会冲垮被调用方,同时能保证调用方的服务体验,继续干本身该干的活,不至于被后台性能拖慢。不过须要付出的代价是一致性的减弱,须要接受数据最终一致性;还有就是后台服务通常要实现幂等性,由于消息发送出于性能的考虑通常会有重复(保证消息的被收到且仅收到一次对性能是很大的考验);最后就是必须引入一个独立的broker,若是公司内部没有技术积累,对分布式管理之broker模式也是一个很大的挑战。broker模式:引入一个Broker组件,解耦客户端和服务端。服务端注册本身到Broker,经过暴露接口的方式容许客户端接入服务。客户端是经过Broker发送请求的,Broker转发请求道服务端,并将请求的结果或异常回发给客户端。经过使用Broker模式,应用能够经过发送消息访问远程的服务。

三 这么多服务,怎么找? 

  在微服务架构中,通常每个服务都是有多个拷贝,来作负载均衡。一个服务随时可能下线,也可能应对临时访问压力增长新的服务节点。服务之间如何相互感知?服务如何管理?这就是服务发现的问题了。通常有两类作法,也各有优缺点。基本都是经过zookeeper等相似技术作服务注册信息的分布式管理。

    客户端作:优势是架构简单,扩展灵活,只对服务注册器依赖。缺点是客户端要维护全部调用服务的地址,有技术难度,通常大公司都有成熟的内部框架支         持,好比Dubbo。

    服务端作:优势是简单,全部服务对于前台调用方透明,通常在小公司在云服务上部署的应用采用的比较多。

四 服务挂了怎么办?

        当咱们的系统是由一系列的服务调用链组成的时候,咱们 必须确保任一环节出问题都不至于影响总体链路。相应的手段有不少:

    重试机制

    限流

    熔断机制

    负载均衡

    降级(本地缓存)

云原生

参考:云原生应用程序架构的五大特性(上)- 12要素应用

参考: 云原生机制的三个核心思想及其将来之路

  在云的时代,应用会更多的迁移到云端,基于云的架构设计和开发模式须要一套全新的理念去承载,因而云原生思想应运而生,而针对云原生应用开发的最佳实践原则,12-Factor脱颖而出。

  云计算平台的三个层次:

    IaaS 基础云设施:提供各类基础资源(Infrastructure)

    PaaS 开发平台:提供各类平台服务(Platform)

    SaaS 交付应用或服务:直面用户,提供应用价值(Application)

12要素

一、基准代码

  一份基准代码,多份部署。每一个可部署的应用程序均被视为在版本控制中的代码库来进行追踪,相同的基准代码可能在多个环境下部署有许多的应用程序实例。

二、依赖

  显式声明依赖关系。应用程序经过适当的工具(如:Maven、Bundler、NPM)隔离依赖性,目的就是不依赖于部署环境。

三、配置

  在环境中存储配置。经过操做系统级的环境变量将配置信息或其余可能存在的不一样信息(如:开发环境、预生产环境、生产环境)应用到各个部署环境中。

四、 后端服务

  把后端服务看成附加资源。数据库、消息队列、邮件发送服务或缓存系统等均被做为是附加资源在不一样环境中被同等地调用,每一个不一样的后端服务都是一份资源 。举个例子,一个MySQL 数据库是一个资源,两个MySQL 数据库(用来给数据分区)就是两个不一样的资源。12要素应用将这些数据库都视做附加资源 ,将它们和部署环境保持松耦合。

五、构建、发布、运行

  严格分离构建和运行。基准代码转化为部署(非开发环境)须要如下三个阶段:

    构建阶段,是指将代码仓库转化为可执行包的过程。构建时会使用指定版本的代码,获取和打包依赖项,编译成二进制文件和资源文件。

    发布阶段,会将构建的结果和当前部署所需的配置相结合,并可以马上在运行环境中投入使用。

    运行阶段,是指针对选定的发布版本在执行环境中启动一系列应用程序的进程。

  以上全部阶段都是严格分离的。

六、进程

  以一个或多个无状态进程运行应用。在运行环境中,应用程序做为一个或多个无共享的无状态进程(如:master/workers)来执行,任何须要持久化的数据都要存储在后端服务内(例如:缓存、对象存储等)。

七、端口绑定

  经过端口绑定(Port Binding)来提供服务。具备12要素的应用可以实现彻底自我加载,不依赖于任何网络服务器就能够建立基于网络的服务。互联网应用能够经过端口绑定来提供服务并随时监听全部发送至该端口的请求。

八、并发

  经过进程模型进行扩展。通常而言,并行由水平向外扩展应用程序进程(尽管必要时进程也可经过内部管理线程多路传输工做)来实现。

九、易处理

  经过快速启动和终止来实现应用程序韧性的最大化。这包括了快速而有弹性的扩展、对变动的部署以及宕机恢复能力。      

十、开发环境与生产环境等价

  经过尽量地保持开发环境、预生产环境和生产环境三者的类似性来实现持续交付与部署。

十一、日志

  将日志做为事件流,容许执行环境经过集中式服务来收集、聚合、检索和分析日志,而非仅仅管理日志文件。

十二、管理进程

  将后台管理任务看成一次性进程运行。当环境就等同于应用程序长时间运行的进程时,管理任务(如:数据库迁移)会被做为一次性进程而执行。

相关文章
相关标签/搜索