Spring Cloud(传参数+熔断器+负载均衡)

本文详细介绍了Spring Cloud中参数传递、熔断器的使用以及客户端负载均衡的实现。通过修改提供者和消费者的相关配置,演示了如何在微服务架构中进行简单参数和对象参数的传递,以及如何利用Hystrix实现服务熔断。同时,文章还探讨了负载均衡的重要性,并以Spring Cloud的Ribbon为例,展示了如何配置和测试客户端负载均衡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring Cloud传参数+熔断器+负载均衡

| 课程回顾

1、配置应用程序名称的属性是什么?

spring.application.name

2、feign接口使用的注解是?

@FeignClient                  

| 预习检查

1、什么是熔断器?

熔断器就相当于电路中的保险丝、保护器,它可以实现快速失败,如果它在某一段时间里侦测到许多类似的错误,它将不再访问远程服务器,会强迫以后的访问都会快速失败,从而防止某个服务不断地尝试执行可能会失败的操作,它会使服务继续执行而不用等待修正错误,或者浪费CPU时间去等到长时间的超时产生,从而进入回路方法。

2、什么是负载均衡?

负载均衡是由多台服务器以对称的方式组成一个服务器集合,每台服务器都具有等价的地位,都可以单独对外提供服务而无须其他服务器的辅助

| 章节目标

  1. 传简单参数。
  2. 传对象参数。
  3. 熔断器。
  4. 客户端负载均衡。

| 章节重点、难点

1)、重点

传参数、熔断器、负载均衡。

2)、难点

熔断器、负载均衡、网关配置。

| 知识点讲解

传简单参数

1、修改提供者的控制器。

上节示例中我们只是讲解了消费者调用提供者的无参方法,接下来演示带参方法。

在dm-user-provider工程中修改UserController类

package com.dm.controller;
//导包省略
@RestController
public class UserController {

    //此处方法加了参数
    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String login(@RequestParam("userName") String userName) throw Exception{
        return " 提供者1 登录成功 " +userName;
    }
}
2、修改消费者的feign接口

在dm-user-comsumer工程中修改UserFeignClient类

@FeignClient(name="dm-user-provider") 
public interface UserFeignClient {
    
    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String login(@RequestParam("userName") String userName) throw Exception;
}
3、修改消费者的控制器类

在dm-user-comsumer工程中修改UserController类

@RestController
public class UserController{
    @Resource
    private UserFeignClient userFeignClient;
    
    @RequestMapping("/userLogin")
    public String login(String name) throw Exception{
        return "收到结果:"+userFeignClient.login(name);
    }
    
}
4、重新启动提供者和消费者测试

访问:

http://localhost:7501/userLogin?name=aa

页面提示如下表示成功

收到结果: 提供者1 登录成功 aa

传对象参数

1、修改提供者的控制器。

上节示例中我们只是讲解了消费者调用提供者的无参方法,接下来演示带参方法。

在dm-user-provider工程中增加User类

public class User implements Serializable {
    private Integer id;
    private String userName;
    private String password;
    
    //get set 省略
}

在dm-user-provider工程中修改UserController类

package com.dm.controller;
//导包省略
@RestController
public class UserController {

    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(@RequestBody User user) throw Exception{
        return " 提供者1 登录成功 " +user;
    }
}
2、修改消费者的feign接口

在dm-user-comsumer工程中增加User类

public class User implements Serializable {
    private Integer id;
    private String userName;
    private String password;
    
    //get set 省略
}

在dm-user-comsumer工程中修改UserFeignClient类

@FeignClient(name="dm-user-provider") 
public interface UserFeignClient {
    
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(@RequestBody User user) throw Exception
}
3、修改消费者的控制器类

在dm-user-comsumer工程中修改UserController类

@RestController
public class UserController{
    @Resource
    private UserFeignClient userFeignClient;
    
    @RequestMapping("/userLogin")
    public String login(User user) throw Exception{
        return "收到结果:"+userFeignClient.login(user);
    }
}
4、重新启动提供者和消费者测试

访问:

http://localhost:7501/userLogin?id=1&userName=aa&password=123

页面提示如下表示成功

收到结果: 提供者1 登录成功 com.szxs.entity.User$1111

熔断器

1、为什么需要熔断器

在分布式中,我们会根据业务或功能将项目拆分为多个服务单元,各个服务单元之间通过服务注册和订阅的方式相互依赖和调用功能,随着项目和业务的不断拓展,服务单元数量也逐渐增多,相互之间的依赖关系也越来越复杂,这时候,可能会有某个服务单元出现问题或网络原因依赖调用出错或延迟,此时如果调用该依赖的请求不断增加,那么要调用该服务的服务将都会等待或者出现故障,如果后续连锁反应越来越多,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务的依赖会导致服务之间的故障传播,从而迎来"雪崩效应"。为了解决这种每个点或多个点的故障,就有了熔断器的出现。

2、什么是熔断器

熔断器就相当于电路中的保险丝、保护器,它可以实现快速失败,如果它在某一段时间里侦测到许多类似的错误,它将不再访问远程服务器,会强迫以后的访问都会快速失败,从而防止某个服务不断地尝试执行可能会失败的操作,它会使服务继续执行而不用等待修正错误,或者浪费CPU时间去等到长时间的超时产生,从而进入回路方法。熔断器也可以使服务能够诊断错误是否已经修正,如果已经修正,服务会再次尝试调用操作。

3、修改消费者工程

修改dm-user-comsumer中的application.yml文件

feign.hystrix.enabled=true 设置启用熔断器

server:
  port: 7501
spring:
  application:
    name: dm-user-consumer
eureka:
  client:
    service-url:
      defaultZone: http://root:dmw@172.16.2.1:7776/eureka/
feign:
  hystrix:
    enabled: true

在此工程中增加一个UserFeignClientFallback类实现UserFeignClient接口

@Component
public class UserFeignClientFallback implements UserFeignClient {
    @Override
    public String login(User user) {

        return "登录1 异常  溶断器 处理 "+user;
    }
}

接下来UserFeignClient接口中配置UserFeignClientFallback的实现,如下:

@FeignClient(name="dm-user-provider",fallback=UserFeignClientFallback.class) 
public interface UserFeignClient {
    
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(@RequestBody User user) throw Exception
}
4、重新启动提供者和消费者测试

访问:

http://localhost:7501/userLogin?id=1&userName=aa&password=123

页面提示如下表示成功

收到结果: 提供者1 登录成功 com.szxs.entity.User$1111

接下来测试熔断器是否生效,可以把提供者(dm-user-provider)停止服务。继续访问测试

http://localhost:7501/userLogin?id=1&userName=aa&password=123

页面提示如下表示熔断器生效了

收到结果: 登录1 异常  溶断器 处理 com.szxs.entity.User$1111

客户端负载均衡

1、为什么需要负载均衡

在网站创立初期,我们一般都使用单台机器对台提供集中式服务,但是随着业务量越来越大,无论是性能上还是稳定性上都有了更大的挑战。这时候我们就会想到通过扩容的方式来提供更好的服务。我们一般会把多台机器组成一个集群对外提供服务。然而,我们的网站对外提供的访问入口都是一个的,比如www.xshiedu.com。那么当用户在浏览器输入www.xshiedu.com的时候如何将用户的请求分发到集群中不同的机器上呢,这就是负载均衡在做的事情。

针对以上情况的解决方案:

(1) 服务器进行硬件升级:采用高性能服务器替换现有低性能服务器。 该方案的弊端:

​ 高成本:高性能服务器价格昂贵,需要高额成本投入,而原有低性能服务器被闲置,造成资 源浪费。

​ 可扩展性差:每一次业务量的提升,都将导致再一次硬件升级的高额成本投入,性能再卓越 的设备也无法满足当前业务量的发展趋势。

(2)组建服务器集群,利用负载均衡技术在服务器集群间进行业务均衡

​ 该方案的优势: 低成本

​ 可扩展性:当业务量增长时,系统可通过增加服务器来满足需求,且不影响已有业务,不降 低服务质量

​ 高可靠性:单台服务器故障时,由负载均衡设备将后续业务转向其他服务器,不影响后续业 务提供,保证业务不中断。

2、负载均衡有哪些

DNS域名解析负载均衡:利用DNS处理域名解析请求的同时进行负载均衡是另一种常用的方案。

数据链路层负载均衡:在通信协议的数据链路层修改mac地址进行负载均衡。

IP负载均衡:在网络层通过修改请求目标地址进行负载均衡。

HTTP重定向负载均衡:这种负载均衡方案的优点是比较简单,缺点是浏览器需要每次请求两次服务器才能拿完成一次访问,性能较差;使用HTTP302响应码重定向,可能是搜索引擎判断为SEO作弊,降低搜索排名。

反向代理负载均衡:反向代理服务器转发请求在HTTP协议层面,因此也叫应用层负载均衡。优点是部署简单,缺点是可能成为系统的瓶颈。

Spring cloud的ribbon是客户端负载均衡

Nginx是服务器端的负载均衡

3、负载均衡算法

随机算法、轮询及加权轮询、最小连接及加权最小连接、Hash(源地址散列)、IP地址散列、URL散列等算法

4、使用Spring Cloud的负载均衡Ribbon

首先要有多个提供者,提供者的服务名要相同。在同一机器上端口号要不一样。消费者可以用一个来调用提供者。

在这里插入图片描述

5、创建第二个提供者

只需要复制一个提供者,把端口号改成不一样就OK(二个提供者不在同一机器可以不改)。

修改第二个工程dm-user-provider的application.yml文件如下。

server:
  port: 7102   #此处是第二个提供者的yml文件,要修改此端口号
spring:
  application:
    name: dm-user-provider   #应用名称不用改
eureka:
  client:
    service-url:
      defaultZone: http://172.16.2.1:7776/eureka/  

第二个工程dm-user-provider中修改UserController类

package com.dm.controller;
//导包省略
@RestController
public class UserController {

    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(@RequestBody User user) throw Exception{
        return " 提供者2 登录成功 " +user;
    }
}
6、修改消费者工程

打开可以看到很多算法类

https://github.com/Netflix/ribbon/tree/master/ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer

常见的策略有:

  • RoundRobinRule(轮询模式)
  • RandomRule(随机策略)
  • BestAvailableRule(并发量)
  • AvailabilityFilteringRule(服务器状态)
  • WeightedResponseTimeRule(根据响应时间)
  • RetryRule(根据策略+重试)
  • ZoneAvoidanceRule(Zone状态+服务状态)

在dm-user-comsumer工程的application.yml中增加策略

server:
  port: 7501
spring:
  application:
    name: dm-user-consumer
eureka:
  client:
    service-url:
      defaultZone: http://root:dmw@172.16.2.1:7776/eureka/
feign:
  hystrix:
    enabled: true

dm-user-provider:  #提供者spring.application.name值  下面使用了轮询策略
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule 
7、重启测试

二个提供者,一个消费者重启。

访问:

http://localhost:7501/userLogin?id=1&userName=aa&password=123

首次页面提示如下表示成功

收到结果: 提供者1 登录成功 com.szxs.entity.User$1111

再次访问页面提示如下表示成功

收到结果: 提供者2 登录成功 com.szxs.entity.User$222
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值