您现在的位置是:首页 > 正文

SpringCloud五大组件

2024-02-29 17:30:13阅读 3

SpringCloud五大组件:
1.注册中心:Eureka,Nacos,Consul;
官方推荐使用的是Eureka,但是常用的是阿里提供的Nacos,而Consul基本很少使用
注册中心的作用:
避免服务与服务之间的调用(服务之间的调用是远程的)时把互相的地址/ip写死。一旦写死,如果有一方服务的地址发生改变,那么调用它的那一方就得修改地址,耦合性太高。
所以这时候就需要使用注册中心来作为一个中间件,服务的提供者负责将自己的ip发送给注册中心,而服务的消费者只需要从注册中心拉取对应提供服务的地址/ip,这样服务的消费者就可以动态获取提供者的地址进行调用了。很好的实现了解耦。

这里就讲一下Nacos的配置,因为Nacos是常用的,而且配置方法都相差不多

Nacos的配置:

首先官网下载Nacos:Nacos1.1.3的版本下载地址
1. 下载完成解压后,进入bin目录,在终端中输入:sh startup.sh -m standalone 指令开启
2.创建一个Maven工程,然后创建一个服务的提供者模块,和一个服务的消费者模块

在这里插入图片描述

 

3.在两个模块中的pom文件中导入依赖:
    <dependencies>
        <!--nacos-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.1.0</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

4.在provider(服务的提供者)模块中创建配置文件:application.yml,并配置参数
server:
  port: 8000
spring:
  cloud:
    nacos:
      discovery:
        server-addr:  127.0.0.1:8848 # 配置nacos 服务端地址
  application:
    name: nacos-provider # 服务名称,大小写不敏感,一般与模块名一致(唯一的)
这样就将该服务注册到了Nacos注册中心中
consumer模块也是一样的配置 将server.port端口和application.name属性改一改就可以了

调用方法演示
package com.MrWang.nacos.controller;


import com.MrWang.nacos.domain.Goods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * 服务的调用方
 */
@RestController
@RequestMapping("/order")
public class OrderController {
    /*
        这个模板类可以自己创建一个包,在包下创建一个spring的配置类,加上@Configuration声明
        在写一个方法,在方法上加上@Bean,返回值就是RestTemplate,方法体直接new RestTemplate()就可以了
    */
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/goods/{id}")
    public Goods findGoodsById(@PathVariable("id") int id){
        //演示discoveryClient 使用
        List<ServiceInstance> instances = discoveryClient.getInstances("nacos-provider");

        //判断集合是否有数据
        if(instances == null || instances.size() == 0){
            //集合没有数据
            return null;
        }

        ServiceInstance instance = instances.get(0);
        String host = instance.getHost();//获取ip
        int port = instance.getPort();//获取端口

        System.out.println(host);
        System.out.println(port);

        String url = "http://"+host+":"+port+"/goods/findOne/"+id;
        // 3. 调用方法
        Goods goods = restTemplate.getForObject(url, Goods.class);


        return goods;
    }
}


6.创建启动类,启动即可
注意事项:Eureka如果想配置注册中心需要单独创建一个模块作为配置中心,不像Nacos和Consul是一个服务,直接下载启动就可以
2.客服端负载均衡:Ribbon
为什么要使用负载均衡策略?
答:服务的提供方可能不仅仅只有一台服务器,而是一个集群,比如上面调用服务时,使用的是instances.get(0);这样就将调用的服务写死了,拿到的永远都是第一个服务,没有实现服务的均衡。
Ribbon可以简化restTemplate的调用
使用:
在创建restTemplate方法时的@Bean上加上@LoadBalanced注解
这样在contorller中代码就可以这样编写了:

package com.MrWang.nacos.controller;


import com.MrWang.nacos.domain.Goods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * 服务的调用方
 */

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/goods/{id}")
    public Goods findGoodsById(@PathVariable("id") int id){

        String url = "http://nacos-provider/goods/findOne/"+id;
        // 3. 调用方法
        Goods goods = restTemplate.getForObject(url, Goods.class);


        return goods;
    }
}



这样就实现了客户端的一个负载均衡
Ribbon负责均衡策略:
随机: RandomRule
轮询 : RoundRobinRule (默认)
最小并发: BestAvailableRule
过滤: AvailabilityFilteringRule
响应时间: WeightedResponse TimeRule
轮询重试: RetryRule
性能可用性: ZoneAvoidanceRule
Ribbon还不是最终解决方案,因为路径写死了String url = “http://nacos-provider/goods/findOne/”+id;
而且每启动一个服务都需要配置该路径,比较麻烦,所以就需要Feign组件完善

3.声明式服务调用:Feign
Feign概述:是一个声明式的 REST 客户端,它用了基于接口的注解方式,很方便实现客户端配置。之前在netfilx公司时是不支持SpringMvc注解的,后来别SpringCloud整合后支持了SpringMvc的注解
1
使用步凑:

导入依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2.编写Feign调用接口,接口编写规则:消费方调用提供方时,接口的编写尽量与消费方暴露的方法(也就是controller中的方法)一直

package com.MrWang.consumer.feign;


import com.MrWang.consumer.config.FeignLogConfig;
import com.MrWang.consumer.domain.Goods;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 *
 * feign声明式接口。发起远程调用的。
 *
 String url = "http://nacos-provider/goods/findOne/"+id;
 Goods goods = restTemplate.getForObject(url, Goods.class);
 *
 * 1. 定义接口
 * 2. 接口上添加注解 @FeignClient,设置value属性为 服务提供者的 应用名称
 * 3. 编写调用接口,接口的声明规则 和 提供方接口保持一致。
 * 4. 注入该接口对象,调用接口方法完成远程调用
 */
@FeignClient(value = "nacos-provider")
public interface GoodsFeignClient {
    @GetMapping("/goods/findOne/{id}")
    public Goods findGoodsById(@PathVariable("id") int id);
}

3.消费方的controller中直接注入该接口并调用方法即可
注意:接口一般是不能注入使用的,但是spring会自动产生接口的代理对象,所以可以直接使用

Feign的超时:两种
1.连接超时 (服务调用服务的时间,默认时间1s)
2.业务逻辑处理超时 (被调用方处理业务的时间,默认时间1s)
可以自己配置,在yml配置文件中

# 设置Ribbon的超时时间
ribbon:
  ConnectTimeout: 1000 # 连接超时时间 默认1s  默认单位毫秒
  ReadTimeout: 3000 # 逻辑处理的超时时间 默认1s 默认单位毫秒

Feign的日志记录
Feign 只能记录 debug 级别的日志信息。也是在yml配置文件中可以配置

# 设置当前的日志级别 debug,feign只支持记录debug级别的日志
logging:
  level:
    com.itheima: debug

定义Feign日志级别Bean
FeignLogConfig

package com.MrWang.consumer.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignLogConfig {
    /*
        NONE,不记录
        BASIC,记录基本的请求行,响应状态码数据
        HEADERS,记录基本的请求行,响应状态码数据,记录响应头信息
        FULL;记录完成的请求 响应数据
     */
    @Bean
    public Logger.Level level(){
        return Logger.Level.FULL;
    }
}


最后在声明的接口中的@FeignClient注解中加上configuration = FeignLogConfig.class属性即可

4.熔断器:Hystrix
Hystrix也是Netflix公司的
用于隔离访问远程服务、第三方服务时出现级联失败(雪崩)
也就是用户访问服务时,而这个服务也需要访问其它的服务,如果最底层的服务挂了,从而导致整条链路的服务都挂了,这就称为雪崩

解决方案:
隔离:
1.线程池隔离(默认)
例如:服务的调用方有一个线程池大小为100,这个服务需要调用其它的四个服务。这个时候,就会对100的线程池进行拆分,给每一个需要调用的服务配置一个单独的线程池,比如都是25的线程容量,如果其中的一个服务挂了,请求一直发一直发,直到25的线程容量用完后就不会在调用了,这样也不会影响其它服务的使用
2.线程量隔离
给服务的提供方设置一个阈值,也就是每次请求该服务的线程最大数是多少,如果超过了这个阈值,请求将不会在发送,也有效的隔离了服务之间的耦合
降级:异常,超时
服务的提供方和消费方都可以配置,也就是说在出现异常或则超时错误时采用自定义解决方案
熔断
用于监控微服务之间的调用情况
该机制默认是关闭状态
当请求的失败率达到一个阈值时(5秒失败20次),就会打开熔断器,打开后的一段时间内(默认5秒)所有的请求都将拒绝,直 到过了这段时间,会呈现一个半开状态,这时会放一些少量请求进来,如果请求失败,回到打开状态;如果成功,就回到关闭状态
限流
具体实现自己另外搜
熔断的监控(可视化工具)
Hystrix 提供了 Hystrix-dashboard 功能,用于实时监控微服务运行状态。
但是Hystrix-dashboard只能监控一个微服务。
Netflix 还提供了 Turbine ,进行聚合监控。
Turbine搭建流程:添加链接描述
5.网关:Gateway(需要单独起一个模块)
概述:
网关旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。
即:用于管理客服端发起请求时的路径,一个请求可能会调用多个微服务,如果每个微服务都需要客户端去调用,那么增加了客服端的压力;所以在这时候就需要一个Gateway组件,用于管理客服端的请求,由Gateway统一接收客户端的请求,在由Gateway去调用微服务。

在这里插入图片描述

 

网关模块yml配置如下:

server:
  port: 80

spring:
  application:
    name: api-gateway-server

  cloud:
    # 网关配置
    gateway:
      # 路由配置:转发规则
      routes: #集合。
      # id: 唯一标识。默认是一个UUID
      # uri: 转发路径
      # predicates: 条件,用于请求网关路径的匹配规则
      # filters:配置局部过滤器的
      - id: gateway-provider
        # 静态路由
        uri: http://localhost:8001/
        predicates:
        - Path=/goods/**

该配置是有问题的,直接写死了微服务的地址,如果微服务的地址发生了改变,或者是个集群,那么这边也需要修改,耦合性太高
解决:网关与微服务之间使用注册中心交互
修改yml文件:

server:
  port: 80

spring:
  application:
    name: api-gateway-server

  cloud:
    # 网关配置
    gateway:
      # 路由配置:转发规则
      routes: #集合。
      # id: 唯一标识。默认是一个UUID
      # uri: 转发路径
      # predicates: 条件,用于请求网关路径的匹配规则
      # filters:配置局部过滤器的

      - id: gateway-provider
          # 静态路由
        # uri: http://localhost:8001/
        # 动态路由
        uri: lb://GATEWAY-PROVIDER
        predicates:
        - Path=/goods/**


5.Gateway过滤器:
局部过滤器:
也就是过滤单独的一个微服务;在yml配置文件中配置:

server:
  port: 80
spring:
  application:
    name: api-gateway-server
  cloud:
    # 网关配置
    gateway:
      # 路由配置:转发规则
      routes: #集合。
      # id: 唯一标识。默认是一个UUID
      # uri: 转发路径
      # predicates: 条件,用于请求网关路径的匹配规则
      # filters:配置局部过滤器的

      - id: gateway-provider
        # 静态路由
        # uri: http://localhost:8001/
        # 动态路由
        uri: lb://GATEWAY-PROVIDER
        predicates:
        - Path=/goods/**
        # 配置局部过滤器
        filters:
        - AddRequestParameter=username,zhangsan


全局过滤器
过滤所有的微服务
1、 在Gateway模块中定义一个类实现GlobalFilter,Ordered接口
2、在重写filter和getOrder方法
代码:

package com.MrWang.gateway.filter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class MyFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        System.out.println("自定义全局过滤器执行了~~~");

        return chain.filter(exchange);//放行
    }

    /**
     * 过滤器排序
     * @return 数值越小 越先执行
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

网站文章

  • 人工智能和计算机科学的关系,人工智能的学科概念、应用领域和技术分支

    人工智能和计算机科学的关系,人工智能的学科概念、应用领域和技术分支

    一、人工智能是一门学科,亦是一门科学。人工智能是研究使计算机来模拟人的某些思维过程和智能行为的学科。它是一门学科,目前很多高校已经专门开设了这么课程。智能行为包括学习、推理、思考和规划。人工智能的研究...

    2024-02-29 17:29:44
  • 浏览器工作原理--渲染流程:HTML,CSS和JavaScript是如何变成页面的?

    浏览器工作原理--渲染流程:HTML,CSS和JavaScript是如何变成页面的?

    一、渲染流水线(1)由于渲染机制过于复杂,所以渲染模块在执行过程中会被划分为很多子阶段,输入的 HTML 经过这些子阶段,最后输出像素。我们把这样的一个处理流程叫做渲染流水线。(2)按照渲染的时间顺序...

    2024-02-29 17:29:37
  • mac安装mongodb

    mac安装mongodb

    1.下载地址:https://www.mongodb.com/try/download/community2.下载成功后,将安装包解压到当前目录3.使用如下命令将解压后的安装包移动到usr/local...

    2024-02-29 17:29:31
  • odoo的字段属性

    1 store=True,计算字段要加2 readonly=True,设置字段只读3 index=True,增加数据库索引,提高搜索查找速度4 required=True设置字段必填5 size=64,char类型字段设置字符大小?6 default=False,默认值7 oldname=" "8 related=‘ ’ , 关系字段9 compute ...

    2024-02-29 17:29:23
  • asus pc server + geforce titan xp + centos 7

    asus pc server + geforce titan xp + centos 7

    系统安装直接采用光盘安装centos7. (安装的时候由于ssd之前已经有了esxi系统,但是直接安装并不会清除掉里面的东西,所以alt+f3切换到命令行,fdisk p d 1-9进行删除,或者直接 dd if=/dev/zero of=/dev/sdc bs=512 count=10, 相当于破坏了分区表,里面的东西自然也就没了)装完了系统,用户问题。 centos 7 不会容忍你只有一个r

    2024-02-29 17:28:56
  • clickhouse 高可用负载均衡chproxy1.17生产环境配置与使用

    的 HTTP 代理和负载平衡器 主要有这几个功能,详细的可以看官网本文提供一些生产环境的例子。官网的例子都比较简单, 也没有相关配置的解释,本文不涉及https部分ClickHouseappserverstats-raw。

    2024-02-29 17:28:48
  • 数据集【NO.7】无人机航拍数据集——VisDrone2019数据集

    数据集【NO.7】无人机航拍数据集——VisDrone2019数据集

    数据集对应应用场景,不同的应用场景有不同的检测难点以及对应改进方法,本系列整理汇总领域内的数据集。

    2024-02-29 17:28:42
  • vue + elementui 通过父子组件实现弹框

    vue + elementui 通过父子组件实现弹框

    文章目录子组件父组件子组件<template> <ModalComponent name="import-set" title="设置" size="85%" width="...

    2024-02-29 17:28:13
  • java:实现小顶堆(附完整源码)

    java:实现小顶堆(附完整源码)

    2024-02-29 17:28:06
  • 【ZJOI2013】bzoj3112 防守战线

    线性规划+费用流

    2024-02-29 17:27:57