精华内容
下载资源
问答
  • 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。说起Dubbo,相信大家都不会陌生!阿里巴巴公司开源...
  • 当然有些内容是参考了别的博客,毕竟我也是初探分布式微服务的,并不是所谓的大神,只是一个新手在初探分布式微服务后写下的一些自己的理解和总结。初入分布式微服务的人问的第一个问题肯定是——分布式微服务是什么...
  • 分布式微服务

    2021-02-24 03:00:11
    如:按照子服务拆分、数据库、接口,依次往下就更加细粒度,当然运维也就越来越难受了。分布式则是偏向与机器将诺大的系统划分为多个模块部署在不同服务器上。微服务和分布式就是作用的“目标不一样”。微服务是一种...
  • 基于分布式微服务系统的跨主机通信问题及其解决方案
  • 主要介绍了详解基于docker 如何部署surging分布式微服务引擎,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 架构: SpringBoot + Dubbo+ Redis + ES + Nginx + FDFS + ActiveMQ 主流分布式微服务架构。本系列教程共15季,本章节为第13季场景: 商品首页、商品详情、购物车、订单、支付、库存管理、全文搜索、秒杀、商家...
  • 架构: SpringBoot + Dubbo+ Redis + ES + Nginx + FDFS + ActiveMQ 主流分布式微服务架构。本系列教程共15季,本章节为第12季场景: 商品首页、商品详情、购物车、订单、支付、库存管理、全文搜索、秒杀、商家...
  • 分布式微服务架构体系学习分享。 作为一个架构师或者想在技术架构领域深耕的开发人员,在做技术选型及方案时,更需要对这些技术的实现思路、算法以及优点和限制进行了解。 把微服务架构结合 Docker 的一些技术选型...
  • spring+dubbo分布式微服务整合;项目结构介绍:dubbo-service 公共接口服务;dubbo-provider 公共接口服务实现(dubbo provider) 服务提供者;dubbo-consumer (dubbo consumer) dubbo服务消费者
  • linux部署分布式微服务架构.docxlinux部署分布式微服务架构.docxlinux部署分布式微服务架构.docx
  • 架构: SpringBoot + Dubbo+ Redis + ES + Nginx + FDFS + ActiveMQ 主流分布式微服务架构。 本系列教程共计15季,本套教程为第五季。 场景: 商品首页、商品详情、购物车、订单、支付、库存管理、全文搜索、秒杀...
  • 使用spring cloud代建完整的分布式微服务架构,包括spring security oauth2权限控制,docker,config动态修改配置文件,eureka服务发现,zuul路由,实现服务和服务之间的调用。等等
  • #资源达人分享计划#
  • #资源达人分享计划#
  • SpringCloud分布式微服务实战,打造大型自媒体3大业务平台视频教程,完整版15章,附源码下载。以前后端分离模式,严守企业级架构和规范,开发门户平台+媒体中心+运营中心三大业务平台。全面掌握主流后端技术栈:...
  • 课程目标 你将能快速学会目前互联网的微服务最先进的企业在用技术框架和架构师思维 适用人群 互联网工作的人群 课程简介 适用人群 互联网的技术人群
  • 分布式微服务架构体系详解

    万次阅读 多人点赞 2018-07-10 23:30:02
    虽然很多文章都说微服务架构是复杂的、会带来很多分布式的问题,但只要我们了解这些问题,并找到解法,就会有种拨开云雾的感觉。 微服务架构也不是完美的,世上没有完美的架构,微服务架构也是随着业务、团队成长而...

    课程介绍

    微服务架构的技术体系、社区目前已经越来越成熟。在最初系统架构的搭建,或者当现有架构已到达瓶颈需要进行架构演进时,很多架构师、运维工程师会考虑是否需要搭建微服务架构体系。虽然很多文章都说微服务架构是复杂的、会带来很多分布式的问题,但只要我们了解这些问题,并找到解法,就会有种拨开云雾的感觉。

    微服务架构也不是完美的,世上没有完美的架构,微服务架构也是随着业务、团队成长而不断演进的。最开始可能就几个、十几个微服务,每个服务是分库的,通过 API Gateway 并行进行服务数据合并、转发。随着业务扩大、不断地加入搜索引擎、缓存技术、分布式消息队列、数据存储层的数据复制、分区、分表等。

    本课程会一一解开微服务架构下分布式场景的问题,以及通过对于一些分布式技术的原理、模型和算法的介绍,来帮助想要实施微服务架构的工程师们知其然并知其所以然。并且,本课程通过对分布式问题的体系化梳理,结合一些方案的对比选型,可以让工程师们一览微服务的知识图谱。

    注:为了方便初学者理解微服务实践,以及掌握怎样在微服务中使用 DDD(Domain-Driven Design)思想,在本课程第 05 课中讲解了 Demo 示例,该示例是基于 Spring Boot、Spring Cloud Eureka 技术写的,Microservice 代码详见这里Gateway 代码详见这里

    专家推荐

    近年来随着互联网的快速发展,尤其是移动互联网以及云计算的迅猛发展,对于软件交付与迭代速度和效率的要求在不断提高。微服务架构凭借其简单清晰、灵活可扩展、独立部署等优势,越来越成为了分布式架构中的主流。相关的书籍和课程也层出不穷,但更多还是集中在基本理论介绍和一个简单的示例上。本系列课程内容融合了作者多年的实践经验,将微服务架构下的一些经典的分布式问题和场景逐一展开,结合最新的技术潮流,理论结合实际,深入剖析讲解,并且给出了很多对于具体实践选型非常有益的建议。可以说,该课程内容融合了作者从阿里巴巴到创业公司这一路走来所积累的精华,是微服务及分布式领域难得的佳作。

    ——阿里巴巴技术专家,荣博

    作者介绍

    李静瑶,2011 年毕业于中南大学(校优秀毕业生、优秀学生干部),毕业后入职阿里巴巴集团,在职期间主要负责淘宝网营销产品线的研发工作,曾担任试用中心产品线 PM。2015 年开始,在终点网络科技公司担任后端架构师,以及参与 Android、iOS 等客户端研发。现就职于赤金信息科技有限公司,担任 CTO 职位。从零搭建基于 Docker 容器技术的微服务分布式企业集群,深度的 DDD 思想践行者。个人博客:https://blog.csdn.net/lijingyao8206/

    课程内容

    导读:微服务架构下的分布式概览

    微服务架构的演变

    微服务是一种服务间松耦合的、每个服务之间高度自治并且使用轻量级协议进行通信的可持续集成部署的分布式架构体系。这一句包含了微服务的特点,微服务架构和其他架构有什么区别?以下对比一些常见的架构。

    单体架构

    单体架构是最简单的软件架构,常用于传统的应用软件开发以及传统 Web 应用。传统 Web 应用,一般是将所有功能模块都打包(jar、war)在一个 Web 容器(JBoss、Tomcat)中部署、运行。随着业务复杂度增加、技术团队规模扩大,在一个单体应用中维护代码,会降低开发效率,即使是处理一个小需求,也需要将所有机器上的应用全部部署一遍,增加了运维的复杂度。

    SOA 架构

    当某一天使用单体架构发现很难推进需求的开发、以及日积月累的技术债时,很多企业会开始做单体服务的拆分,拆分的方式一般有水平拆分和垂直拆分。垂直拆分是把一个应用拆成松耦合的多个独立的应用,让应用可以独立部署,有独立的团队进行维护;水平拆分是把一些通用的,会被很多上层服务调用的模块独立拆分出去,形成一个共享的基础服务,这样拆分可以对一些性能瓶颈的应用进行单独的优化和运维管理,也在一定程度上防止了垂直拆分的重复造轮子。

    SOA 也叫面向服务的架构,从单体服务到 SOA 的演进,需要结合水平拆分及垂直拆分。SOA 强调用统一的协议进行服务间的通信,服务间运行在彼此独立的硬件平台但是需通过统一的协议接口相互协作,也即将应用系统服务化。举个易懂的例子,单体服务如果相当于一个快餐店,所有的服务员职责都是一样的,又要负责收银结算,又要负责做汉堡,又要负责端盘子,又要负责打扫,服务员之间不需要有交流,用户来了后,服务员从前到后负责到底。SOA 相当于让服务员有职责分工,收银员负责收银,厨师负责做汉堡,保洁阿姨负责打扫等,所有服务员需要用同一种语言交流,方便工作协调。

    微服务和 SOA

    微服务也是一种服务化,不过其和 SOA 架构的服务化概念也是有区别的,可以从以下几个关键字来理解:

    • 松耦合:每个微服务内部都可以使用 DDD(领域驱动设计)的思想进行设计领域模型,服务间尽量减少同步的调用,多使用消息的方式让服务间的领域事件来进行解耦。
    • 轻量级协议:Dubbo 是 SOA 的开源的标准实现之一,类似的还有像 gRPC、Thrift 等。微服务更倾向于使用 Restful 风格的 API,轻量级的协议可以很好地支持跨语言开发的服务,可能有的微服务用 Java 语言实现,有的用 Go 语言,有的用 C++,但所有的语言都可以支持 Http 协议通信,所有的开发人员都能理解 Restful 风格 API 的含义。
    • 高度自治和持续集成:从底层的角度来说,SOA 更加倾向于基于虚拟机或者服务器的部署,每个应用都部署在不同的机器上,一般持续集成工具更多是由运维团队写一些 Shell 脚本以及提供基于共同协议(比如 Dubbo 管理页面)的开发部署页面。微服务可以很好得和容器技术结合,容器技术比微服务出现得晚,但是容器技术的出现让微服务的实施更加简便,目前 Docker 已经成为很多微服务实践的基础容器。因为容器的特色,所以一台机器上可以部署几十个、几百个不同的微服务。如果某个微服务流量压力比其他微服务大,可以在不增加机器的情况下,在一台机器上多分配一些该微服务的容器实例。同时,因为 Docker 的容器编排社区日渐成熟,类似 Mesos、Kubernetes 及 Docker 官方提供的 Swarm 都可以作为持续集成部署的技术选择。

    其实从架构的演进的角度来看,整体的演进都是朝着越来越轻量级、越来越灵活的应用方向发展,甚至到近两年日渐成熟起来的 Serverless(无服务)架构。从单体服务到分层的服务,再到面向服务、再到微服务甚至无服务,对于架构的挑战是越来越大。

    微服务架构和分布式

    微服务架构属于分布式系统吗?答案是肯定的。微服务和 SOA 都是典型的分布式架构,只不过微服务的部署粒度更细,服务扩展更灵活。

    理解微服务中的分布式

    怎样理解微服务中的分布式?举个招聘时某同学来面试的例子。A 同学说,目前所在公司在做从单应用到微服务架构迁移,已经差不多完成了。提到微服务感觉就有话题聊了,于是便问“是否可以简单描述下服务拆分后的部署结构、底层存储的拆分、迁移方案?”。于是 A 同学说,只是做了代码工程结构的拆分,还是原来的部署方式,数据库还是那个库,所有的微服务都用一个库,分布式事务处理方式是“避免”,尽量都同步调用……于是我就跟这位同学友好地微笑说再见了。

    微服务的分布式不仅仅是容器应用层面的分布式,其为了高度自治,底层的存储体系也应该互相独立,并且也不是所有的微服务都需要持久化的存储服务。一个“手机验证码”微服务可能底层存储只用一个 Redis;一个“营销活动搭建页面”微服务可能底层存储只需要一个 MongoDB。

    微服务中的分布式场景除了服务本身需要有服务发现、负载均衡,微服务依赖的底层存储也会有分布式的场景:为了高可用性和性能需要处理数据库的复制、分区,并且在存储的分库情况下,微服务需要能保证分布式事务的一致性。

    课程背景

    微服务架构的技术体系、社区目前已经越来越成熟,所以在初期选择使用或者企业技术体系转型微服务的时候,需要了解微服务架构中的分布式的问题:

    • 在所有服务都是更小单元的部署结构时,一个请求需要调动更多的服务资源,怎样获得更好的性能?
    • 当业务规模增大,需要有地理分布不同的微服务集群时,其底层的数据存储集群是多数据中心还是单数据集群?
    • 数据存储如何进行数据复制?
    • 业务数据达到大数据量时怎样进行数据的分区?
    • 分布式事务怎样保证一致性?
    • 不同程度的一致性有什么差别?
    • 基于容器技术的服务发现怎么处理?
    • 应该用哪些 RPC 技术,用哪些分布式消息队列来完成服务通信和解耦?
    • 那么多的分布式技术框架、算法、服务应该选哪个才适合企业的业务场景?

    本课程从微服务不得不面对和解决的分布式问题出发,包含分布式技术的一系列理论以及架构模型、算法的介绍,同时结合技术选型和实践应用,提供一系列解决方案的梳理。相信阅读完整个课程,你会对微服务的分布式问题有个系统地理解。本课程会对微服务的分布式场景问题一一击破,为你提供解决思路。

    课程内容

    本课程示例代码地址如下:

    分布式系统的问题

    • 引出分布式系统的可能问题:节点故障、网络延迟,结合错误检测的可行方案进行介绍;
    • 分布式中的时间和顺序的问题,以及标量时钟和向量时钟的实现。

    分布式数据存储

    • 分布式数据存储的技术选型、关系型数据库以及一些流行的 NoSQL 技术介绍(MongoDB、Redis、Neo4j 及 Cassandra 等);
    • 分布式存储技术使用的数据结构,了解底层数据存储原理(HashTable、SSTable、LSMTree、BTree 等);
    • 各个存储方案使用的场景以及对比。

    数据复制

    • 对于大规模存储集群,需要进行数据库的复制、排除单点故障;
    • 数据复制的模型和实现以及几种复制日志的实现方式;
    • 主备同步、主主复制、多数据中心的数据复制方案;
    • 数据复制中的读写一致性问题以及写冲突问题的解决;
    • 介绍以 MySQL 为例延伸集群数据复制方案。

    数据分区

    • 当单个领域模型维度的数据已经到一定规模时,需要进行数据分区,减轻单库压力。数据分区和分表又有哪些不同?数据分区可以如何实现?
    • 以 MySQL 的分区策略为例介绍不同分区策略的实现。
    • 数据分区后,请求的路由有哪些解决方案?会展开介绍不同的方案又有什么差别。

    服务发现和服务通信

    • 基于容器技术的微服务体系,怎样选择服务发现、负载均衡的技术实现?不同的服务发现的技术有什么区别,如何选型?
    • 为了达到松耦合的目的以及基于 DDD 思想,微服务之间减少服务调用可以通过哪些技术实现?API Gateway 可以用哪些技术框架实现?远程调用可以有哪些技术框架?怎样提高同步通信的性能?
    • 分布式的消息队列都有哪些开源、商业实现?应该怎样选择适合的消息队列?
    • 使用 DDD 思想应该如何应对服务通信,如何在实践中应用 DDD?

    分布式存储集群的事务

    • 理解分布式中的事务以及本地事务的基础概念;
    • 分布式存储的隔离级别以及各个 DB 支持的隔离方案的实现原理;
    • 以 MySQL InnoDB 中的 MVCC 为例看并发控制的在 MySQL 的实现,学习存储系统对于分布式事务的实现思想。

    分布式一致性

    • 了解分布式系统的一致性有哪些问题以及一致性的几种实现程度的模型:线性一致性(强一致性)、顺序一致性及因果一致性、最终一致性;
    • 分布式一致性相关的理论 CAP(CA、CP、AP 的相关算法)的介绍以及适合用于哪些实践;
    • 介绍 FLP 不可能结果,以及 BASE 理论。

    分布式事务实践

    • 了解微服务中分布式事务的问题;
    • 介绍强一致性的实践:二阶段、三阶段。2PC、3PC 的优缺点和限制,XA 协议的介绍和实践方案,以及最终一致性实践:TCC 模型和实践方案;
    • 分布式锁的实现模型和实践方案;
    • 基于微服务下的分布式事务实践案例分析。

    共识问题

    • 了解为什么分布式场景下有共识问题;
    • 介绍共识算法和全局消息广播的实现,公式算法的基础:leader 选举和 quorum 算法,以及一些已实现的算法的介绍和对比:VSR、Raft、Paxos、ZAB;
    • 共识算法在微服务体系的应用场景介绍:服务发现、一致性 kv 存储(Etcd、Zk)以及技术的选型如何权衡一致性的追求和性能。

    架构设计

    • 了解了很多分布式的问题和解决方案之后,回归微服务架构模型、技术选型、再回顾下微服务的弊端和特点;
    • 微服务体系的架构要素分析:安全、伸缩性、性能、可用性、扩展性;
    • 结合团队、业务场景的 DDD 实践和总结。

    课程寄语

    • 如果你是一位开发工程师,相信阅读完本系列课程,将会了解很多分布式系统的理论知识,同时也会理解一些分布式存储、中间件技术的原理,对工作中的分布式架构会有体系化的清晰认知。
    • 如果你是一位架构师,本系列课程提供了对于分布式系统问题的全面梳理,以及一些技术背后的理论,结合实践和目前业界先进的方案,对于技术选型和架构搭建提供了参考。

    点击了解更多《案例上手分布式微服务架构》

    第01课:分布式系统的问题

    前言

    无论是 SOA 或者微服务架构,都是必须要面对和解决一些分布式场景下的问题。如果只是单服务、做个简单的主备,那么编程则会成为一件简单幸福的事,只要没有 bug,一切都会按照你的预期进行。然而在分布式系统中,如果想当然的去按照单服务思想编程和架构,那可能会收获很多意想不到的“惊喜”:网络延迟导致的重复提交、数据不一致、部分节点挂掉但是任务处理了一半等。在分布式系统环境下编程和在单机器系统上写软件最大的差别就是,分布式环境下会有很多很“诡异”的方式出错,所以我们需要理解哪些是不能依靠的,以及如何处理分布式系统的各种问题。

    理想和现实

    微服务架构跟 SOA 一样,也是服务化的思想。在微服务中,我们倾向于使用 RESTful 风格的接口进行通信,使用 Docker 来管理服务实例。我们的理想是希望分布式系统能像在单个机器中运行一样,就像客户端应用,再坏的情况,用户只要一键重启就可以重新恢复,然而现实是我们必须面对分布式环境下的由网络延迟、节点崩溃等导致的各种突发情况。

    在决定使用分布式系统,或者微服务架构的时候,往往是因为我们希望获得更好的伸缩性、更好的性能、高可用性(容错)。虽然分布式系统环境更加复杂,但只要能了解分布式系统的问题以及找到适合自己应用场景的方案,便能更接近理想的开发环境,同时也能获得伸缩性、性能、可用性。

    分布式系统的可能问题

    分布式系统从结构上来看,是由多台机器节点,以及保证节点间通信的网络组成,所以需要关注节点、网络的特征。

    (1)部分失败

    在分布式环境下,有可能是节点挂了,或者是网络断了,如下图:

    part failure

    如果系统中的某个节点挂掉了,但是其他节点可以正常提供服务,这种部分失败,不像单台机器或者本地服务那样好处理。单机的多线程对象可以通过机器的资源进行协调和同步,以及决定如何进行错误恢复。但在分布式环境下,没有一个可以来进行协调同步、资源分配以及进行故障恢复的节点,部分失败一般是无法预测的,有时甚至无法知道请求任务是否有被成功处理。

    所以在开发需要进行网络通讯的接口时(RPC 或者异步消息),需要考虑到部分失败,让整个系统接受部分失败并做好容错机制,比如在网络传输失败时要能在服务层处理好,并且给用户一个好的反馈。

    (2)网络延迟

    网络是机器间通信的唯一路径,但这条唯一路径并不是可靠的,而且分布式系统中一定会存在网络延迟,网络延迟会影响系统对于“超时时间”、“心跳机制”的判断。如果是使用异步的系统模型,还会有各种环节可能出错:可能请求没有成功发出去、可能远程节点收到请求但是处理请求的进程突然挂掉、可能请求已经处理了但是在 Response,可能在网络上传输失败(如数据包丢失)或者延迟,而且网络延迟一般无法辨别。

    即使是 TCP 能够建立可靠的连接,不丢失数据并且按照顺序传输,但是也处理不了网络延迟。对于网络延迟敏感的应用,使用 UDP 会更好,UDP 不保证可靠传输,也不会丢失重发,但是可以避免一些网络延迟,适合处理音频和视频的应用。

    (3)没有共享内存、锁、时钟

    分布式系统的节点间没有共享的内存,不应理所当然认为本地对象和远程对象是同一个对象。分布式系统也不像单机器的情况,可以共享同一个 CPU 的信号量以及并发操作的控制;也没有共享的物理时钟,无法保证所有机器的时间是绝对一致的。时间的顺序是很重要的,夸张一点说,假如对于一个人来说,从一个时钟来看是 7 点起床、8 点出门,但可能因为不同时钟的时间不一致,从不同节点上来看可能是 7 点出门、8 点起床。

    在分布式环境下开发,需要我们能够有意识地进行问题识别,以上只是举例了一部分场景和问题,不同的接口实现,会在分布式环境下有不同的性能、扩展性、可靠性的表现。下面会继续上述的问题进行探讨,如何实现一个更可靠的系统。

    概念和处理模型

    对于上述分布式系统中的一些问题,可以针对不同的特征做一些容错和处理,下面主要看一下错误检测以及时间和顺序的处理模型。在实际处理中,一般是综合多个方案以及应用的特点。

    错误检测

    对于部分失败,需要一分为二的看待。

    节点的部分失败,可以通过增加错误检测的机制,自动检测问题节点。在实际的应用中,比如有通过 Load Balancer,自动排除问题节点,只将请求发送给有效的节点。对于需要有 Leader 选举的服务集群来说,可以引入实现 Leader 选举的算法,如果 Leader 节点挂掉了,其余节点能选举出新的 Leader。实现选举算法也属于共识问题,在后续文章中会再涉及到几种算法的实现和应用。

    网络问题:由于网络的不确定性,比较难说一个节点是否真正的“在工作”(有可能是网络延迟导致的错误),通过添加一些反馈机制可以在一定程度确定节点是否正常运行,比如:

    • 健康检查机制,一般是通过心跳检测来实现的,比如使用 Docker 的话,Consul、Eureka 都有健康检查机制,当发送心跳请求发现容器实例已经无法回应时,可以认为服务挂掉了,但是却很难确认在这个 Node/Container 中有多少数据被正确的处理了。
    • 如果一个节点的某个进程挂了,但是整个节点还可以正常运行。在使用微服务体系中是比较常见的,一台机器上部署着很多容器实例,其中个容器实例(即相当于刚才描述挂掉的进程)挂掉了,可以有一个方式去通知其他容器来快速接管,而不用等待执行超时。比如 Consul 通过 Gossip 协议进行多播,关于 Consul,可以参考这篇 Docker 容器部署 Consul 集群 内容。在批处理系统中,HBase 也有故障转移机制。

    在实际做错误检测处理时,除了需要 节点、容器 做出积极的反馈,还要有一定的重试机制。重试的实现可以基于网络传输协议,如使用 TCP 的 RTT;也可以在应用层实现,如 Kafka 的 at-least-once 的实现。基于 Docker 体系的应用,可以使用 SpringCloud 的 Retry,结合 Hytrix、Ribbon 等。对于需要给用户反馈的应用,不太建议使用过多重试,根据不同的场景进行判断,更多的时候需要应用做出积极的响应即可,比如用户的“个人中心页面”,当 User 微服务挂了,可以给个默认头像、默认昵称,然后正确展示其他信息,而不是反复请求 User 微服务。

    时间和顺序

    在分布式系统中,时间可以作为所有执行操作的顺序先后的判定标准,也可以作为一些算法的边界条件。在分布式系统中决定操作的顺序是很重要的,比如对于提供分布式存储服务的系统来说,Repeated Read 以及 Serializable 的隔离级别,需要确定事务的顺序,以及一些事件的因果关系等。

    物理时钟

    每个机器都有两个不同的时钟,一个是 time-of-day,即常用的关于当前的日期、时间的信息,例如,此时是 2018 年 6 月 23 日 23:08:00,在 Java 中可以用 System.currentTimeMillis() 获取;另一个是 Monotonic 时钟,代表着单调递增的时间,一般是测量时间间距,在 Java 中调用 System.nanoTime() 可以获得 Monotonic 时间,常常用于测量一个本地请求的返回时间,比如 Apache commons 中的 StopWatch 的实现。

    在分布式环境中,一般不会使用 Monotonic,测量两台不同的机器的 Monotonic 的时间差是无意义的。

    不同机器的 time-of-day 一般也不同,就算使用 NTP 同步所有机器时间,也会存在毫秒级的差,NTP 本身也允许存在前后 0.05% 的误差。如果需要同步所有机器的时间,还需要对所有机器时间值进行监控,如果一个机器的时间和其他的有很大差异,需要移除不一致的节点。因为能改变机器时间的因素比较多,比如无法判断是否有人登上某台机器改变了其本地时间。

    虽然全局时钟很难实现,并且有一定的限制,但基于全局时钟的假设还是有一些实践上的应用。比如 Facebook Cassandra 使用 NTP 同步时间来实现 LWW(Last Write Win)。Cassandra 假设有一个全局时钟,并基于这个时钟的值,用最新的写入覆盖旧值。当然时钟上的最新不代表顺序的最新,LWW 区分不了实际顺序;另外还有如 Google Spanner 使用 GPS 和原子时钟进行时间同步,但节点之间还是会存在时间误差。

    逻辑时钟

    在分布式系统中,因为全局时钟很难实现,并且像 NTP 同步过程,也会受到网络传输时间的影响,一般不会使用刚才所述的全局同步时间,当然也肯定不能使用各个机器的本地时间。对于需要确认操作执行顺序的时候,不能简单依赖一个基于 time-of-day 的 timestamps,所以需要一个逻辑时钟,来标记一些事件顺序、操作顺序的序列号。常见的方式是给所有操作加上递增的计数器。

    这种所有操作都添加一个全局唯一的序列号的方式,提供了一种全局顺序的保证,全局顺序也包含了因果顺序一致的概念。关于分布式一致性的概念和实现会在后续文章详细介绍,我们先将关注点回归到时间和顺序上。下面看两种典型的逻辑时钟实现。

    (1)Lamport Timestamps

    Lamport timestamps 是 Leslie Lamport 在 1978 年提出的一种逻辑时钟的实现方法。Lamport Timestamps 的算法实现,可以理解为基于每个节点的一对值(NodeId,Counter)的全局顺序的同步。在集群中的每个节点(Node)都有一个唯一标识,并且每个 Node 都持有一个本地的对于所有操作顺序的一个 Counter(计数器)。

    Lamport 实现的核心思想就是把事件分成三类(节点内处理的事件、发送事件、接收事件):

    • 如果一个节点处理一个事件,节点 counter +1。
    • 如果是发送一个消息事件,则在消息中带上 counter 值。
    • 如果是接收一个消息事件,则更新 counter = max(本地 counter,接收的消息中带的 counter) +1。

    简单画了个示例如下图:

    lamport timestamps example

    初始的 counter 都是 0,在 Node1 接收到请求,处理事件时 counter+1(C:1表示),并且再发送消息带上 C:1。

    在 Node1 接受 ClientA 请求时,本地的 Counter=1 > ClientA 请求的值,所以处理事件时 max(1,0)+1=2(C:2),然后再发送消息,带上 Counter 值,ClientA 更新请求的最大 Counter 值 =2,并在下一次对 Node2 的事件发送时会带上这个值。

    这种序列号的全局顺序的递增,需要每次 Client 请求持续跟踪 Node 返回的 Counter,并且再下一次请求时带上这个 Counter。lamport 维护了全局顺序,但是却不能更好的处理并发。在并发的情况下,因为网络延迟,可能导致先发生的事件被认为是后发生的事件。如图中红色的两个事件属于并发事件,虽然 ClientB 的事件先发出,但是因为延迟,所以在 Node 1 中会先处理 ClientA,也即在 Lamport 的算法中,认为 Node1(C:4) happens before Node1(C:5)。

    Lamport Timestamps 还有另一种并发冲突事件:不同的 NodeId,但 Counter 值相同,这种冲突会通过 Node 的编号的比较进行并发处理。比如 Node2(C:10)、Node1(C:10) 是两个并发事件,则认为 Node2 的时间顺序值 > Node1 的序列值,也就认为 Node1(C:10) happens before Node2(C:10)。

    所以可见,Lamport 时间戳是一种逻辑的时间戳,其可以表示全局的执行顺序,但是无法识别并发,以及因果顺序,并发情况无法很好地处理 偏序

    (2)Vector Clock

    Vector Clock 又叫向量时钟,跟 Lamport Timestamps 比较类似,也是使用 SequenceNo 实现逻辑时钟,但是最主要的区别是向量时钟有因果关系,可以区分两个并发操作,是否一个操作依赖于另外一个。

    Lamport Timestamps 通过不断把本地的 counter 更新成公共的 MaxCounter 来维持事件的全局顺序。Vector Clock 则各个节点维持自己本地的一个递增的 Counter,并且会多记录其他节点事件的 Counter。通过维护了一组 [NodeId,Counter] 值来记录事件的因果顺序,能更好得识别并发事件,也即,Vector Clock 的 [NodeId,Counter] 不仅记录了本地的,还记录了其他 Node 的 Counter 信息。

    Vector Clock 的 [NodeId,Counter] 更新规则:

    • 如果一个节点处理一个事件,节点本地的逻辑时钟的 counter +1。
    • 当节点发送一个消息,需要包含所有本地逻辑时钟的一组 [NodeId,Counter] 记录值。
    • 接受一个事件消息时, 更新本地逻辑时钟的这组 [NodeId,Counter] 值:
      • 让这组 [NodeId,Counter] 值中每个值都是 max(本地 counter,接收的消息中的counter)。
      • 本地逻辑时钟 counter+1。

    如下图简单示意了 Vector Clock 的时间顺序记录:

    Vector clock example

    三个 Node,初始 counter 都是 0。NodeB 在处理 NodeC 的请求时,记录了 NodeC 的 Counter=1,并且处理事件时,本地逻辑时钟的 counter=0+1,所以 NodeB 处理事件时更新了本地逻辑时钟为 [B:1,C:1]。在事件处理时,通过不断更新本地的这组 Counter,就可以根据一组 [NodeId,Counter] 值来确定请求的因果顺序了,比如对于 NodeB,第二个处理事件 [A:1,B:2,C:1] 早于第三个事件:[A:1,B:3,C:1]。

    在数值冲突的时候,如图中红色箭头标记的。NodeC 的 [A:2,B:2,C:3] 和 NodeB[A:3,B:4,C:1]。C:3 > C:1、B:2 < B:4,种情况认为是没有因果关系,属于同时发生。

    Vector Clock 可以通过各个节点的时间序列值的一组值,识别两个事件的先后顺序。Vector 提供了发现数据冲突的方式,但是具体怎样解决冲突需要由发现冲突的节点决定,比如可以将并发冲突抛给 Client 决定,或者用 Quorum-NRW 算法进行读取修复(Read Repair)。

    Amazon Dynamo 就是通过 Vector Clock 来做并发检测的一个很好的分布式存储系统的例子。对于复制节点的数据冲突使用了 Quorum NRW 决议,以及读修复(Read Repair)处理最新更新数据的丢失,详细实现可以参考这篇论文 Dynamo: Amazon’s Highly Available Key-value Store ,Dynamo 是典型的高可用、可扩展的,提供弱一致性(最终一致性)保证的分布式 K-V 数据存储服务。后续文章再介绍 Quorums 算法时,也会再次提到。Vector Clock 在实际应用中,还会有一些问题需要处理,比如如果一个上千节点的集群,那么随着时间的推移,每个 Node 将需要记录大量 [NodeId,Counter] 数据。Dynamo 的解决方案是通过添加一个 timestamp 记录每个 Node 更新 [NodeId,Counter] 值的时间,以及一个设定好的阈值,比如说阈值是 10,那么本地只保存最新的 10 个 [NodeId,Counter] 组合数据。

    小结

    本文引出了一些分布式系统的常见问题以及一些基础的分布式系统模型概念,微服务的架构目前已经被更广泛得应用,但微服务面临的问题其实也都是经典的分布式场景的问题。本文在分布式系统的问题中,主要介绍了关于错误检测以及时间和顺序的处理模型。

    关于时间和顺序的问题处理中,没有一个绝对最优的方案,Cassandra 使用了全局时钟以及 LWW 处理顺序判定;Dynamo 使用了 Vector clock 发现冲突,加上 Quorum 算法处理事件并发。这两个存储系统都有很多优秀的分布式系统设计和思想,在后续文章中会更详细的介绍数据复制、一致性、共识算法等。

    参考资料

    点击了解更多《案例上手分布式微服务架构》

    第02课:数据存储

    前言

    微服务架构下,很适合用 DDD(Domain-Drive Design)思维来设计各个微服务,使用领域驱动设计的理念,工程师们的关注点需要从 CRUD 思维中跳出来,更多关注通用语言的设计、实体以及值对象的设计。至于数据仓库,会有更多样化的选择。分布式系统中数据存储服务是基础,微服务的领域拆分、领域建模可以让数据存储方案的选择更具灵活性。

    不一定所有的微服务都需要有一个底层的关系型数据库作为实体对象实例的存储。以一个简单的电商系统为例:“用户微服务”和“商品微服务”都分别需要关系型数据库存储结构化的关联数据。但比如有一个“关联推荐微服务“需要进行用户购买、加购物车、订单、浏览等多维度的数据整合,这个服务不能将其他所有订单,用户、商品等服务的数据冗余进来,这种场景可以考虑使用图形数据库。又比如有一个“验证码微服务”,存储手机验证码、或者一些类似各种促销活动发的活动码、口令等,这种简单的数据结构,而且读多写少,不需长期持久化的场景,可以只使用一个 K-V(键值对)数据库服务。

    本文先简单介绍下适合微服务架构体系的一些分布式数据存储方案,然后深入介绍下这些存储服务的数据结构实现,知其然知其所以然。后续文章会继续介绍分布式数据存储的复制、分区。

    数据存储类型介绍

    不同的数据存储引擎有着不同的特征,也适合不同的微服务。在做最初的选型时,需要先根据对整体业务范围的判断,选择尽量普适于大多数微服务的存储。例如,初创型企业,需要综合考虑成本节约以及团队的知识掌握度等问题,MySQL 是比较常见的选择,电商类型的微服务应用更适合 InnoDB 引擎(事务、外键的支持、行锁的性能),虽然 InnoDB 的读性能会比 MyISAM 差,但是读场景有很多可以优化的方案,如搜索引擎、分布式缓存、本地缓存等。

    下面会以不同场景为例,整理一部分常用的数据存储引擎,实际的企业应用中会针对不同场景、服务特征综合使用多种存储引擎。

    关系型数据库

    存储结构化数据,以及需要更多维度关联,需要给用户提供丰富的实时查询场景时,应该使用关系型数据库。从开源以及可部署高可用性集群的方面来看,MySQLPostgreSQL 都是不错的选择。PostgreSQL 的历史更为悠久,两者都有很多大互联网公司如 Twitter、Facebook、Yahoo 等部署着大规模分布式存储集群,集群的复制、分区方案会在后续文章详细介绍。

    NoSQL

    NoSQL 即 Not Only SQL,其概念比关系型数据库更新,NoSQL 为数据的查询提供了更灵活、丰富的场景。下面简单列举了一些 NoSQL 数据库及其应用场景。工程师不一定需要掌握所有的 NoSQL 数据库的细节,对于不同的领域模型的设计,能有更多的灵感会更好。

    KeyValue 存储

    KeyValue 可以说是 NoSQL 中比较简单的一族,大多数操作只有 get()、put(),基础的数据格式也都是简单的 Key-Value。

    目前比较流行的键值存储服务有 RedisMemcached 以及上篇文中提到的 Dynamo。其中 Redis 有 Redis Cluster 提供了支持 Master 选举的高可用性集群。Dynamo 也有分布式高可用集群,基于 Gossip 协议的节点间故障检测,以及支持节点暂时、永久失效的故障恢复,这两者为了保证高可用以及性能,牺牲了强一致性的保证,但是都支持最终一致性。Memcached 提供了高性能的纯基于内存的 KV 存储,并且提供 CAS 操作来支持分布式一致性,但 Memcached 没有官方提供的内置集群方案,需要使用一些代理中间件,如 Magento 来部署集群。

    在实际选择时,如果需要高速缓存的性能并且可以接受缓存不被命中的情况,以及可以接受 Memcached 服务实例重启后数据全部丢失,可以选择 Memcached。用 Memcached 做二级缓存来抗住一些高 QPS 的请求是很适合的,比如对于一些 Hot 商品的信息,可以放到 Memcached 中,缓解 DB 压力。

    如果既需要有数据持久化的需求,也希望有好的缓存性能,并且会有一些全局排序、数据集合并等需求,可以考虑使用 Redis。Redis 除了支持 K-V 结构的数据,还支持 list、set、hash、zset 等数据结构,可以使用 Redis 的 SET key value 操作实现一些类似手机验证码的存储,对于需要按照 key 值排序的 kv 数据可以用 ZADD key score member。利用 Redis 的单线程以及持久化特性,还可以实现简单的分布式锁,具体可以参考笔者之前写的这篇 《基于 Redis 实现分布式锁实现》 文章。

    文档型数据库

    面向文档的数据库可以理解成 Value 是一个文档类型数据的 KV 存储,如果领域模型是个文件类型的数据、并且结构简单,可以使用文档型数据库,比较有代表性的有 MongoDBCouchDB。MongoDB 相比可用性,更关注一致性,Value 存储格式是内置的 BSON 结构,CouchDB 支持内置 JSON 存储,通过 MVCC 实现最终一致性,但保证高可用性。

    如果你需要的是一个高可用的多数据中心,或者需要 Master-Master,并且需要能承受数据节点下线的情况,可以考虑用 CouchDB。如果你需要一个高性能的,类似存储文档类型数据的 Cache 层,尤其写入更新比较多的场景,那就用 MongoDB 吧。另外,2018 年夏天可以期待下,MongoDB 官方宣布即将发布的 4.0 版本,支持跨副本集(Replica set)的 ACID 事务,4.2 版本将支持跨集群的事务,详情可以关注 MongoDB 的 Beta 计划

    图形数据库

    在现实世界中,一个图形的构成主要有“点”和“边”,在图形数据库中也是一样,只不过点和边有了抽象的概念,“点”代表着一个实体、节点,“边”代表着关系。开源的 Neo4j 是可以支持大规模分布式集群的图形数据库。一般被广泛用于道路交通应用、SNS 应用等,Neo4j 提供了独特的查询语言 CypherQueryLanguage

    为了直观了解 Neo4j 的数据结构,可以看下这个示例(在运行 Neo4j 后,官方的内置数据示例),图中绿色节点代表“Person”实体,中间的有向的剪头连线就是代表节点之间的关系“Knows”。

    eo4j example query

    通过以下 CQL 语句就可以查询所有 Knows、Mike 的节点以及关系:

    MATCH p=()-[r:KNOWS]->(g) where g.name ='Mike' RETURN p LIMIT 25 

    neo4j example res

    以上只是单个点和单维度关系的例子,在实际中 Person 实体间可能还存在 Follow、Like 等关系,如果想找到 Knows 并且 Like Mike,同时又被 Jim Follow 的 Person。在没有图形数据库的情况下,用关系型数据库虽然也可以查询各种关联数据,但这需要各种表 join、union,性能差而且需要写很多 SQL 代码,用 CQL 只要一行即可。

    在 SpringBoot 工程中,使用 Springboot-data 项目,可以很简单地和 Neo4j 进行集成,官方示例可以直接 checkout 查看 java-spring-data-neo4j

    文档数据库一般都是很少有数据间的关联的,图形数据库就是为了让你快速查询一切你想要的关联。如果想更进一步了解 Neo4j,可以直接下载 Neo4j 桌面客户端,一键启动、然后在浏览器输入 http://localhost:7474/browser/ 就可以用起来了。

    列族数据库

    列族数据库一般都拥有大规模的分布式集群,可以用来做灵活的数据分析、处理数据报表,尤其适合写多读少的场景。列族和关系型数据库的差别,从应用角度来看,主要是列族没有 Schema 的概念,不像关系型数据库,需要建表的时候定义好每个列的字段名、字段类型、字段大小等。

    列族数据库中目前比较广泛应用的有 Hbase,Hbase 是基于 Google BigTable 设计思想的开源版。BigTable 虽然没开源,但是其论文 Bigtable: A Distributed Storage System for Structured Data 提供了很多设布式列族 DB 的实现逻辑。另外 Facebook Cassandra 也是一个写性能很好的列族数据库,其参考了 Dynamo 的分布式设计以及 BigTable 的数据存储结构,支持最终一致性,适合跨地域的多数据中心的分布式存储。不过 Cassandra 中文社区相对薄弱,国内还是 Hbase 的集群更为广泛被部署。

    存储服务的数据结构

    在了解了一些分布式数据存储的产品之后,为了能更深地理解,下面会对分布式存储引擎的一些常用数据结构做进一步介绍。一台计算机,可以作为数据存储的地方就是内存、磁盘。分布式的数据存储就是将各个计算机(Node)的内存和磁盘结合起来,不同类型的存储服务使用的核心数据结构也会不同。

    哈希表

    哈希表是一种比较简单 K-V 存储结构,通过哈希函数将 Key 散列开,Key 哈希值相同的 Value 一般会以单链表结构存储。哈希表查找效率很高,常用于内存型存储服务如 Memcached、Redis。Redis 除了哈希表,因为其支持的操作的数据类型很多,所以还有像 Skiplist、SDS、链表等存储结构,并且 Redis 的哈希表结构可以通过自动再哈希进行扩容。

    哈希表一般存储在内存中,随着哈希表数据增多,会影响查询效率,并且内存结构也没法像磁盘那样可以持久化以及进行数据恢复。Redis 默认提供了 RDB 持久化方案,定时持久化数据到 RDB。用 RDB 来做数据恢复、备份是很合适的方案,但是因为其定期执行,所以无法保证恢复数据的一致性、完整性。Redis 还支持另一种持久化方案——基于 AOF(Append Only File) 方式,对每一次写操作进行持久化,AOF 默认不启用,可以通过修改 redis.conf 启用,AOF 增加了 IO 负荷,比较影响写性能,适合需要保证一致性的场景。

    SSTable

    在我们平常在 Linux 上分析日志文件的时候,比如用 grep、cat、tail 等命令,其实可以想象成在 Query 一个持久化在磁盘的 log 文件。我们可以用命令轻松查询以及分析磁盘文件,查询一个记录的时间复杂度是 O(n) 的话(因为要遍历文件),查询两个记录就是 2*O(n),并且如果文件很大,我们没法把文件 load 到内存进行解析,也没法进行范围查询。

    SSTable(Sorted String Table) 就解决了排序和范围查询的问题,SSTable 将文件分成一个一个 Segment(段),不同的 Segment File 可能有相同的值,但每个 Segement File 内部是按照顺序存储的。不过虽然只是将文件分段,并且按照内容顺序(Sorted String)存储可以解决排序,但是查询磁盘文件的效率是很低的。

    为了能快速查询文件数据,可以在内存中附加一个 KV 结构的索引:(key-offset)。key 值是索引的值并且也是有序的,Offset 指向 Segment File 的实际存储位置(地址偏移)。

    如下图简单画了一个有内存 KV 存储的 SSTable 数据结构:

    memtable sstable exm

    这个 k-v 结构的存储结构又叫 Memtable,因为 Memtable 的 key 也是有序的,所以为了实现内存快速检索,Memtable 本身可以使用红黑树、平衡二叉树、skip list 等数据结构来实现。Ps:B-Tree、B+Tree 的结构适合做大于内存的数据的索引存储(如 MySQL 使用 B+ 树实现索引文件的存储),所以其更适合磁盘文件系统,一般不会用来实现 Memtable。

    SSTable 也是有些局限性的,内存的空间是有限的,随着文件数越来越多,查询效率会逐渐降低。为了优化查询,可以将 Segment File 进行合并,减少磁盘 IO,并且一定程度持久化 Memtable(提高内存查询效率)——这就是 LSM-tree(Log-structured Merge-Tree)。LSM-tree 最初由 Google 发布的 Bigtable 的设计论文 提出,目前已经被广泛用于列族数据库如 HBase、Cassandra,并且 Google 的 LevelDB 也是用 LMS-tree 实现,LevelDB 的 Memtable 使用的是 skip list 数据结构。

    这种提供 SSTable 合并、压缩以及定期 flush Memtable 到磁盘的优化,使 LMS-tree 的写入吞吐量高,适合高写场景。下面以 Cassandra 为例介绍下 LMS-tree 的典型数据流。

    (1)Cassandra LMS-tree 写

    数据先写到 Commit Log 文件中(Commit Log 用 WAL 实现)WAL 保证了故障时,可以恢复内存中 Memtable 的数据。

    数据顺序写入 Memtable 中。

    随着 Memtable Size 达到一定阀值或者时间达到阀值时,会 flush 到 SSTable 中进行持久化,并且在 Memtable 数据持久化到 SSTable 之后,SSTables 都是不可再改变的

    后台进程会进行 SSTable 之间的压缩、合并,Cassendra 支持两种合并策略:对于多写的数据可以使用 SizeTiered 合并策略(小的、新的 SSTable 合并到大的、旧的 SSTable 中),对于多读的数据可以使用 Leveled 合并策略(因为分层压缩的 IO 比较多,写多的话会消耗 IO),详情可以参考 when-to-use-leveled-compaction

    (2)Cassandra LMS-tree 读

    先从 Memtable 中查询数据。

    Bloom Filter 中读取 SStable 中数据标记,Bloom Filter 可以简单理解为一个内存的 set 结构,存储着被“删除”的数据,因为刚才介绍到 SSTable 不能改变,所以一些删除之后的数据放到这个 set 中,读请求需要从这个标记着抛弃对象们的集合中读取“不存在”的对象,并在结果中过滤。对于 SSTables 中一些过期的,会在合并时被清除掉。

    从多个 SSTables 中读取数据。

    合并结果集、返回。另外,对于“更新”操作,是直接更新在 Memtable 中的,所以结果集会优先返回 Memtable 中的数据。

    BTree、B + Tree

    BTree 和 B + Tree 比较适合磁盘文件的检索,一般用于关系型数据库的索引数据的存储,如 Mysql-InnoDB、PostgreSQL。为了提高可用性,一般 DB 中都会有一个 append-only 的 WAL(一般也叫 redo-log)用来恢复数据,比如 MySQL InnoDB 中用 binlog 记录所有写操作,binlog 还可以用于数据同步、复制。

    使用 Btree、B+Tree 的索引需要每个数据都写两次,一次写入 redo-log、一次将数据写入 Tree 中对应的数据页(Page)里。LMS-tree 结构其实需要写入很多次,因为会有多次的数据合并(后台进程),因为都是顺序写入,所以写入的吞吐量更好,并且磁盘空间利用率更高。而 B 树会有一些空的 Page 没有数据写入、空间利用率较低。读取的效率来说,Btree 更高,同样的 key 在 Btree 中存储在一个固定的 Page 中,但是 LSM-tree 可能会有多个 Segment File 中存储着同个 Key 对应的值。

    小结

    本篇介绍了很多分布式存储服务,在实际的开发中,需要结合领域服务的特点选择。有的微服务可能只需要一个Neo4j,有的微服务只需要 Redis。微服务的架构应该可以让领域服务的存储更加灵活和丰富,在选择时可以更加契合领域模型以及服务边界。

    文章后半部分介绍了部分存储服务的数据结构。了解了实现的数据结构可以让我们更深刻理解存储引擎本身。从最简单的 append-only 的文件存储,再到哈希表、SSTable、BTree,基本涵盖了目前流行的存储服务的主流数据结构。如果想深入理解 LSM-tree,可以读一下 BigTable 的那篇经典论文。

    除了数据库服务,像 Lucene 提供了全文索引的搜索引擎服务,也使用了类似 SSTable 的结构。对于用 Docker 部署 Elasticsearch 集群的实践可以参考下之前写的 Elasticsearch 实践(一)用 Docker 搭建 Elasticsearch 集群Elasticsearch 实践(二)用 Docker 搭建 Elasticsearch 集群

    参考资料

    第03课:数据复制
    第04课:数据分区
    第05课:服务发现和服务通信
    第06课:分布式存储系统的事务
    第07课:分布式一致性
    第08课:分布式事务实践
    第09课:共识问题
    第10课:架构设计理念

    阅读全文: http://gitbook.cn/gitchat/column/5b444ae694c0f60b4ec4a68c

    展开全文
  • 前后端分离式分布式微服务架构项目 学成在线开发项目 源码 视频 文档 工具 合集百度云下载地址-附件资源
  • 1.3 分布式微服务架构 5 1.3.1 微服务概述 5 1.3.2 SOA与微服务 6 1.3.3 微服务架构的特点 6 1.3.4 微服务架构的缺点 7 1.3.5 微服务架构全景图 7 1.3.6 微服务类型 9 1.3.7 微服务拆分原则与步骤 9 第2章 ...

    开心一笑

    一次批小学语文卷,要求用"有……有……还有……"造句。一学生是这样写的:昨天去奶奶家,奶奶给我拿个鸡腿,我都吃完了问奶奶还有吗,奶奶答:“有,有,还有!”

    购买地址

    淘宝:https://s.taobao.com/search?q=%E5%88%86%E5%B8%83%E5%BC%8F%E5%BE%AE%E6%9C%8D%E5%8A%A1%EF%BC%9A%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E6%88%98&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20191031&ie=utf8

    书籍目录

    资料目录:
    第1章 从架构演进启程 1
    1.1 水平分层架构 1
    1.1.1 概述 1
    1.1.2 MVC架构/水平分层架构 2
    1.2 SOA服务化架构 4
    1.2.1 SOA概述 5
    1.2.2 SOA的特征 5
    1.2.3 SOA面临的问题 5
    1.3 分布式微服务架构 5
    1.3.1 微服务概述 5
    1.3.2 SOA与微服务 6
    1.3.3 微服务架构的特点 6
    1.3.4 微服务架构的缺点 7
    1.3.5 微服务架构全景图 7
    1.3.6 微服务类型 9
    1.3.7 微服务拆分原则与步骤 9
    第2章 微服务开发框架 11
    2.1 环境准备 11
    2.1.1 安装JDK 11
    2.1.2 安装 Intellij IDEA 14
    2.1.3 安装 Apache Maven 14
    2.2 一分钟快速搭建Spring Boot项目 15
    2.2.1 使用Spring Initializr新建项目 15
    2.2.2 测试 18
    2.3 Spring Boot简单介绍 18
    2.3.1 Spring Boot核心功能及特性 19
    2.3.2 Spring Boot的缺点 20
    2.4 Spring Boot目录介绍 20
    2.4.1 Spring Boot工程目录 20
    2.4.2 Spring Boot入口类 21
    2.4.3 Spring Boot测试类 22
    2.4.4 pom文件 23
    2.5 Spring Boot生产级特性 24
    2.5.1 应用监控 24
    2.5.2 健康检查 28
    2.5.3 跨域访问 29
    2.5.4 外部配置 30
    第3章 分布式RPC框架 31
    3.1 RPC框架概述 31
    3.1.1 定义 31
    3.1.2 RPC核心组件 31
    3.1.3 RPC调用过程 32
    3.1.4 RPC框架调用分类 33
    3.1.5 RPC框架性能 35
    3.1.6 RPC框架与分布式服务框架 35
    3.2 RPC框架 36
    3.2.1 RMI远程方法调用 36
    3.2.2 Thrift 37
    3.2.3 Hessian 38
    3.2.4 Avro-RPC 38
    3.2.5 gRPC 38
    3.2.6 其他RPC框架 39
    第4章 序列化与反序列化 40
    4.1 序列化与反序列化 40
    4.1.1 序列化/反序列化概念 40
    4.1.2 序列化/反序列化特性 41
    4.2 常用序列化框架 41
    4.2.1 Java默认序列化 41
    4.2.2 XML序列化框架 46
    4.2.3 JSON序列化框架 48
    4.2.4 ProtoBuf序列化框架 50
    第5章 微服务底层通信与协议 54
    5.1 Java网络通信 54
    5.1.1 传统BIO编程 54
    5.1.2 伪异步I/O编程 60
    5.1.3 NIO编程 62
    5.2 Netty框架 78
    5.2.1 Netty概述 78
    5.2.2 第一个Netty应用程序 78
    5.2.3 Netty架构设计 84
    5.3 分布式服务框架协议 89
    5.3.1 主流公有协议 89
    5.3.2 私有协议设计 90
    第6章 服务路由与负载均衡 94
    6.1 服务路由概述 94
    6.1.1 定义 94
    6.1.2 服务信息存放方式 94
    6.2 服务路由概述 95
    6.2.1 定义 95
    6.2.2 负载均衡的实现 95
    6.2.3 负载均衡算法 98
    第7章 微服务注册中心 103
    7.1 微服务注册中心 103
    7.1.1 注册中心几个概念 103
    7.1.2 注册中心 104
    7.2 ZooKeeper实现服务注册中心 104
    7.2.1 ZooKeeper概述 104
    7.2.2 ZooKeeper的原理 105
    7.2.3 ZooKeeper的安装 106
    7.2.4 ZooKeeper搭建集群环境 109
    7.2.5 ZooKeeper集群总体架构 110
    7.2.6 命令行客户端zkCli.sh 112
    7.2.7 ZkClient连接ZooKeeper 116
    7.2.8 ZooKeeper实现服务注册与发现 120
    第8章 微服务框架服务调用与容错 122
    8.1 服务调用概述 122
    8.2 服务调用方式 123
    8.2.1 同步服务调用 123
    8.2.2 异步服务调用 125
    8.2.3 并行服务调用 130
    8.2.4 泛化调用 132

    第9章 分布式微服务封装与部署 133
    9.1 微服务封装技术 133
    9.1.1 Docker概述 133
    9.1.2 Docker的基本概念 135
    9.1.3 Docker架构 135
    9.1.4 Docker的安装 137
    9.1.5 Docker的常用命令 138
    9.1.6 制作镜像 142
    9.1.7 使用Dockerfile构建镜像 144
    9.1.8 Spring Boot集成Docker 147
    9.2 微服务部署概述 150
    9.2.1 蓝绿部署 150
    9.2.2 滚动发布 152
    9.2.3 灰度发布/金丝雀部署 154
    第10章 分布式服务限流 155
    10.1 服务限流概述 155
    10.1.1 限流定义 155
    10.1.2 限流算法 155
    10.2 限流设计 157
    10.2.1 限流设计 157
    10.2.2 分级限流 158
    第11章 服务降级、熔断、调度 159
    11.1 服务降级概述 159
    11.2 服务降级方式 159
    11.2.1 服务降级开关 159
    11.2.2 自动降级 160
    11.2.3 读服务降级 161
    11.2.4 写服务降级 161
    11.3 服务容错策略 161
    11.3.1 失败转移(Failover) 162
    11.3.2 失败自动恢复(Failback) 162
    11.3.3 快速失败(Failfast) 162
    11.3.4 失败缓存(FailCache) 162
    11.4 Hystrix降级、熔断 162
    11.4.1 Hystrix简介 162
    11.4.2 Hystrix实现降级/熔断 164
    11.5 服务优先级设计 165
    11.5.1 服务实例数量调整 165
    11.5.2 加权优先级队列 166
    11.5.3 线程调度器 167
    第12章 服务版本与服务发布 168
    12.1 概述 168
    12.2 服务版本概述 168
    12.2.1 概述 168
    12.2.2 Snapshot和Release 169
    12.3 服务发布 169
    12.3.1 概述 169
    12.3.2 服务发布方式 170
    第13章 分布式微服务日志中心 173
    13.1 分布式日志概述 173
    13.1.1 结构化日志/非结构化日志 173
    13.1.2 日志类型 175
    13.2 日志框架 175
    13.2.1 JDK Logger 175
    13.2.2 Apache Commons Logging 177
    13.2.3 Log4j/Log4j 2 177
    13.2.4 Spring Boot集成Log4j 179
    13.2.5 Docker日志框架 181
    13.2.6 Linux系统Syslog 183
    13.3 搭建日志中心 183
    13.3.1 ELK概述 183
    13.3.2 Elasticsearch日志存储 184
    13.3.3 Logstash日志收集 189
    13.3.4 Fluentd日志收集 191
    13.3.5 Kibana日志查询 193
    13.3.6 ELK架构与Docker整合 194
    13.3.7 ELK架构原理 195
    第14章 分布式微服务监控 197
    14.1 分布式服务架构监控 197
    14.1.1 监控的价值 197
    14.1.2 监控的完整体系 197
    14.1.3 微服务监控类型 198
    14.1.4 Spring Boot应用监控 198
    14.1.5 Spring Boot Admin监控系统 201
    14.2 搭建系统监控中心 206
    14.2.1 概述 206
    14.2.2 时序数据收集系统:cAdvisor 206
    14.2.3 时序数据存储系统:InfluxDB 209
    14.2.4 时序数据分析系统:Grafana 212
    14.2.5 集成InfluxDB + cAdvisor + Grafana 214
    第15章 分布式微服务配置中心 218
    15.1 配置中心概述 218
    15.1.1 概述 218
    15.1.2 配置中心解决问题 218
    15.1.3 全局配置 219
    15.1.4 配置中心 221
    15.2 Spring Cloud Config 223
    15.2.1 概述 223
    15.2.2 Spring Cloud Config快速入门 224
    第16章 分布式微服务存储与解耦 232
    16.1 分布式数据库架构 232
    16.1.1 分库 232
    16.1.2 分表 233
    16.1.3 水平切分的方式 233
    16.1.4 垂直切分的方式 235
    16.1.5 分组 235
    16.1.6 Mycat分库分表实战 236
    16.1.7 Spring+MyBatis+Mycat快速体验 240
    16.2 分布式事务 249
    16.2.1 数据库事务 249
    16.2.2 分布式事务 249
    16.2.3 CAP定理 250
    16.2.4 BASE理论 251
    16.2.5 两阶段提交(2PC) 252
    16.2.6 补偿事务(TCC) 252
    16.2.7 后置提交 254
    16.2.8 本地消息表(异步确保) 255
    16.3 分布式缓存架构 256
    16.3.1 Memcache与Redis 256
    16.3.2 进程内缓存 257
    16.3.3 Redis单节点安装 259
    16.3.4 Redis持久化策略 260
    16.3.5 Redis主从复制模式 263
    16.3.6 Redis哨兵模式 266
    16.3.7 Redis哨兵模式安装部署 271
    16.3.8 Redis集群模式 277
    16.3.9 Redis集群环境搭建 280
    16.3.10 Redis缓存穿透和雪崩 288
    16.4 微服务解耦 294
    16.4.1 服务解耦概述 294
    16.4.2 Kafka介绍 295
    16.4.3 Kafka安装 299
    16.4.4 Kafka搭建集群环境 300
    16.4.5 Kafka Manager的安装 301
    16.4.6 Kafka常用命令 301
    16.4.7 Spring Boot集成Kafka 311
    16.5 分布式服务Session 315
    16.5.1 Session与Cookie 315
    16.5.2 Session一致性问题 315
    16.5.3 Session同步 316
    第17章 分布式微服务测试 318
    17.1 分布式微服务测试 318
    17.1.1 概述 318
    17.1.2 微服务测试 319
    17.2 Spring Boot单元测试 321
    17.3 Mockito/PowerMockito测试框架 323
    17.3.1 Mockito概述 323
    17.3.2 Mockito简单实例 324
    17.3.3 PowerMock概述 327
    17.3.4 PowerMockito简单实例 327
    17.4 H2内存型数据库 330
    17.4.1 H2概述 330
    17.4.2 Spring Boot集成H2 330
    17.5 REST API测试 333
    17.5.1 Postman概述 333
    17.5.2 Postman简单使用 333
    17.6 性能测试 336
    17.6.1 ab概述 336
    17.6.2 ab测试 336
    17.6.3 其他性能测试工具 338
    第18章 分布式微服务架构经典案例 341
    18.1 微服务架构案例 341
    18.1.1 概述 341
    18.1.2 微服务架构平台选择 342
    18.1.3 微服务接口类型 342
    18.1.4 微服务类型 343
    18.2 分布式服务框架Dubbo 344
    18.2.1 Dubbo概述 344
    18.2.2 Dubbo原理 344
    18.3 Spring Boot + Spring Cloud解决方案 345
    18.3.1 Spring Boot概述 345
    18.3.2 Spring Cloud概述 345
    18.3.3 微服务、Spring Boot、Spring Cloud的关系 347
    18.3.4 Spring Cloud与Dubbo的优劣 348
    18.4 Spring Boot + Kubernetes + Docker解决方案 348
    18.4.1 Docker概述 348
    18.4.2 Kubernetes概述 349
    18.4.3 Kubernetes的基本概念 349
    18.4.4 Kubernetes的使用 352
    18.4.5 Kubernetes的架构 356
    18.4.6 Kubernetes集群监控 360
    18.4.7 Kubernetes集群日志管理 360
    18.4.8 Kubernetes解决方案 360
    参考文献 362

    读书感悟

    来着 纳西姆·尼古拉斯·塔勒布《反脆弱》

    • 唤醒天才的是困难。
    • 反脆弱的策略就是记住:意外总会发生。
    • 让人上瘾的东西里,害处最大的三种是海洛因、碳水化合物和月薪。
    • 人们了解的很多东西其实都不值得去了解。
    • 如果有人跟你说“我很忙”,那他要么是在宣称自己的无能(以及对自己的生活的缺乏控制),要么是在试图摆脱你。
    • 不管在哪个领域,业余爱好者往往都是最优秀的。
    • 这个世界上真正的贵人从来不是别人,而是我们自己。人只要记住一个原则,不管是做什么事,不管是在什么环境中,尽可能做到利人利己,你会发现事情一定会越来越好,你的贵人也会越来越多。
    • 与一个无知的人保持距离相当于与一个聪明人为伍。

    经典故事

    赵国有一户人家被老鼠害苦了,就到中山国去借猫,中山人给了他一只。
    这只猫很会捉老鼠,但是也喜欢捉鸡吃。
    一个月之后,他家的老鼠被捉干净了,而鸡也被吃光了。
    他的儿子认为这只猫是个祸害,对父亲说:“为什么不把它除掉呢?”
    父亲说:“我们的祸患在于家里有老鼠,不在于没有鸡。老鼠偷吃粮食,咬烂衣物,钻穿墙壁,啃坏家具,这样下去我们就要挨饿受冻,这比没有鸡更糟!没有鸡,我们只不过不吃鸡肉罢了,离挨饿受冻还远呢!为什么要把猫除掉呢?”
    点评:【古人云:“两害相权取其轻,两利相权取其重。”意思是两种利益同时放面前,当然是选择利益较大的那种;两种损害放面前,当然是选择伤害较轻的那种。简单地说,就是权衡利弊,首选利重害轻。】

    大神文章

    其它

    如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎鼓励,点赞、顶、欢迎留下宝贵的意见、多谢支持!

    展开全文
  • 昨天已经搭建好了SpringBoot基于Maven的基础父子级项目,今天开始进入项目分模块及分布式实现。首先我们基于昨天的项目,在父级工程下建lyn-sys,lyn-customer,lyn-goods,lyn-order四个西模块。 这四个模块将...

    昨天已经搭建好了SpringBoot基于Maven的基础父子级项目,今天开始进入项目分模块及分布式实现。首先我们基于昨天的项目,在父级工程下建lyn-sys,lyn-customer,lyn-goods,lyn-order四个西模块。

    这四个模块将作为Dubbo服务的提供者,里面主要写对应模块的Service接口及实现及Mapper等。把这四个模块作为提供者,那可能大家得问了,消费者是谁呢?这里的消费者就是昨天写的接口服务lyn-web。

    现在,我们以商品服务模块lyn-goods为例创建并实现提供者。

    右击“lyn-goods”,选择“New”>>>"Module",进入下面的页面

    点击“Next”

    先建一个api依赖的模块goods-api,然后点击“Next”

    点击“Finish”。再以相同的方式创建goods-service模块。创建完成如下:

    以上面相同的方式为lyn-sys,lyn-customer,lyn-order三个模块创建服务接口***-api和服务实现***-service。

    二,分环境部署及端口号统一配置

    新建一个lyn-commom模块作为放公共资源,并在resoures下添加application.properties。如下图:

    spring.profiles.active 是配置的SpringBoot的分环境部署;

    lyn.***.port 这几个配置是几个要启动的服务的端口号;

    统一配置需要在对应模块的resources下创建application-dev.properties和application-pro.properties,并在这两个配置里添加service.port=${lyn.***.port},然后让此模块依赖lyn-common即可。当服务启动时,首先会找到lyn-common下的application.properties文件,并读取里面的属性,再根据读到的spring.profiles.active值去匹配加载对应本模块下的application-***.properties。并将读到的lyn.***.port值赋值给本模块service.port属性。具体模块下的配置以lyn-customer为例。

    三,Dubbo提供者及消费者配置

    1,提供者配置及实现

    先在四个提供者模块里的***-service下的pom里配置Dubbo依赖,并依赖自己模块里的***-api。如图下(其他几个模块依赖相似)

    添加提供者配置信息。需要注意点:dubbo.applicaiton.name可以以模块命名,dubbo.protocol.port从20880递增,每个提供者的这个值不可重复。

    然后在这四个提供者的业务接口***-api里写service接口服务。并且每个模块下的***Service里都写一个相同的方法:test(String name)。

    然后在对应的每个模块的***-service里写service接口的实现。

    再写四个提供者的启动类(其他模块的一样,都在***-service下),注意一定要有@EnableDubbo注解,用来开启Dubbo服务。

    2,消费者配置及实现

    在消费服务lyn-web下的pom里添加Dubbo依赖及提供者的Service接口依赖。

    添加消费者配置

    编写消费者启动类:

    编写测试Controller接口

    四,测试

     启动四个提供者和消费者服务,然后根据Controller下的接口进行测试

    打开浏览器访问接口(四个接口各自对应不同的提供者为其提供服务)

    总结:本期主要讲解了基于SpringBoot实现分布式微服务下的统一配置、分环境部署配置。以及服务端模块的分离(每一个提供者就是一个独立的微服务)、微服务落地、Dubbo提供者及消费者的配置实现。

    扫码关注公共号获取更对文章咨询,也可获取Java相关开发资料。等你你们的关注留言!

     

    展开全文
  • JavaWeb_Cloud微服务平台是一款基于SpringCloud框架研发的分布式微服务框架,主要使用技术栈包括: SpringCloud、Vue、ElementUI、MybatisPlus,是一款精心打造的权限(RBAC)及内容管理系统,致力于做更简洁的后台...

    项目介绍

    JavaWeb_Cloud微服务平台是一款基于SpringCloud框架研发的分布式微服务框架,主要使用技术栈包括: SpringCloud、Vue、ElementUI、MybatisPlus,是一款精心打造的权限(RBAC)及内容管理系统,致力于做更简洁的后台管理框架,包含系统管理、代码生成、权限管理、站点、广告、布局、字段、配置等一系列常用的模块,整套系统一键生成所有模块(包括前端UI),一键实现CRUD,简化了传统手动抒写重复性代码的工作。 同时,框架提供长大量常规组件,如上传单图、上传多图、上传文件、下拉选择、复选框按钮、单选按钮,城市选择、富文本编辑器、权限颗粒度控制等高频使用的组件,代码简介,使用方便,节省了大量重复性的劳动,降低了开发成本,提高了整体开发效率,整体开发效率提交80%以上,专注于为中小企业提供最佳的行业基础后台框架解决方案,执行效率、扩展性、稳定性值得信赖,操作体验流畅,使用非常优化,欢迎大家使用及进行二次开发。

    开发者信息

    系统名称:JavaWeb_Cloud权限(RBAC)及内容管理框架
    作者:鲲鹏
    作者QQ:1175401194
    官网网址:http://www.javaweb.vip/
    文档网址:http://docs.cloud.javaweb.vip

    后台演示

    演示地址:http://manage.cloud.javaweb.vip
    登录用户名:admin
    登录密码:123456

    技术支持

    效果图展示

    • 系统登录

    在这里插入图片描述

    • 后台首页
      在这里插入图片描述

    • 用户管理
      在这里插入图片描述

    • 角色管理
      在这里插入图片描述

    • 职级管理
      在这里插入图片描述

    • 岗位管理
      在这里插入图片描述

    • 部门管理
      在这里插入图片描述

    • 菜单管理
      在这里插入图片描述

    • 代码生成器
      在这里插入图片描述

    • 项目结构
      在这里插入图片描述

    展开全文
  • Structs(UI交互层)、Spring(业务逻辑实现)、Hibernate(对象领域的模型与关系型数据库模式映射)StructsMVC模型:Spring:逻辑层实现核心容器,核心思想IOC和AOPa、IOC(控制反转):EJB实现:实现服务化组件...
  • Java分布式微服务技术专题讲解是一个微服务开发管理工具集,是目前比较热门的Web开发技术。它提供了整套的微服务开发技术解决方案,如在微服务开发时所需的配置管理、服务注册于发现、断路器、智能路由、控制总线、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 62,591
精华内容 25,036
关键字:

分布式微服务