https://blog.csdn.net/weixin_43591980/article/details/106255122#t4

Spring Cloud 五大组件

  • 服务注册与发现——Netflix Eureka
  • 负载均衡:

    1. 客户端负载均衡——Netflix Ribbon<br /> 服务端负载均衡:——Feign(其也是依赖于Ribbon,只是将调用方式RestTemplete 更改成Service 接口)
  • 断路器——Netflix Hystrix

  • 服务网关——Netflix Zuul
  • 分布式配置——Spring Cloud Config

    什么是微服务?

  • 微服务是一种架构风格

  • 一个应用拆分为一组小型服务
  • 每个服务运行在自己的进程内,也就是可独立部署和升级
  • 服务之间使用轻量级HTTP交互
  • 服务围绕业务功能拆分
  • 可以由全自动部署机制独立部署
  • 去中心化,服务自治。服务可以使用不同的语言、不同的存储技术

    微服务优缺点

    优点

  • 单一职责原则;

  • 每个服务足够内聚,足够小,代码容易理解,这样能聚焦一个指定的业务功能或业务需求;
  • 开发简单,开发效率高,一个服务可能就是专一的只干一件事;
  • 微服务能够被小团队单独开发,这个团队只需2-5个开发人员组成;
  • 微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的;
  • 微服务能使用不同的语言开发;
  • 易于和第三方集成,微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如jenkins,Hudson,bamboo;
  • 微服务易于被一个开发人员理解,修改和维护,这样小团队能够更关注自己的工作成果,无需通过合作才能体现价值;
  • 微服务允许利用和融合最新技术;
  • 微服务只是业务逻辑的代码,不会和HTML,CSS,或其他的界面混合;
  • 每个微服务都有自己的存储能力,可以有自己的数据库,也可以有统一的数据库

    缺点

  • 开发人员要处理分布式系统的复杂性;

  • 多服务运维难度,随着服务的增加,运维的压力也在增大;
  • 系统部署依赖问题;
  • 服务间通信成本问题;
  • 数据一致性问题;
  • 系统集成测试问题;
  • 性能和监控问题

    微服务技术栈

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

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

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

      SpringCloud入门概述

      SpringCloud和SpringBoot的关系

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

    Dubbo 和 SpringCloud技术选型

    1. 分布式+服务治理Dubbo

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

    2. Dubbo 和 SpringCloud对比

    | | Dubbo | SpringCloud | | —- | —- | —- | | 服务注册中心 | Zookeeper | Spring Cloud Netfilx Eureka | | 服务调用方式 | RPC | REST API | | 服务监控 | Dubbo-monitor | Spring Boot Admin | | 断路器 | 不完善 | Spring Cloud Netfilx Hystrix | | 服务网关 | 无 | Spring Cloud Netfilx Zuul | | 分布式配置 | 无 | Spring Cloud Config | | 服务跟踪 | 无 | Spring Cloud Sleuth | | 消息总栈 | 无 | Spring Cloud Bus | | 数据流 | 无 | Spring Cloud Stream | | 批量任务 | 无 | Spring Cloud Task |

最大区别:Spring Cloud 抛弃了Dubbo的RPC通信,采用的是基于HTTP的REST方式
Dubbo的定位是一款RPC框架,而SpringCloud的目标是微服务架构下的一站式解决方案。

SpringCloud能干嘛

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

    SpringCloud Rest学习环境搭建:服务提供者

    介绍

  • 我们会使用一个Dept部门模块做一个微服务通用案例Consumer消费者(Client)通过REST调用Provider提供者(Server)提供的服务。

  • 回顾Spring,SpringMVC,Mybatis等以往学习的知识。
  • Maven的分包分模块架构复习 ```xml 一个简单的Maven模块结构是这样的:

— app-parent: 一个父项目(app-parent)聚合了很多子项目(app-util\app-dao\app-web…) |— pom.xml | |— app-core ||—— pom.xml | |— app-web ||—— pom.xml

  1. 一个父工程带着多个Moudule子模块<br />MicroServiceCloud父工程(Project)下初次带着3个子模块(Module)
  2. - microservicecloud-api 【封装的整体entity/接口/公共配置等】
  3. - microservicecloud-consumer-dept-80 【服务提供者】
  4. - microservicecloud-provider-dept-8001 【服务消费者】
  5. <a name="wiCPi"></a>
  6. #### 创建父工程
  7. - 新建父工程项目springcloud,切记**Packageingpom模式**
  8. - 主要是定义POM文件,将后续各个子模块公用的jar包等统一提取出来,类似一个抽象父类
  9. ![20200521130052880.png](https://cdn.nlark.com/yuque/0/2021/png/25363273/1637377786413-601f81fb-6412-4e97-8a5a-1f1ff09291dc.png#clientId=udea2075f-620d-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=uc975763d&margin=%5Bobject%20Object%5D&name=20200521130052880.png&originHeight=148&originWidth=435&originalType=binary&ratio=1&rotation=0&showTitle=false&size=12371&status=done&style=none&taskId=u912b711b-a2b4-4acd-9182-82264c3e83c&title=)
  10. <a name="HSmLL"></a>
  11. #### pom.xml
  12. ```xml
  13. <?xml version="1.0" encoding="UTF-8"?>
  14. <project xmlns="http://maven.apache.org/POM/4.0.0"
  15. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  16. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  17. <modelVersion>4.0.0</modelVersion>
  18. <groupId>com.haust</groupId>
  19. <artifactId>springcloud</artifactId>
  20. <version>1.0-SNAPSHOT</version>
  21. <modules>
  22. <module>springcloud-api</module>
  23. <module>springcloud-provider-dept-8001</module>
  24. <module>springcloud-consumer-dept-80</module>
  25. <module>springcloud-eureka-7001</module>
  26. <module>springcloud-eureka-7002</module>
  27. <module>springcloud-eureka-7003</module>
  28. <module>springcloud-provider-dept-8002</module>
  29. <module>springcloud-provider-dept-8003</module>
  30. <module>springcloud-consumer-dept-feign</module>
  31. <module>springcloud-provider-dept-hystrix-8001</module>
  32. <module>springcloud-consumer-hystrix-dashboard</module>
  33. <module>springcloud-zuul-9527</module>
  34. <module>springcloud-config-server-3344</module>
  35. <module>springcloud-config-client-3355</module>
  36. <module>springcloud-config-eureka-7001</module>
  37. <module>springcloud-config-dept-8001</module>
  38. </modules>
  39. <!--打包方式 pom-->
  40. <packaging>pom</packaging>
  41. <properties>
  42. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  43. <maven.compiler.source>1.8</maven.compiler.source>
  44. <maven.compiler.target>1.8</maven.compiler.target>
  45. <junit.version>4.12</junit.version>
  46. <log4j.version>1.2.17</log4j.version>
  47. <lombok.version>1.16.18</lombok.version>
  48. </properties>
  49. <dependencyManagement>
  50. <dependencies>
  51. <dependency>
  52. <groupId>org.springframework.cloud</groupId>
  53. <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  54. <version>0.2.0.RELEASE</version>
  55. <type>pom</type>
  56. <scope>import</scope>
  57. </dependency>
  58. <!--springCloud的依赖-->
  59. <dependency>
  60. <groupId>org.springframework.cloud</groupId>
  61. <artifactId>spring-cloud-dependencies</artifactId>
  62. <version>Greenwich.SR1</version>
  63. <type>pom</type>
  64. <scope>import</scope>
  65. </dependency>
  66. <!--SpringBoot-->
  67. <dependency>
  68. <groupId>org.springframework.boot</groupId>
  69. <artifactId>spring-boot-dependencies</artifactId>
  70. <version>2.1.4.RELEASE</version>
  71. <type>pom</type>
  72. <scope>import</scope>
  73. </dependency>
  74. <!--数据库-->
  75. <dependency>
  76. <groupId>mysql</groupId>
  77. <artifactId>mysql-connector-java</artifactId>
  78. <version>5.1.47</version>
  79. </dependency>
  80. <dependency>
  81. <groupId>com.alibaba</groupId>
  82. <artifactId>druid</artifactId>
  83. <version>1.1.10</version>
  84. </dependency>
  85. <!--SpringBoot 启动器-->
  86. <dependency>
  87. <groupId>org.mybatis.spring.boot</groupId>
  88. <artifactId>mybatis-spring-boot-starter</artifactId>
  89. <version>1.3.2</version>
  90. </dependency>
  91. <!--日志测试~-->
  92. <dependency>
  93. <groupId>ch.qos.logback</groupId>
  94. <artifactId>logback-core</artifactId>
  95. <version>1.2.3</version>
  96. </dependency>
  97. <dependency>
  98. <groupId>junit</groupId>
  99. <artifactId>junit</artifactId>
  100. <version>${junit.version}</version>
  101. </dependency>
  102. <dependency>
  103. <groupId>log4j</groupId>
  104. <artifactId>log4j</artifactId>
  105. <version>${log4j.version}</version>
  106. </dependency>
  107. <dependency>
  108. <groupId>org.projectlombok</groupId>
  109. <artifactId>lombok</artifactId>
  110. <version>${lombok.version}</version>
  111. </dependency>
  112. </dependencies>
  113. </dependencyManagement>
  114. </project>

父工程为springcloud,其下有多个子mudule,详情参考完整代码了解
20200521130118985.png
springcloud-consumer-dept-80访问springcloud-provider-dept-8001下的controller使用REST方式
DeptConsumerController.java

  1. /**
  2. * @Auther: csp1999
  3. * @Date: 2020/05/17/22:44
  4. * @Description:
  5. */
  6. @RestController
  7. public class DeptConsumerController {
  8. /**
  9. * 理解:消费者,不应该有service层~
  10. * RestTemplate .... 供我们直接调用就可以了! 注册到Spring中
  11. * (地址:url, 实体:Map ,Class<T> responseType)
  12. * <p>
  13. * 提供多种便捷访问远程http服务的方法,简单的Restful服务模板~
  14. */
  15. @Autowired
  16. private RestTemplate restTemplate;
  17. /**
  18. * 服务提供方地址前缀
  19. * <p>
  20. * Ribbon:我们这里的地址,应该是一个变量,通过服务名来访问
  21. */
  22. private static final String REST_URL_PREFIX = "http://localhost:8001";
  23. //private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
  24. /**
  25. * 消费方添加部门信息
  26. * @param dept
  27. * @return
  28. */
  29. @RequestMapping("/consumer/dept/add")
  30. public boolean add(Dept dept) {
  31. // postForObject(服务提供方地址(接口),参数实体,返回类型.class)
  32. return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
  33. }
  34. /**
  35. * 消费方根据id查询部门信息
  36. * @param id
  37. * @return
  38. */
  39. @RequestMapping("/consumer/dept/get/{id}")
  40. public Dept get(@PathVariable("id") Long id) {
  41. // getForObject(服务提供方地址(接口),返回类型.class)
  42. return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
  43. }
  44. /**
  45. * 消费方查询部门信息列表
  46. * @return
  47. */
  48. @RequestMapping("/consumer/dept/list")
  49. public List<Dept> list() {
  50. return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
  51. }
  52. }

使用RestTemplete先需要放入Spring容器中
ConfigBean.java

  1. @Configuration
  2. public class ConfigBean {//@Configuration -- spring applicationContext.xml
  3. //配置负载均衡实现RestTemplate
  4. // IRule
  5. // RoundRobinRule 轮询
  6. // RandomRule 随机
  7. // AvailabilityFilteringRule : 会先过滤掉,跳闸,访问故障的服务~,对剩下的进行轮询~
  8. // RetryRule : 会先按照轮询获取服务~,如果服务获取失败,则会在指定的时间内进行,重试
  9. @Bean
  10. public RestTemplate getRestTemplate(){
  11. return new RestTemplate();
  12. }
  13. }

springcloud-provider-dept-8001的dao接口调用springcloud-api模块下的pojo,可使用在springcloud-provider-dept-8001的pom文件导入springcloud-api模块依赖的方式

  1. <!--我们需要拿到实体类,所以要配置api module-->
  2. <dependency>
  3. <groupId>com.haust</groupId>
  4. <artifactId>springcloud-api</artifactId>
  5. <version>1.0-SNAPSHOT</version>
  6. </dependency>

Eureka服务注册中心

什么是Eureka

  • Netflix在涉及Eureka时,遵循的就是API原则.
  • Eureka是Netflix的有个子模块,也是核心模块之一
  • Eureka是基于REST的服务,用于定位服务,以实现云端中间件层服务发现和故障转移,服务注册与发现对于微服务来说是非常重要的,有了服务注册与发现,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了,功能类似于Dubbo的注册中心,比如Zookeeper

    原理理解

    Eureka基本的架构

  • Springcloud 封装了Netflix公司开发的Eureka模块来实现服务注册与发现 (对比Zookeeper).

  • Eureka采用了C-S的架构设计,EurekaServer作为服务注册功能的服务器,他是服务注册中心.
  • 而系统中的其他微服务,使用Eureka的客户端连接到EurekaServer并维持心跳连接

20200521130157770.png

  • 和Dubbo架构对比

20201120091517323.png

  • Eureka 包含两个组件:Eureka Server 和 Eureka Client.
  • Eureka Server 提供服务注册,各个节点启动后,回在EurekaServer中进行注册,这样Eureka Server中的服务注册表中将会储存所有课用服务节点的信息,服务节点的信息可以在界面中直观的看到.
  • Eureka Client 是一个Java客户端,用于简化EurekaServer的交互,客户端同时也具备一个内置的,使用轮询负载算法的负载均衡器
  • 三大角色
    • Eureka Server:提供服务的注册与发现
    • Service Provider:服务生产方,将自身服务注册到Eureka中,从而使服务消费方能狗找到
    • Service Consumer:服务消费方,从Eureka中获取注册服务列表,从而找到消费服务

      EureKa自我保护机制

      好死不如赖活着

      一句话总结就是:
      某时刻某一个微服务不可用,eureka不会立即清理,依旧会对该微服务的信息进行保存!

      构建步骤

      1. eureka-server

  1. springcloud-eureka-7001 模块建立
  2. pom.xml 配置

    1. <!--导包~-->
    2. <dependencies>
    3. <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
    4. <!--导入Eureka Server依赖-->
    5. <dependency>
    6. <groupId>org.springframework.cloud</groupId>
    7. <artifactId>spring-cloud-starter-eureka-server</artifactId>
    8. <version>1.4.6.RELEASE</version>
    9. </dependency>
    10. <!--热部署工具-->
    11. <dependency>
    12. <groupId>org.springframework.boot</groupId>
    13. <artifactId>spring-boot-devtools</artifactId>
    14. </dependency>
    15. </dependencies>
  3. application.yml ```yaml server: port: 7001

Eureka配置

eureka: instance:

  1. # Eureka服务端的实例名字
  2. hostname: 127.0.0.1

client:

  1. # 表示是否向 Eureka 注册中心注册自己(这个模块本身是服务器,所以不需要)
  2. register-with-eureka: false
  3. # fetch-registry如果为false,则表示自己为注册中心,客户端的化为 ture
  4. fetch-registry: false
  5. # Eureka监控页面~
  6. service-url:
  7. defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
源码中Eureka的默认端口以及访问路径:<br />![20200521130439891.png](https://cdn.nlark.com/yuque/0/2021/png/25363273/1637800463424-c3fc8cfe-1f48-4e92-a519-933552469042.png#clientId=u5920f370-04b6-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=ua8a38e5c&margin=%5Bobject%20Object%5D&name=20200521130439891.png&originHeight=203&originWidth=953&originalType=binary&ratio=1&rotation=0&showTitle=false&size=34558&status=done&style=none&taskId=u297bd345-4fd5-4610-8bb1-2d4269f4143&title=)

4. 主启动类
```java
/**
 * @Auther: csp1999
 * @Date: 2020/05/18/10:26
 * @Description: 启动之后,访问 http://127.0.0.1:7001/
 */
@SpringBootApplication
// @EnableEurekaServer 服务端的启动类,可以接受别人注册进来~
@EnableEurekaServer
public class EurekaServer_7001 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_7001.class,args);
    }
}
  1. 启动成功后访问 http://localhost:7001/ 得到以下页面

20200521130420201.png

2. eureka-client

调整之前创建的springlouc-provider-dept-8001

  1. 导入Eureca依赖

    <!--Eureka依赖-->
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
    <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-eureka</artifactId>
     <version>1.4.6.RELEASE</version>
    </dependency>
    
  2. application中新增Eureca配置

    # Eureka配置:配置服务注册中心地址
    eureka:
    client:
     service-url:
       defaultZone: http://localhost:7001/eureka/
    
  3. 为主启动类添加@EnableEurekaClient注解

    /**
    * @Auther: csp1999
    * @Date: 2020/05/17/22:09
    * @Description: 启动类
    */
    @SpringBootApplication
    // @EnableEurekaClient 开启Eureka客户端注解,在服务启动后自动向注册中心注册服务
    @EnableEurekaClient
    public class DeptProvider_8001 {
     public static void main(String[] args) {
         SpringApplication.run(DeptProvider_8001.class,args);
     }
    }
    
  4. 先启动7001服务端后启动8001客户端进行测试,然后访问监控页http://localhost:7001/ 产看结果如图

20200521130507106.png

对比和Zookeeper区别

回顾CAP原则

  • RDBMS (MySQL\Oracle\sqlServer) ===> ACID
  • NoSQL (Redis\MongoDB) ===> CAP

    ACID是什么?

  • A (Atomicity) 原子性

  • C (Consistency) 一致性
  • I (Isolation) 隔离性
  • D (Durability) 持久性

    CAP是什么?

  • C (Consistency) 强一致性

  • A (Availability) 可用性
  • P (Partition tolerance) 分区容错性

    CAP理论的核心

    一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求
    根据CAP原理,将NoSQL数据库分成了满足CA原则,满足CP原则和满足AP原则三大类

  • CA:单点集群,满足一致性,可用性的系统,通常可扩展性较差

  • CP:满足一致性,分区容错的系统,通常性能不是特别高
  • AP:满足可用性,分区容错的系统,通常可能对一致性要求低一些

    Eureka比Zookeeper好在哪

    著名的CAP理论指出,一个分布式系统不可能同时满足C (一致性) 、A (可用性) 、P (容错性)
    由于分区容错性P再分布式系统中是必须要保证的,因此我们只能再A和C之间进行权衡

  • Zookeeper 保证的是 CP —> 满足一致性,分区容错的系统,通常性能不是特别高

  • Eureka 保证的是 AP —> 满足可用性,分区容错的系统,通常可能对一致性要求低一些

    Ribbon:负载均衡(基于客户端)

    负载均衡以及Ribbon

    Ribbon是什么?

    Spring Cloud Ribbon 是基于Netflix Ribbon 实现的一套客户端负载均衡的工具

    Ribbon能干嘛?

    负载均衡 (LoadBalancer) ,在微服务或分布式集群中经常用的一种应用
    负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA (高用)
    负载均衡简单分类:

  • 集中式LB

即在服务的提供方和消费方之间使用独立的LB设施,如Nginx(反向代理服务器),由该设施负责把访问请求通过某种策略转发至服务的提供方

  • 进程式 LB

将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一个合适的服务器。
Ribbon 就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址

集成Ribbon

springcloud-consumer-dept-80向pom.xml中添加Ribbon和Eureka依赖

<!--Ribbon-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
<!--Eureka: Ribbon需要从Eureka服务中心获取要拿什么-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>

在application.yml文件中配置Eureka

# Eureka配置
eureka:
  client:
    register-with-eureka: false # 不向 Eureka注册自己
    service-url: # 从三个注册中心中随机取一个去访问
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

主启动类加上@EnableEurekaClient注解,开启Eureka

//Ribbon 和 Eureka 整合以后,客户端可以直接调用,不用关心IP地址和端口号
@SpringBootApplication
@EnableEurekaClient //开启Eureka 客户端
public class DeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_80.class, args);

自定义Spring配置类:ConfigBean.java 配置负载均衡实现RestTemplate

@Configuration
public class ConfigBean {//@Configuration -- spring  applicationContext.xml

    @LoadBalanced //配置负载均衡实现RestTemplate
    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

修改conroller:DeptConsumerController.java

//Ribbon:我们这里的地址,应该是一个变量,通过服务名来访问
//private static final String REST_URL_PREFIX = "http://localhost:8001";
private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";

使用Ribbon实现负载均衡

20200521131315626.png
每次访问http://localhost/consumer/dept/list随机访问集群中某个服务提供者,这种情况叫做轮询,轮询算法在SpringCloud中可以自定义

@Configuration
public class ConfigBean {//@Configuration -- spring  applicationContext.xml

    /**
     * IRule:
     * RoundRobinRule 轮询策略
     * RandomRule 随机策略
     * AvailabilityFilteringRule : 会先过滤掉,跳闸,访问故障的服务~,对剩下的进行轮询~
     * RetryRule : 会先按照轮询获取服务~,如果服务获取失败,则会在指定的时间内进行,重试
     */
    @Bean
    public IRule myRule() {
        return new RandomRule();//使用随机策略
        //return new RoundRobinRule();//使用轮询策略
        //return new AvailabilityFilteringRule();//使用轮询策略
        //return new RetryRule();//使用轮询策略
    }
}

也可以自定义规则,在myRule包下自定义一个配置类MyRule.java,注意:该包不要和主启动类所在的包同级,要跟启动类所在包同级
MyRule.java

/**
 * @Auther: csp1999
 * @Date: 2020/05/19/11:58
 * @Description: 自定义规则
 */
@Configuration
public class MyRule {

    @Bean
    public IRule myRule(){
        return new MyRandomRule();//默认是轮询RandomRule,现在自定义为自己的
    }
}

主启动类开启负载均衡并指定自定义的MyRule配置类

//Ribbon 和 Eureka 整合以后,客户端可以直接调用,不用关心IP地址和端口号
@SpringBootApplication
@EnableEurekaClient
//在微服务启动的时候就能加载自定义的Ribbon类(自定义的规则会覆盖原有默认的规则)
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MyRule.class)//开启负载均衡,并指定自定义的规则
public class DeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_80.class, args);
    }
}

Feign:负载均衡(基于服务端)

Feign简介

Feign是声明式Web Service客户端,它让微服务之间的调用变得更简单,类似controller调用service。SpringCloud集成了Ribbon和Eureka,可以使用Feigin提供负载均衡的http客户端
只需要创建一个接口,然后添加注解即可~

Feign能干什么?

  • Feign旨在使编写Java Http客户端变得更容易
  • 前面在使用Ribbon + RestTemplate时,利用RestTemplate对Http请求的封装处理,形成了一套模板化的调用方法

    Feign默认集成了Ribbon

  • 利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡

  • 而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用

    Feign和Ribbon二者对比

    前者显现出面向接口编程特点,代码看起来更清爽
    Feign调用方式更符合我们之前在做SSM或者SprngBoot项目时,Controller层调用Service层的编程习惯