SpringCloud服务间通信方式(RestTemplate)及负载均衡(Ribbon)

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: 🍅程序员小王的博客:程序员小王的博客🍅 欢迎点赞 👍 收藏 ⭐留言 📝🍅 如有编辑错误联系作者,如果有比较好的文章欢迎分享给我,我会取其精华去其糟粕🍅java自学的学习路线:java自学的学习路线

一、RestTemplate服务间通信方式

接下来在整个微服务架构中,我们比较关心的就是服务间的服务如何调用,有哪些调用方式?


0.png


总结:在springcloud中服务间调用方式主要是使用 http restful方式进行服务间调用


1、基于RestTemplate的服务调用

spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。


2、RestTemplate 服务调用

(1)创建两个服务并注册到consul注册中心中


- users    代表用户服务 端口为 9999
- products 代表商品服务 端口为 9998
  `注意:这里服务仅仅用来测试,没有实际业务意义


(2)两个项目一样的依赖

    <parent>
        <artifactId>SpringCloud_Parent</artifactId>
        <groupId>com.tjcu</groupId>
        <version>1.0-RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>user9999</artifactId>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 这个包是用做健康度监控的-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--引入consul依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <!--引入lombok日志-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>


(3)两个项目端口号不一样


1.png


(4)在商品服务中提供服务方法


@RestController
@Slf4j
public class UserAction {
    @Value("${server.port}")
    private  int port;
    @GetMapping("/product/findAll")
    public Map<String,Object> findAll(){
        log.info("商品服务调度成功,当前服务端口[{}]",port);
        HashMap<String, Object> map = new HashMap<>();
        map.put("msg","服务调度成功,服务端口为"+port);
        map.put("status",true);
        return map;
    }
}

(5)在用户服务中使用restTemplate进行调用


@RestController
@Slf4j
public class UserAction {
    @GetMapping("/user/findAll")
    public String findAll(){
        log.info("调度用户服务。。");
        //    使用restTemplate调用商品服务
        RestTemplate restTemplate = new RestTemplate();
        String forObject = restTemplate.getForObject("http://localhost:9998/product/findAll", String.class);
        return  forObject;
    }
}

(6)启动服务


3.png2.png


(7)总结


rest Template是直接基于服务地址调用没有在服务注册中心获取服务,也没有办法完成服务的负载均衡如果需要实现服务的负载均衡需要自己书写服务负载均衡策略。


调用服务的路径主机和端口直接写死在url中,无法实现服务集群时实现负载均衡


不利于后期维护


4.png


自定义负载均衡无法实现健康检查,负载均衡策略过于单一


九、Ribbon(ruiben)服务间通信方式

ribbon:SpringCloud-netfix-ribbon 作用:负载均衡的客户端组件,用来实现请求调用的负载均衡


官方网址: GitHub - Netflix/ribbon: Ribbon is a Inter Process Communication (remote procedure calls) library with built in software load balancers. The primary usage model involves REST calls with various serialization scheme support.


5.png


Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。


Ribbon负载均衡原理:


6.png


1.Ribbon 服务调用

(1)项目中引入依赖


如果使用的是eureka [juˈrikə] client 和 consul client,无须引入依赖,因为在eureka,consul中默认集成了ribbon[ˈrɪbən]组件


如果使用的client中没有ribbon依赖需要显式引入如下依赖


<!--引入ribbon依赖-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

(2) 查看consul client中依赖的ribbon


7.png


(3)使用restTemplate + ribbon进行服务调用


设置两个商品列表的端口号分别为9997,9998


启动项目端口号9998


8.png


启动项目端口号9997


9.png


2、三种ribbon负载均衡对象

(1)discoveryClient:服务发现客户端对象


服务发现客户端对象:根据服务id去服务注册中心获取对应服务列表到本地中


使用discovery(服务注册和发现) client 进行客户端调用


@RestController
@Slf4j
public class UserAction {
    /**
     * 服务注册和发现服务端对象
     */
    @Autowired
    private DiscoveryClient discoveryClient;
    @GetMapping("/user/findAll")
    public String findAll() {
        //2.使用ribbon组件+RestTemplate实现负载均衡调用   1.DiscoveryClient   2.LoadBalanceClient    @LoadBalance
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances("products");
        serviceInstances.forEach(serviceInstance -> {
            log.info("服务主机: {} 服务端口:{} 服务地址:{}", serviceInstance.getHost(), serviceInstance.getPort(), serviceInstance.getUri());
        });
        String result = new RestTemplate().getForObject(serviceInstances.get(0).getUri() + "/product/findAll", String.class);
        return result;
    }
}


10.png


(2)LoadBalancerClient:负载均衡客户端对象


负载均衡客户端对象:根据服务id去服务注册中心获取对应服务列表,根据负载均衡策略选择列表中一台集群进行返回


使用loadBalancer(负载均衡)Client 进行客户端调用

    /**
     * 负载均衡对象
     */
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    @GetMapping("/user/findUser")
    public String findUser() {
        //使用ribbon组件+RestTemplate实现负载均衡调用
        ServiceInstance products = loadBalancerClient.choose("products");
        log.info("服务端口:{} 服务主机:{} 服务地址:{}", products.getPort(), products.getHost(), products.getUri());
        String result = new RestTemplate().getForObject(products.getUri() + "/product/findAll", String.class);
        return result;
    }

11.png


(3)@LoadBalanced 负载均衡客户端注解


使用@loadBalanced 进行客户端调用,用在方法上,让当前对象具有ribbon负载均衡的特性


配置类


@Configuration   //代表这是一个Spring配置类 spring.xml工厂
public class BasicConfig {
    @Bean
    @LoadBalanced  //实现负载均衡 让对象具有Ribbon负载均衡的特性
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

控制层


 

    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/user/find")
    public String LoadBalancedFind() {
        return restTemplate.getForObject("http://products/product/findAll", String.class);
    }

12.png


3、Ribbon负载均衡策略

(1)ribbon负载均衡算法


RoundRobinRule 轮训策略 按顺序循环选择 Server


RandomRule 随机策略 随机选择 Server


AvailabilityFilteringRule 可用过滤策略 `会先过滤由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问


WeightedResponseTimeRule 响应时间加权策略

根据平均响应的时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高,刚启动时如果统计信息不足,则使用RoundRobinRule`策略,等统计信息足够会切换到


RetryRule 重试策略

先按照RoundRobinRule的策略获取服务,如果获取失败则在制定时间内进行重试,获取可用的服务。


BestAviableRule 最低并发策略

`会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务


13.png


5、Ribbon组件细节

(1)Ribbon组件实现负载均衡原理


原理:根据调用服务id去服务注册中获取对应服务id的服务列表,并将服务列表拉去本地进行缓存,然后在本地通过默认的轮训的负载均衡策略在现有列表中选中一个可用节点提供服务


注意:客户端负载均衡


6、修改服务的默认负载均衡策略随机

服务id.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule `下面的products为服务的唯一标识

products.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

14.png


7、Ribbon停止维护

官方停止维护说明


GitHub - Netflix/ribbon: Ribbon is a Inter Process Communication (remote procedure calls) library with built in software load balancers. The primary usage model involves REST calls with various serialization scheme support.


15.png

16.png



8、服务注册中心和Ribbon组件总结


17.png

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
1月前
|
弹性计算 监控 负载均衡
|
3月前
|
负载均衡 算法 Java
Spring Cloud全解析:负载均衡算法
本文介绍了负载均衡的两种方式:集中式负载均衡和进程内负载均衡,以及常见的负载均衡算法,包括轮询、随机、源地址哈希、加权轮询、加权随机和最小连接数等方法,帮助读者更好地理解和应用负载均衡技术。
102 2
|
1月前
|
运维 负载均衡 算法
|
2月前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo:微服务通信的高效解决方案
【10月更文挑战第15天】随着信息技术的发展,微服务架构成为企业应用开发的主流。Spring Cloud Dubbo结合了Dubbo的高性能RPC和Spring Cloud的生态系统,提供高效、稳定的微服务通信解决方案。它支持多种通信协议,具备服务注册与发现、负载均衡及容错机制,简化了服务调用的复杂性,使开发者能更专注于业务逻辑的实现。
74 2
|
4月前
|
Dubbo Java 应用服务中间件
💥Spring Cloud Dubbo火爆来袭!微服务通信的终极利器,你知道它有多强大吗?🔥
【8月更文挑战第29天】随着信息技术的发展,微服务架构成为企业应用开发的主流模式,而高效的微服务通信至关重要。Spring Cloud Dubbo通过整合Dubbo与Spring Cloud的优势,提供高性能RPC通信及丰富的生态支持,包括服务注册与发现、负载均衡和容错机制等,简化了服务调用管理并支持多种通信协议,提升了系统的可伸缩性和稳定性,成为微服务通信领域的优选方案。开发者仅需关注业务逻辑,而无需过多关心底层通信细节,使得Spring Cloud Dubbo在未来微服务开发中将更加受到青睐。
90 0
|
1月前
|
负载均衡 算法 Java
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
89 5
|
2月前
|
负载均衡 Kubernetes 区块链
随机密码生成器+阿里k8s负载均衡型服务加证书方法+移动终端设计+ico生成器等
随机密码生成器+阿里k8s负载均衡型服务加证书方法+移动终端设计+ico生成器等
64 1
|
3月前
|
消息中间件 存储 Java
SpringCloud基础9——服务异步通信-高级篇
消息可靠性、死信交换机、惰性队列、MQ集群
SpringCloud基础9——服务异步通信-高级篇
|
3月前
|
负载均衡 Java Nacos
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
|
4月前
|
存储 设计模式 缓存
OpenFeign集成Ribbon负载均衡-过滤和选择服务核心实现
该文章主要介绍了如何在OpenFeign中集成Ribbon以实现负载均衡,并详细分析了Ribbon中服务选择和服务过滤的核心实现过程。文章还涉及了Ribbon中负载均衡器(ILoadBalancer)和负载均衡策略(IRule)的初始化方式。
OpenFeign集成Ribbon负载均衡-过滤和选择服务核心实现