微服务篇:

  • springcloud 常见组件有哪些
  • nacos 的服务注册表结构是怎样的
  • nacos 如何支撑阿里内部数十万服务注册压力
  • nacos 如何避免并发读写冲突问题
  • nacos 和eureka 的区别
  • sentinel 的线程隔离与hystix 的线程隔离有什么差别
  • sentinel 限流与gateway 限流有什么差别

微服务引言

项目组之间相互依赖,代码冲突,上线测试等问题,我们需要对业务进行拆分。

最开始时,业务实践是利用ngix拆分系统,每拆除一个系统,分配一个二级域名,这就是最开始的微服务拆分实践。这样做,后台会慢慢增加很多机器。

后来慢慢dubblo+zookeeper 分布式架构,再后来springCloud Alibaba 微服务架构技术栈。

他们帮我们引入了一个注册中心,从服务端拿到机器信息,在客户端实现负载均衡。

微服务拆分

  • 会员服务,
  • 商品服务,
  • 库存服务,
  • 交易服务,
  • 积分服务,
  • 仓储服务,
  • 日志服务...

一、服务注册中心-Nacos

首先,假设现在有两个系统,咱们就假设是系统A和系统B吧,这俩系统现在的需求就是要让系统A可以发送一个请求给系统B来实现系统间的接口调用。现在有一个最大的问题,系统A是部署在一台服务器上的,系统B又是部署在另外一台服务器上的,那系统A怎么可能莫名其妙的就知道系统B部署在哪台机器上呢?其实对于您的系统A来说,这时就必须引入一个SpringCloudAlibaba的关键技术组件,叫做Nacos。大家请擦亮眼睛,这个Nacos是一个关键名词,一定要记住了,他的学术定位叫做【服务注册中心】。

Nacos是知道你的系统B部署在哪台机器上的,因为系统B在启动的时候会主动向Nacos服务注册中心进行服务注册,告诉Nacos说自己部署在哪台机器上,自己的机器ip地址是172.86.76.251,自己的端口号是20880。这个时候,系统A如果想要调用系统B的接口,就可以发送请求给Nacos服务注册中心说,兄弟,能告诉我系统B部署在哪台机器上吗?我想调用一下他的接口,这个动作有专业术语,叫做【服务发现】。

我们再来看下一个问题,假设系统B是个大美女,然后还有多个孪生姐妹花,也就是说系统B部署在了多台服务器上,我们管这种情况叫做系统B有多个服务实例部署在了多台服务器上,然后这个时候系统A想要调用系统B,应该怎么办呢?其实也很简单,系统B的每个服务实例部署了一台机器后,他们都得对Nacos服务注册中心发起服务注册的请求,所以Nacos是知道系统B部署的每台机器的ip地址和端口号的。然后这个系统A找Nacos进行服务发现的时候,一下子就会发现系统B部署在了两台机器上,也就是说两台机器的ip地址和端口号他都会发现。

这个时候问题就来了,系统A很犹豫啊,到底调用系统B的哪个机器呢?很简单,他可以第一次调用机器1,第二次调用机器2,第三次调用机器1,第四次机器2,以此类推,循环往复,这个过程叫做负载均衡,系统A可以通过负载均衡把自己的所有请求均匀的分发给系统B的每台机器。

二、RPC-Dubbo

那么下一个问题又来了,系统A如果要想办法去调用系统B的某个接口的话,就必须要跟系统B建立一个网络连接,然后通过这个网络连接发送请求过去给系统B,接着系统B收到了请求,以后就会调用自己本地的某个接口的代码,然后再把响应结果通过网络连接返回给系统A,这个过程就叫做RPC远程调用。其实这个RPC调用的过程,说白了就类似于跟人聊微信的过程,微信聊天你总得先加个好友,完了再发个消息过去,接着人家再给你回一个消息吧?没错,咱们这 RPC 调用也是同理,你两台机器总得先建立个网络连接,然后系统A发个请求过去,系统B本地代码执行一下,再返回个响应给你。

那现在问题来了,这个系统A那里要对系统B部署的多台机器实现负载均衡,然后建立网络连接,接着发起RPC调用,就是系统A发个请求过去,系统B执行一下代码返回个响应,就这套看起来很复杂的流程是谁负责搞定的呢?简单,就是SpringCloudAlibaba里的另外一个关键组件Dubbo。这个Dubbo就是一个RPC的框架,他就是专门负责帮你做负载均衡、网络连接、RPC调用这些事情的的,这是SpringCloudAlibaba组件体系中的第二个关键组件。

三、流量防护-Sentinel

3.1 一台4核8G的服务器-QPS

接着再来讨论下一个问题,很多人可能知道,也可能不知道,那就是:一台4核8G的服务器,每秒钟可以抗多少并发请求?

有一些同学平时玩儿过高并发系统,应该是知道这个数值的,那就是4核8G的服务器上部署的如果是一个Java系统,这个Java系统连接的是MySQL数据库的话,那么通常来说,这一台服务器每秒大致可以抗1000以内的QPS。这是为什么呢?原因很简单,我们要从两个维度来分析

  • 第一个维度是,我们的系统A有多少个线程来处理请求,每个请求要耗费多少ms来完成,每个线程每秒可以执行多少个请求。

  • 第二个维度是,我们系统A的n多线程拼命处理请求,这个时候会对机器的CPU负载造成多大压力,大概所有线程每秒处理多少请求的时候,机器的CPU就扛不住了。

把这两个问题解决清楚了,也就知道系统每秒可以抗多少请求了。首先看第一个维度,系统A一般来说对外接受用户的请求,都是通过Tomcat这种web服务器,对外用spring mvc提供controller这种接口的,接收的都是http请求,所以实际上tomcat一般来说,我们都会配置200左右的线程,就是说系统A有200个线程会并发的处理用户发来的请求。

3.2 Tomcat线程处理一个请求耗时

那么下一个问题来了:tomcat线程处理一个请求要耗费多长时间?

这个就不好说了,因为一个线程处理一个请求的时候,往往会执行你自己写的一大堆业务代码,从controller到service再到dao,如果你用mybatis做数据持久层框架,那么应该会用mybatis mapper执行一大堆的SQL语句。这往往取决于你的系统代码有多复杂,执行的SQL语句有多复杂,要执行多少个SQL,数据库里的表数据是万级、十万级、还是百万级,甚至是千万级、亿级。

所以影响因素太多,我们这里取一个不多不少的均值,假设你一个请求需要调用n多次数据库,执行n个SQL语句,而且数据库里的数据量还小,基本在十万到百万级,那么此时大概你一个请求处理要耗费200ms

所以一个简单的小学公式就可以计算出来了,你一个线程处理一个请求要耗费200ms,那么每秒就可以处理5个请求,你有200个线程,每秒可以处理200*5=1000个请求。所以说,按这个维度来说,系统A部署在4核8G的系统上,连接了mySQL数据库,然后开200个tomcat线程处理请求,每秒处理1000个请求是比较合理的。

第二个维度呢?就是CPU负载这个角度来看,其实也是差不多的,这个没法用算数来计算,只能告诉大家一个经验值,那就是当你的系统部署在4核8G机器上,连接mySQL数据库,然后每个请求都要执行一堆SQL语句的时候,往往你的系统每秒处理到1000左右的请求量,你的机器CPU负载就会达到80%甚至90%的使用率,这个时候系统负载已经很高了,再让机器处理更多请求,他已经完全就做不到了。

那么针对这个系统A每秒可以处理1000个请求的经验值,我们来考虑一个问题,万一要是你公司搞个活动,突然之间每秒有2000个请求过来,或者是被黑客来了个攻击,每秒的请求数量特别多,这个时候你怎么办?显而易见你的系统A会被打死。

3.3 Sentinel

所以这个时候怎么办呢?我们就得引入SpringCloudAlibaba里的第三个组件了,就是Sentinel,这个Sentinel就是帮助你的系统实现流量防护的。当你在系统A里加入Sentinel以后,如果要是每秒请求超过了1000,Sentinel会直接帮你把多出来的那些请求都直接拒绝掉,这就叫做限流,限制你的系统可以处理的请求数量,这样就可以保护你的系统不会被打死。

四、分布式事务-Seata

那现在我们已经搞明白SpringCloudAlibaba里的三个组件的运行原理和使用场景了,Nacos是服务注册中心,Dubbo是RPC调用框架,Sentinel是流量防护组件,接着来看最后一个组件,那就是Seata,分布式事务组件。

既然提到了分布式事务,那就肯定是跟事务是有关系的了,这个事务相信大家都知道,就是我们对MySQL可以开启一个事务,事务里执行n条SQL,但凡有一个SQL失败了,事务就会回滚,这 n 个SQL都不会生效的。

可是在系统A调用系统B这种分布式的场景下,事务会怎么样呢?大家看下图,假设系统A处理一个请求的时候,先对自己的数据库执行了一堆SQL,提交了事务A,然后通过Dubbo发起RPC调用系统B,系统B对自己的数据库执行了一堆SQL,提交了事务B。

那么现在问题来了,假设我系统A的事务A都提交了,结果到系统B的时候,事务B执行失败,事务B回滚了,这可怎么整!也就是说一个请求的处理不一致了,一个系统的事务成功都提交完了,没法回滚了,另外一个系统的事务失败了。

别着急,只要你引入Seata分布式事务框架,就可以轻松搞定这个问题,Seata这个框架会自动记录你的事务A执行的SQL语句的逆向补偿SQL。什么意思呢?假设你事务A执行的是insert,那么Seata就知道补偿的时候可以delete删除,假设你执行的是update,那么Seata就可以记录你update之前的老数据,补偿的时候可以把数据重新update回老版本数据,而且这个逆向补偿日志也是记录在数据库里的。

接着Seata还会提供一个Seata server来监控你的各个系统的事务执行情况,系统A的事务A执行成功了得告诉Seata server,系统B的事务B执行失败了也得告诉Seata server。

当Seata server知道你的系统B的事务B执行失败了,他会告诉系统A里的Seata框架,小兄弟,人家系统B都失败了,你赶紧的吧,别墨迹,把你之前记录的事务A逆向补偿日志拿出来,把你之前提交的事务恢复到提交前的数据状态,搞一个逆向回滚。

springcloud 常见组件有哪些

远程调用-openFeign,dubbo

注册中心-eureka, nacos

负载均衡-ribbon

配置管理-springcloudconfig,nacos

微服务网关-zuul,gateway

服务保护组件-sentinel,hystrix

nacos 的服务注册表结构是怎样的

  • nacos 分级存储模型
  • nacos 服务端源码

nacos 采用了数据的存储模型,最外层是namespace, 用来隔离环境。然后是group, 用来对服务分组。接下来就是服务 service ,一个服务包含多个实例,但是可能处于不同机房,因此service 下有多个集群 cluster。集群下是不同的实例Instance

对应到java 代码中,nacos 采用了一个多层的map 来表示,结构为Map<String, Map<String,Service>>, 其中最外层map 的key 就是namespaceId, 值是一个map, 内层map 的key 是group 拼接serviceName, 值是service 对象。

service 对象内部又是一个map, key是集群名称,值是cluster 对象。而cluster 对象内部维护了Instance 集合。

nacos 如何支撑高并发的服务注册压力

  • 集群
  • 底层实现

nacos 内部接收到注册的请求时,不会立即写数据,而是将服务注册的任务放入一个阻塞队列就立即响应给客户端,然后利用线程池读取阻塞队列中的任务,异步来完成实例更新,从而提高并发写能力。

nacos 如何避免并发读写冲突问题

nacos 在更新实例列表时,会采用copyOnWrite 技术,首先将旧的实例列表拷贝一份,然后更新拷贝的实例列表,再用更新后的实例列表来覆盖旧的实例列表。

这样在更新的过程中,就不会对读实例列表的请求产生影响,也不会出现脏读问题了。

如果是并发写写冲突问题,代码有对service 加锁,保证串行。

nacos 和eureka 的区别

服务健康检测。

  • 接口方式:nacos 和 eureka 都对外暴露了rest 风格的api 接口,用来实现服务注册、发现等功能
  • 实例类型:nacos 的实例有永久和临时实例的区别,而eureka 只支持临时实例
  • 健康检测:nacos 对临时实例采用心跳模式检测,对永久实例采用主动请求来检测;eureka 只支持心跳模式
  • 服务发现:nacos 支持定时拉取和订阅推送两种模式;eureka 只支持定时拉取模式。

sentinel 的线程隔离与hystix 的线程隔离有什么差别

线程隔离胡两种方式实现:

  • 线程池隔离 (Hystix 默认):支持主动超时,支持异步调用
  • 信号量隔离(Sentinel 默认),更轻量,因为不用创建线程池,只用维护计数器就行了

Hystix 默认是基于纯种池实现的线程隔离,每一人被隔离的业务都要创建一个独立的线程池,线程过多会带来额外的CPU 开销,性能一般,但是隔离性强

Sentinel 是基于信号量(计数器)实现的线程隔离,不用创建线程池,性能较好,但是隔离性一般

sentinel 限流与gateway 限流有什么差别

限流:对应用服务器的请求做限制,避免因过多请求而导致嗠器过载甚至宕机。

限流算法常见的包括:

  • 1 计数器算法,又包括窗口计数器算法、滑动窗口计数器算法

  • 2 令牌桶算法(Token Bucket):以固定的速率生成令牌,存入令牌桶中,如果令牌桶满了以后,多余令牌丢弃。请求进入后,必须先尝试从桶中获取令牌,获取令牌后才可以被处理。如果令牌中没有令牌,则请求等待或丢弃。

  • 3 漏桶算法(Leaky Bucket):将每个请求视作‘水滴’放入‘漏桶’进行存储。漏桶以固定速率向外漏出请求来执行,如果漏桶空了则停止漏水。如果漏桶满了则多余的水滴会被直接丢弃。

sentinel 在实现漏桶时,采用了排队等待模式:让所有请求进入一个队列中,然后按照阈值允许的时间间隔依次执行。并发的多个请求必须等待,预期的等待时长=最近一次请求的预期等待时间+允许的间隔。如果请求预期的等待时间超出最大时长,则会被拒绝。

例如:QPS=5,意味着每200ms 处理一个队列中的请求;timeout = 2000,意味着预期等待超过2000ms 的请求会被拒绝并抛出异常。

对比项 滑动时间窗口 令牌桶 漏桶
能否保证流量曲线平滑 不能,但是窗口内区间越小,流量控制越平滑 基本能,在请求量持续高于令牌生成速度时,流量平滑。但请求是天令牌生成速率上下波动时,无法保证曲线平滑 能。所有请求进入桶内,以恒定速率放行,绝对平滑
能否应对突增流量 不能,徒增流量,只要高出限流阈值都会被拒绝 能。桶内积累的令牌可以应对突增流量 能。请求可以暂存在桶内
流量控制精确度 低。窗口区间越小,精度越高

所以,限流算法常见有三种实现:滑动时间窗口,令牌桶算法,漏桶算法。Gateway 则采用基于redis 实现的令牌桶算法。而sentinel 内部却比较复杂。

  • 默认限流模式是基于滑动时间窗口算法
  • 排除等待的限流模式则基于漏桶算法
  • 热点参数限流则基于令牌桶算法。

springCloud allibaba 微服务引言的更多相关文章

  1. 用SpringCloud进行微服务架构演进

    在<架构师必须要知道的阿里的中台战略与微服务> 中已经阐明选择SpringCloud进行微服务架构实现中台战略,因此下面介绍SpringCloud的一些内容,SpringCloud已经出来 ...

  2. 基于Spring-Cloud的微服务框架设计

    基于Spring-Cloud的微服务框架设计 先进行大的整体的框架整理,然后在针对每一项进行具体的详细介绍

  3. SpringCloud学习--微服务架构

    目录 微服务架构快速指南 SOA Dubbo Spring Cloud Dubbo与SpringCloud对比 微服务(Microservice)架构快速指南 什么是软件架构? 软件架构是一个包含各种 ...

  4. springCloud搭建微服务集群+Zuul服务器端负载均衡

    概述 最近研究了一下springCloud的微服务集群,主要用到了SpringCloud的服务发现和服务器端负载均衡,所有的项目都是用的springboot,可以和springCloud无缝对接. 技 ...

  5. SpringCloud与微服务系列专栏

    一. 前置知识 学习SpringCloud之前需要具备和掌握如下框架和工具的使用:SpringMVC,Spring,Spring Boot,Mybatis,Maven,Git. SpringCloud ...

  6. springCloud进阶(微服务架构&Eureka)

    springCloud进阶(微服务架构&Eureka) 1. 微服务集群 1.1 为什么要集群 为了提供并发量,有时同一个服务提供者可以部署多个(商品服务).这个客户端在调用时要根据一定的负责 ...

  7. 一个C#开发者学习SpringCloud搭建微服务的心路历程

    前言 Spring Cloud很火,很多文章都有介绍如何使用,但对于我这种初学者,我需要从创建项目开始学起,所以这些文章对于我的启蒙,帮助不大,所以只好自己写一篇文章,用于备忘. SpringClou ...

  8. SpringCloud的微服务网关:zuul(理论)

    参考链接:https://springcloud.cc/spring-cloud-dalston.html 一.概念与定义 1.为什么要引入API网关 后期维护:路由规则和服务实例列表困难 系统架构: ...

  9. springcloud 新增微服务

    个人记录 记录公司微服务项目,模块添加的步骤 一  创建Module 选择maven groupid和artifactid 参考 pom文件 <project xmlns="http: ...

  10. 深入理解SpringCloud与微服务构建

    旭日Follow_24 的CSDN 博客 ,全文地址请点击: https://blog.csdn.net/xuri24/article/details/81742534 目录 一.SpringClou ...

随机推荐

  1. Docker使用Dockerfile部署项目

    什么是dockerfile? Dockerfile是一个包含用于组合映像的命令的文本文档.可以使用在命令行中调用任何命令. Docker通过读取Dockerfile中的指令自动生成镜像. 如何通过do ...

  2. Nginx常用操作

    Nginx Nginx的最重要的几个使用场景 静态资源服务,通过本地文件提供服务 反向代理服务,延伸出包括缓存,负载均衡等 API服务,OpenResty 相关概念 简单请求和非简单请求 请求方法是H ...

  3. node.js 手稿

  4. Linux 鉴定故障

    导读 进入linux,输入root账户,密码输入是正确的,提示"鉴定故障",刚开始以为是系统挂了,后来百度说,需要重置root密码,具体步骤如下. 重置root密码 重启Linux ...

  5. 咬文嚼图式的介绍二叉树、B树/B-树

    前言 因为本人天资愚钝,所以总喜欢将抽象化的事务具象化表达.对于各类眼花缭乱的树,只需要认知到它们只是一种数据结构,类似数组,切片,列表,映射等这些耳熟能详的词汇.对于一个数据结构而言,无非就是增删改 ...

  6. TP5系列 | Queue消息队列

    消费信息如下ThinkPHP5 Queue消息队列 优点 1.Queue内置了 Redis,Database,Topthink ,Sync这四种驱动,本文使用Redis驱动 2.Queue消息队列适用 ...

  7. [oeasy]python0129_unicode_中文字符序号_十三道大辙_字符编码解码_eval_火星文

    unicode 中文字符分类 回忆上次内容 字符集 从博多码 到 ascii 再到 iso-8859 系列 各自割据   如何把世界上各种字符统进行编码 unicode顺势而生不断进化 不过字符总量超 ...

  8. [oeasy]python0088_字节_Byte_存储单位_KB_MB_GB_TB

    编码进化 回忆上次内容 上次 回顾了 字符大战的结果 ibm 曾经的 EBCDIC 由于字符不连续的隐患 导致后续 出现 无数问题 无法补救 7-bit 的 ASA X3.4-1963 字母序号连续 ...

  9. .NET科普:.NET简史、.NET Standard以及C#和.NET Framework之间的关系

    最近在不少自媒体上看到有关.NET与C#的资讯与评价,感觉大家对.NET与C#还是不太了解,尤其是对2016年6月发布的跨平台.NET Core 1.0,更是知之甚少.在考虑一番之后,还是决定写点东西 ...

  10. springMvc使用自定义View生成Excel表格

    1:通过自定义的View视图可以让请求直接到一个Excel表去. 2:自定义的视图必须继承  AbstractXlsView /AbstractXlsxView / AbstractXlsxStrea ...