Spring Cloud 服务治理

1. Eureka

1.1 Eureka 简介

在这里插入图片描述

  • Eureka 是 Netflix 公司开源的一个服务注册与发现的组件
  • Eureka 和其他 Netflix 公司的服务组件(例如负载均衡、熔断器、网关等) 一起,被 Spring Cloud 社区整合为 Spring-Cloud-Netflix 模块。
  • Eureka 包含两个组件:Eureka Server (注册中心) 和 Eureka Client (服务提供者、服务消费者)。

1.2 Eureka 学习步骤

一、搭建 Provider 和 Consumer 服务。

  1. 打开 IDEA --> New Project --> Empty Project --> 填写 Project name

    在这里插入图片描述

  2. 选择 JDK

    在这里插入图片描述

  3. File --> New Module --> Maven --> 填写父工程信息

    在这里插入图片描述

  4. 删除 src 文件夹后,项目目录如下

    在这里插入图片描述

  5. 在父工程下,创建子模块 Provider 和 Consumer

    在这里插入图片描述

  6. 添加依赖

    spring-cloud-parent 的 pom 添加 spring-boot 父工程:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
    </parent>
    

    eureka-consumer 和 eureka-provider 添加 spring-boot 依赖:

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    

二、使用 RestTemplate 完成远程调用

RestTemplate 简介:

  1. Spring 提供的一种简单便捷的模板类,用于在 java 代码里访问 restful 服务。
  2. 其功能与 HttpClient 类似,但是 RestTemplate 实现更优雅,使用更方便。

步骤如下:

  1. 在 eureka-provider 中创建类

    启动类

    package com.zt.provider;
    
    @SpringBootApplication
    public class ProviderApp {
        public static void main(String[] args) {
            SpringApplication.run(ProviderApp.class, args);
        }
    }
    

    Controller

    package com.zt.provider.controller;
    
    /**
     * Goods Controller 服务提供方
     */
    @RestController
    @RequestMapping("/goods")
    public class GoodsController {
    
        @Autowired
        private GoodsService goodsService;
    
        @GetMapping("/findOne/{id}")
        public Goods findOne(@PathVariable("id") int id){
    
            Goods goods = goodsService.findOne(id);
    
            return goods;
        }
    }
    

    Service

    package com.zt.provider.service;
    
    /**
     * Goods 业务层
     */
    @Service
    public class GoodsService {
    
        @Autowired
        private GoodsDao goodsDao;
    
    
        /**
         * 根据id查询
         * @param id
         * @return
         */
        public Goods findOne(int id){
            return goodsDao.findOne(id);
        }
    }
    

    dao

    package com.zt.provider.dao;
    
    /**
     * 商品Dao
     */
    @Repository
    public class GoodsDao {
    
        public Goods findOne(int id){
            return new Goods(id,"华为手机",3999,10000);
        }
    }
    

    domain

    package com.zt.provider.domain;
    
    /**
     * 商品实体类
     */
    public class Goods {
    
        private int id;
        private String title;//商品标题
        private double price;//商品价格
        private int count;//商品库存
        
        // 构造方法 和 getter and setter 省略
    }
    

    application.yml

    server:
      port: 8000
    

    启动 eureka-provider,打开浏览器访问如下 url

    http://localhost:8000/goods/findOne/1
    
    {"id":1,"title":"华为手机","price":3999.0,"count":10000}
    
  2. 在 eureka-consumer 中创建类

    启动类

    package com.zt.consumer;
    
    @SpringBootApplication
    public class ConsumerApp {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApp.class, args);
        }
    }
    

    配置类

    @Configuration
    public class RestTemplateConfig {
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    

    Controller

    package com.zt.consumer.controller;
    
    /**
     * 服务的调用方
     */
    
    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @GetMapping("/goods/{id}")
        public Goods findGoodsById(@PathVariable("id") int id){
            /*
                //远程调用Goods服务中的findOne接口
                使用RestTemplate
                1. 定义Bean  restTemplate
                2. 注入Bean
                3. 调用方法
             */
    
            String url = "http://localhost:8000/goods/findOne/"+id;
            // 3. 调用方法
            Goods goods = restTemplate.getForObject(url, Goods.class);
    
            return goods;
        }
    }
    

    domain

    package com.zt.provider.domain;
    
    /**
     * 商品实体类
     */
    public class Goods {
    
        private int id;
        private String title;//商品标题
        private double price;//商品价格
        private int count;//商品库存
        
        // 构造方法 和 getter and setter 省略
    }
    

    application.yml

    server:
      port: 9000
    

    启动 eureka-consumer,打开浏览器访问如下 url

    http://localhost:9000/order/goods/1
    
    {"id":1,"title":"华为手机","price":3999.0,"count":10000}
    

    eureka-consumer 成功远程调用 eureka-provider,但如果此时 eureka-provider 的 url 发生变化,eureka-consumer 也要跟着变化,所以我们需要使用注册中心来解决耦合的问题

三、搭建 Eureka Server 服务。

  1. 创建 eureka-server 模块

    在这里插入图片描述

  2. 引入 SpringCloud 和 euraka-server 相关依赖

    在父工程的 pom 文件中引入 Spring Cloud 依赖

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
    </properties>
    
    <!--引入Spring Cloud 依赖-->
    <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>
    

    在 euraka-server 的 pom 文件中引入依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <!-- eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
    
  3. 完成 Eureka Server 相关配置

    启动类

    package com.zt.eureka;
    
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaApp {
        public static void main(String[] args) {
            SpringApplication.run(EurekaApp.class, args);
        }
    }
    

    application.yml

    server:
      port: 8761
    
    # eureka 配置
    # eureka 一共有 4 部分配置
    # 1. dashboard:eureka 的 web 控制台配置,默认开启 true
    # 2. server:eureka的服务端配置
    # 3. client:eureka的客户端配置
    # 4. instance:eureka的实例配置
    
    eureka:
      instance:
        hostname: localhost # 主机名
      client:
        service-url:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
    
        register-with-eureka: false # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要
        fetch-registry: false # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要
    
  4. 启动该模块,访问 Web 控制台

    http://localhost:8761
    

    Web 控制台组成部分:

    • System Status:系统状态信息

    • DS Replicas:Eureka 集群节点副本

    • Instances currently registered with Eureka:当前注册到 Eureka 的实例

    • General Info:一般信息

    • Instance Info:实例信息

    在这里插入图片描述

四、改造 Provider 和 Consumer 称为 Eureka Client,下面以 Provider 为例,Consumer 同样。

  1. 引 eureka-client 相关依赖

    <!-- eureka-client -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
  2. 完成 eureka client 相关配置

    启动类添加 EurekaClient 注解

    package com.zt.provider;
    
    @SpringBootApplication
    @EnableEurekaClient
    public class ProviderApp {
        public static void main(String[] args) {
            SpringApplication.run(ProviderApp.class, args);
        }
    }
    

    application.yml

    server:
      port: 8000
    
    eureka:
      instance:
        hostname: localhost # 主机名
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
    spring:
      application:
        name: eureka-provider # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径
    
  3. 启动测试

    在这里插入图片描述

五、Consumer 服务 通过从 Eureka Server 中抓取 Provider 地址完成远程调用

  1. 修改 Controller

    package com.zt.consumer.controller;
    
    /**
     * 服务的调用方
     */
    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private DiscoveryClient discoveryClient;
    
        @GetMapping("/goods/{id}")
        public Goods findGoodsById(@PathVariable("id") int id){
            /*
                动态从Eureka Server 中获取 provider 的 ip 和端口
                 1. 注入 DiscoveryClient 对象.激活
                 2. 调用方法
             */
    
            //演示discoveryClient 使用
            List<ServiceInstance> instances = discoveryClient.getInstances("EUREKA-PROVIDER");
    
            //判断集合是否有数据
            if(instances == null || instances.size() == 0){
                //集合没有数据
                return null;
            }
    
            ServiceInstance instance = instances.get(0);
            String host = instance.getHost();//获取ip
            int port = instance.getPort();//获取端口
    
            String url = "http://"+host+":"+port+"/goods/findOne/"+id;
            // 3. 调用方法
            Goods goods = restTemplate.getForObject(url, Goods.class);
    
            return goods;
        }
    }
    
  2. 启动类添加服务发现注解

    package com.zt.consumer;
    
    @SpringBootApplication
    @EnableEurekaClient
    @EnableDiscoveryClient
    public class ConsumerApp {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApp.class, args);
        }
    }
    
  3. 启动 eureka-consumer,打开浏览器访问如下 url

    http://localhost:9000/order/goods/1
    
    {"id":1,"title":"华为手机","price":3999.0,"count":10000}
    

1.3 Eureka 相关配置及特性

eureka 一共有 4 部分配置:

  • server : eureka 的服务端配置

    eureka:
      server:
        #是否开启自我保护机制,默认true
        enable-self-preservation:
        #清理间隔(单位毫秒,默认是60*1000)
        eviction-interval-timer-in-ms:
    
  • client : eureka 的客户端配置

    eureka:
      client:
        service-url:
             # eureka服务端地址,将来客户端使用该地址和eureka进行通信
             defaultZone: 
        register-with-eureka: # 是否将自己的路径 注册到eureka上。
        fetch-registry: # 是否需要从eureka中抓取数据。
    
  • instance : eureka 的实例配置

    eureka:
      instance:
        hostname: localhost # 主机名
        prefer-ip-address: # 是否将自己的ip注册到eureka中,默认false 注册 主机名
        ip-address: # 设置当前实例ip
        instance-id:  # 设置控制台显示的实例id
        lease-renewal-interval-in-seconds: 30 # 每一次eureka client 向 eureka server发送心跳的时间间隔
        lease-expiration-duration-in-seconds: 90 # 如果90秒内eureka server没有收到eureka client的心跳包,则剔除该服务
    
  • dashboard : eureka 的 web 控制台配置

    eureka:
      dashboard:
        enabled: true # 是否启用eureka web控制台
        path: / # 设置eureka web控制台默认访问路径
    

1.4 Eureka 自我保护机制

自我保护背景

默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与 Eureka Server 之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制

自我保护机制

官方对于自我保护机制的定义:自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使 Eureka 集群更加的健壮、稳定的运行。

自我保护机制的工作机制是:如果在 15 分钟内超过 85% 的客户端节点都没有正常的心跳,那么 Eureka 就认为客户端与注册中心出现了网络故障,Eureka Server 自动进入自我保护机制

此时会出现以下几种情况:

  1. Eureka Server 不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
  2. Eureka Server 仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可用。
  3. 当网络稳定时,当前 Eureka Server 新的注册信息会被同步到其它节点中。

因此 Eureka Server 可以很好的应对因网络故障导致部分节点失联的情况,而不会像 ZK 那样如果有一半不可用的情况会导致整个集群不可用而变成瘫痪。

开发环境中如果要实现服务失效能自动移除,只需要修改以下配置。

  1. 注册中心关闭自我保护机制,修改检查失效服务的时间。

    eureka:
      server:
         enable-self-preservation: false
         eviction-interval-timer-in-ms: 3000
    
  2. 微服务修改减短服务心跳的时间。

    # 默认90秒
    lease-expiration-duration-in-seconds:  10
    
    # 默认30秒
    lease-renewal-interval-in-seconds:  3
    

    以上配置建议在生产环境使用默认的时间配置。

1.5 Eureka 高可用

高可用:服务一直对外提供,一直可用。单机肯定无法实现高可用,所以需要搭建 Eureka 集群才能实现高可用。

在这里插入图片描述

搭建高可用步骤:

  1. 准备两个 Eureka Server

    在这里插入图片描述

  2. 分别进行配置,相互注册

    eureka-server1:

    server:
      port: 8761
    
    eureka:
      instance:
        hostname: eureka-server1 # 主机名
      client:
        service-url:
          defaultZone: http://eureka-server2:8762/eureka
        register-with-eureka: false # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要
        fetch-registry: false # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要
    spring:
      application:
        name: eureka-server-ha
    

    eureka-server2:

    server:
      port: 8762
    
    eureka:
      instance:
        hostname: eureka-server2 # 主机名
      client:
        service-url:
          defaultZone: http://eureka-server1:8762/eureka
        register-with-eureka: false # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要
        fetch-registry: false # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要
    spring:
      application:
        name: eureka-server-ha
    

    修改 host 文件

    # My hosts
    127.0.0.1 eureka-server1
    127.0.0.1 eureka-server2
    

    分别访问 url,它们相互都是副本

    http://localhost:8761/
    http://localhost:8762/
    

    在这里插入图片描述

  3. Eureka Client 分别注册到这两个 Eureka Server 中

    修改 Provider 的 application.yml

    server:
      port: 8001
    
    eureka:
      instance:
        hostname: localhost # 主机名
      client:
        service-url:
          defaultZone: http://eureka-server1:8761/eureka,http://eureka-server2:8762/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
    spring:
      application:
        name: eureka-provider # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径
    

    修改 Consumer 的 application.yml

    server:
      port: 9000
    
    eureka:
      instance:
        hostname: localhost # 主机名
      client:
        service-url:
          defaultZone: http://eureka-server1:8761/eureka,http://eureka-server2:8762/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
    spring:
      application:
        name: eureka-consumer # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径
    
    
  4. 启动后测试,如果功能正常,就任意关掉一个 eureka-server,再次测试功能是否正常,如果还是正常则高可用搭建成功。

2. Consul

2.1 Consul 简介

  • Consul 是由 HashiCorp 基于 Go 语言开发的,支持多数据中心,分布式高可用的服务发布和注册服务软件,因为是软件,所以需要先进行安装。
  • 用于实现分布式系统的服务发现与配置。
  • 使用起来也较为简单。具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署 。
  • 官网地址: https://www.consul.io

2.2 Consul 安装运行

  1. 进入官网下载 Consul,解压后就一个 consul.exe 执行文件

    在这里插入图片描述

  2. 启动 Consul,打开 cmd 输入下面命令

    .\consul.exe agent -dev
    
  3. 访问 Consul 控制台

    在这里插入图片描述

2.3 Consul 快速入门

在这里插入图片描述

  1. 搭建 Provider 和 Consumer 服务,和上面未改造 Provider 和 Consumer 为 Eureka Client 之前的微服务保持一致。

    在这里插入图片描述

  2. 将 Provider 服务注册到 Consul 中。

    添加 Consul 依赖

    <dependencies>
        <!--consul 客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
    

    添加 application.yml

    server:
      port: 8000
    spring:
      cloud:
        consul:
          host: localhost # consul 服务端的 ip
          port: 8500 # consul 服务端的端口 默认8500
          discovery:
            service-name: ${spring.application.name} # 当前应用注册到consul的名称
            prefer-ip-address: true # 注册ip
    
      application:
        name: consul-provider # 应用名称
    
  3. Consumer 服务通过从 Consul 中抓取 Provider 地址完成远程调用

    添加 Consul 依赖和 application.yml 同上

    使用 Consul 完成远程调用和 Eureka 中一模一样,代码如下:

    package com.zt.consumer.controller;
    
    /**
     * 服务的调用方
     */
    
    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private DiscoveryClient discoveryClient;
    
        @GetMapping("/goods/{id}")
        public Goods findGoodsById(@PathVariable("id") int id){
            System.out.println("findGoodsById..."+id);
    
    
            /*
                //远程调用Goods服务中的findOne接口
                使用RestTemplate
                1. 定义Bean  restTemplate
                2. 注入Bean
                3. 调用方法
             */
    
            /*
                动态从Eureka Server 中获取 com.zt.provider 的 ip 和端口
                 1. 注入 DiscoveryClient 对象.激活
                 2. 调用方法
    
    
             */
    
            //演示discoveryClient 使用
            List<ServiceInstance> instances = discoveryClient.getInstances("CONSUL-PROVIDER");
    
            //判断集合是否有数据
            if(instances == null || instances.size() == 0){
                //集合没有数据
                return null;
            }
    
            ServiceInstance instance = instances.get(0);
            String host = instance.getHost();//获取ip
            int port = instance.getPort();//获取端口
    
            System.out.println(host);
            System.out.println(port);
    
            String url = "http://"+host+":"+port+"/goods/findOne/"+id;
            // 3. 调用方法
            Goods goods = restTemplate.getForObject(url, Goods.class);
    
    
            return goods;
        }
    }
    
  4. 启动 Provider 和 Consumer 服务,进行测试

    在这里插入图片描述

    打开浏览器访问如下 url

    http://localhost:9000/order/goods/1
    
    {"id":1,"title":"华为手机","price":3999.0,"count":10000}
    

3. Nacos

3.1 Nacos 简介

  • Nacos(Dynamic Naming and Configuration Service) 是阿里巴巴2018年7月开源的项目。
  • 它专注于服务发现和配置管理领域 致力于帮助您发现、配置和管理微服务。Nacos 支持几乎所有主流类型的“服务”的发现、配置和管理。
  • 一句话概括就是Nacos = Spring Cloud注册中心 + Spring Cloud配置中心。
  • 官网:https://nacos.io/
  • 下载地址: https://github.com/alibaba/nacos/releases

3.2 Nacos 安装运行

  1. 进入官网下载 Nacos,解压后进到 bin 目录

    D:\nacos-server\nacos\bin
    
  2. 打开 cmd 输入下面命令,以单机模式启动

    startup.cmd -m standalone
    
  3. 访问 Nacos 控制台,登录名密码都为 Nacos

    http://localhost:8848/nacos/
    

    在这里插入图片描述

3.3 Nacos 快速入门

  1. 搭建 Provider 和 Consumer 服务,和上面未改造 Provider 和 Consumer 为 Eureka Client 之前的微服务保持一致。

  2. 将 Provider 服务注册到 Nacos 中。

    添加 Nacos 依赖

    <dependencies>
        <!--nacos-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.2.2.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.1.0</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
    

    添加 application.yml

    server:
      port: 8000
    
    spring:
      cloud:
        nacos:
          discovery:
            server-addr:  localhost:8848 # 配置nacos 服务端地址
      application:
        name: nacos-provider # 服务名称
    
  3. Consumer 服务通过从 Nacos 中抓取 Provider 地址完成远程调用

    添加 Nacos 依赖和 application.yml 同上

    使用 Nacos 完成远程调用和 Eureka 中一模一样,代码如下:

    package com.zt.consumer.controller;
    
    /**
     * 服务的调用方
     */
    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private DiscoveryClient discoveryClient;
    
        @GetMapping("/goods/{id}")
        public Goods findGoodsById(@PathVariable("id") int id){
            System.out.println("findGoodsById..."+id);
    
    
            /*
                //远程调用Goods服务中的findOne接口
                使用RestTemplate
                1. 定义Bean  restTemplate
                2. 注入Bean
                3. 调用方法
             */
    
            /*
                动态从Eureka Server 中获取 com.zt.provider 的 ip 和端口
                 1. 注入 DiscoveryClient 对象.激活
                 2. 调用方法
    
    
             */
    
            //演示discoveryClient 使用
            List<ServiceInstance> instances = discoveryClient.getInstances("nacos-provider");
    
            //判断集合是否有数据
            if(instances == null || instances.size() == 0){
                //集合没有数据
                return null;
            }
    
            ServiceInstance instance = instances.get(0);
            String host = instance.getHost();//获取ip
            int port = instance.getPort();//获取端口
    
            System.out.println(host);
            System.out.println(port);
    
            String url = "http://"+host+":"+port+"/goods/findOne/"+id;
            // 3. 调用方法
            Goods goods = restTemplate.getForObject(url, Goods.class);
    
    
            return goods;
        }
    }
    
  4. 启动 Provider 和 Consumer 服务,进行测试

    在这里插入图片描述

    打开浏览器访问如下 url

    http://localhost:9000/order/goods/1
    
    {"id":1,"title":"华为手机","price":3999.0,"count":10000}
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bm1998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值