前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >微服务之间的通信的方式

微服务之间的通信的方式

作者头像
端碗吹水
发布于 2020-09-24 03:16:36
发布于 2020-09-24 03:16:36
83100
代码可运行
举报
运行总次数:0
代码可运行

RestTemplate的三种使用方式

SpringCloud中服务之间的两种调用RESTful接口通信的方式:

  1. RestTemplate
  2. Feign

RestTemplate是一个Http客户端,类似于HTTPClient,org但比HTTPClient更简单。我们通过RestTemplate来简单演示一下服务之间的调用,我们使用两个服务来做演示。一个商品服务,一个订单服务。首先创建一个商品服务工程:

选择相应的依赖:

项目创建完成后,编辑配置文件,需要配置服务的名称以及服务注册中心的地址:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring:
  application:
    name: product

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

注:如果对eureka还不太清楚的话,可以参考我的另一篇关于eureka的文章:Spring Cloud Eureka-服务注册与发现

不要忘了在启动类中,加上@EnableEurekaClient注解:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package org.zero.example.product;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class ProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class, args);
    }
}

接着创建一个controller类,用于模拟商品列表接口,提供给订单服务调用。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package org.zero.example.product.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @program: product
 * @description: product demo
 * @author: 01
 * @create: 2018-09-06 22:09
 **/
@RestController
@RequestMapping("/product")
public class ProductController {

    /**
     * 模拟商品列表接口
     *
     * @return product list
     */
    @GetMapping("/list")
    public List<String> list() {
        List<String> productList = new ArrayList<>();
        productList.add("肥皂");
        productList.add("可乐");

        return productList;
    }
}

然后启动项目,启动完成后,此时,在eureka的信息面板上应该可以看到product注册上去了,如下:


商品服务准备好后,使用同样的步骤创建order项目,这里就不再赘述了。配置文件中除了服务名称需为order,其他的配置项和product一样。因为8080已经被product服务占用了,所以还需要手动设置一下项目的端口号:

新建一个ClientController类,我们来看看RestTemplate的第一种使用方式,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package org.zero.example.order.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @program: order
 * @description: order demo
 * @author: 01
 * @create: 2018-09-06 22:24
 **/
@RestController
@RequestMapping("/order")
public class OrderController {

    @GetMapping("/info")
    public List info() {
        // 1.第一种方式,直接使用。缺点:需要指定url地址,不灵活,也无法适应多个地址
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject("http://localhost:8080/product/list", List.class);
    }
}

写完后启动项目,可以看到order服务也注册到eureka上了:

接口测试结果如下,可以看到成功调用了商品服务的接口:


然后是RestTemplate的第二种使用方式,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
...

import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;

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

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @GetMapping("/info")
    public List info() {
        // 2.第二种方式,借助LoadBalancerClient获取服务实例,缺点:需要拼接url依旧不灵活
        RestTemplate restTemplate = new RestTemplate();
        // 参数传的是服务注册的id
        ServiceInstance serviceInstance = loadBalancerClient.choose("PRODUCT");
        String url = String.format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort() + "/product/list");

        return restTemplate.getForObject(url, List.class);
    }
}

接着是RestTemplate的第三种使用方式,这种方式下我们需要先创建一个配置类,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package org.zero.example.order.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @program: order
 * @description: RestTemplate Config
 * @author: 01
 * @create: 2018-09-06 22:47
 **/
@Configuration
public class RestTemplateConfig {

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

然后在controller中注入使用,这种方式虽然最简洁,其实本质上还是第二种方式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
...
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/info")
    public List info() {
        // 3.第三种方式,利用@LoadBalanced注解,可在restTemplate里使用应用名称进行调用
        return restTemplate.getForObject("http://PRODUCT/product/list", List.class);
    }
}

负载均衡器:Ribbon

eureka是客户端发现机制的,所以使用的是客户端负载均衡器,所谓客户端负载均衡,也就是说负载的策略在客户端完成,俗称软负载。如果我们的商品服务部署在多个节点上的话,当使用Feign进行服务调用的时候,默认会使用Ribbon来做负载均衡。当然使用RestTemplate的时候也是可以结合Ribbon做负载均衡的,例如上一小节中演示的第二、三种使用RestTemplate的方式就是结合了Ribbon。

Ribbon是Netflix发布的负载均衡器,是一种客户端负载均衡器,运行在客户端上,它有助于控制HTTP和TCP的客户端的行为。为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。

我们在配置文件中可以自定义负载均衡策略,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PRODUCT:  # 服务的名称
  ribbon:  # 负载均衡器
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  # 规则完整的类名,这里使用的是随机

注:如非必须,一般使用默认的轮询策略即可

Ribbon特性:

  • 服务发现
  • 服务选择规则
  • 服务监听
  • ServerList,获取可用服务列表
  • IRule,选择最终调用,即负载策略
  • ServerListFilter,过滤不可用地址

在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。下图展示了Ribbon与Eureka配合使用时的架构:


Feign的使用

Feign是从Netflix中分离出来的轻量级项目,是一个声明式的REST客户端,它的出现使得我们在服务中编写REST客户端变得更加容易。利用 Feign 可以创建一个接口并对它进行注解,该接口就会具有可插拔的注解支持包括Feign注解与JAX-RS注解,Feign还支持可插拔的编码器与×××。Feign 灵感来源于Retrofit、JAXRS-2.0和WebSocket,Feign 最初是为了降低统一绑定 Denominator 到 HTTP API 的复杂度,不区分是否支持 Restful。

Spring Cloud 增加了对 Spring MVC的注解,Spring Web 默认使用了HttpMessageConverters, Spring Cloud 集成 Ribbon 和 Eureka 提供的负载均衡的HTTP客户端 Feign。

Feign特性:

  • 声明式REST客户端(伪RPC)
  • 采用了基于接口的注解
  • 同样使用ribbon做负载均衡器

接下来我们尝试一下使用Feign编写REST客户端,实现订单服务调用商品服务接口,看看Feign到底有多方便。在商品和订单服务的项目中,都加入Feign的依赖,pom.xml文件配置的依赖如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

注:若出现使用阿里云的仓库地址不能下载到该依赖的话,可以尝试使用maven中央仓库的地址进行下载

首先到商品服务工程中,新建一个client包。本来应该是新建一个Client模块的,但是为了方便演示,我就直接用包了。在client包下新建一个 ProductClinet 接口,编写代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package org.zero.example.product.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@Component
// 此注解用于声明一个Feign客户端,name属性指定服务的名称
@FeignClient(name = "PRODUCT")
public interface ProductClinet {

    /**
     * 商品列表接口,注意这里的uri要写全
     *
     * @return Product List
     */
    @GetMapping("/product/list")
    List<String> list();
}

我们在使用RestTemplate的时候,都是在订单服务上编写接口调用相关代码的,但是为什么使用Feign就在商品服务上去写这个代码呢?这是因为使用Feign的时候,只需要通过注解就能在接口上声明客户端,当我们在订单服务里面使用的时候,注入这个ProductClinet接口调用相应的方法即可实现商品服务接口的调用。而这些接口属于商品服务对外暴露的接口,由于职责的关系,所以都应该由商品服务去维护,不应该写在订单服务里。

编写好ProductClinet接口的代码后,使用如下命令将这个项目安装到本地的maven仓库中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mvn clean -Dmaven.test.skip=true install

接着到订单服务的工程中,加入商品服务的依赖,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
    <groupId>org.zero.example</groupId>
    <artifactId>product</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

然后在启动类中,加上@EnableFeignClients注解表示开启 Feign 客户端以及配置client包的路径,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package org.zero.example.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableEurekaClient
@SpringBootApplication
@EnableFeignClients(basePackages = "org.zero.example.product.client")
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

修改 OrderController 代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
...

import org.zero.example.product.client.ProductClinet;

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

    @Autowired
    private ProductClinet productClinet;

    @GetMapping("/info")
    public List info() {
        return productClinet.list();
    }
}

重启这两个项目,测试接口如下:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/09/07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
SpringCloud入门系列之微服务之间的通信
Ribbon作为消费者微服务一端,也会向注册中心进行注册,注册中心Eureka service会向消费者Ribbon提供当前注册的所有节点数据(url、端口)信息。然后根据轮循(默认)策略请求服务提供者。
AI码真香
2022/09/13
7880
SpringCloud(三)-应用间通信(慕课网廖师兄SpringCloud微服务实战)
1. RestTemplate直连消费服务 核心依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--HttpClient--> <dependency> <groupId>org.ap
Meet相识
2018/09/12
1.8K0
SpringCloud(三)-应用间通信(慕课网廖师兄SpringCloud微服务实战)
springcloud微服务架构开发实战:常见微服务的消费者
本节就常见的微服务的消费者进行介绍。在Java领域比较常用的消费者框架主要有HttpClient、Ribbon、Feign 等。
愿天堂没有BUG
2022/10/28
2560
springcloud微服务架构开发实战:常见微服务的消费者
Spring-Boot:Spring Cloud构建微服务架构
概述:   从上一篇博客《Spring-boot:5分钟整合Dubbo构建分布式服务》 过度到Spring Cloud,我们将开始学习如何使用Spring Cloud 来搭建微服务。继续采用上一篇博客
九灵
2018/03/09
2.2K0
Spring-Boot:Spring Cloud构建微服务架构
微服务(七)——OpenFeign服务调用
官方文档:https://cloud.spring.io/spring-cloud-static/Hoxton.SR1/reference/htmlsingle/#spring-cloud-openfeign
不愿意做鱼的小鲸鱼
2022/09/26
3950
微服务(七)——OpenFeign服务调用
SpringCloud 服务调用
​ https://github.com/Netflix/ribbon/wiki/Getting-Started
OY
2022/03/17
3880
SpringCloud 服务调用
Spring Cloud Ribbon原理、算法策略、示例代码及与Feign的关系
Spring Cloud Ribbon是Spring Cloud中一个基于HTTP和TCP客户端的负载均衡工具,它可以在分布式系统中基于Netflix Ribbon库实现客户端侧的负载均衡。 原理: 1. 当一个服务消费端需要调用服务提供端时,Ribbon会根据用户自定义的规则(如轮询、随机、最少并发数等)从服务注册中心获取到该服务的所有实例列表。 2. 然后,Ribbon在本地维护了这些服务实例的元数据信息,并根据选择的负载均衡策略,在每次请求时动态地选择一个服务实例进行通信。 算法及策略: 1. 轮询(Round Robin):默认策略,将请求均匀分发到每个服务器,即使服务器的处理速度有差异,也会均等地对待所有的服务器。 2. 随机(Random):随机选择一台服务器。 3. 权重响应时间加权轮询(Weighted Response Time):根据服务器处理请求的时间长短和服务权重进行选择,响应时间越长的服务器被选中的概率越低,权重越高的服务器被选中的概率越高。 4.区域可用性优先(Availability Filtered):先过滤掉由于多次访问故障而处于断路器跳闸状态的服务实例,然后根据轮询策略选择。 5. 自定义策略:通过IRule接口可以自定义负载均衡策略,实现更复杂的逻辑,如根据服务器性能、网络状况等因素动态调整。 使用过程中,可以在配置文件中指定负载均衡策略,例如: yaml
用户7353950
2024/06/18
2860
Spring Cloud Ribbon原理、算法策略、示例代码及与Feign的关系
【Spring底层原理高级进阶】微服务 Spring Cloud 的注册发现机制:Eureka 的架构设计、服务注册与发现的实现原理,深入掌握 Ribbon 和 Feign 的用法 ️
Eureka是Spring Cloud中的一个服务注册和发现组件,它采用了客户端-服务器的架构设计。
苏泽
2024/03/01
5900
springcloud3-服务到服务调用ribbon及openfeign
1,课程回顾 2,本章重点 ribbon (负载均衡器)如何实现服务到服务的调用 feign 服务到服务的调用 3,具体内容 3.1 ribbon 3.1.1 概念 Ribbon是一种客户端负载平衡器,可让您对HTTP和TCP客户端的行为进行大量控制(借助spring封装类RestTemplate,所有的入参,请求URL及出参数都是自己配置)。Feign已使用Ribbon,因此,如果使用@FeignClient,则本节也适用。 Ribbon中的中心概念是指定客户的概念。每个负载均衡器都是组件的一部分,这些组件可以一起工作以按需联系远程服务器,并且该组件具有您作为应用程序开发人员提供的名称(指定远程调用的服务名称,例如,使用@FeignClient批注)。根据需要,Spring Cloud通过使RibbonClientConfiguration为每个命名的客户端创建一个新的集合作为ApplicationContext。其中包含ILoadBalancer,RestClient和ServerListFilter。
用户9184480
2024/12/13
1110
springcloud3-服务到服务调用ribbon及openfeign
SpringCloud服务间通信方式
接下来在整个微服务架构中,我们比较关心的就是服务间的服务改如何调用,有哪些调用方式? 总结:在springcloud中服务间调用方式主要是使用 http restful方式进行服务间调用 1. 1基于
用户4283147
2022/10/27
4550
SpringCloud服务间通信方式
Spring Cloud【Finchley】实战-03订单微服务与商品微服务之间的调用
访问 http://localhost:8081/order/getServerInfoFromClient
小小工匠
2021/08/17
5470
SpringCloud 微服务分布式 笔记(二)
微服务在消费远程API时总是使用本地缓存中的数据。 因此一般来说,即使Eureka Server发生宕机,也不会影响到服务之间的调用。
Java_慈祥
2024/08/06
1650
SpringCloud 微服务分布式 笔记(二)
Nacos Discovery--服务治理
先来思考一个问题 通过上一章的操作,我们已经可以实现微服务之间的调用。但是我们把服务提供者的网络地址 (ip,端口)等硬编码到了代码中,这种做法存在许多问题:
用户10196776
2022/11/22
7160
Nacos Discovery--服务治理
微服务(六)——Ribbon负载均衡服务调用
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
不愿意做鱼的小鲸鱼
2022/09/26
3240
微服务(六)——Ribbon负载均衡服务调用
微服务学习计划——SpringCloud
在学习并掌握了众多基础框架之后,我们的项目繁杂且难以掌握,那么我们就需要开启一门新的课程,也就是我们常说的微服务架构
秋落雨微凉
2023/03/08
6510
微服务学习计划——SpringCloud
一起来学Spring Cloud(F版) | 第二篇:Ribbon软负载
Ribbon 是 Netflix 开源的基于 HTTP 和 TCP 的客户端负载均衡器框架,目前也已被 SpringCloud 团队集成在 spring-cloud-netflix 子项目下,主要用于客户端软负载功能,内部已实现了 随机、 轮询、 权重、 减压(选取压力最小的) 等常见的负载算法,同时也提供了 ILoadBalance 与 IRule 两个接口方便我们自己编写适合自己的负载算法
battcn
2018/10/18
5440
一起来学Spring Cloud(F版) | 第二篇:Ribbon软负载
Spring-Cloud微服务实战(五)-Feign应用通信
Feign是声明式的Web服务客户端。它使编写Web服务客户端更加容易。要使用Feign,请创建一个接口并添加注解。它支持可插拔的注解,包括Feign注解和JAX-RS(Java API for RESTful Web Services)注解。
JavaEdge
2021/02/22
4120
Nacos Discovery--服务治理
通过上一章的操作,我们已经可以实现微服务之间的调用。但是我们把服务提供者的网络地址(ip,端 口)等硬编码到了代码中,这种做法存在许多问题:
IT小马哥
2021/02/01
1.2K0
Nacos Discovery--服务治理
Spring Cloud微服务技术栈(五):客户端负载均衡Spring Cloud Ribbon部分源码分析
为了使客户端具备负载均衡的能力,我们在代码中将RestTemplate交给Spring管理的时候,会加上@LoadBalanced注解,如下代码所示:
itlemon
2020/04/03
6810
Spring Cloud微服务技术栈(五):客户端负载均衡Spring Cloud Ribbon部分源码分析
Ribbon负载均衡
文章目录 1、Ribbon基础知识 2、Ribbon服务调用 2.1 项目中引入依赖 2.2 查看consul client中依赖的ribbon 2.3 启动consul服务注册中心 2.4 将订单服务进行注册 2.5 将RestTemplate交给Spring工厂去管理 2.6 使用RestTemplate+ribbon进行服务调用 2.6.1 使用discovery client形式调用 2.6.2 使用LoadBalancerClient形式调用 2.6.3 使用 @LoadBalanced注解
别团等shy哥发育
2023/02/25
3600
Ribbon负载均衡
推荐阅读
相关推荐
SpringCloud入门系列之微服务之间的通信
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文