springCloud

微服务概述

  • 什么是微服务?

微服务是最近几年流行起来的一直架构思想。更直白的说可以理解为一种新的思维方式,为问题的解决提供了一种不同的解决思路,与此同时,也提供了大量的就业机会。

微服务将的单一的应用程序划分为一组小的服务,每个服务运行在其自己独立的进程之中,服务之间可以相互协调,互相配置。为用户提供了最终的价值,服务之间采用轻量级别的通信机制(HTTP)。

微服务的核心思想是将传统的一站式应用,根据业务的拆分成一个一个的服务,彻底的去耦合,每一个微服务能够提供的单个的业务功能, 一个服务做一件事情,从技术的角度看就是一种小而独立的处理过程,类似进程的个概念。

  • 优点
  1. 单一的职责原则
  2. 高内聚,足够小,代码容易理解
  3. 开发简单,效率高
  4. 能够使用不同的语言开发
  5. 可以集成第三方的软件
  6. ……………
  • 缺点
  1. 服务间的通信成本
  2. 系统部署依赖问题
  3. 数据的一致性问题
  4. 性能和监控问题

SpringCloud

SpringCloud和SpringBoot的关系

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

Eureka

  • Netflix在涉及Eureka时,遵循的就是API原则.
  • Eureka是Netflix的有个子模块,也是核心模块之一。Eureka是基于REST的服务,用于定位服务,以实现云端中间件层服务发现和故障转移,服务注册与发现对于微服务来说是非常重要的,有了服务注册与发现,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了,功能类似于Dubbo的注册中心,比如Zookeeper.
  • Eureka 包含两个组件:Eureka ServerEureka Client.
  • Eureka Server 提供服务注册,各个节点启动后,回在EurekaServer中进行注册,这样Eureka Server中的服务注册表中将会储存所有课用服务节点的信息,服务节点的信息可以在界面中直观的看到.
  • Eureka Client 是一个Java客户端,用于简化EurekaServer的交互,客户端同时也具备一个内置的,使用轮询负载算法的负载均衡器。在应用启动后,将会向EurekaServer发送心跳 (默认周期为30秒) 。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除掉 (默认周期为90s).
  • Eureka Server:提供服务的注册与发现
  • Service Provider:服务生产方,将自身服务注册到Eureka中,从而使服务消费方能狗找到
  • Service Consumer:服务消费方,从Eureka中获取注册服务列表,从而找到消费服务

配置步骤

1. eureka-server

  • 导入依赖

  • <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> <version>1.4.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> - 配置yml- ```yml server: port: 7001 # Eureka配置 eureka: instance: # Eureka服务端的实例名字 hostname: 127.0.0.1 client: # 表示是否向 Eureka 注册中心注册自己(这个模块本身是服务器,所以不需要) register-with-eureka: false # fetch-registry如果为false,则表示自己为注册中心,客户端的化为 ture fetch-registry: false # Eureka监控页面~ service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ YAML

  • 启动类注解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

    //启动之后,访问 http://localhost:7001/
    @SpringBootApplication
    @EnableEurekaServer //服务端的启动类,可以接受别人注册进来
    public class EurekaServer_7001 {

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


    JAVA

    访问 http://localhost:7001/

2.eureka-client

  • 导入依赖
1
2
3
4
5
6
7
8
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>


MAVEN
  • 配置yml
1
2
3
4
5
6
7
8
9
10
# Eureka配置:配置服务注册中心地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: springcloud-provider-dept-8001 #修改Eureka上的默认描述信息
#如果此时停掉springcloud-provider-dept-8001 等30s后 监控会开启保护机制:

YML
  • 注解
  • 主启动类中加入@EnableDiscoveryClient 注解 //开启服务发现客户端的注解,可以用来获取一些配置的信息,得到具体的微服务
1
2
3
4
5
6
7
8
9
10
11
@SpringBootApplication
// @EnableEurekaClient 开启Eureka客户端注解,在服务启动后自动向注册中心注册服务
@EnableEurekaClient
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class,args);
}
}


JAVA

3.配置关于服务加载的监控信息

  • 导入依赖
1
2
3
4
5
6
7
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>


MAVEN
  • 配置yml
1
2
3
4
5
6
7
8
9
# info配置
info:
# 项目的名称
app.name: NYNUywg-springcloud
# 公司的名称
company.name: 南阳师范学院计算机科学与技术学院


YML

4.EureKa自我保护机制

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

  • 默认情况下,当eureka server在一定时间内没有收到实例的心跳,便会把该实例从注册表中删除(默认是90秒),但是,如果短时间内丢失大量的实例心跳,便会触发eureka server的自我保护机制,比如在开发测试时,需要频繁地重启微服务实例,但是我们很少会把eureka server一起重启(因为在开发过程中不会修改eureka注册中心),当一分钟内收到的心跳数大量减少时,会触发该保护机制。可以在eureka管理界面看到Renews threshold和Renews(last min),当后者(最后一分钟收到的心跳数)小于前者(心跳阈值)的时候,触发保护机制,会出现红色的警告:EMERGENCY!EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT.RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEGING EXPIRED JUST TO BE SAFE.从警告中可以看到,eureka认为虽然收不到实例的心跳,但它认为实例还是健康的,eureka会保护这些实例,不会把它们从注册表中删掉。
  • 该保护机制的目的是避免网络连接故障,在发生网络故障时,微服务和注册中心之间无法正常通信,但服务本身是健康的,不应该注销该服务,如果eureka因网络故障而把微服务误删了,那即使网络恢复了,该微服务也不会重新注册到eureka server了,因为只有在微服务启动的时候才会发起注册请求,后面只会发送心跳和服务列表请求,这样的话,该实例虽然是运行着,但永远不会被其它服务所感知。所以,eureka server在短时间内丢失过多的客户端心跳时,会进入自我保护模式,该模式下,eureka会保护注册表中的信息,不在注销任何微服务,当网络故障恢复后,eureka会自动退出保护模式。自我保护模式可以让集群更加健壮。
    但是我们在开发测试阶段,需要频繁地重启发布,如果触发了保护机制,则旧的服务实例没有被删除,这时请求有可能跑到旧的实例中,而该实例已经关闭了,这就导致请求错误,影响开发测试。所以,在开发测试阶段,我们可以把自我保护模式关闭,只需在eureka server配置文件中加上如下配置即可:eureka.server.enable-self-preservation=false【不推荐关闭自我保护机制】

集群搭建

1
2
3
4
5
6
7
8
9
server:
port: 7002


server:
port: 7003


YML

Eureka保证的是AP

Ribbon

负载均衡以及Ribbon

  • Spring Cloud Ribbon 是基于Netflix Ribbon 实现的一套客户端负载均衡的工具。
  • 简单的说,Ribbon 是 Netflix 发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将 Netflix 的中间层服务连接在一起。Ribbon 的客户端组件提供一系列完整的配置项,如:连接超时、重试等。简单的说,就是在配置文件中列出 LoadBalancer (简称LB:负载均衡) 后面所有的及其,Ribbon 会自动的帮助你基于某种规则 (如简单轮询,随机连接等等) 去连接这些机器。我们也容易使用 Ribbon 实现自定义的负载均衡算法!

LB,即负载均衡 (LoadBalancer) ,在微服务或分布式集群中经常用的一种应用。

负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA (高用)。

常见的负载均衡软件有 Nginx、Lvs 等等。

Dubbo、SpringCloud 中均给我们提供了负载均衡,SpringCloud 的负载均衡算法可以自定义。

负载均衡简单分类:

集中式LB

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

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

集成Ribbon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!--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>


MAVEN
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/


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


JAVA
@Configuration
public class ConfigBean {
//@Configuration -- spring applicationContext.xml
@LoadBalanced //配置负载均衡实现RestTemplate
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}


JAVA

如何切换或者自定义规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
在这里插入代码片@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();//使用轮询策略
}
}


JAVA

Feign

Feign简介

Feign是声明式Web Service客户端,它让微服务之间的调用变得更简单,类似controller调用service。SpringCloud集成了Ribbon和Eureka,可以使用Feigin提供负载均衡的http客户端

Feign的使用步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!--Feign的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>


MAVEN
// @FeignClient:微服务客户端注解,value:指定微服务的名字,这样就可以使Feign客户端直接找到对应的微服务
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DeptClientService {

@GetMapping("/dept/get/{id}")
public Dept queryById(@PathVariable("id") Long id);
@GetMapping("/dept/list")
public List<Dept> queryAll();
@GetMapping("/dept/add")
public boolean addDept(Dept dept);
}


JAVA
@SpringBootApplication
@EnableEurekaClient
// feign客户端注解,并指定要扫描的包以及配置接口DeptClientService
@EnableFeignClients(basePackages = {"com.yang.springcloud.service"})
// 切记不要加这个注解,不然会出现404访问不到
//@ComponentScan("com.yang.springcloud.service")
public class FeignDeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(FeignDeptConsumer_80.class, args);
}
}


JAVA

Hystrix服务熔断

什么是服务熔断?
熔断机制是赌赢雪崩效应的一种微服务链路保护机制。

当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阀值缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是:@HystrixCommand。

服务熔断解决如下问题:

  • 当所依赖的对象不稳定时,能够起到快速失败的目的;
  • 快速失败后,能够根据一定的算法动态试探所依赖对象是否恢复。
  1. 导依赖
1
2
3
4
5
6
7
8
9
<!--导入Hystrix依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>


MAVEN
  1. yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
server:
port: 8001

#mybatis配置
mybatis:
# springcloud-api 模块下的pojo包
type-aliases-package: com.yang.springcloud.pojo
# 本模块下的mybatis-config.xml核心配置文件类路径
config-location: classpath:mybatis/mybatis-config.xml
# 本模块下的mapper配置文件类路径
mapper-locations: classpath:mybatis/mapper/*.xml

#spring配置
spring:
application:
name: springcloud-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=UTF-8
username: root
password: root
# Eureka配置:配置服务注册中心地址
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
#修改Eureka上的默认描述信息
instance:
instance-id: springcloud-provider-dept-8001
#prefer-ip-address: true #改为true后默认显示的是ip地址而不再是localhost
# info配置
info:
# 项目的名称
app.name: NYNUywg-springcloud
# 公司的名称
company.name: 南阳师范学院计算机科学与技术学院


YML
  1. java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
/**
* 根据id查询部门信息
* 如果根据id查询出现异常,则走hystrixGet这段备选代码
* @param id
* @return
*/
@HystrixCommand(fallbackMethod = "hystrixGet")
@RequestMapping("/dept/get/{id}")//根据id查询
public Dept get(@PathVariable("id") Long id){
Dept dept = deptService.queryById(id);
if (dept==null){
throw new RuntimeException("这个id=>"+id+",不存在该用户,或信息无法找到~");
}
return dept;
}
/**
* 根据id查询备选方案(熔断)
* @param id
* @return
*/
public Dept hystrixGet(@PathVariable("id") Long id){
return new Dept(id,"这个id=>"+id+",没有对应的信息,null---@Hystrix~","在MySQL中没有这个数据库");
}
}


JAVA

主启动类添加@EnableCircuitBreaker熔断注解

服务雪崩

什么是Hystrix

Hystrix能做什么

服务熔断

服务降级

什么是服务降级?
服务降级是指 当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理,或换种简单的方式处理,从而释放服务器资源以保证核心业务正常运作或高效运作。说白了,就是尽可能的把系统资源让给优先级高的服务。
资源有限,而请求是无限的。如果在并发高峰期,不做服务降级处理,一方面肯定会影响整体服务的性能,严重的话可能会导致宕机某些重要的服务不可用。所以,一般在高峰期,为了保证核心功能服务的可用性,都要对某些服务降级处理。比如当双11活动时,把交易无关的服务统统降级,如查看蚂蚁深林,查看历史订单等等。

服务降级主要用于什么场景呢?当整个微服务架构整体的负载超出了预设的上限阈值或即将到来的流量预计将会超过预设的阈值时,为了保证重要或基本的服务能正常运行,可以将一些 不重要 或 不紧急 的服务或任务进行服务的 延迟使用 或 暂停使用。

降级的方式可以根据业务来,可以延迟服务,比如延迟给用户增加积分,只是放到一个缓存中,等服务平稳之后再执行 ;或者在粒度范围内关闭服务,比如关闭相关文章的推荐。

由上图可得,当某一时间内服务A的访问量暴增,而B和C的访问量较少,为了缓解A服务的压力,这时候需要B和C暂时关闭一些服务功能,去承担A的部分服务,从而为A分担压力,叫做服务降级。

服务降级需要考虑的问题

那些服务是核心服务,哪些服务是非核心服务
那些服务可以支持降级,那些服务不能支持降级,降级策略是什么
除服务降级之外是否存在更复杂的业务放通场景,策略是什么?
自动降级分类

1)超时降级:主要配置好超时时间和超时重试次数和机制,并使用异步机制探测回复情况

2)失败次数降级:主要是一些不稳定的api,当失败调用次数达到一定阀值自动降级,同样要使用异步机制探测回复情况

3)故障降级:比如要调用的远程服务挂掉了(网络故障、DNS故障、http服务返回错误的状态码、rpc服务抛出异常),则可以直接降级。降级后的处理方案有:默认值(比如库存服务挂了,返回默认现货)、兜底数据(比如广告挂了,返回提前准备好的一些静态页面)、缓存(之前暂存的一些缓存数据)

4)限流降级:秒杀或者抢购一些限购商品时,此时可能会因为访问量太大而导致系统崩溃,此时会使用限流来进行限制访问量,当达到限流阀值,后续请求会被降级;降级后的处理方案可以是:排队页面(将用户导流到排队页面等一会重试)、无货(直接告知用户没货了)、错误页(如活动太火爆了,稍后重试)。

服务熔断和服务降级的区别

Dashboard流监控

Zull

概述

入门

Grateway

SpringCloudConfig


springCloud
https://lfrok.top/2022/11/27/Java/SpringCloud/
作者
B612🚀
发布于
2022年11月27日
许可协议