什么是 SpringCloud

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

SpringCloud 与 SpringBoot 的关系

  $\color{green}{Spring Boot 是 Spring 的一套快速配置脚手架,可以基于 Spring Boot 快速开发单个微服务,}$ $\color{blue}{Spring Cloud 是一个基于 Spring Boot 实现的云应用开发工具;Spring Boot 专注于快速、方便 集成的单个微服务个体,Spring Cloud 关注全局的服务治理框架,}$Spring Boot 使用了默认大 于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置,Spring Cloud 很大的 一部分是基于 Spring Boot 来实现,可以不基于 Spring Boot 吗?不可以。 $\color{red}{Spring Boot 可以离开 Spring Cloud 独立使用开发项目,但是 Spring Cloud 离不开 Spring Boot,属于依赖的关系。}$

SpringCloud 主要框架

  • 服务发现——Netflix Eureka
  • 服务调用——Netflix Feign
  • 熔断器——Netflix Hystrix
  • 服务网关——Netflix Zuul
  • 分布式配置——Spring Cloud Config
  • 消息总线 —— Spring Cloud Bus

SpringCloud 与 Dubbo 对比

  或许很多人会说 Spring Cloud 和 Dubbo 的对比有点不公平,Dubbo 只是实现了服务治理,而 Spring Cloud 下面有 17 个子项目(可能还会新增)分别覆盖了微服务架构下的方方面面,服 务治理只是其中的一个方面,一定程度来说,Dubbo 只是 Spring CloudNetflix 中的一个子集。
alt springCloud与dubbo比较

说说 SpringCloud 的版本

  我们目前课程采用的 SpringCloud 版本为 Finchley.M9 。你可能会觉得这个版本怎么这么奇 怪?SpringCloud 由于是一系列框架组合,为了避免与包含的自框架版本产生混淆,采用伦 敦地铁站的名称作为版本名,形式为版本名+里程碑号。 M9 为第 9 个里程碑版本。以下是 SpringBoot 与 Spring Cloud 版本的对照表,大家看看有没有找到什么规律呢? alt springcloud版本

服务发现组件 Eureka

  Eureka 是 Netflix 开发的服务发现框架,SpringCloud 将它集成在自己的子项目 spring-cloud-netflix 中,实现 SpringCloud 的服务发现功能。Eureka 包含两个组件: Eureka Server 和 Eureka Client。

  Eureka Server 提供服务注册服务,各个节点启动后,会在 Eureka Server 中进行注 册,这样 EurekaServer 中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信 息可以在界面中直观的看到。

  Eureka Client 是一个 java 客户端,用于简化与 Eureka Server 的交互,$\color{blue}{客户端同时也就别 一个内置的、使用轮询(round-robin)负载算法的负载均衡器。}$$\color{blue}{在应用启动后,将会向 Eureka Server 发送心跳,默认周期为 30 秒,}$如果 Eureka Server 在多个心跳周期内没有接收到某个节 点的心跳,Eureka Server 将会从服务注册表中把这个服务节点移除(默认 90 秒)。

  $\color{blue}{Eureka Server 之间通过复制的方式完成数据的同步,}$Eureka 还提供了客户端缓存机制, 即使所有的 Eureka Server 都挂掉,客户端依然可以利用缓存中的信息消费其他服务的 API。 综上,$\color{green}{Eureka 通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。}$

建议Eureka Server

引入依赖
父工程

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M9</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

Eureka Server


    <!--eureka-server-->
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

application.yml配置

1
2
3
4
5
6
7
8
server:
  port: 6868 #服务端口
eureka:
  client:
    registerWithEureka: false #是否将自己注册到 Eureka 服务中,本身就是服务无需注册
    fetchRegistry: false #是否从 Eureka 中获取注册信息
    serviceUrl: #Eureka 客户端与 Eureka 服务端进行交互的地址
     defaultZone: http://127.0.0.1:${server.port}/eureka/

启动器

1
2
3
4
5
6
7
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer.class, args);
    }
}

主界面中 system status 为系统信息 General Info 为一般信息 Instances currentlyregistered with Eureka 为注册到的所有微服务列表

服务注册(Eureka Client)

我们现在就将所有的微服务都注册到 Eureka 中,这样所有的微服务之间都可以互相调用了 将其他微服务模块添加依赖

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

修改每个微服务的 application.yml,添加注册 eureka 服务的配置

1
2
3
4
5
6
eureka:
	client:
		service‐url:
			defaultZone: http://localhost:6868/eureka
	instance:
		prefer‐ip‐address: true

修改每个服务类的启动类,添加注解

1
@EnableEurekaClient

启动测试:将每个微服务启动起来,会发现 eureka 的注册列表中可以看到这些微服务了。

保护模式

如果在 Eureka Server 的首页看到以下这段提示,则说明 Eureka 已经进入了保护模式:
  Eureka Server 在运行期间,会统计心跳失败的比例在 15 分钟之内是否低于 85%,如果出现 低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳定导 致),Eureka Server 会将当前的实例注册信息保护起来,同时提示这个警告。保护模式主要 用于一组客户端和 Eureka Server 之间存在网络分区场景下的保护。一旦进入保护模式, Eureka Server 将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据(也就是 不会注销任何微服务)。

Feign 实现服务间调用

  Feign 是简化 Java HTTP 客户端开发的工具(java-to-httpclient-binder),它的灵感 来自于 Retrofit、JAXRS-2.0 和 WebSocket。Feign 的初衷是降低统一绑定 Denominator 到 HTTP API 的复杂度,不区分是否为 restful。

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

启动器

1
2
@EnableDiscoveryClient
@EnableFeignClients

创建接口,并重写需要调用的服务的具体方法

1
2
3
4
5
@FeignClient("tensquare-base")
public interface LabelClient {
@RequestMapping(value="/label/{id}", method = RequestMethod.GET)
public Result findById(@PathVariable("id") String id);
}

@FeignClient 注解用于指定从哪个服务中调用功能 ,注意 里面的名称与被调用的服务 名保持一致,并且不能包含下划线。

@RequestMapping 注解用于对被调用的微服务进行地址映射。注意 @PathVariable 注 解一定要指定参数名称,否则出错。
调用并实现该方法

1
2
3
4
5
6
7
@Autowired
private LabelClient labelClient;
@RequestMapping(value = "/label/{labelid}")
public Result findLabelById(@PathVariable String labelid){
Result result = labelClient.findById(labelid);
return result;
}

负载均衡

同时开启多个微服务,看是否是轮流调用
启动微服务后,修改端口和输出信息,再次启动微服务