SpringCloud及注册中心eureka

springcloud

目标

  • springcloud是什么
  • springcloud能解决什么问题
  • 了解springcloud版本
  • 理解微服务概念+SOA
  • 通过RestTemplate实现远程调用
  • springcloud eureka的组件(掌握)
  • springcloud ribbon的组件(掌握)
  • 实现微服务的调用
springboot是什么 基于spring的框架
springboot提高开发效率 减少配置 自动配置
springboot 配置(yml/properties)配置的方式  读取的方式@value environment @configurationProperties
springboot的环境切换 profile
springboot整合 Mybatis
springboot整合redis 
springboot整合junit
....
springboot部署war jar
springboot的自动配置原理
	+ 启动mian方法的时候
	+ 初始化,根据注解@springbootapplication注解进行自动配置
	+ 通过里面@EnableAutoConfiguration注解来实现自动配置
		+ 需要从META-INF/spring.factories 文件根据EnableAutoConfiguration的全路径作为key 加载 里面的所有的自动配置类的全路径
		+ 返回一个字符串数组给spring框架
		+ 根据字符串数组 加载配置对应配置类(根据各种条件注解实现不同的情况下的配置项)
		+ 将需要 的配置项配置好交给spring容器

单体架构

在这里插入图片描述

1、优点
	单一架构模式在项目初期很小的时候开发方便,测试方便,部署方便,运行良好
2、缺点
	- 应用随着时间的推进,加入的功能越来越多,最终会变得巨大,一个项目中很有可能数百万行的代码,互相之间繁琐的jar包。
	- 久而久之,开发效率低,代码维护困难
	- 还有一个如果想整体应用采用新的技术,新的框架或者语言,那是不可能的。
	- 任意模块的漏洞或者错误都会影响这个应用,降低系统的可靠性
总结:
	单体架构前期开发部署都很方便
	但是随着项目越来越大,维护麻烦,一个地方出错会导致整体不可用

微服务架构

在这里插入图片描述

1、优点
- 将服务拆分成多个单一职责的小的服务,进行单独部署,服务之间通过网络进行通信
- 每个服务应该有自己单独的管理团队,高度自治
- 服务各自有自己单独的职责,服务之间松耦合,避免因一个模块的问题导致服务崩溃
2、缺点
- 开发人员要处理分布式系统的复杂性
- 多服务运维难度,随着服务的增加,运维的压力也在增大
- 服务治理 和 服务监控 关键

总结:
	微服务 就是根据功能点将功能拆分成不同的系统,这个系统是独立的可以完成业务功能

有哪些问题需要解决:

1、微服务之间的通信如何解决?---》dubbo
2、并发量大的问题如何解决?---》集群
3、如何解决负载均衡的问题?---》nginx
4、如何解决登录的问题?---》spring session,spring security auth2.0 cas,shrio
5、服务过多 需要进行服务的治理 治理中心(注册中心)需要解决?--》zookeeper eureka nacos consule
6、日志管理如何解决?---》ELK
7、解决级联失败---》hystrix,sentinel 。。。

效率不高,兼容性不好。需要到处找,需要配置。
springcloud出现了。统统解决以上的问题。

1、注解
2、起步依赖
3、Enable**组件

1、springcloud简介

(1)SpringCloud介绍
Spring Boot擅长的是集成,把世界上最好的框架集成到自己项目中

Spring Cloud本身也是基于SpringBoot开发而来,SpringCloud是一系列框架的有序集合,也是把非常流行的微服务的技术整合到一起,是属于微服务架构的一站式技术解决方案。

Spring Cloud包含了:

注册中心:Eureka、consul、Zookeeper

负载均衡:Ribbon

熔断器:Hystrix

服务通信:Feign

网关:Gateway

配置中心 :config

消息总线:Bus

集群状态等等…功能。

Spring Cloud协调分布式环境中各个微服务,为各类服务提供支持。
在这里插入图片描述
(2)Spring Cloud的版本
在这里插入图片描述
版本说明:

SpringCloud是一系列框架组合,为了避免与框架版本产生混淆,采用新的版本命名方式,形式为大版本名+子版本名称
  大版本名用伦敦地铁站名
  子版本名称三种
    SNAPSHOT:快照版本,尝鲜版,随时可能修改
    M版本,MileStone,M1表示第一个里程碑版本,一般同时标注PRE,表示预览版
    SR,Service Release,SR1表示第一个正式版本,同时标注GA(Generally Available),稳定版

(3)SpringCloud与SpringBoot版本匹配关系

SpringBootSpringCloud
1.2.xAngel版本
1.3.xBrixton版本
1.4.xCamden版本
1.5.xDalston版本、Edgware
2.0.xFinchley版本
2.1.xGreenwich GA版本 (2019年2月发布)

鉴于SpringBoot与SpringCloud关系,SpringBoot建议采用2.1.x版本

小结:

  • 微服务架构:就是将相关的功能独立出来,单独创建一个项目,并且连数据库也独立出来,单独创建对应的数据库。
  • Spring Cloud本身也是基于SpringBoot开发而来,SpringCloud是一系列框架的有序集合,也是把非常流行的微服务的技术整合到一起。

2 服务调用方式

2.1 目标

  • 理解RPC和HTTP的区别
  • 能使用RestTemplate发送请求

2.2 讲解

2.2.1 RPC和HTTP

常见远程调用方式:

RPC:(Remote Produce Call)远程过程调用

1.基于Socket
2.自定义数据格式
3.速度快,效率高
4.典型应用代表:Dubbo,WebService,ElasticSearch集群间互相调用

HTTP:网络传输协议

1.基于TCP/IP
2.规定数据传输格式
3.缺点是消息封装比较臃肿、传输速度比较慢
4.优点是对服务提供和调用方式没有任何技术限定,自由灵活,更符合微服务理念

RPC和HTTP的区别:RPC是根据语言API来定义,而不是根据基于网络的应用来定义。

Http客户端工具

常见Http客户端工具:HttpClient、OKHttp、URLConnection。

2.2.2 Spring的RestTemplate

(1)RestTemplate介绍

  • RestTemplate是Rest的HTTP客户端模板工具类
  • 对基于Http的客户端进行封装
  • 实现对象与JSON的序列化与反序列化
  • 不限定客户端类型,目前常用的3种客户端都支持:HttpClient、OKHttp、JDK原生URLConnection(默认方式)

(2)RestTemplate入门案例
在这里插入图片描述

1.创建两个工程(springboot开发)
2.创建restTemplate
3.使用restTemplate模拟GET 请求 发起远程调用
4.获取返回过来JSON-->转换成POJO
5.打印

springcloud和dubbo的区别?

dubbo ---》
	+ RPC框架 
	+ 速度效率高 
	+ 目前只支持JAVA
	+ 本身的功能有限(只是一个通信框架)
	+ 使用麻烦
springcloud ---》(RestTemplate---》httpclient)
 + 属于http协议 
 + 速度低 跨平台
 + 微服务可以使用任何语言开发
 + 本身就是一套解决方案(整合了所有的流行的分布式框架)
 + 使用方便,开发效率高

springboot整合spring data jpa

1.添加起步依赖
2.创建POJO 通过使用JPA的注解进行映射 到数据库的表中
3.编写一个DAO的接口 继承 JpaRepository<User,Integer> 基本的CRUD的功能全有了

1、注册中心eureka

  • https://github.com/Netflix/eureka/wiki
  • Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务。SpringCloud将它集成在其子项目spring-cloud-netflix中, 以实现SpringCloud的服务注册和发现功能。
    Eureka包含两个组件:Eureka Server和Eureka Client。

单体应用 ------> 分类服务 商品服务 订单服务 用户服务…

Eureka Server 组件 : 服务注册中心组件 管理所有服务 支持所有服务注册

Eureka Client 组件 : 分类服务 商品服务 订单服务(微服务)

在这里插入图片描述

使用springcloud eureka

1、创建服务端(eureka server)本身就是一个微服务
2、创建客户端(eureka client–>各种微服务)

开发eureka server

1.创建项目并引入eureka server依赖

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

在这里插入图片描述
2.编写配置application.properties

server:
  port: 8761 #执行服务端口
spring:
  application:
    name: eurekaserver  # 指定服务名称 唯一标识
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka  #指定服务注册中心的地址

3.开启Eureka Server,入口类加入注解

@SpringBootApplication
//开启eureka server
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class,args);
    }
}

访问Eureka的服务注册页面http://localhost:8761
在这里插入图片描述

5.虽然能看到管理界面为什么项目启动控制台报错? eureka server 服务注册中心 & client 微服务
在这里插入图片描述

出现上述问题原因:
eureka组件包含 eurekaserver 和 eurekaclient。
server是一个服务注册中心,用来接受客户端的注册。
client的特性会让当前启动的服务把自己作为eureka的客户端进行服务中心的注册,
当项目启动时服务注册中心还没有创建好,
所以找我不到服务的客户端组件就直接报错了,当启动成功服务注册中心创建好了,日后client也能进行注册,就不再报错啦!

6.关闭Eureka自己注册自己

server:
  port: 8761 #执行服务端口
spring:
  application:
    name: eurekaserver  # 指定服务名称 唯一标识
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka  #指定服务注册中心的地址
    register-with-eureka: false  # 不再将自己同时作为客户端注册
    fetch-registry: false #关闭作为客户端时从eureka server获取服务信息

7.再次启动,当前应用就是一个单纯Eureka Server,控制器也不再报错
在这里插入图片描述

开发Eureka Client

1.创建项目并引入eureka client依赖

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

2.编写配置application.yaml

server:
  port: 18081
spring:
  application:
    name: user-provider
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka  #指定服务注册中心的地址

3.开启eureka客户端加入注解

@SpringBootApplication
//@EnableEurekaClient
@EnableDiscoveryClient//也可以,这是通用的,任选其一
public class Eurekaclient8888Application {
    public static void main(String[] args) {
        SpringApplication.run(Eurekaclient8888Application.class, args);
    }
}

4.启动之前的8761的服务注册中心,在启动eureka客户端服务
5.查看eureka server的服务注册情况
在这里插入图片描述
user-provider默认注册时使用的是主机名,如果我们想用ip进行注册,可以在yaml中进行配置
在这里插入图片描述

eureka:
  instance:
    ip-address: 127.0.0.1 # ip地址
    prefer-ip-address: false #更倾向于使用ip 而不是host名
    instance-id: ${eureka.instance.ip-address}:${server.port} #自定义的实例id

eureka的自我保护机制

0.服务频繁启动时 EurekaServer出现警告

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

在这里插入图片描述

默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。Eureka Server在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期。这种设计的哲学原理就是"宁可信其有不可信其无!"。自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的健壮、稳定的运行。

在这里插入图片描述

2.在eureka server端关闭自我保护机制

eureka:
  server:
    enable-self-preservation: false #关闭自我保护
    eviction-interval-timer-in-ms: 3000 #超时3s自动清除

3、微服务修改减短服务心跳的时间

eureka:
  instance:
    lease-expiration-duration-in-seconds: 10 #用来修改eureka server默认接受心跳的最大时间 默认是90s
    lease-renewal-interval-in-seconds: 5 #指定客户端多久向eureka server发送一次心跳 默认是30s

4.尽管如此关闭自我保护机制还是会出现警告,官方不建议在生产情况下关闭
在这里插入图片描述

eureka总结:
(1)eureka作为服务注册中心
(2)eureka client每30秒发送一次心跳到eureka server
(3)eureka server 每60秒将当前清单中超过90秒没有续约的服务剔除
(4)eureka的自我保护机制:服务频繁的起停或由于网络原因没有按时发送心跳续约,eureka会统计最近15分钟心跳续约的比例是否低于85%,eureka不会移除该服务,就会触发自我保护机制.。一句话: 某时刻某一个微服务不可用了,Eureka不会立即清理,依旧会对该微服务的信息进行保存。属于CAP里面的AP分支

eureka 停止更新

在1.x版本项目还是活跃的,但是在2.x版本中停止维护,出现问题后果自负!!!
可以使用consul,zookeeper作为注册中心

不同注册中心的区别

1.CAP定理 服务注册中心集群 node1 node2 node3 … eureka(AP) consul zk(CP)
CAP定理:CAP定理又称CAP原则,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本) 写之后的读操作 必须返回该值
可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性) 只要收到用户请求,必须给出响应
分区容忍性(P),就是高可用性,一个节点崩了,并不影响其它的节点(100个节点,挂了几个,不影响服务,越多机器越好) 区间通信可能失败
2.Eureka特点(AP)
Eureka中没有使用任何的数据强一致性算法保证不同集群间的Server的数据一致,仅通过数据拷贝的方式争取注册中心数据的最终一致性,虽然放弃数据强一致性但是换来了Server的可用性,降低了注册的代价,提高了集群运行的健壮性。
3.Consul特点(CP)
基于Raft算法,Consul提供强一致性的注册中心服务,但是由于Leader节点承担了所有的处理工作,势必加大了注册和发现的代价,降低了服务的可用性。通过Gossip协议,Consul可以很好地监控Consul集群的运行,同时可以方便通知各类事件,如Leader选择发生、Server地址变更等。
node1 node2(leader) node3,假node2是leader,由node2承担处理工作,所有数据由leader确认,然后写入node1,node3。等1,3全部写入后,才认为数据可用
4.zookeeper特点(CP)
基于Zab协议,Zookeeper可以用于构建具备数据强一致性的服务注册与发现中心,而与此相对地牺牲了服务的可用性和提高了注册需要的时间。
node1 node2(master)node3,可以往任意一个节点写,假设往3写,3会通知master,由master对外做原子广播,等其他节点写入后,才认为数据可用

在这里插入图片描述

RestTemplate服务调用方式

说明
spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。

@RestController
@RequestMapping("/consumer")
public class UserController {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;
    /****
     * 在user-consumer服务中通过RestTemplate调用user-provider服务
     * @param id
     * @return
     */

    @GetMapping("/{id}")
    public User queryById(@PathVariable(value = "id")Integer id){
        //1.restTemplate模拟浏览器发送请求给用户微服务,获取用户信息
        //1.1 创建restTemplate交给spring容器
        //1.2 直接注入使用 调用get方法获取用户信息
        // String url = "http://localhost:18081/user/find/"+id;
        //从eureka注册中心中动态获取IP和端口 拼接
        //参数 指定serviceId 注册到注册中心的微服务的服务名(spring.application.name:指定的值)
        List<ServiceInstance> instances = discoveryClient.getInstances("user-provider");
        //ip和端口都在ServiceInstance中
        ServiceInstance serviceInstance = instances.get(0);
        User user = restTemplate.getForObject("http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/user/find/" + id, User.class);
        //String url = "http://localhost:18081/user/find/"+id;
        return user;
    }

}

总结
rest Template是直接基于服务地址调用没有在服务注册中心获取服务,也没有办法完成服务的负载均衡如果需要实现服务的负载均衡需要自己书写服务负载均衡策略。
restTemplate直接调用存在问题

  • 1.直接使用restTemplate方式调用没有经过服务注册中心获取服务地址,代码写死不利于维护,当服务宕机时不能高效剔除
  • 2.调用服务时没有负载均衡需要自己实现负载均衡策略

所以就有了Ribbon组件


版权声明:本文为zzh18856960604原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。