SpringCloud Alibaba详解

目录

 

微服务架构概念

服务治理

服务调用

服务网关 

 服务容错

链路追踪

SpringcloudAlibaba组件

Nacos

负载均衡

Ribbon 

Fegin

Sentinel

高并发测试

容错方案

 Sentinel入门

Feign整合Sentinel


 

微服务架构概念

35bf953e4cac4b9899d73f249ebb73fe.png

 

服务治理

服务治理就是进行服务的自动化管理,其核心是服务的自动注册与发现。

服务注册:服务实例将自身服务信息注册到注册中心。

服务发现:服务实例通过注册中心,获取到注册到其中的服务实例的信息,通过这些信息去请求它们提供的服务。

服务剔除:服务注册中心将出问题的服务自动剔除到可用列表之外,使其不会被调用到。

49ae99a4c87c42d5a142b4d016890acb.png

 

 

服务调用

在微服务架构中,通常存在多个服务之间的远程调用的需求。目前主流的远程调用技术有基于HTTP的RESful接口以及基于TCP的的RPC协议。

 REST(Representational State Transfer)

这是一种HTTP调用的格式,更标准,更通用,无论哪种语言都支持http协议

RPC (Remote Promote Call)
一种进程间通信方式。允许像调用本地服务一样调用远程服务。RPC框架的主要目标就是让远程服务调用更简单、透明。RPC框架负责屏蔽底层的传输方式、序列化方式和通信细节。开发人员在使用的时候只需要了解谁在什么位置提供了什么样的远程服务接口即可,并不需要关心底层通信细节和调用过程。

区别和联系

e99b7e90c0b1455c80fa34df3ed103b8.png
 

 

服务网关 

随着微服务的不断增多,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信可能出现:


1.客户端需要调用不同的url地址,增加难度。
2.在一定的场景下,存在跨域请求的问题。
3.每个微服务都需要进行单独的身份认证针对这些问题,API网关顺势而生。


API网关直面意思是将所有API调用统一接入到API网关层,由网关层统一接入和输出。一个网关的基本功能有:统一接入、安全防护、协议适配、流量管控、长短链接支持、容错能力。有了网关之后,各个API服务提供团队可以专注于自己的的业务逻辑处理,而API网关更专注于安全、流量、路由等问题。

d64bcbe0083545b289cdad37b780d00d.png
 

 服务容错

在微服务当中,一个请求经常会涉及到调用几个服务,如果基中某个服务不可用,没有做服务容错的话,极有可能会造成—连串的服务不可用,这就是雪崩效应。我们没法预防雪崩效应的发生,只能尽可能去做好容错。

服务容错的三个核心思想是:
不被外界环境影响
不被上游请求压垮
不被下游响应拖垮
 

be9079f082904ebfa5a9070a450e25c0.png

 

链路追踪

随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。因此,就需要对一次请求涉及的多个服务链路进行日志记录,性能监控即链路追踪。

 

SpringcloudAlibaba组件

Nacos

下载安装

# 下载源码
git clone https://github.com/alibaba/nacos.git

启动

# Linux
./startup.sh -m standalone

# Windows
startup.cmd
 

导入Nacos依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

application.yml文件配置

spring:
  application:
    name: user

  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: SH //集群

发现这个服务的各个实例并获取每个实例的host和port代码如下

    @Autowired
    DiscoveryClient discoveryClient;

    @GetMapping("/user/{id}")
    public User user(@PathVariable("id") Long id){
        List<ServiceInstance> user1 = discoveryClient.getInstances("user");
        for (ServiceInstance serviceInstance : user1) {   
      System.out.println("http://"+serviceInstance.getHost()+":"
      +serviceInstance.getPort());
        }
   
    }

负载均衡

通俗的讲,负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上进行执行。根据负载均衡发生位置的不同,一般分为服务端负载均衡和客户端负载均衡。
服务端负载均衡指的是发生在服务提供者—方,比如常见的nginx负载均衡。
客户端负载均衡指的是发生在服务请求的一方,也就是在发送请求之前已经选好了由哪个实例处理请求。

ed9d57170e664832a299f107e2720e18.png
 

Ribbon 

负载均衡使用Ribbon组件,为Springcloud中的一个组件

导入依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

配置文件

@Configuration
public class RestTemplateConfiguration {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

在不同的服务调用的时候,只需要调用服务名就可以调用该服务,其中是以轮询的方式访问服务中的各个实例。这里设置一个订单微服务和一个用户微服务,通过查询订单返回订单信息,订单中有用户信息,所有需要根据订单中的用户id调用用户微服务进行查询然后进行赋值返回订单信息,代码如下:

    @Autowired
    OrdersMapper ordersMapper;
    String url="http://user/user/";

 
    @Autowired
    RestTemplate restTemplate;


    @GetMapping("/order/{id}")
    public Orders orders(@PathVariable("id") Long id){
        Orders orders = ordersMapper.selectById(id);
        User forObject = restTemplate.getForObject(url + orders.getUserId(), User.class);
        User user = feign.findbyId(orders.getUserId());
        orders.setUser(user);
        return orders;
    }

上面是轮询模式,如果负载均衡改成随机模式,可以在订单服务中的application.yml文件中进行下面配置:

user: //调用的微服务名称
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

Fegin

Feign是Spring Cloud提供的一个声明式的伪Http客户端,它使得调用远程服务就像调用本地服务一样简单,只需要创建—个接口并添加—个注解即可。
Nacos很好的兼容了Feign, Feign默认集成了Ribbon,所以在Nacos下使用Eegin默认就实现了负载均衡的效果。
 

导入依赖

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

在Springboot主启动类上添加

@EnableFeignClients

配置接口

@FeignClient("user")//指定调用哪个微服务名称
public interface Feign {

    @GetMapping("/user/{id}")
    User findbyId(@PathVariable("id") Long id);
}

修改对应上面的代码

    @Autowired
    Feign feign;

    @GetMapping("/order/{id}")
    public Orders orders(@PathVariable("id") Long id){
        
        Orders orders = ordersMapper.selectById(id);
        User user = feign.findbyId(orders.getUserId());
        orders.setUser(user);
        return orders;
    }

Sentinel

Sentinel是阿里巴巴开源的一款断路器实现,本身在阿里内部已经被大规模采用,非常稳定。

在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用,但是由于网络原因或者自身的原因,服务并不能保证服务的100%可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大是的网络涌入会导致瘫痪。这里通过举例子说明,上面的代码假如订单服务在调用用户服务的时候,发生异常导致线程无法释放请求堵塞在这里,然后在高并发场景下,大量的请求又都会占用在这里,就会导致系统崩溃。

高并发测试


然后我们来测试一下高并发情况,首先修改订单服务的调用用户微服务的方法,修改代码如下

 @GetMapping("/order/{id}")
    public Orders orders(@PathVariable("id") Long id){
        Orders orders = ordersMapper.selectById(id);
        User user = feign.findbyId(orders.getUserId());
        //模拟调用延迟
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        orders.setUser(user);
        return orders;
    }

然后添加一个测试方法

 @GetMapping("/test")
    public String test(){
        return "测试高并发";
    }

在访问订单微服务的test方法的时候访问速度特别快,然后使用Jmeter进行压测

c37f2e914c434553af571a4faf323746.png

 在进行压测的时候然后访问test方法一直在打圈,然后验证了我们的实验结果。在分布式系统中,由于网络原因或自身的原因,服务一般无法保证100%可用。如果一个服务出现了问题,调用这个服务就会出现线程阻塞的情况,此时若有大量的请求涌入,就会出现多条线程阻塞等待,进而导致服务瘫痪。由于服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩效应”。

9c09df8ed6524be3ad4bd104597bf3fa.png

 雪崩发生的原因多种多样,有不合理的容量设计,或者是高并发下某一个方法响应变慢,亦或是某台机器的资源耗尽。我们无法完全杜绝雪崩源头的发生,只有做好足够的容错,保证在一个服务发生问题,不会影响到其它服务的正常运待。也就是“雪落而不雪崩”。

容错方案

要防止雪崩的扩散,我们就要做好服务的容错,容错说白了就是保护自己不被猪队友拖垮的一些措施,下面介绍常见的服务容错思路和组件。常见的容错思路有隔离、超时、限流、熔断、降级这几种,下面分别介绍一下。


隔离
它是指将系统按照一定的原则划分为若干个服务模块,各个模块之间相对独立,无强依赖。当有故障发生时,能将问题和影响隔离在某个模块内部,而不扩散风险,不波及其它模块,不影响整体的系统服务。常见的隔离方式有:线程池隔离和信号量隔离。

这里说明一下线程池隔离方法,为微服务中的每个方法分配一个线程池如下图

01a68a34028245249952b9c9c2bbf50f.png

 

超时

在上游服务调用下游服务的时候,设置一个最大响应时间,如果超过这个时间,下游未作出反应,就断开请求,释放掉线程。

de4d5321fccd4c35b364935398381e06.png

 

限流

限流就是限制系统的输入和输出流量已达到保护系统的目的。为了保证系统的稳固运行,一旦达到的需要限制的阈值,就需要限制流量并采取少量措施以完成限制流量的目的。

d85200ce2efe434a8f7647b7db8340b3.png

 

 

 

熔断

在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断。

5fb0d708349249b7b0106ca71af119fd.png

 

服务熔断—般有三种状态:。

熔断关闭状态(Closed)
服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制。

熔断开启状态(Open)
后续对该服务接口的调用不再经过网络,直接执行本地的fallback方法。

半熔断状态(Half-Open)
尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断关闭状态。
 

降级
降级其实就是为服务提供一个托底方案,一旦服务无法正常调用,就使用托底方案。

8256bacd2aaa41e082215f881efebec0.png
 

 Sentinel入门

Sentinel (分布式系统的流量防卫兵)是阿里开源的一套用于服务容错的综合性解决方案。它以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。
Sentinel的主要功能就是容错,主要体现为下面这三个:
流量控制
流量控制在网络传输中是一个常用的概念,它用于调整网络包的数据。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流星进行控制。Sentinel作为一个调配器,可以根据需要把随机的请求调整成合适的形状。
熔断降级
当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障。
Sentinel对这个问题采取了两种手段:

通过并发线程数进行限制
Sentinel通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。

通过响应时间对资源进行降级
除了对并发线程数进行控制以外,Sentinel还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。

Sentinel和 Hystrix的区别
两者的原则是一致的,都是当一个资源出现问题时,让其快速失败不要波及到其它服务但是在限制的手段上,确采取了完全不一样的方法:
Hystrix采用的是线程池隔离的方式,优点是做到了资源之间的隔离,缺点是增加了线程切换的成本。Sentinel采用的是通过并发线程的数基和响应时间来对资源做限制。

系统负载保护
Sentinel同时提供系统维度的自适应保护能力。当系统负载较高的时候,如果还持续让请求进入可能会导致系统崩溃,无法响应。在集群环境下,会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,Sentinel提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
 


 

整合Sentinel

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

从Releases · alibaba/Sentinel · GitHub中下载sentinel客户端,然后java -jar 运行即可,一般默认端口为8080端口,访问8080端口即可,账号密码都是sentinel。

application.yml文件中注册,这里在用户微服务里进行注册。sentinel客户端就可以检测到。

spring:
  application:
    name: user

  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: SH
    sentinel:
      transport:
        dashboard: localhost:8080

在客户端如何使用限流规则和降级规则等等,由于不太好写这方面的操作,这里进行省略。

Feign整合Sentinel

Sentinel 适配了 Feign 组件。但默认是关闭的。需要在配置文件中配置打开它,在配置文件增加以下代码:

feign:
  sentinel:
    enabled: true

容错类

//容错的工厂类,泛型传递对应的接口
@Component
@Slf4j
public class Fallback implements FallbackFactory<Feign> {

    public Feign create(final Throwable throwable) {
        return new Feign() {
            public User findbyId(Long id) {
               log.error(String.valueOf(throwable));
               User user=new User();
               user.setId((long) -1);
               return user;
            }
        };
    }
}

Feign接口


@FeignClient(value = "user",fallbackFactory = Fallback.class)//指定调用哪个微服务名称
public interface Feign {

    @GetMapping("/user/{id}")
    User findbyId(@PathVariable("id") Long id);
}

订单服务业务修改代码如下

@GetMapping("/order/{id}")
    public Orders orders(@PathVariable("id") Long id){
        Orders orders = ordersMapper.selectById(id);
//        User forObject = restTemplate.getForObject(url + orders.getUserId(), User.class);
        User user = feign.findbyId(orders.getUserId());
       if(user.getId()==-1l) {
           orders.setUser(user);
           return orders;
       }
        orders.setUser(user);
        return orders;
    }

 

这篇文章到此结束,未完待续,剩余内容下篇文章见
 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/20821.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pod的基本介绍| harbor仓库的搭建 tomcat镜像拉取

pod的基本介绍| harbor仓库的搭建 tomcat镜像拉取 一 Pod基础概念&#xff1a;二 通常把Pod分为两类&#xff1a;三 Pod容器的分类&#xff1a;四 应用容器&#xff08;Maincontainer&#xff09;五 镜像拉取策略&#xff08;image PullPolicy&#xff09;六 部署 harbor 创建私…

SpringMVC高手进阶

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开兴好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

解密Netty中的Reactor模式

文章目录 单线程Reactor模式多线程Reactor模式Reactor模式中IO事件的处理流程Netty中的通道ChannelNetty中的反应器ReactorNetty中的处理器HandlerNetty中的通道Channel和处理器Handler的协作组件Pipeline Reactor(反应器)模式是高性能网络编程在设计和架构方面的基础模式.Doug…

Science文章复现(Python):图1 - Aircraft obs(机载的观测 CO2)

之前有写过science文章后处理的复现Science文章复现&#xff08;Python&#xff09;&#xff1a;在机载观测中明显的强烈南大洋碳吸收 在这里是针对图细节的理解&#xff1a; 首先需要下载这个项目 https://github.com/NCAR/so-co2-airborne-obs 这里的环境配置会比较麻烦 con…

00后卷起来,真没我们老油条什么事了···

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。 这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪20K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。…

【刷题之路】LeetCode 232. 用栈实现队列

【刷题之路】LeetCode 232. 用栈实现队列 一、题目描述二、解题1、图解主要思路2、先实现栈3、实现各个接口3.1、初始化接口3.2、入队接口3.3、出队接口3.4、取队头接口3.5、判空接口3.6、释放接口 一、题目描述 原题连接&#xff1a; 232. 用栈实现队列 题目描述&#xff1a;…

网站测试的主要方法

网站测试的主要方法 网站测试是保证网站质量的重要手段&#xff0c;通过对网站进行测试可以及时发现问题并修复&#xff0c;提高用户体验和网站的可靠性。本文将介绍网站测试的主要方法。 1.功能测试&#xff1a;测试网站的所有功能是否正常。通过模拟用户的操作&#xff0c;确…

在外包干了三年,我废了……不吹不黑!

没错&#xff0c;我也干过外包&#xff0c;一干就是三年&#xff0c;三年后&#xff0c;我废了…… 虽说废的不是很彻底&#xff0c;但那三年我几乎是出差了三年、玩了三年、荒废了三年&#xff0c;那三年&#xff0c;我的技术能力几乎是零成长的。 说起这段三年的外包经历&a…

文档管理-gitlab+markdown网页插件

特点 使用git进行版本管理&#xff0c;本地编辑使用Typora。使用gitlab进行权限管理可以在线阅读通过Markdown在线阅读插件实现&#xff0c;可显示目录显示与链接跳转&#xff0c;界面优于自带的wiki。 与其他方式对比 gitlab的wiki&#xff1a;显示界面效果不好&#xff0c…

【数据结构】栈及其实现

目录 &#x1f920;前言 什么是栈&#xff1f; 栈的定义及初始化 栈的定义 栈的初始化 栈的判空 栈顶压栈 栈顶出栈 栈的数据个数 栈的销毁 完整代码 总结 &#x1f920;前言 学了相当长一段时间的链表&#xff0c;总算是跨过了一个阶段。从今天开始我们将进入栈和…

[IOT物联网]Python快速上手开发物联网上位机程序——前言

一、什么是Python Python是一种简单易学、高级、通用的编程语言。它是一种解释型语言&#xff0c;不需要编译即可运行&#xff0c;因此可以快速地进行开发和测试。Python具有简洁优美的语法&#xff0c;使用它可以提高生产力和代码可读性。Python拥有强大的标准库和第三方库&am…

Linux Shell 实现一键部署virtualbox

VirtualBox 前言 VirtualBox 是一款开源虚拟机软件。VirtualBox 是由德国 Innotek 公司开发&#xff0c;由Sun Microsystems公司出品的软件&#xff0c;使用Qt编写&#xff0c;在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。Innotek 以 GNU General Public Licens…

孙鑫VC++第四章 1.简单绘图-MFC消息映射机制

1. MFC消息映射机制 接下来将剖析MFC消息映射机制&#xff0c;探讨发送给窗口的消息是如何被MFC框架通过窗口句柄映射表和消息映射表来用窗口类的处理函数进行响应的。另外&#xff0c;还将讲述“类向导”这一工具的运用&#xff0c;讨论设备描述表及其封装类CDC的使用&#x…

玩转ChatGPT:魔改文章成果格式

一、写在前面 首先&#xff0c;我让小Chat替我吐槽一下&#xff1a; 科研人员天天都在填各种表格&#xff0c;简直成了我们的“表格王子”和“表格公主”。从申请项目、提交论文到汇报成果&#xff0c;表格无处不在。我们填表格的时候总是期待着它能让我们的工作更高效、更顺…

遇到一个同事,喜欢查其他同事的BUG,然后截图发工作大群里,还喜欢甩锅,该怎么办?...

职场上都有哪些奇葩同事&#xff1f; 一位网友吐槽&#xff1a; 遇到一个同事&#xff0c;喜欢查同级别同事的bug&#xff0c;截图发工作群&#xff0c;甚至发大群里&#xff0c;还喜欢甩锅&#xff0c;该怎么办&#xff1f; 职场工贼&#xff0c;人人喊打&#xff0c;网友们纷…

asm 加盘 udev 重启 导致网络异常

Network interface going down when dynamically adding disks to storage using udev in RHEL 6 (Doc ID 1569028.1)正在上传…重新上传取消To Bottom In this Document APPLIES TO: Oracle Database - Enterprise Edition - Version 11.2.0.3 and later Oracle Net Servi…

UART驱动情景分析-read

一、源码框架回顾 shell读数据&#xff0c;一开始的时候没有就休眠。数据从串口发送到驱动&#xff0c;驱动接收到中断&#xff0c;驱动读取串口数据&#xff0c;这个数据会传给行规程。 行规程获取到数据后&#xff0c;会回显。按下删除就删除一个字符&#xff0c;按下回车&am…

【Linux升级之路】3_Linux进程概念

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【Linux升级之路】 ✒️✒️本篇内容&#xff1a;认识冯诺依曼系统&#xff0c;操作系统概念与定位&#xff0c;深入理解进程概念&#xff08;了解PCB&…

【#ifndef, #define, 和 #endif】

前言 学习AFNetWoring源码的时候&#xff0c;在AFN的h借接口文件又看到了这几个宏定义&#xff0c;学习记录一下。 作用 #ifndef, #define, 和 #endif是C/CPP的预处理指令&#xff0c;常常用来条件编译和防止头文件重复包含。 简介 #ifndef 它是if not define的简写&…

Cy5.5-PEG-SH近红外荧光PEG试剂 Cyanine5.5-PEG-SH,Thiol-PEG-Cy5.5可用于活体成像

Cy5.5-PEG-SH &#xff0c;Cy5.5聚乙二醇巯基 英文名称&#xff1a;Cy5.5-PEG-SH 中文名称&#xff1a;Cy5.5聚乙二醇巯基 性状: 深蓝色固体或粘性液体&#xff0c;取决于分子量 溶剂&#xff1a;溶于水、 DMSO等常规性有机溶剂 激发/发射波长&#xff1a;684 nm/710 nm …