14年 新的架构
官方定义 : 微服务就是由一系列围绕自己业务开发的微小服务构成,他们独立部署运行在自己的进程里,基于分布式的管理
集群:同一种软件的多个服务节点共同为系统提供服务
分布式:不同软件集群共同为系统提供服务
通俗定义 : 微服务是一种架构,这种架构是将单个的整体应用程序分割成更小的项目关联的独立的服务。一个服务通常实现一组独立的特性或功能,包含自己的业务逻辑和适配器。各个微服务之间的关联通过暴露api来实现。这些独立的微服务不需要部署在同一个虚拟机,同一个系统和同一个应用服务器中。
优点
缺点
优点
缺点
创建一个空的项目(空文件夹)
创建一个父项目(maven)进行版本控制,删除src目录,pom文件使用parent
标签,引入SpringBoot父项目
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>org.examplegroupId>
<artifactId>SpringCloudAgainartifactId>
<packaging>pompackaging>
<version>1.0-SNAPSHOTversion>
<modules>
<module>01_eureka_servermodule>
modules>
<parent>
<artifactId>spring-boot-starter-parentartifactId>
<groupId>org.springframework.bootgroupId>
<version>2.2.6.RELEASEversion>
parent>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
<spring.cloud-version>Hoxton.SR6spring.cloud-version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring.cloud-version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
project>
所谓服务注册中心就是在整个的微服务架构中单独提出一个服务,这个服务不完成系统的任何的业务功能,仅仅用来完成对整个微服务系统的服务注册和服务发现,以及对服务健康状态的监控和管理功能。
springcloud支持的多种注册中心Eureka (netfilx)、Consul (go)、Zookeeper (java)、以及阿里巴巴推出Nacos (java)。这些注册中心在本质上都是用来管理服务的注册和发现以及服务状态的检查的。
开发Eureka 注册中心
创建Springboot子项目
引入依赖(pom文件)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SpringCloudAgainartifactId>
<groupId>org.examplegroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>01_eureka_serverartifactId>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<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>
project>
配置端口
# eureka server 默认端口号8761
server:
port: 8761
# 服务名 建议大写 且不运行名称中带有下划线_(注意服务名称唯一,不区分大小写,推荐大写)
spring:
application:
name: EUREKASERVER
# 注册中心 管理页面地址 http://localhost:8761 不带/eureka
eureka:
client:
# 关闭eureka的立即注册功能 默认true,启动就注册,关闭后,启动不会报错
fetch-registry: false
# 让当前应用仅为注册中心,启动后不再把自己注册进去(关闭自己注册自己,自己不在作为客户端,仅仅作为服务端)
register-with-eureka: false
service-url:
defaultZone: http://localhost:8761/eureka
编写启动类,添加注解、测试是否能够启动成功
package com.ma;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class MyEurekaServerSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MyEurekaServerSpringBootApplication.class,args);
}
}
Eureka Client就是一个个微服务,例如订单服务、支付服务等等
创建一个SpringBoot子项目
引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
dependencies>
编写配置文件
#配置端口
server:
port: 8989
#客户端名称,也就是服务名称
spring:
application:
name: EUREKACLIENT
#配置服务注册中心的地址
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
编写启动类,添加注解
package com.ma;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class MyEurekaClientSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MyEurekaClientSpringBootApplication.class,args);
}
}
如果注册到服务中心上的服务因为某种缘故造成服务宕机了,eureka开启自我保护模式,eureka服务注册中心不会移除任何已注册的服务
默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。
EurekaServer在运行期间会去统计心跳失败比例在15分钟之内是否低于85%,如果低于85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期。这种设计的哲学原理就是"宁可信其有不可信其无!"。自我保护模式正是一种针对网络异常被动的安全保护措施,使用自我保护模式能使Eureka集群更加的健社、稳定的运行。
关键字:网络分区
自我保护模式什么时候失效?
自定义自我保护机制
consui是一个可以提供服务发现,健康检查,多数据中心,Key/Value存储等功能的分布式服务框架,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,使用起来也较为简单。consu1用Golang实现,因此具有天然可移楂性(支持Linux、 windows和Mac 0S x);安装包仅包含一个可执行文件,方便部署。
健康检查
的依赖存在问题:consul服务不能注册
存在的问题:
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于wetflix Ribbon实现。通过Spring cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。
DiscoveryClient
LoadBalanceClient
@LoadBanlanced
存在问题:
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性(可以使用springmvc的注解),可使用Feign注解和AX-RS注解。Feign支持可插拔的编码器和解码器。Feignr默认集成了Ribbon,默认实现了负载均衡的效果并且springcloud为feign添加了springmvc注解的支持。
创建Demo(category、product两个服务),分类服务要调用商品服务
引入OpenFeign依赖(在服务调用方,也就是category服务)
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
服务调用方主启动类添加注解@EnableFeignClients
开启Feign服务支持(加注解、写接口)
开发客户端接口
零散参数:零散传参主要分为两种,一种是路径传参,一种是queryString传参
注意:服务调用方,在接口对应的方法上要使用@RequestParam
和@Pathvarible
进行声明,目的是为了让这个Openfeign组件(伪http客户端)知道使用哪种方式进行传参。
对象:json对象格式和form表单格式
使用@RequestBody
注解和@RequestPart
注解
数组
使用@RequestParam
注解
集合
注意:SpringMVC不能直接接收集合,需要借助对象进行接收,在对象中声明一个集合;
OO:面向对象
VO:value object 值对象,用户接收
DTO:data transfer object数据传输对象,用来传输
在微服务之间进行服务调用是由于某一个服务故障,导致级联服务故障的现象,称为雪崩效应。雪崩效应描述的是提供方不可用,导致消费方不可用并将不可用逐渐放大的过程。
而此时,service A的流量波动很大,流量经常会突然性增加!那么在这种情况下,就算service A能扛得住请求,service B和lService c未必能扛得住这突发的请求。此时,如果service c因为抗不住请求,变得不可用。那么Service s的请求也会阻塞,慢慢耗尽service B的线程资源,serviceB就会变得不可用。紧接着,Service A也会不可用。
定义
““熔断器”"本身是一种开关装置,当某个服务单元发生故障之后,通过断路器(hystrix)的故障监控,某个异常条件被触发,直接熔断整个服务。向调用方法返回一个符合预期的、可处理的备选响应(Fa11Back),而不是长时间的等待或者抛出调用方法无法处理的异常,就保证了服务调用方的线程不会被长时间占用,避免故障在分布式系统中蔓延,乃至雪崩。如果目标服务情况好转则恢复调用。服务熔断是解决服务雪崩的重要手段。
开关条件
1、当满足一定的阀值的时候(默认10秒内超过20个请求次数)
2、当失败率达到一定的时候(默认10秒内超过50%的请求失败)-
3、到达以上阀值,断路器将会开启
4、当开启的时候,所有请求都不会进行转发
5、一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5
服务压力剧增的时候根据当前的业务情况及流量对一些服务和页面有策略的降级,以此缓解服务器的压力,以保证核心任务的进行。同时保证部分甚至大部分任务客户能得到正确的响应。也就是当前的请求处理不了了或者出错了,给一个默认的返回。
服务降级:关闭微服务系统中某些边缘服务保证系统核心服务正常运行,例如:确认收货---->服务繁忙!
共同点
目的很一致,都是从可用性可靠性着想,为防止系统的整体缓慢甚至崩溃,采用的技术手段;-最终表现类似,对于两者来说,最终让用户体验到的是某些功能暂时不可达或不可用;
粒度一般都是服务级别,当然,业界也有不少更细粒度的做法,比如做到数据持久层(允许查询,不允许增删改);
自治性要求很高,熔断模式一般都是服务基于策略的自动触发,降级虽说可人工干预,但在微服务架构下,完全靠人显然不可能,开关预置、配置中心都是必要手段:sentinel
异同点
触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;
管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务边缘服务开始)
总结
熔断必会触发降级,所以熔断也是降级一种,区别在于熔断是对调用链路的保护,而降级是对系统过载的一种保护处理
译:在分布式环境中,许多服务依赖项不可避免地会失败。Hystrix是一个库,它通过添加延迟容忍和容错逻辑来帮助您控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止它们之间的级联故障以及提供后备选项来实现这一点,所有这些都可以提高系统的整体弹性。
通俗定义:Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统中,许多依赖不可避免的会调用失败,超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障(服务雪崩现象),提高分布式系统的弹性。
在所有微服务中添加Hystrix添加对应依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
dependency>
主启动类添加注解
//开启服务熔断
@EnableCircuitBreaker
Hystrix Dashboard的一个主要优点是它收集了关于每个HystrixCcommand的一组度量。lystrix仪表板以高效的方式显示每个断踏器的运行伏况
引入依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-netflix-hystrix-dashboardartifactId>
dependency>
主启动类添加注解,开启HystrixDashBord
@EnableHystrixDashboard//开启仪表盘监控
访问对应web界面地址
http://localhost:配置的端口/hystrix
BUG
网关统一服务入口,可方便实现对平台众多服务接口进行管控,对访问服务的身份认证、防报文重放与防数据篡改、功能调用的业务鉴权、响应数据的脱敏、流量与并发控制,甚至基于API调用的计量或者计费等等。
网关=路由转发+过滤器
路由转发:接收一切外界请求,转发到后端的微服务上去;
在服务网关中可以完成一系列的横切功能,例如权限校验、限流以及监控等,这些都可以通过过滤器完成
网关可以实现服务的统一管理
引入网关依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
网关配置的方式
网关路由规则
网关实现负载均衡
lb://PRODUCT #负载均衡 服务id PRODUCT
网关断言
网关过滤器
config(配置)又称为统一配置中心顾名思义,就是将配置统─管理,配置统一管理的好处是在日后大规模集群部署服务应用时相同的服务配置一致,日后再修改配置只需要统一修改全部同步,不需要一个一个服务手动维护。
创建远程仓库
注意:远程仓库要公开
创建config服务端(SpringBoot模块),引入依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-config-serverartifactId>
dependency>
配置文件配置远程仓库连接地址
spring.cloud.config.server.git.uri=https://gitee.com/himatengfei/configs.git
spring.cloud.config.server.git.default-label=master
创建configclient(Config客户端)
创建一个SpringBoot应用
将配置文件交给远程仓库处理
引入Config客户端依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-configartifactId>
dependency>
SpringBoot应用配置文件bootstrap.properties
配置文件进行配置(注意文件名称)
手动配置刷新
当远端git仓库中配置发生变化时,不需要重启微服务就可以直接读取远端修改之后配置信息,这种就叫手动配置刷新
@RefreshScope
注解在统一配置中心中引入Bus组件依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-bus-amqpartifactId>
dependency>
配置配置文件
通过bus组件连接rabbitmq服务
在所有微服务中配置mq的连接,包括引入bus组件依赖、配置mq连接
配置完成之后,其他所有引入Bus组件的微服务存在报错configServerRetryInterceptor
,原因就是项目还没来的及引入远程仓库的依赖
解决方式在配置文件中进行如下配置:
# 设置 启动时当远端信息还没有拉取完全时的失败是被允许的
spring.cloud.config.fail-fast=true
暴露路径,通过bus组件提供的一个post请求,能够自动刷新,实现其他微服务自动拉去远端配置
http://localhost:8848/actuator/bus-refresh
注意必须是post请求
# 暴露路径
management.endpoints.web.exposure.include=*
提问:怎么实现指定服务配置刷新
http://localhost:8848/actuator/bus-refresh
路径名称后面知道微服务的id就可以实现知道服务配置刷新
netapp官网进行注册登录
进行cmd命令启动natapp -authtoken=2cb0b20ab2b69cc3
配置webhooks(注意:每一次启动natapp.exe程序生成的公网域名都不一样)
注意:存在bug,测试码云的webhooks报400错误
spring cloud 阿里巴巴为分布式开发提供一了一站式解决方法
Linux指令:find / -name java
全文搜索java相关
查看log日志:tail -f nacos.log
tar.gz
上传到linux中tar -zxvf 安装包
进行解压,注意事先需要安装jdk,因为nacos本质是一个SpringBoot应用./startup.sh -m standalone
startup.cmd -m standalone
或者双击startup.cmd文件tail -f nacos.log
创建SpringBoot应用(maven)
引入nacos依赖
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
创建主启动类,编写配置文件
server.port=8081
spring.application.name=NACOSCLIENT
配置服务注册中心地址 spring.cloud.nacos.server-addr=8.xxx.99.127:8848
RestTemplate
RestTemplate+Ribbon
OpenFegin
nacos作为统一配置中心:
在nacos的web端管理界面添加配置文件:
bootstrap.properties
nacos三个重要概念:
默认nacos存在配置信息持久化,默认的持久化方式为内嵌数据库debery;缺点是无法友好的展示数据。官方建议,在生产情况下推荐将配置存入mysql数据库注意: nacos到目前为止仅仅支持mysql
将nacos上的配置信息持久化到mysql中
5.6.5+
sentinel-dashbord下载地址:https://kgithub.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
使用java -jar jar包名称直接启动
, 默认端口8080
用户名和密码默认:sentinel
创建maven(SpringBoot)子项目
引入依赖
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
dependency>
配置文件进行配置
server.port=8988
spring.application.name=NACOSSENTINEL
# nacos相关配置
spring.cloud.nacos.server-addr=192.168.43.131
# sentinel相关配置
# 开启sentinel组件的保护
spring.cloud.sentinel.enabled=true
# 声明sentinel dashbord web的地址
spring.cloud.sentinel.transport.dashboard=192.168.43.131:8070
# sentinel和sentinel dashbord web之间的通信地址
spring.cloud.sentinel.transport.port=8719
流控规则(流量控制)flow control
降级规则(熔断降级)degrade service
热点规则
系统规则
授权规则