SpringCloud常用组件总结

SpringCloud

什么是SpringCloud?

SpringCloud是基于Spring Framework的一套开源工具集,用于构建分布式系统和微服务架构的解决方案。它提供了一系列的开发工具和组件,简化了分布式系统中常见的开发、配置、服务注册和发现、负载均衡、断路器、路由、配置管理等任务。

常用组件

1、Eureka注册中心

(1)使用场景

Eureka主要是用来进行服务的管理,考虑到服务的增加,对于服务提供者来说,服务者要对外暴露自己的调用地址,对于调用者来说,它要记录提供者的服务地址,如果微服务的数量增大,或者说提供者的端口、ip等信息发生变更,而调用者不知道,就会给项目带来问题,不利于项目的维护。

那么Eureka就负责管理、记录服务提供者的信息,服务调用者无需自己寻找服务,而是把自己的需求告诉Eureka,然后Eureka会把符合你需求的服务告诉你。

提供者与注册中心之间维持“心跳”机制,提供者向注册中心定时发送自己还“活着”的信息,防止被Eureka从服务列表中移除。

(2)使用方法

①:搭建EurekaServer项目

引依赖:
    <!-- SpringCloud依赖管理 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
 版本管理:
        <properties>
           <spring-cloud.version>Finchley.SR2</spring-cloud.version>
        </properties>
注意:版本要和SpringBoot的版本使用一致

②:引入Eureka依赖

Eureka服务端:  
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
客户端:
<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

③:修改配置文件(提供端口、ip等信息)

server:
  port: 10086 # eureka访问服务端口
spring:
  application:
    name: eureka-server # 应用名称  会在Eureka中显示
eureka:
  client:
    service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址。
      defaultZone: http://127.0.0.1:10086/eureka

④:服务提供端与调用端也要注册到Eureka上

eureka:  #服务提供方
  client:
    service-url: # EurekaServer地址,提供方注册地址
      defaultZone: http://localhost:10086/eureka/
eureka:  #服务调用方
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka/

⑤:启动类上加注解

@EnableEurekaServer //启用Eureka服务端
@EnableDiscoveryClient  //两个客户端的启动类上

如果要搭建Eureka集群,参考另外一个文章。

2、负载均衡Ribbon

(1)使用场景

为了降低某个提供者服务的压力,或者说把服务部署在多个实例上,用来提高系统的可用性和容错性(一个坏了,可以调其他的服务)根据预定义的负载均衡策略将请求分发到不同的实例,提高系统的性能和可靠性。

(2)使用方法

Eureka中已经帮我们集成了负载均衡组件,在此无需引入新的依赖。因为负载均衡是指针对服务调用者来说,这个不行调另外的,所以改动consumer模块的代码

①:引入依赖:无

②:在调用者的启动类中注入

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

③:修改服务的调用方式如:

String url = "http://service-provider/provider/findById/" + id;
User user = restTemplate.getForObject(url, User.class);

可以打断点跟踪负载均衡策略(默认是简单的轮询策略)也可以修改

3、Hystrix

(1)使用场景

主要起到一个保护机制。作用是隔离访问远程服务、第三方库,防止出现级联失败等问题。

以雪崩问题为例:(在微服务中,完成一个服务请求可能需要依赖多个服务接口才能实现。形成非常复杂的调用链路。如果其中的某个服务出现了异常,用户得不到响应,但是Tomcat也不会释放线程,越来越多的线程堵塞。形成雪崩)

使用Hystrix做一些容错保护(服务熔断)、弹性控制(线程池控制请求)。

(2)使用方法

线程隔离、服务降级

弹性控制中使用线程隔离,服务降级处理雪崩问题。通过提供线程池,控制资源的请求数来限制访问服务,如果线程池数满,或者请求超时,就会进行降级处理并返回给用户友好的提示信息。

①:在服务调用方引入Hystrix依赖

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

②:引导类上加注解

@EnableCircuitBreaker

③:定义降级方法(局部/全局)

局部:

3.1:写降级方法

  //降级方法要和被降级方法的参数列表一致,返回值类型一致
   public String queryUserByIdFallBack(Integer id){
        return "系统繁忙,请稍后再试";
   }

3.2:在需要降级的方法上打注解

 @HystrixCommand(fallbackMethod = "queryUserByIdFallBack") //用来声明一个降级逻辑的方法

全局:

3.1:写全局降级方法

//    设置全局降级方法,如果谁需要降级熔断。就在谁上指定注解
//降级方法要和被降级方法的参数列表一致 不能有参数
    public String queryUserByIdFallBack(){
        return "系统繁忙,请稍后再试";
    }

3.2:在需要降级的方法上打注解 并指定属性

@HystrixCommand //使用了全局降级方法  在指定的controller方法上添加注解@HystrixCommand
@DefaultProperties(defaultFallback = "queryUserByIdFallBack") //全局指定默认的降级方法,Contrller类上面

服务熔断

服务熔断就是说如果请求时存在大量请求超时或者反应慢的情况,调用方会自行熔断,变为打开状态,不让请求过去,但是这个打开状态不是永久的,在打开状态后会进行5s的休眠时间,变为半打开状态,放一部分请求过去探路,如果没问题,会变为关闭状态,所有请求正常访问。

4、Feign

(1)使用场景

进一步简化,学会“伪装”,改变之前服务调用者在Controller层,这种看着很硬编码的方式,把这些地址以SpringMVC +注解的方式做到“返璞归真,回归原始”。

String url = "http://" + instance.getHost()+":"+instance.getPort()+"/provider/findById/" + id;
String url = "http://service-provider/provider/findById/" + id;

Feign可以把Rest的请求进行隐藏,伪装成类似SpringMVC的Controller一样

(2)使用方法

①:添加依赖(服务调用方)

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

②:是否需要覆盖默认配置(比如使Feign的熔断机制生效)

feign:
  hystrix:
    enabled: true # 开启Feign的熔断功能

③:在启动类上添加注解

@EnableFeignClients   //开启Feign功能

④:编写Fiegn的客户端,在接口上添加@FeignClient注解(以下都是以Feign的熔断机制为例)

//声明这是一个Feign客户端,类似`@Mapper`注解。同时通过`value`属性指定服务名称
//fallback 属性为熔断策略的实现类。熔断策略实现类应实现 Feign 客户端接口,并提供处理熔断逻辑的方法。
@FeignClient(value = "service-provider",fallback = UserFeignClientFallback.class)
public interface UserFeignClient {
    //把Controller中对应的方法声明放在这里
    @GetMapping("/provider/findById/{id}")
     User findById(@PathVariable Integer id);
}

⑤:编写熔断策略(其实就是Fiegn的客户端的一个实现类,实现具体的降级逻辑)

@Component
public class UserFeignClientFallback implements UserFeignClient{
    //这里编写的是接口方法中的具体的降级逻辑
    @Override
    public User findById(Integer id) {
        User user = new User();
        user.setUsername("系统繁忙,请稍后再试");
        return user;
    }
}

⑥:Controller层注入并进行调用

@RestController
@RequestMapping("/consumer")
public class UserController {
    @Autowired
    UserFeignClient userFeignClient;
    public String findById(@PathVariable Integer id){
        User user = userFeignClient.findById(id);
        System.out.println(user);
        return user.toString();
    }
}

5、Zuul

(1)使用场景

  • 权限认证
  • 服务路由
  • 负载均衡

(2)使用方法

①:搭建Zuul-server网关服务

②:引入依赖

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

③:修改配置文件,配置路由规则

server:
  port: 10010 #服务端口
spring:
  application:
    name: api-gateway #指定服务名
zuul:
  routes:
    service-provider: service-provider/**
    service-consumer: service-consumer/**

④在启动类上加注解

@EnableZuulProxy  //开启网关功能

过滤器

Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的。

①:自定义过滤器 实现IZuulFilter

public abstract ZuulFilter implements IZuulFilter{

    abstract public String filterType();

    abstract public int filterOrder();
    
    boolean shouldFilter();// 来自IZuulFilter

    Object run() throws ZuulException;// IZuulFilter  编写过滤规则
}
posted @ 2023-06-27 19:36  有点儿意思  阅读(258)  评论(0编辑  收藏  举报