SpringCloud系列SpringCloud概述及微服务技术栈的使用

Posted 一宿君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud系列SpringCloud概述及微服务技术栈的使用相关的知识,希望对你有一定的参考价值。

SpringCloud概述及微服务技术栈的使用

1、SpringCloud的简介

SpringCloud是一系列框架的有序集合。它利用SpringBoot的开发便利性巧妙地简化了分布式系统基础设置的开发,如服务发现与注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用SpringBoot的开发风格做到一键启动和部署。SpringCloud并没有重复制造轮子,它只是将目前各家公司开发比较成熟、经得起考研的服务框架组合起来,通过SpringBoot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者流下了一套简单易懂、易部署和易维护的分布式系统开发工具。

1.1、SpringCloud中的五大核心组件

Spring Cloud的本质是在SpringBoot的基础上,增加了一堆微服务相关的规范,并对应用上下文(ApplicationContext)进行功能增强,既然SpringCloud是规范,那么就需要去实现,目前Spring Cloud规范已有Spring官方,Spring Cloud Netflix,Spring Cloud Alibaba等是实现。 通过组件化的方式,Spring Cloud将这些实现整合到一起构成全家桶式的微服务技术栈。

SpringCloud Netflix组件

组件名称作用
Eureka服务注册中心
Ribbon客户端负载均衡
Feign声明式服务端调用(基于Ribbon,将调用方式RestTemplate,改为service接口调用)
Hystrix客户端容错报保护(熔断降级服务)
ZuulAPI服务网关

Spring Cloud Alibaba组件

组件名称作用
Nacos服务注册中心
Sentinel客户端容错保护

Spring Cloud原生及其他组件

组件作用
Consul(Eureka替代者)服务注册中心
Config分布式配置中心
Gateway(Zuul替代者)API服务网关
Sleuth分布式链路追踪

1.2、SpringCloud的架构


从上图可以看出SpringCloud各个组件的相互配合,合作支持了一套完整的微服务架构。

  • 注册中心: 负责服务的注册与发现,很好的将个服务连接起来
  • 断路器: 负责监控服务之间的调用情况,连续多次的失败,将进行熔断降级保护
  • API网关: 负责转发所有对外的请求和服务
  • 配置中心: 提供了统一的配置信息管理服务,可以实时的通知各个服务获取最新的配置信息
  • 链路追踪技术: 可以将所有的数据记录下来,方便我们进行后续分析
  • 各个组件又提供了功能完善的dashboard监控平台,可以当便的监控各组件的运行状况

1.3、微服务与微服务架构

微服务:

强调的是服务的大小,它关注的是某个一个点,是具体解决某一个问题/提供落地式对应服务的一个服务应用,狭义的看,可以看做是IDEA中的一个个微服务工程或者Moudle模块。IDEA工具里面使用Maven开发的一个个独立的Moudel,它具体是使用SpringBoot开发的一个小模块,专业的事情交给专业的模块来做,一个模块就做一件事情,强调的是一个个个体,每个个体完成一个具体的任务或者功能。

微服务架构:

一种新的架构形式,Martin Fowler于2014年提出。
微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间相互协调互相配合,为用户提供最终价值,每个服务运行在其独立的进程中,服务与服务之间采用轻量级的通信机制(如HTTP协议)互相协作,每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境中,另外,应尽量避免统一的,集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具(如maven)对其进行统一构建。

1.4、微服务技术栈概括

微服务技术条目技术支持
服务开发Spring、SpringBoot、SpringMVC
服务配置与管理Netflix公司的Archaius、阿里的Diamond等
服务注册与发现Eureka、Consul、Zookeeper
服务调用Rset、RPC、gRPC
服务熔断器Hystrix、Envoy等
负载均衡Ribbon、nginx
服务接口调用(客户端调用服务的简化工具)Feign等
消息队列RabbitMQ、ActiveMQ、Kafka等
服务配置中心管理SpringCLoudConfig、Chef等
服务路由(API网关)Zuul等
服务监控Zabbix、Nagios、Metrics、Specatator等
全链路追踪Zipkin、Brave、Dapper等
数据流操作开发包SpringCloud Stream(封装与Redis、Rabbit、Kafka等发送接收消息)
时间消息总栈SpringCloud Bus
服务部署Docker、OpenStack、Kuberneters等

1.5、为什么选择SpringCloud作为微服务架构?

选型一依据

  • 整体解决方案和框架成熟度
  • 社区热度
  • 可维护性
  • 学习曲线

当前各大IT公司用的微服务架构有哪些?

  • 阿里:dubbo+HFS
  • 京东:JFS
  • 新浪:Motan
  • 当当网:DubboX

1.6、SpringCloud与SpringBoot的关系

  • SpringBoot专注于快速方便的开发出当个个体微服务
  • SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务,整合并管理起来,为各个微服务之间提供:配置管理、服务发现、断路器、路由、代理、事件总栈、决策竞选、分布式会话等等集成服务
  • SpringBoot可以离开SpringCloud独立使用,开发项目,但是SpringCloud离不开SpringBoot,属于依赖关系

1.7、Dubbo和SpringCloud技术选型

1、分布式+服务治理Dubbo

  • 目前成熟的互联网架构,应用服务化拆分+消息中间件

2、Dubbo与SpringCloud对比
可以看一下社区活跃度:DubboSpringCloud

DubboSpringCloud
服务注册中心ZookeeperSpring Cloud Netflix Eureka
服务调用方式RPCREST API
服务监控Dubbo-monitorSpringBoot Admin
断路器不完善SpringCloud Netflix Hystrix
服务网关Spring Cloud Netflix Zuul
分布式配置Spring Cloud Config
服务追踪Spring Cloud Sleuth
消息总栈Spring Cloud Bus
数据流Spring Cloud Stream
批量任务Spring Cloud Task

两者最大的区别在于通信方式:
SpringCloud抛弃了Dubbo的RPC通信,采用的是基于轻量级HTTP协议的REST API方式。
严格来说,这两种方式各有优劣,在性能上RPC要优于REST,但是在灵活度上REST相比RPC是更灵活,服务提供方和调用方只需要一致契约,不存在代码级别的强依赖,这个优点在当下强调快速演化的微服务环境下,显得更加合适。

二者解决的问题域不同:Dubbo的定位是一款RPC框架,而SpringCloud的目标是微服务架构下的一站式解决方案。

1.8、SpringCloud可以做什么?

  • Distributed/Versioned configuration 分布式/版本控制系统
  • Service registration and discovery 服务注册与发现
  • Routing 路由
  • Service-to-service calls 服务到服务之间的调用
  • Load balancing 负载均衡策略
  • Circuit Breakers 断路器
  • Distributed messaging 分布式消息管理

1.9、SpringCloud官网下载

SpringCloud官网

SpringCloud没有采用数字编号的方式命名版本号,而是采用了伦敦地铁站的名称,同时根据字母表的顺序来对应版本时间顺序:

  • 最早的Realse版本:Angel,
  • 第二个Realse版本:Brixton,
  • 然后依次是Camden、Dalston、Edgware,
  • 目前最新的是Hoxton SR4 CURRENT GA通用稳定版。

1.10、SpringCloud版本选择

大版本说明

SpringBootSpringCloud关系
1.2XAngel版本兼容SpringBoot1.2X
1.3XBrixton版本(布里克斯顿)兼容SpringBoot1.3X,也兼容SpringBoot1.4X
1.4XCamden版本(卡姆登)兼容SpringBoot1.4X,也兼容SpringBoot1.5X
1.5XDalston版本(多尔斯顿)兼容SpringBoot1.5X,不兼容SpringBoot2.0X
1.5XEdgware版本(埃奇韦尔)兼容SpringBoot1.5X,不兼容SpringBoot2.0X
2.0XFinchley版本(芬奇利)不兼容SpringBoot1.5X ,兼容SpringBoot2.0X
2.1XGreenwich版本(格林威治)

实际开发版本关系

spring-boot-starter-parentspring-cloud-dependencies
版本号发布日期版本号发布日期
1.5.2.RELEASE2017-03Dalston.RC12017-x
1.5.9.RELEASE2017-11Edgware.RELEASE2017-11
1.5.16.RELEASE2018-04Edgware.SR52018-10
1.5.20.RELEASE2018-09Edgware.SR52018-10
2.0.2.RELEASE2018-05Fomchiey.BULD-SNAPSHOT2018-x
2.0.6.RELEASE2018-10Fomchiey-SR22018-10
2.1.4.RELEASE2019-04Greenwich.SR12019-03

2、基于Eureka注册中心的案例搭建与分析

SpringCloud系列(一)、服务注册中心Eureka基础【详细教程】

3、Eureka的替换方案Consul

Eureka的闭源影响

在Euraka的GitHub上,宣布Eureka 2.x闭源。近这意味着如果开发者继续使用作为 2.x 分支上现有工作repo 一部分发布的代码库和工件,风险则将自负。

Eureka的替换方案如下:

  • ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等
  • Consul是近几年比较流行的服务发现工具,工作中用到,简单了解一下。consul的三个主要应用场景:服务发现、服务隔离、服务配置
  • Nacos是阿里巴巴推出来的一个新开源项目,这是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

3.1、Consul概述


Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其它分布式服务注册与发现的方案,Consul 的方案更“一站式”,

  • 内置了服务注册与发现框 架
  • 分布一致性协议实现
  • 健康检查
  • Key/Value 存储
  • 多数据中心方案

不再需要依赖其它工具(比如 ZooKeeper 等),使用起来也较 为简单。Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。

3.2、Consul的优势

  • 使用Raft算法来保证一致性,比复杂的Paxoa算法更直接,相比较而言,Zookeeper采用的是Paxos,而etcd使用的则是Raft
  • 支持多数据中心,内外网的服务采用不同的端口监听。多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟,分片等情况,zookeeper和etcd均不提供多数据中心功能的支持
  • 支持健康检测,etcd不提供此功能
  • 支持HTTP和DNS协议接口。 zookeeper的继承较为复杂,etcd只支持http协议
  • 官方提供web管理界面,etcd无此功能
  • 综合比较,Consul作为服务注册和配置管理,比较值得关注和研究

Consul的特征:

  • 服务发现
  • 多数据中心
  • key/value存储
  • 健康检测

3.3、Consul与Eureka的区别

Consul具有强一致性(CP):

  • 服务注册相比Eureka会稍慢一些,因为Consul的Raft协议要求必须过半数的节点都写入成功才认为注册成功
  • Leader挂点后,重新选举期间整个Consul不可用,保证了强一致性,但牺牲了可用性

Eureka保证高可用性和最终一致性(AP):

  • 服务注册相对要快,因为不需要等注册信息replicate到其他节点上,也不保证注册信息是否replicate成功
  • 当数据出现不一致时,虽然A、B上的注册信息不完全相同,但每个Eureka节点依然能够正常对外提供服务,这会出现查询服务信息时,如果请求A查不到,但请求B可以查到(但内容不一定一致),如此保证了高可用性,但是牺牲了一致性

开发语言和使用:

  • Eureka就是个servlet程序,跑在servlet容器中
  • Consul则是go编写而成,安装启动即可

3.4、Consul的下载与安装

访问 Consul 官网下载 Consul 的最新版本,Consul 需要单独安装,我这里是consul1.5x。根据不同的系统类型选择不同的安装包,从下图也可以看出 Consul 支持所有主流系统。

在Linux虚拟机在中安装Consul服务:

## 从官网下载最新版本的Consul服务
wget https://releases.hashicorp.com/consul/1.5.3/consul_1.5.3_linux_amd64.zip
##使用unzip命令解压
unzip consul_1.5.3_linux_amd64.zip
##将解压好的consul可执行命令拷贝到/usr/local/bin目录下
cp consul /usr/local/bin
##测试一下
consul

启动Consul服务:

##已开发者模式快速启动,-client指定客户端可以访问的ip地址
[root@node01 ~]# consul agent -dev -client=0.0.0.0
==> Starting Consul agent...
     Version: 'v1.5.3'
     Node ID: '49ed9aa0-380b-3772-a0b6-b0c6ad561dc5'
    Node name: 'node01'
   Datacenter: 'dc1' (Segment: '<all>')
     Server: true (Bootstrap: false)
   Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600)
  Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
     Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false,
Auto-Encrypt-TLS: false

启动成功之后访问: http://IP地址:8500 ,可以看到 Consul 的管理界面:

我们此处暂时先使用windows下的版本启动Consul服务:从官网下载windows版本的zip,解压后免安装:

输入启动Consu命令:

#-client=0.0.0.0 是为了开放所有ip访问
consul agent -dev -client=0.0.0.0

启动之后,访问地址栏:localhost:8500

3.5、Consul的K/V存储

可以参照Consul提供的KV存储的 API完成基于Consul的数据存储

含义请求路径请求方式
查看keyv1/kv/:keyGET
保存或更新v1/kv/:keyPUT
删除v1/kv/:keyDELETE
  • key值中可以带/, 可以看做是不同的目录结构。
  • value的值经过了base64_encode加密,获取到数据后base64_decode解密才能获取到原始值。数据不能大于512Kb
  • 不同数据中心的kv存储系统是独立的,使用dc=?参数指定。

3.6、基于Consul的服务注册案例

工程配置仍然和Eureka保持一致(可做参考):
SpringCloud系列(一)、服务注册中心Eureka基础【详细教程】

ebuy-consul-parent(父模块)
---ebuy-consul-product(商品微服务)
---ebuy-consul-order(订单微服务)

修改商品和订单微服务模块的pom文件:

	<!--SpringCloud提供的基于Consul的服务发现-->
	<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
	<!--actuator用于心跳检查-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

配置服务注册
ebuy-consul-product的application.yml

server:
  port: 9011 #端口号

spring:
  application:
    name: ebuy-product #商品模块服务名称
  datasource:
    username: root #数据库用户名
    password: root #数据库密码
    driver-class-name: com.mysql.jdbc.Driver #mysql加载驱动
    url: jdbc:mysql://localhost:3306/ebuy?useUnicode=true&characterEncoding=utf8
  cloud:
    consul:
      host: 127.0.0.1 #指定consul服务地址
      port: 8500 #指定consul服务端口号
      discovery:
        register: true #是否注册
        instance-id: ${spring.application.name}-1 #指定实例id名
        server-name: ${spring.application.name} #服务实例名称
        port: ${server.port} #服务实例端口号
        health-check-path: /actuator/health  #健康检测路径
        health-check-interval: 15s #指定健康检测时间间隔
        prefer-ip-address: true #开启ip地址注册
        ip-address: ${spring.cloud.client.ip-address} #实例请求ip

#mybatis相关配置
mybatis:
  type-aliases-package: com.ebuy.product.pojo  #mybatis简化pojo实体类别名
  mapper-locations: com/ebuy/product/mapper/*.xml #mapper映射文件路径

#打印日志
logging:
  level:
    com.ebuy: DEBUG #日志级别

ebuy-consul-order的application.yml

server:
  port: 9013 #端口号
  address: 127.0.0.1
  tomcat:
    max-threads: 10 #最大线程数(默认为200台)

spring:
  application:
    name: ebuy-order #服务名
  cloud:
    consul:
      host: 127.0.0.1 #指定consul服务地址
      port: 8500 #指定consul服务端口号
      discovery:
        register: true #是否注册
        instance-id: ${spring.application.name}-1 #指定实例id名
        server-name: ${spring.application.name} #服务实例名称
        port: ${server.port} #服务实例端口号
        health-check-path: /actuator/health  #健康检测路径
        health-check-interval: 15s #指定健康检测时间间隔
        prefer-ip-address: true #开启ip地址注册
        ip-address: ${spring.cloud.client.ip-address} #实例请求ip
        health-check-url: http://${server.address}:${server.port}/**/health
        health-check-critical-timeout: 30s #check失败后,多少秒剔除该服务

#打印日志
logging:
  level:
    com.ebuy: DEBUG

其中 spring.cloud.consul 中添加consul的相关配置:

  • host:表示Consul的Server的请求地址
  • port:表示Consul的Server的端口
  • discovery:服务注册与发现的相关配置
    • instance-id : 实例的唯一id(推荐必填),spring cloud官网文档的推荐,为了保证生成一个唯一的id ,也可以换成${spring.application.name}:${spring.cloud.client.ipAddress}
    • prefer-ip-address:开启ip地址注册
    • ip-address:当前微服务的请求ip

启动两个微服务:查看Consul监控中心

基于微服务的发现:
由于SpringCloud对Consul进行了封装。对于在消费者端获取服务提供者信息和Eureka是一致的。同样使用 DiscoveryClient完成调用获取微服务实例信息,其余用法基本都和Eureka保持一致。

4、Ribbon:基于客户端服务调用(负载均衡)

经过以上的学习,已经实现了服务的注册和服务发现。当启动某个服务的时候,可以通过HTTP的形式将信息注册到注册中心,并且可以通过SpringCloud提供的工具获取注册中心的服务列表。但是服务之间的调用还存在很多的问题,如何更加方便的调用微服务,多个微服务的提供者如何选择,如何负载均衡等。

4.1、什么是Ribbon?

Ribbon是Netflix发布的一个负载均衡器,有助于控制HTTP和TCP客户端行为,在SpringCloud中,Eureka一般配合Ribbon进行使用,Ribbon提供了客户端负载均衡的功能,Ribbon利用从Eureka或者Consul中读取到的服务信息,在调用服务节点提供的服务时,会合理的进行负载,默认为轮询策略。

在SpringCloud中可以将注册信息和Ribbon配合使用,Ribbon自动的从注册中心获取服务提供者的列表信息,并基于内置的负载均衡算法,请求服务。

4.2、Ribbon的主要作用

客户端服务调用:

  • 基于Ribbon实现服务调用,是通过拉取到的所有服务列表组成(服务名:请求路径)的一种映射关系,借助于RestTemplate最终实现调用。

负载均衡:

  • 当有多个服务提供者时,Ribbon可以根据负载均衡的算法自动的选择需要调用的服务地址。

4.3、Ribbon的关键组件

  • ServerList:可以响应客户端的特定服务的服务器列表。
  • ServerListFilter:可以动态获得的具有所需特征的候选服务器列表的过滤器。
  • ServerListUpdater:用于执行动态服务器列表更新。
  • Rule:负载均衡策略,用于确定从服务器列表返回哪个服务器。
  • Ping:客户端用于快速检查服务器当时是否处于活动状态。
  • LoadBalancer:负载均衡器,负责负载均衡调度的管理。

4.4、工程改造

上述讲解了Consul替代Eureka,此处我们暂时先将注册中心改为Eureka注册,并配置两台注册中心集群:
application.yml(将8000注册到9000)互相注册,application.yml(将9000注册到8000)即可

server:
  port: 8000 #端口号

spring:
  application:
    name: eureka-server #eurekaServer服务名

eureka:
  #instance:
    #hostname: 127.0.0.1 #服务器ip地址
  client:
    register-with-eureka: true #是否将自己注册到注册中心
    #fetch-registry: false #是否从注册中心获取服务列表
    serviceUrl: #配置暴露给Eureka Client的请求地址
      defaultZone: http://127.0.0.1:9000/eureka/
  server:
    enable-self-preservation: false #关闭自我保护机制(一旦发现有网络不稳定的服务,直接剔除)
    eviction-interval-timer-in-ms: 4000 #剔除时间间隔,单位:毫秒
    #wait-time-in-ms-when-sync-empty: 5

服务提供者和消费者:修改application.yml文件中注册中心配置:

server:
  port: 90XX #端口号
  address: 127.0.0.1
  tomcat:
    max-threads: 10 #最大线程数(默认为200台)

spring:
  application:
    name: ebuy-XXXX #服务名
#  cloud:
#    consul:
#      host: 127.0.0.1 #指定consul服务地址
#      port: 8500 #指定consul服务端口号
#      discovery:
#        register: true #是否注册
#        instance-id: ${spring.application.name}-1 #指定实例id名
#        server-name: ${spring.application.name} #服务实例名称
#        port: ${server.port} #服务实例端口号
#        health-check-path: /actuator/health  #健康检测路径
#        health-check-interval: 15s #指定健康检测时间间隔
#        prefer-ip-address: true #开启ip地址注册
#        ip-address: ${spring.cloud.client.ip-address} #实例请求ip
#        health-check-url: http://${server.address}:${server.port}/**/health
#        health-check-critical-timeout: 30s #check失败后,多少秒剔除该服务

#使用eureka注册中心
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8000/eureka/,http://127.0.0.1:9000/eureka/
  instance:
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address: true   #使用ip地址注册(在注册中心显示名字以ip地址显示)
    lease-expiration-duration-in-seconds: 10 #eureka client发送心跳给eureka server服务端后,续约到期时间(默认为90秒)
    lease-renewal-interval-in-seconds: 5 #发送心跳续约时间间隔

#打印日志
logging:
  level:
    com.ebuy: DEBUG

4.5、服务调用Ribbon高级,什么是负载均衡?

在搭建网站时,如果节点的web服务性能和可靠性都无法达到要求,或者是在使用外网服务时,经常担心被人攻击,一不小心就会有打开外网端口的情况,通常这个时候加入负载均衡就能有效的解决服务访问问题。

负载均衡是一种基础的网络服务,其原理是通过运行在前面的负载均衡服务,按照指定的负载均衡算法,将流量分配到后端服务集群上,从而为系统提供并行扩展的能力。

负载均衡的应用场景包括流量包、转发规则以及后端服务,由于服务有内外网个例,健康检查等功能,能够有效提高系统的安全性和可靠性。

4.6、客户端负载均衡和服务端负载均衡

客户端负载均衡:

  • 客户端从注册中心会获取到一个服务提供者的服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这是客户端负载均衡,即在客户端就进行负载均衡算法分配。

服务端负载均衡:

  • 先发送请求到负载均衡服务器或软件,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端再进行服务在均衡算法分配

4.7、基于Ribbon实现负载均衡

首先要搭载多态服务器,上述已经搭建好Eureka注册中心的集群,然后再搭建两台ebuy-product和一台ebuy-order即可,如下:

1、服务提供者ebuy-product

服务提供者:修改ebuy-product模块下的ProductController#findById()方法:

@RestController
@RequestMapping("/product")
public class ProductController {

	/**
	 * 回去客户端ip地址
	 */
	@Value("${spring.cloud.client.ip-address}")
	private String ip;

	/**
	 * 获取客户端的端口号
	 */
	@Value("${server.port}")
	private String port;

	@Autowired
	private EasybuyProductService productService;

	@RequestMapping(value = "/{id}",method = RequestMethod.GET)
	public EasybuyProduct findById(@PathVariable Long id) {
		EasybuyProduct product = productService.selectByPrimaryKey(id);
		product.setEpDescription("调用ebuy-product服务,ip:"+ip+",服务提供者端口:"+port);
 		return product;
	}
}

ebuy-product服务提供者启动两台:9011,9012
ebuy-order服务消费者启动一台:9013

2、服务消费者ebuy-order

然后在ebuy-order的EbuyOrderApplication启动类处,创建RestTemplate方法,并添加@LoadBalanced注解实现与Ribbon搭配的负载均衡:

@SpringBootApplication
@EnableEurekaClient  //开启Eureka客户端服务注册
@EnableDiscoveryClient  //开启服务发现
public class EbuyOrderApplication {

    /**
     * @Bean 配置RestTemplate交给spring管理
     * @LoadBalanced 实现负载均衡(Ribbon原理)
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

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

在ebuy-order服务模块的OrderController下添加下单方法:

	@Autowired
    RestTemplate restTemplate;

    
    @RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
    public EasybuyProduct findById(@PathVariable Long id) {
        EasybuyProduct easybuyProduct=new EasybuyProduct();
        //easybuyProduct=restTemplate.getForObject("http://127.0.0.1:9011/product/"+id,EasybuyProduct.class);<

以上是关于SpringCloud系列SpringCloud概述及微服务技术栈的使用的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud学习系列-SpringCloud

SpringCloud系列SpringCloud概述及微服务技术栈的使用

SpringCloud系列教程汇总整理手册

从零开始,轻松搞定SpringCloud微服务系列

SpringCloud系列——网关springcloud gateway实战

SpringCloud系列SpringCloud微服务网关概述