SpringCloud(一、快速入门微服务和搭建Eureka集群)

内容概述

spring cloud 入门
初识 Spring Cloud
Spring Cloud 服务治理【掌握】
负载均衡Ribbon【掌握】

一、初识 Spring Cloud-微服务架构

疑问: 什么是微服务?有什么用?

分析:

系统演变:

在这里插入图片描述
演变的原因是由于项目的内容越来越复杂,开发的人员越来越多,项目访问的并发度越来越高。

什么是微服务?

• "微服务”一词源于 Martin Fowler的名为 Microservices的博文,可以在他的官方博客上找到
http://martinfowler.com/articles/microservices.html

• 微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务之间一般通过 HTTP 的 RESTfuLAPI 进行通信协作。

有什么用?解决什么问题?什么时候用?

• 被拆分成的每一个小型服务都围绕着系统中的某一项或某些耦合度较高的业务功能进行构建,并且每个服务都维护着自身的数据存储、业务开发自动化测试案例以及独立部署机制。
• 由于有了轻量级的通信协作基础,所以这些微服务可以使用不同的语言来编写。

总结:
​ 解决互联网大型项目的开发,测试,部署,运维问题。

dubbo和springcloud之间的区别?

两项技术,都是用于微服务(不同的服务)之间进行调用。
dubbo: RPC协议,效率高,只支持JAVA。
springcloud: HTTP协议,支持各种语言,更加灵活。

二、初识 Spring Cloud-初识 Spring Cloud

疑问:spring cloud是什么?能为我们做什么?

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

spring cloud能为我们做什么?
Spring 公司将其他公司中微服务架构常用的组件整合起来,并使用 SpringBoot 简化其开发、配置。称为 Spring Cloud
spring cloud的版本信息
​ Spring Cloud 版本命名方式采用了伦敦地铁站的名称,同时根据字母表的顺序来对应版本时间顺序,比如:最早的Release版本:Angel,第二个Release版本:Brixton,然后是Camden、Dalston、Edgware,Finchley,Greenwich,Hoxton。
目前最新的是Hoxton版本。
我们课程学习的版本Greenwich,使用spring cloud就要使用和他对应的spring boot的版本。

三、初识 Spring Cloud-Spring Cloud 与 Dubbo 对比

面试题:

Spring Cloud 与 Dubbo 都可以完成微服务的搭建,它们有什么区别?面试题

分析:
• Spring Cloud 与 Dubbo 都是实现微服务有效的工具。

• Dubbo 只是实现了服务治理,而 Spring Cloud 子项目分别覆盖了微服务架构下的众多部件。

• Dubbo 使用 RPC 通讯协议,Spring Cloud 使用 RESTful 完成通信,Dubbo 效率略高于 Spring Cloud。

• Dubbo只能用于JAVA工程之间的微服务搭建。Spring Cloud对调用方无要求.

总结:
• 微服务就是将项目的各个模块拆分为可独立运行、部署、测试的架构设计风格。
• Spring 公司将其他公司中微服务架构常用的组件整合起来,并使用 SpringBoot 简化其开发、配置。称为 Spring Cloud
• Spring Cloud 与 Dubbo都是实现微服务有效的工具。Dubbo 性能更好,而 Spring Cloud 功能更全面。

四、Spring Cloud 服务治理-Eureka介绍

疑问:
​ 服务治理就是注册中心?那么Spring Cloud使用什么软件作为注册中心?

分析:
微服务之间相互调用需要知道对方服务器的IP和端口,服务治理就是管理各个服务的地址和状态。

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

五、Spring Cloud 服务治理-Eureka快速入门-环境搭建

步骤:

  1. 搭建 Provider 和 Consumer 服务。
  2. 使用 RestTemplate 完成远程调用。
  3. 搭建 Eureka Server 服务。
  4. 改造 Provider 和 Consumer 称为 Eureka Client。
  5. Consumer 服务 通过从 Eureka Server 中抓取 Provider
    地址 完成 远程调用

总结:
​ Provider 和 Consumer 服务就是使用spring boot搭建的普通应用。
​ 为了保证Provider 和 Consumer 服务基于相同的实体对象,一般会抽成新模块,双方都依赖。
​ 微服务比较小,内容单一,内部不对外暴漏信息。所以可以不用接口。通过HTTP的方式对外提供服务。

六、Spring Cloud 服务治理-Eureka快速入门-RestTemplate远程调用

疑问:
​ Consumer 如何调用Provider 服务?
​ 使用RestTemplate

分析:

  1. 配置RestTemplate

    @Configuration
    public class RestTemplateConfig {
    
    
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    
  2. 注入RestTemplate并远程调用

    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @GetMapping("/goods/{id}")
        public Goods findGoodsById(@PathVariable("id") int id){
            System.out.println("findGoodsById..."+id);
            String url = "http://localhost:8000/goods/findOne/"+id;
            Goods goods = restTemplate.getForObject(url, Goods.class);
        }
    }
    

总结:
​ RestTemplate的方法:

//发送get请求
//url: 请求的url
//Goods.class : 将返回的JSON自动转换成对象 
Goods goods = restTemplate.getForObject(url, Goods.class);

//  发送post请求
//第二个参数:Object类型 param ,将该对象转为JSON作为请求体的内容发送
Goods goods = restTemplate.postForObject(url,param,Goods.class);

七、Spring Cloud 服务治理-Eureka快速入门-Eureka Server搭建

疑问:
​ 远程调用的服务器IP和端口都是写死的,如果环境发生变化怎么办?

分析:
​ 搭建Eureka Server,注册中心进行服务治理。

步骤:
① 创建 eureka-server 模块

   
	<parent>
        <artifactId>spring-cloud-parentartifactId>
        <groupId>com.itheimagroupId>
        <version>1.0-SNAPSHOTversion>
    parent>

② 引入 SpringCloud 和 euraka-server 相关依赖

    <dependencies>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
        dependency>
        
    dependencies>

③ 完成 Eureka Server 相关配置

server:
  port: 8761

# eureka 配置
# eureka 一共有4部分 配置
# 1. dashboard:eureka的web控制台配置
# 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 需要
  server:
    enable-self-preservation: false # 关闭自我保护机制
    eviction-interval-timer-in-ms: 3000 # 检查服务的时间间隔

④ 启动该模块

@SpringBootApplication
// 启用EurekaServer
@EnableEurekaServer
public class EurekaApp {

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

    }
}

八、Spring Cloud 服务治理-Eureka快速入门-Eureka控制台

疑问:
​ 如何查看Eureka注册中心?

分析:
​ 控制台地址: http://localhost:8761/

九、Spring Cloud 服务治理-Eureka快速入门-Eureka Client

疑问:
​ 搭建好了注册中心怎么使用?

不管是Provider 还是 Consumer都是Eureka Client。他们都是Eureka 的客户端。

分析:
搭建Eureka Client的步骤:
① 引 eureka-client 相关依赖

        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>

② 完成 eureka client 相关配置

server:
  port: 9000

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

③ 启动 测试

@EnableEurekaClient //该注解 在新版本中可以省略
@SpringBootApplication
public class ProviderApp {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApp.class,args);
    }
}

十、Spring Cloud 服务治理-Eureka快速入门-动态获取路径

疑问:
​ 现在Provider 和 Consumer都注册到Eureka 注册中心了,那么如何通过Eureka 来获取请求的路径。

分析:
在Consumer中动态获取Provider 的IP和端口:

  1. 启动类激活DiscoveryClient

    @EnableDiscoveryClient // 激活DiscoveryClient
    @EnableEurekaClient
    @SpringBootApplication
    public class ConsumerApp {
    
  2. controller注入DiscoveryClient

        @Autowired
        private DiscoveryClient discoveryClient;
    
  3. 根据配置的应用名称来动态获取IP和端口

    //演示discoveryClient 使用
    //参数就是配置文件中设置的
    /*  application.yml
    spring:
      application:
        name: eureka-provider
    */      
    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();//获取端口
    

总结:

  1. 搭建 Provider 和 Consumer 服务。
  2. 使用 RestTemplate 完成远程调用。
  3. 搭建 Eureka Server 服务。【重点】
  4. 改造 Provider 和 Consumer 称为 Eureka Client。【重点】
  5. Consumer 服务 通过从 Eureka Server 中抓取 Provider
    地址 完成 远程调用

十一、Spring Cloud 服务治理-Eureka属性-instance

疑问: Eureka的属性比较复杂,关于实例的配置。
注意:使用spring cloud就是为了快速搭建,框架设置的默认值都非常合理,一般在开发中并不修改。

分析:
​ Eureka默认注册主机名,但是如果不是局域网,我们希望将当前实例的IP地址注册到Eureka中。
​ prefer-ip-address
​ ip-address

配置:

eureka:
  instance:
    hostname: localhost # 主机名
    prefer-ip-address: true # 将当前实例的ip注册到eureka server 中。默认是false 注册主机名
    ip-address: 127.0.0.1 # 设置当前实例的ip
    instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port} # 设置web控制台显示的 实例id
    lease-renewal-interval-in-seconds: 3 # 每隔3 秒发一次心跳包
    lease-expiration-duration-in-seconds: 9 # 如果9秒没有发心跳包,服务器呀,你把我干掉吧~

十二、Spring Cloud 服务治理-Eureka属性-server

疑问: Eureka关于服务端的配置。
分析:
配置信息:

eureka:
  server:
    enable-self-preservation: false # 关闭自我保护机制
    eviction-interval-timer-in-ms: 3000 # 检查服务的时间间隔

自我保护机制

  1. Eureka作为注册中心,需要知道其中注册的应用的状态是否可用

  2. 客户端应用需要设置向注册中心Eureka发生心跳检查的时间,和超时删除应用的时间

    eureka:
      instance:
        lease-renewal-interval-in-seconds: 30 # 每隔30 秒发一次心跳包
        lease-expiration-duration-in-seconds: 90 # 如果90秒没有发心跳包,服务器呀,你把我干掉吧~
    
  3. 服务器设置了检查应用的时间间隔

    eureka:
      server:
        enable-self-preservation: false # 关闭自我保护机制
        eviction-interval-timer-in-ms: 3000 # 检查服务的时间间隔
    
  4. 开启保护机制

    Renews threshold    # 期望的心跳包数量,(n+1)*2*0.85  n表示实例数,只取整数
    Renews (last min)   # 实际收到的数量,根据lease-renewal-interval-in-seconds的设置
    
    期望的比实际的大,就会开启保护机制。
    
    1. 保护机制的目的

      1. 当注册中心忽然失去大量心跳,低于预期85%,为了保障服务的可用,进入自我保护状态,暂时不进行应用的移除。
      2. 当心跳恢复超过期望值,会退出自我保护状态,再次移除应用。

面试

什么是Eureka的自我保护机制?为什么要有这个机制?
​ Eureka中注册的应用,有超过15%的心跳没有被发送,他就进入自我保护状态。进入自我保护状态,不再剔除应用。
​ 避免网络波动的时候,删除了大量的正常应用。一次性的大量的应用被删除。

十三、Spring Cloud 服务治理-Eureka高可用-介绍

疑问:
​ 注册中心坏了,那么系统就无法使用了,所以要保证Eureka高可用,就是搭建Eureka集群。

分析:

  1. 准备两个Eureka Server
  2. 分别进行配置,相互注册
  3. Eureka Client 分别注册到这两个 Eureka Server中

十四、Spring Cloud 服务治理-Eureka高可用-搭建

疑问:
​ 如何来搭建Eureka集群?

分析:
各个注册中心Eureka相互注册。

搭建步骤:

  1. 创建两个Eureka server应用

  2. 配置

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

    hostname主机名不能一致,需要使用hosts配置为不同。

    defaultZone 为集群中其他Eureka server的地址,多个使用,逗号分隔。

    application.name应用名称要一致

  3. 修改hosts文件。C:\Windows\System32\drivers\etc

    127.0.0.1       eureka-server1
    127.0.0.1       eureka-server2
    
  4. 启动测试

十五、Spring Cloud 服务治理-Eureka高可用-客户端测试

看看集群的效果

客户端需要配置集群中所有Eureka的地址,使用,逗号分隔。

  client:
    service-url:
      defaultZone: http://eureka-server1:8761/eureka,http://eureka-server2:8762/eureka

十六、Spring Cloud 服务治理-Consul概述

疑问: spring could支持的其他注册中心软件?

分析:
​ consul有点类似zookeeper,需要我们自己运行服务。
解压consul_1.6.1_windows_amd64.zip
进入服务所在的目录,运行命令

.\consul agent -dev

控制台地址: http://localhost:8500/

十七、Spring Cloud 服务治理-Consul快速入门

疑问: consul作为注册中心,客户端如何配置并使用?

分析:

  1. 搭建 Provider 和 Consumer 服务。

            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-consul-discoveryartifactId>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-actuatorartifactId>
            dependency>
    
  2. 使用 RestTemplate 完成远程调用。(省略)

  3. 将Provider服务注册到Consul中。consumer调用方也要配,只需要改应用名。

    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 # 应用名称
    
  4. Consumer 服务 通过从 Consul 中抓取 Provider 地址 完成 远程调用

代码无需改动。注意设置实例的name不区分大小写.

discoveryClient.getInstances(“CONSUL-PROVIDER”);

  @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/goods/{id}")
    public Goods findGoodsById(@PathVariable("id") int id){
        //演示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;
    }

十八、Spring Cloud 服务治理-Nacos概述

国产注册中心
分析:

Nacos

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

使用步骤:

  1. 解压nacos-server-1.1.3.zip

  2. 运行nacos\bin\startup.cmd

  3. 进入控制台:http://localhost:8848/nacos

    账号,密码都是: nacos

十九、Spring Cloud 服务治理-Nacos快速入门

使用步骤:

  1. 搭建 Provider 和 Consumer 服务。

            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
                <version>0.2.2.RELEASEversion>
            dependency>
            <dependency>
                <groupId>com.alibaba.nacosgroupId>
                <artifactId>nacos-clientartifactId>
                <version>1.1.0version>
            dependency>
    
  2. 使用 RestTemplate 完成远程调用。(省略)

  3. 将Provider服务注册到Consul中。consumer调用方也要配,只需要改应用名。

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

    代码无需改动。注意设置实例的name不区分大小写.

    discoveryClient.getInstances(“nacos-provider”);

      @Autowired
        private DiscoveryClient discoveryClient;
    
        @GetMapping("/goods/{id}")
        public Goods findGoodsById(@PathVariable("id") int id){
            //演示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;
        }
    

二十、Spring Cloud负载均衡-Ribbon

疑问: 如果服务的提供端是集群,每次都访问第一个是不科学的。

分析:
负载均衡是一个算法,可以通过该算法实现从地址列表中获取一个地址进行服务调用。
在Spring Cloud中提供了负载均衡器:Ribbon
Ribbon提供了轮询、随机等负载均衡算法(默认是轮询)可以实现从地址列表中使用负载均衡算法获取地址进行服务调用。

面试

  1. Ribbon功能
    1. 化简远程调用的代码
    2. 客户端负载均衡
  2. 负载均衡
    1. 服务端
    2. 客户端

二十一、Spring Cloud负载均衡-Ribbon应用

需求:
通过服务名称,使用RestTemplate访问 http://user-service/user/8 获取服务数据。

实现步骤:

  1. 启动多个eureka-provider 实例(8001,8002);

    复制eureka-provider2

    修改pom.xml中的模块名:

SpringCloud(一、快速入门微服务和搭建Eureka集群)_第2张图片

修改application.yml中的端口号:
SpringCloud(一、快速入门微服务和搭建Eureka集群)_第3张图片
注意:两个应用的name一定要一致,这样才是集群。

修改dao,便于观察。
SpringCloud(一、快速入门微服务和搭建Eureka集群)_第4张图片

  1. 修改RestTemplate实例化方法,添加负载均衡注解;

    @Configuration
    public class RestTemplateConfig {
    
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    
    
  2. 修改ConsumerController;

        @GetMapping("/goods2/{id}")
        public Goods findGoodsById2(@PathVariable("id") int id){
            String url = "http://eureka-provider/goods/findOne/"+id;
    
            Goods goods = restTemplate.getForObject(url, Goods.class);
    
            return goods;
        }
    

    注意:服务器的地址就是应用服务的名称name.

  3. 测试

    http://localhost:9000/order/goods2/1

  4. 修改负载均衡策略

        @Bean
        public IRule myRule(){
            //return new RoundRobinRule();//轮询
            return new RandomRule();//随机
    
        }
    

你可能感兴趣的:(JavaEE框架)