当前位置:   article > 正文

SpringCloud-五大常用组件_spring cloud微服务常用组件

spring cloud微服务常用组件

SpringCloud五大组件的理解

1.Eureka:注册中心

如果一个电商平台里面有许多的业务,如果订单,派送,积分服务的,一个服务想要去调用另外的一个服务,也不知道发送请求,也不知道发送给那个,这个时候就需要Eureka提供Eureka-Server,因为每一个服务都有一个Eureka-Client,Eureka就提供注册和发现,Eureka里面有一个注册表,保存各个服务的名字和端口
在这里插入图片描述
在这里插入图片描述

一.单节点故障
1.什么是EurekaServer单节点故障

如果只有一个EurekaSever,如果EurekaSever挂了那么整个微服务都不可用

2.解决方案

EurekaServer高可用集群

二.EurekaServer集群
1.原理图

在这里插入图片描述

2.搭建EurekaServer集群

创建两个本地域名 C:\Windows\System32\drivers\etc\hosts

127.0.0.1 peer1
127.0.0.1 peer2
  • 1
  • 2

修改注册中心eureka-server-1000

spring:
  profiles:
    active: peer1
---
server:
  port: 1000
eureka:
  instance:
    hostname: peer1 #主机
  client:
    registerWithEureka: false #禁止注册中心向自己注册
    fetchRegistry: false #禁止注册中心拉取注册地址清单
    serviceUrl: #微服务向注册中心注册的地址
      defaultZone: http://peer2:1001/eureka/
spring:
  profiles: peer1
---
server:
  port: 1001
eureka:
  instance:
    hostname: peer2 #主机
  client:
    registerWithEureka: false #禁止注册中心向自己注册
    fetchRegistry: false #禁止注册中心拉取注册地址清单
    serviceUrl: #微服务向注册中心注册的地址
      defaultZone: http://peer1:1000/eureka/
spring:
  profiles: peer2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

注意:这里使用的SpringBoot多环境配置的方式 来实现多个Eureka的配置,启动的时候需要修改 spring.profiles.active=peer1来指定启动使用哪个配置 , 然后IDEA的启动器需要取消勾选:

3.修改EurekaClient (UserServer ,OrderServer)
eureka:
  client:
    serviceUrl:
      defaultZone: http://peer1:1000/eureka/,http://peer2:1001/eureka/ #注册中心地址
      ...
  • 1
  • 2
  • 3
  • 4
  • 5

2.Feign

此时已经知道每个服务放在那里,和各自端口,问题来了,订单模块写了很大代码,要和积分模块简历网络通信,此时就又必须写很多的代码,但是feign很好的解决了这个问题,因为feigin接口里面有一个注解是@FeiginClien,动态静态会通过Restmapping注解去创建,去请求网络地址
在这里插入图片描述
总结:
1.feign通过FeignCIient动态代理通过@RuestMapping,来动态的构造你请求服务的地址,最好根据这个地址发起请求,解析响应

一.什么是Feign

基于Ribbon封装的客户端负载均衡器

二.Feign的集成

springcloud-dept-server-4000

1.导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
2.配置类开启Feign
@SpringBootApplication
@EnableFeignClients("cn.itsource.client")
public class DeptServerApplication4000 
...
  • 1
  • 2
  • 3
  • 4
3.编写Feign的接口
/**
 * @FeignClient(value="user-server") : 针对于用户服务调用的 Fiegn的客户端接口
 *  value属性就是该接口要调用的目标服务的名字
 * Feign是如何实现服务调用的:
 *   1.通过@FeignClient(value="user-server")标签上的服务名字能够找到要调用的目标服务
 *   2.通过接口中的方法的 @GetMapping的url路径找到目标服务的controller的方法 ,
 *   所以要保证Feign客户端接口的方法和目标服务的对应的方法要完全一致。
 *
 */
@FeignClient(value="user-server")
public interface UserFeignClient {

    @GetMapping("/user/{id}")
    User getUserById(@PathVariable("id")Long id);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Feign客户端接口的方法和目标服务的对应的方法要完全一致

4.调用
@RestController
public class DeptConsumerController {

    @Autowired
    private UserFeignClient userFeignClient ;

    /**
     * 该方法是浏览器来调用
     * @param id
     * @return
     */
    @GetMapping("/dept/user/{id}")
    public User getUserById(@PathVariable("id") Long id){
        User user = userFeignClient.getUserById(id); //使用Feign的接口调用
        return user;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3.Ribbon

Ribbon是负载均衡器,是基于RestTemplate ,它赋予了RestTemplate 负载均衡的能力
Ribbon复制均衡器,当订单服务访问积分服务的时候,发现积分服务部署在5台机器上,Feign就不知道去访问那个,Ribbon此时就派出用场了,轮询算法,如果订单服务队积分服务发起10次请求,就会先请求第一台机器,然第二,第三,第四,第五,在第一

  • 首先Ribbon会从Eureka-client获取服务注册表,然后知道机器在哪里,端口是多少
  • 接着Ribbon就会使用默认的轮询算法
  • Feign就会针对这台机器发请请求,解析响应

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200312080258105.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTQ3NDM2MQ==,size_16,color_FFFFFF,t_70

1.创建user-server服务2001 - 赋值
2.修改配置
eureka:
  client:
    serviceUrl:
      defaultZone: http://peer1:1000/eureka/,http://peer2:1001/eureka/ #注册中心地址
  instance:
    prefer-ip-address: true #使用ip地址注册
    instance-id: user-server1  #指定服务的id
server:
  port: 2000 
spring:
  application:
    name: user-server
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

注意:instance-id需要修改 , 而 spring.application.name 不需要修改 , 端口需要修改

3.修改主类名,pom中的名字,parent中的模块增加
三.order-server集成Ribbon
1.导入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
2.修改RestTemplate的Bean的定义
 /**
     * SpringMvc提供的一个基于Rest风格的http调用工具
     * @LoadBalanced :ribbon的负载均衡标签,赋予RestTemplate有负债均衡的能力
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

@LoadBalanced :ribbon的负载均衡标签,赋予RestTemplate有负债均衡的能力

3.修改Controller调用方式
 @GetMapping("/order/user/{id}")
    public User getUserById(@PathVariable("id") Long id){
        System.out.println("OrderConsumerController.getUserById被调用了......");
        //String url = "http://localhost:2000/user/"+id;
        String url = "http://user-server/user/"+id;
        User user = restTemplate.getForObject(url, User.class);
        return user;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

修改效果: String url = “http://user-server/user/”+id;

ribbon默认使用的轮询策略

四.Ribbon底层源码分析

@LoadBalanced赋予 RestTemplate 有负载均衡的能力 , 在 RestTemplate 的底层通过一个 RibbonLoadBalancerClient.exec 客户端工具类实现负载均衡 , 而 RibbonLoadBalancerClient.exec方法中做了如下事情:通过调用的服务名获取一个 ILoadBalancer , 通过ILoadBalancer.chooseServer 选择一个服务 .这个ILoadBalancer 中会加载该服务名对应的所有目标服务的通信地址清单 ,而在 ILoadBalancer.chooseServer 方法中会去调用 IRule.choose进行服务的选择 ,而IRule.choose方法就会按照某种算法进行服务的选择然后返回 , 然后再使用http调用选择后的服务

RibbonLoadBalancerClient#execute -> ILoadBalancer

com.netflix.loadbalancer.BaseLoadBalancer#chooseServer ->

ZoneAvoidanceRule.choose -> PredicateBasedRule.choose ->

Hystric

Hystrics是一个熔断,隔离,降级的框架,当积分服务挂了的时候,订单服务有100一个线程去访问,然后订单服务也就发起100此请求,发现访问失败,订单服务也会死掉,此时Hystric就出现了,他会把订单服务的业务模块如,调用调用积分模块,物流模块,库存模块份为三个线程池,调用积分去访问积分服务,然后5分钟内请求服务直接返回就行了,发现,其他的物流模块和库存会正常运行,不会导致订单服务也挂掉,这就是熔断,光返回也不行,那就来一个降级,每次访问积分服务就是记录某某人加了多少积分,因为积分服务访问失败,等积分服务好了之后,在手动去记录下积分,这就是降级

一.雪崩效应

一个微服务的故障导致整个微服务调用链全部瘫痪

二.Hystrix介绍

解决服务器故障(雪崩)的一个组件 ,它可以实现:隔离 ,熔断 ,降级,缓存

  • 隔离 :包括线程池隔离和信号量隔离,限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。

  • 熔断 :当请求次数达到规定的阀值都出现服务故障(超时),Hystrix就把服务标记为短路状态.

    正常情况下,断路器处于关闭状态(Closed),如果调用持续出错或者超时,电路被打开进入熔断状态(Open),后续一段时间内的所有调用都会被拒绝(Fail Fast),一段时间以后,保护器会尝试进入半熔断状态(Half-Open),允许少量请求进来尝试,
    如果调用仍然失败,则回到熔断状态
    如果调用成功,则回到电路闭合状态;
    
    • 1
    • 2
    • 3
  • 降级 :高并发情况下 ,为了保证一些主要的服务有足够的资源不出问题 ,会认为的关掉一些无关紧要的服务,然后返回一些托底的数据,给用户一个友好的提示。

  • 缓存 :Hystrix内部会把请求做缓存

三.Ribbon集成Hystrix

springcloud-order-server-3000

1.导入依赖
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
  • 1
  • 2
  • 3
  • 4
2.controller方法贴注解
 /**
     * 该方法是浏览器来调用
     *  @HystrixCommand :开启方法的短路功能 , 如果方法出现异常,会调用 fallbackMethod
     *  指向的方法 ,然后返回托底数据
     */
    @HystrixCommand(fallbackMethod = "getUserByIdFallback")
    @GetMapping("/order/user/{id}")
    public JsonResult getUserById(@PathVariable("id") Long id){
        System.out.println("OrderConsumerController.getUserById被调用了......");
        String url = "http://user-server/user/"+id;
        User user = restTemplate.getForObject(url, User.class);
        return JsonResult.me().setData(user);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
3.托底方法
 public JsonResult getUserByIdFallback(@PathVariable("id") Long id){
        return JsonResult.me().setSuccess(false)
        .setMessage("服务展示不可用,请骚后重试[服务降级]");
    }
  • 1
  • 2
  • 3
  • 4

注意:托底方法的参数和返回结果要和原方法一致

四.Feign集成Hystrix

springcloud-dept-server-4000

1.开启Hystrix
feign:
  hystrix:
    enabled: true #开启熔断支持
  client:
    config:
      remote-service:           #服务名,填写default为所有服务
        connectTimeout: 30000
        readTimeout: 30000
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 30000
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
2.修改Fiegn客户端接口
@FeignClient(value="user-server" ,fallback = UserFeignClientFallback.class)
public interface UserFeignClient {

    @GetMapping("/user/{id}")
    User getUserById(@PathVariable("id")Long id);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

fallback = UserFeignClientFallback.class : 该类是当前接口的实现类 ,也是托底数据所在的处理类

3.托底实现
@Component
public class UserFeignClientFallback implements UserFeignClient {
    @Override
    public User getUserById(Long id) {
        System.out.println("托底数据执行....");
        return new User(-1L,"托底数据","");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

ZUUl网关

ZUUL微服务网关,这个组件是配置网关路由的,打个比方,如前端访问你的服务,不可能去访问一个
user-service,部署在5台机器上,不可能人家去记,就算去记,你后面还有好几百台机器啦,那前端肯定就来干了,此时zuul的作用就出来了,统一网关,ios,andori,h5,都往这个网关走,网关在根据请求的特征,对到各自的服务中去。
Zuul是一个SpringCloud的网关组件 , 它是微服务的入口,网络关卡 ,通过Zuul我们可以实现请求的分发(负载均衡),鉴权,限流等等操作。
在这里插入图片描述

配置中心config

1.什么是配置中心

集中管理微服务的配置: SpringCloud-config 是分布式配置中心组件

2.配置中心原理图

在这里插入图片描述

总结

Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从而知道其他服务在哪里
Ribbon:服务间发起请求的时候,基于Ribbon做负载均衡,从一个服务的多台机器中选择一台
Feign:基于Feign的动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求
Hystrix:发起请求是通过Hystrix的线程池来走的,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题
Zuul:如果前端、移动端要调用后端系统,统一从Zuul网关进入,由Zuul网关转发请求给对应的服务

在这里插入图片描述

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号