框架
2025-10-20 19:21:59 0 举报
AI智能生成
spring ,springMvc,spingBoot,springCloud,mybatis,netty相关总结
作者其他创作
大纲/内容
rpc
dubbo
支持的通信协议
序列化协议
子主题 3
mybatis
ibatis
缓存
一级缓存
二级缓存
缓存淘汰算法
mybatis-plus
自带雪花算法
实现逻辑
DefaultIdentifierGenerator类
根据时间戳,数据中心,机器标识部分,序列化,做位于运算
图示
子主题
乐观锁插件
mybatis工作流程
详细流程图
详细步骤
1、读取配置文件
这个文件为mybatis的全局配置文件
构建Configuration保存所有的配置信息
2、加载xml映射文件
也就是sql映射文件
这些文件配置了操作数据库的sql语句
3、创建 SqlSessionFactory 会话工厂
SqlSessionFactory 相当于连接池工厂,负责创建 SqlSession
4、创建sqlSeesion会话对象
由会话工厂SqlSessionFactory对象创建SqlSession
5、创建Mapper 代理对象
通过sqlSeesion会话对象获取Mapper对象
6、执行sql语句;
Excutor执行器根据传入的参数动态生成需要执行
底层还是调用 JDBC:
1. 获取 Connection
2. 预编译 SQL(PreparedStatement)
3. 设置参数
4. 执行 SQL
5. 处理结果集
7、封装结果
结果集交给 ResultSetHandler,映射到 Java 对象;类型可以是map,list类型,实体类,基本数据类型
8、关闭资源
使用完 SqlSession 需要手动关闭,避免资源泄漏。
spring
spring
spring理解
1、是spring整个生态圈的核心基石
2、简化企业级开发
1、基于pojo的轻量级和最小的侵入性编程
2、通过依赖注入还有切面接口实现松耦合
3、通过切面编程减少模板代码
3、ioc,aop的容器框架
spring使用的优势
1、Spring框架之外还存在一个构建在核心框架之上的庞大生态圈
2、低侵入式设计,代码的污染极低
3、独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺
4、Spring的loC容器降低了业务对象替换的复杂性,提高了组件之间的解耦
5、Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式处理,从而提供了更好的复用
6、Spring的ORM和DAO提供了与第三方持久层框架的的良好整合,并简化了底层的数据库访问
7、Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部
spring的核心
为了简化项目开发而且有自己生态圈的一个开源框架
核心
IOC(控制反转,Inversion of Control)
由容器负责对象的创建和依赖管理,开发者只关注业务逻辑。
AOP(面向切面编程,Aspect Oriented Programming)
把日志、事务、安全等横切关注点从业务代码中解耦,降低耦合度,提高可维护性。
spring是一个ioc和aop的容器框架
ioc
控制反转
Aop
切面编程
容器
存储bean对象且控制bean生命周期的容器
IOC
IOC的理解
总体回答
容器:存储对象,使用map结构来存储,在spring中一般存在三级缓存,singleionObjects存放完整的bean对象,
IOC原理
Spring 容器通过读取 Bean 定义(BeanDefinition),利用反射创建 Bean 实例,再通过依赖注入(构造器、Setter 或字段注入)注入所需依赖,最后通过初始化方法和后置处理器完成 Bean 生命周期管理
其实就是和bean对象的构建离不开。
IOC的实现
简化流程如下
1. 扫描/注册 BeanDefinition:读取 XML、注解或配置类,保存 Bean 的元数据。
2. 实例化 Bean:通过反射或工厂方法创建对象。
3. 依赖注入(DI):把 Bean 所需依赖注入(构造器、Setter、字段)。
4. 初始化 Bean:调用 @PostConstruct、afterPropertiesSet() 或 XML 配置的 init-method。
5. 后置处理:BeanPostProcessor 对 Bean 做增强(如 AOP)。
6. 加入容器缓存:单例 Bean 放入缓存,原型 Bean 每次获取新实例。
2. 实例化 Bean:通过反射或工厂方法创建对象。
3. 依赖注入(DI):把 Bean 所需依赖注入(构造器、Setter、字段)。
4. 初始化 Bean:调用 @PostConstruct、afterPropertiesSet() 或 XML 配置的 init-method。
5. 后置处理:BeanPostProcessor 对 Bean 做增强(如 AOP)。
6. 加入容器缓存:单例 Bean 放入缓存,原型 Bean 每次获取新实例。
依赖注入
DI:依赖注入,把对应的属性的值注入到具体的对象中,(SJAutowired, populateBean完成属性值的注入
控制反转
控制反转:理论思想,原来的对象是由使用者来进行控制,有了spring之后,可以把整个对象交给spring来帮我们进行管理
容器的生命周期
容器的生命周期
整个bean的生命年期,从创建到使用到销毁的过程全部都是由容器来管理(bean的生命周期)
如何实现一个ioc容器
1、先准备一个基本的容器对象,包含一些map结构的集合,用来方便后续过程中存储具体的对象
2、进行配置文件的读取工作或者注解的解析工作,将需要创建的bean对象都封装成BeanDefinition对象存储在容器中
3、容器将封装好的BeanDefinition对象通过反射的方式进行实例化,完成实例化工作
4、进行对象的初始化操作,也就是给类中的对应属性值就行设置,也就是进行依赖注入,完成整个对象创建一个完整的bean对象,存储在容器的某个map结构中
5、通过容器对象来获取对象,进行对象的获取和逻辑处理工作
6、提供销毁操作,当对象不用或者容器关闭的时候,将无用的对象进行销毁
AOP
AOP的理解
AOP全称叫做Aspect Oriented Programming面向切面编程.它是为解耦而生;
实现原理
Spring AOP 基于代理模式(JDK 动态代理或 CGLIB 动态代理),在方法执行前后织入横切逻辑,实现切面编程
AOP 核心思想
核心机制:通过动态代理,在方法调用的前、后或异常时,执行额外逻辑(Advice)。
AOP(面向切面编程):把事务、日志、安全校验等通用逻辑抽离出来,不和业务代码耦合。
Spring AOP 执行流程
容器启动时,Spring 解析 @Aspect 注解,生成切面信息。
根据切点表达式,找到需要增强的 Bean。
使用 JDK 或 CGLIB 动态代理 创建代理对象。
方法调用时:
进入代理对象 → 匹配切点 → 按顺序执行增强逻辑(Advice) → 调用目标方法。
任何一个系统都是由不同的组件组成的,每个组件负责一块特定的功能,当然会存在很多组件是跟业务无关
的,例如日志、事务、权限等核心服务组件,这些核心服务组件经常融入到具体的业务逻辑中,如果我们为每
一个具体业务逻辑操作都添加这样的代码,很明显代码冗余太多,因此我们需要将这些公共的代码逻辑抽象出
来变成一个切面,然后注入到目标对象(具体业务)中去,AOP正是基于这样的一个思路实现的,通过动态代
理的方式,将需要注入切面的对象进行代理,在进行调用的时候,将公共的逻辑直接添加进去,而不需要修改
原有业务的逻辑代码,只需要在原来的业务逻辑基础之上做一些增强功能即可。
的,例如日志、事务、权限等核心服务组件,这些核心服务组件经常融入到具体的业务逻辑中,如果我们为每
一个具体业务逻辑操作都添加这样的代码,很明显代码冗余太多,因此我们需要将这些公共的代码逻辑抽象出
来变成一个切面,然后注入到目标对象(具体业务)中去,AOP正是基于这样的一个思路实现的,通过动态代
理的方式,将需要注入切面的对象进行代理,在进行调用的时候,将公共的逻辑直接添加进去,而不需要修改
原有业务的逻辑代码,只需要在原来的业务逻辑基础之上做一些增强功能即可。
AOP相关概念
切面( Aspect)
指关注点模块化,这个关注点可能会横切多个对象。事务管理是企业级Java应用中有关横切 [否要开启事物)
正常 J能,开起事物无压力关注点的例子.在Spring AOP中,切面可以使用通用类基于模式的方式(schema-based叩proach) 或者在 ationAfterThrowing 执行普通类中以©Aspect注解(@AspectJ注解方式)来实现
正常 J能,开起事物无压力关注点的例子.在Spring AOP中,切面可以使用通用类基于模式的方式(schema-based叩proach) 或者在 ationAfterThrowing 执行普通类中以©Aspect注解(@AspectJ注解方式)来实现
连接点Uoin point)
在程序执行过程中某个特定的点,例如某个方法调用的时间点或者处理异常的时间点。
在Spring AOP中,Y连接点总是代表T方法的执行
通知(Advice)
通知(Advice) :在切面的某个特定的连接点上执行的动作.通知有多种类型,包括忆round", "before" and "afteL等等.通知的类型;许多AOP框架,包括Spring在内,都是以拦截器做通知 模型的,并维护着一个以连接点为中心的拦截器链
切点( Pointcut)
匹配连接点的断言.通知和切点表达式相关联,并在满足这个切点的连接点上运行(例 如,当执行某个特定名称的方法时)。切点表达式如何和连接点匹配是AOP的核心:Spring默认使用Aspect」切点语义。
引入( Introduction
声明额外的方法或者某个类型的字段.Spring^许引入新的接口(以及一个对应的实现)至用田可被通知的对象上.例如,可以使用引入来使bean实现工sModified接口,以便简化缓存机制(在AspectJ社区,引入也被称为内部类型声明 )
目标对象(Target object
被一个或者多个切面所通知的对象.也被称作被通知(advised) 对象。既然 SpringAOP是通过运行时代理实现的,那么这个对象永远是一个被代理( proxied) 的对象。
Aop代理
AOP框架创建的对象,用来实现切面契约(aspect contract) (包括通知方法执行
织人(Weaving):
把切面连接到其它的应用程序类型或者对象上,并创建一个被被通知的对象的过程.这个
过程可以在编译时(例如使用AspectJ编译器)、类加载时或运行时中完成.Spring和其他纯Java庆0「框架一
样,是在运行时完成织人的
过程可以在编译时(例如使用AspectJ编译器)、类加载时或运行时中完成.Spring和其他纯Java庆0「框架一
样,是在运行时完成织人的
AOP的使用场景
事务、日志
和AspectJ AOP区别
切面的通知类型
1、before
2、after
3、AfterReturning
4、AfterThrowing
5、Around
spring容器
spring容器添加组件
1.包扫描(包下面的类全部都是使用@Controller,@Service,@Respository,@Component注解)
2.@Bean直接给定义bean对象
3.@import相关注解给容器添加组件
1.@Import 导入一个对象
@Import({ 类名.class , 类名.class... })public class TestDemo {}
2.在@Import注解中导入ImportSelector接口的实现类(一次导入多个对象);
步骤1:public class Myclass implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{"com.yc.Test.TestDemo3"}; }}
步骤2:@Import({TestDemo2.class,Myclass.class})public class TestDemo { @Bean public AccountDao2 accountDao2(){ return new AccountDao2(); }}
3.ImportBeanDefinitionRegistrar
步骤1:public class Myclass2 implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { //指定bean定义信息(包括bean的类型、作用域...) RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestDemo4.class); //注册一个bean指定bean名字(id) beanDefinitionRegistry.registerBeanDefinition("TestDemo4444",rootBeanDefinition); }}
步骤2:@Import({TestDemo2.class,Myclass.class,Myclass2.class})public class TestDemo { @Bean public AccountDao2 accountDao222(){ return new AccountDao2(); }}
差异和区别
ImportSelector接口和ImportBeanDefinitionRegistrar最终都是需要使用@Import 来做实现的导入,才能实现对组件的添加
4.使用FactoryBean往工厂里面手动添加bean
后置处理器(BeanFactoryPostProcessor)
后置处理器功能
扩展 Spring 容器功能的关键机制。它们允许在 BeanDefinition 阶段 或 Bean 生命周期阶段 对 Bean 做增强。
后置处理器是什么
后置处理器的处理过程
spring的事物管理
spring的事物传播特性
种类
1、required
requires_new
newsted
support
not_support
never
madatory
场景问题
某一个事务嵌套另一个事务的时候怎么办?
A方法调用B方法,AB方法都有事务,并且传播特性不同,那么A如果有异常,B怎么办,B如果有异常,A怎么办?
核心处理逻辑非常简单:
1、判断内外方法是否是同一个事务:
是:异常统一在外层方法处理.
不是:内层方法有可能影响到外层早去,但是外层方法是不会影响内层方法的
1、判断内外方法是否是同一个事务:
是:异常统一在外层方法处理.
不是:内层方法有可能影响到外层早去,但是外层方法是不会影响内层方法的
实现方式
编程式事务(Programmatic Transaction)
通过代码显式管理事务,使用 TransactionTemplate 或 PlatformTransactionManager。
@Autowired
private PlatformTransactionManager transactionManager;
public void doBusiness() {
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
// 业务操作
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
throw e;
}
}
private PlatformTransactionManager transactionManager;
public void doBusiness() {
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
// 业务操作
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
throw e;
}
}
优点:可控、灵活
缺点:代码侵入性强
声明式事务(Declarative Transaction)
通过 注解或 XML 配置方式定义事务边界,不修改业务逻辑。
@Service
public class UserService {
@Transactional
public void createUser(User user) {
userRepository.save(user);
// 其他操作
}
}
public class UserService {
@Transactional
public void createUser(User user) {
userRepository.save(user);
// 其他操作
}
}
优点:侵入性小,业务代码与事务解耦
缺点:底层依赖 AOP 代理
Spring 事务管理器(TransactionManager)
Spring 事务管理是对底层事务的抽象,不同的数据源对应不同实现:
JDBC DataSourceTransactionManager
JPA JpaTransactionManager
Hibernate HibernateTransactionManager
JTA JtaTransactionManager
JPA JpaTransactionManager
Hibernate HibernateTransactionManager
JTA JtaTransactionManager
核心接口:PlatformTransactionManager
核心方法:
getTransaction(TransactionDefinition definition):开启事务
commit(TransactionStatus status):提交事务
rollback(TransactionStatus status):回滚事务
getTransaction(TransactionDefinition definition):开启事务
commit(TransactionStatus status):提交事务
rollback(TransactionStatus status):回滚事务
事物的实现
总
由spring aop通过一个TransactionInterceptor实现的
声明式事务实现原理
详细步骤
1、spring 先解析当前事物的属性信息(根据具体的属性判断是否要开启事物)
2、当前需要开启的时候,获取数据库连接,关闭自动提交的功能,开起事物
3、执行具体的sql逻辑
4、在操作过程中,如果执行失败嘞,会通过completeTeanscationAfterThrowing执行回滚操作,然后再通过doRollBack方法来完成具体的事物的回滚操作,最终还是调用的jdbc中的rollbcak方法做回滚操作
5、在操作过程,如果正常,那么通过commitTransactionAfterReturning来完成事物的提交,具体的提交逻辑通过doCommint方法执行实现的时候先获取jdbc链接,然后通过调用jdbc的事物提交方法提交事物;
6、当事物执行完毕之后,需要通过cleanTransactionInfo方法清理事物相关的信息
spring事物失效
bean对象没有被spring容器管理
方法修饰符不是public
方法是本类调用
事物的实现是通过aop实现的,aop的实现是通过代理来实现;如果不能形成其他类的接口调用,那么就无法生效
实际中失效最多的
数据源没有配置事物管理器
数据库不支持事物
数据库本身不支持事物
异常被捕获了
捕获的异常和配置的异常并不一致
spring的事物隔离级别
和当前项目使用的数据的隔离级别是一致的
bean
bean对象属性说明
bean对象作用域
通过配置scope属性值
prototype
多例;每次需要用到的bean的时候就会去创建这个bean,也就是在一个request请求中可能会多次创建bean对象;
singleton
单例,整个容器都会只用这一个对象,作用域就是整个容器
request
同一次请求创建一个对象;bean对象的作用域就在一起请求当中
session
同一次会话创建一个对象;这个Bean对象的作用域就在这次会话当中
global session
懒加载
通过设置lazy-init
true
懒加载
false
非懒加载,也就是提前加载
懒加载概述
懒加载只是针对多例bean才生效;单实例的bean都是提前加载;多实例的bean默认都是懒加载的形式加载,也就是首次需要用到的时候才会加载;
spring默认是提前加载,所以在启动的时候控制台就会有很多对bean对象的加载
懒加载和非懒加载区别
懒加载在第一需要用到这个对象的时候加载;非懒加载就是在环境启动的时候就提前把对象加载;
懒加载可以节约内存,但是不利于提前发现问题;非懒加载,可以提前发现加载的问题;
注意事项:
1.如果懒加载依赖了非懒加载的bean,那么这个懒加载就会失效;
bean注入的注解
1.@AutoWried
注解是spring提供的;
@Component
public class UserRepository {}
@Service
public class UserService {
@Autowired // 默认按类型注入
private UserRepository userRepository;
}
public class UserRepository {}
@Service
public class UserService {
@Autowired // 默认按类型注入
private UserRepository userRepository;
}
根据类型注入从bean容器中找到UserRepository类型的做注入
2.@Resource
注解是JDK提供的
@Component("userRepo")
public class UserRepository {}
@Service
public class UserService {
@Resource // 默认按名称注入
private UserRepository userRepo;
}
public class UserRepository {}
@Service
public class UserService {
@Resource // 默认按名称注入
private UserRepository userRepo;
}
根据“userRepo” 这个名称从 bean容器中找到 userRepo bean对象注入
相同点不同点
相同点:
1.字段和setter都生效
不同点:
1.一个是spring提供的,一个是JDK提供的
2.注解中的属性不一样;
bean的生命周期
spring bean创建的大致过程
0.实例化spring容器,根据扫描对应的包,把标记是bean对象的类存储在一个Map集合之中;
2.然后在遍历集合中类的对象,把对象的相应的属性都存储到BeanDefintion 中,也就是每一个被遍历的要被构建bean对象的对象都会有一个专属的BeanDefintion 对象;这个BeanDefintion对象存储当前被遍历对象的一切属性,这些属性也是构建bean对象的基础;
3.每一个BeanDefintion 会被存储到 BeanDefintionMap 对象之中;
4.然后还会调用后置处理器去修改增BeanDefintionMap,执行对bean的修改拓展操作(spring内置还有我们自定义的后置处理器)来参与到生命周期的过程;
5.遍历BeanDefintionMap 中BeanDefintion对象,做相关的是否单例,是否抽象,注入模型,循环依赖,是不是懒加载,是不是需要有DepondsOn
6.根据BeanDefintion对象中的信息中的构造方法信息,推断出构造方法;
7.再通过构造方法再去通过反射实例化对象;
11.完成属性注入;
12.回调Aware接口,也就是spring内置的Aware接口(也是修改bean对象的属性)再调用生命周期初始化回调方法(在类中间被@PostConstruct注解修饰,还有实现了InitilizingBean接口的afterPropertiesSet方法,还有xml中配置的afterPropertiesSet方法),执行方法
13.完成aop代理,事件分发,事件监听;
14.生成了Bean,把bean放在单例池;
15.关闭spring容器,那么这些bean对象也会跟着被销毁
bean的实例化过程
bean的作用域
singleton
使用该属性定义Bean时,IOC容器仅创建一个Bean实例,IOC容器每次返回的是同一个Bean实例.
prototype
使用该属性定义Bean时,IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例.
request
该属性仅对HTTP请求产生作用,使用该属性定义Bean时,每次HTTP请求都会创建一个新的Bean,适用于 WebApplicationContexl 环境
session
该属性仅用于HTTP Session,同一个Session共享一个Bean实例.不同Sessio雷用不同的实例.
global-session
该属性仅用于HTTP Session,同session作用域不同的是,所有的Session共享一个Bean实例
bean注入方式
属性注入(最常用的一种方式)
构造器注入
方法上注入
参数上注入
循环依赖
什么是循环依赖
BeanA依赖BeanB;而BeanB又依赖BeanA
spring是怎么解决循环依赖
单例bean是否是线程安全
spring没有对bean对象做多线程处理;bean对象是否安全,主要看定义者怎么定义bean;如果这个bean对象中定义了线程不安全的全局变量,那么这个bean对象就是不安全的;如果定义的对象就是安全,那么这个bean就是安全的;
bean的线程并发问题
定义bean为无状态的bean(对象的时候不要定义全局变量),这样才能再多线程环境下被访问,使用ThreadLoacl来对bean进行线程封闭处理;如果不是无状态的,最好就是把bean定义成多例,每一个线程,或者每一个请求,每一个会话都是一个单独的bean对象
循环依赖创建bean对象过程
具体过程
1、获取ABean对象,从Abean的各级缓存中获取
2发现没有,那么就开始创建bean实例
创建流程
1. 容器创建 A
容器检测 A 不在缓存中 → 开始实例化
实例化对象:调用构造器创建 A(尚未注入 B)
将 A 放入 三级缓存 singletonFactories
提供一个 ObjectFactory,用于获取早期 A 对象
2.容器创建 B
容器检测 B 不在缓存中 → 开始实例化
B 依赖 A → 查找缓存
一级缓存:无
二级缓存:无
三级缓存:有 A 的 ObjectFactory
查三级缓存获取 A 的 ObjectFactory → 提供早期引用
通过 ObjectFactory 获取 早期 A 对象 → 注入 B
3.完成属性注入
1. B 的属性注入完成 → 放入一级缓存
2. 回到 A → 注入 B 完成
3. A 的初始化完成 → 放入一级缓存
4. Bean 初始化完成
BeanPostProcessor 处理前/后置方法
A、B 都可以正常使用
三级缓存
三级缓存各自作用
一级缓存
单例池
使用ConcurrentHashMap
存放构建完成后的完整的bean对象
二级缓存
作用
存放属性还未填充完整的早期暴露出来的bean
特殊说明
也只有处于循环引用中的bean才会被存放在这个二级缓存
三级缓存
作用
存放用于ObjectFactory对象,这个对象是用于来构建bean对象;所以刚刚被创建出来的bean对象都是放在三级缓存
三级缓存流转顺序
有循环依赖
1、反射创建bean实例的时候,将bean对象对应ObjectFactory放在三级缓存
2、有循环依赖时,从三级缓存中获取ObjectFactory实例,然后通过ObjectFactory实例的getObject方法方法来获取早期的bean还没有完全构建完成的bean,且放入二级缓存,从三级缓存中将ObjectFactory实例删除,
3、bean初始化完成,生命周期的相关方法都执行了,就会把bean对象放入一级缓存,然后删除二级缓存;
无循环依赖
1、反射创建bean实例的时候,将bean对象对应ObjectFactory放在三级缓存
3、bean初始化完成,生命周期的相关方法都执行了,就会把bean对象放入一级缓存,然后删除二级缓存;
总结
也就是有循环依赖:三级缓存到二级缓存,再到一级缓存
没有循环依赖就是三级缓存,到一级缓存
循环依赖创建bean对象过程
具体过程
1、获取ABean对象,从Abean的各级缓存中获取
2发现没有,那么就开始创建bean实例
子主题
图片展示
子主题
图片展示
子主题
@Resource和@Autowired
区别
来源不一样
@Resource是jdk提供的注解
@Autowired
注入方式
@Resource默认通过byname注入,也就数已通过名称注入,通过的接口名称来做注入;也可以指定byType注入
@Autowired默认是通过byType(也就是类型注入),也就是默认注入接口的子类;如果接口有多个子类,搭配使用@Qualifier注解指定某一个特定子类
使用差别
如果接口都只有一个子类,那么没有使用上的区别,如果接口有多个实现类,那么只能用@Autowried 搭配@Qualifier 来使用
作用
都可以完成bean对象的注入标识
spring框架组件
核心组件
bean组件(bean对象组件)
封装对象
core组件(核心组件)
发现,构建,维护每一个bean关系所有需要的一些列的关系
context组件(上下文组件)
发现,构建,并且维护每一个bean对象之间依赖关系;可以看成是bean对象的集合,
spring核心类
IOC 容器相关核心类
ApplicationContext
什么是ApplicationContext
BeanFactory 的高级子接口,功能更丰富(国际化、事件发布、AOP 支持)。
FactoryBean
BeanFactory
Spring IOC 容器的顶级接口,定义了 Bean 的获取方式。
BeanDefinition
Bean 的元信息抽象,保存类名、作用域、依赖等。
IOC 容器就是通过 BeanDefinition 来描述和创建 Bean。
BeanWrapper
提供 Bean 的属性访问和修改能力,底层基于 Java 的反射和内省机制。
BeanPostProcessor
Bean 初始化前后提供扩展能力的接口。
比如 AutowiredAnnotationBeanPostProcessor 用来处理 @Autowired 注解。
InstantiationAwareBeanPostProcessor
在 Bean 实例化之前进行扩展(Spring 解决循环依赖时非常关键)。
AOP 相关核心类
ProxyFactoryBean
用来生成代理对象的核心类,基于 JDK 动态代理 / CGLIB。
AdvisedSupport
AOP 配置的核心抽象,包含了切面、通知、目标对象等信息。
MethodInterceptor
方法拦截器,环绕通知的底层接口。
Advisor
切面和通知的组合,封装了 “切点 + 通知”。
上下文与扩展相关
Environment
管理配置文件、属性源(Spring Boot 常用来读取 application.yml)。
ApplicationEvent / ApplicationListener
事件模型,支持事件驱动开发。
Resource / ResourceLoader
Spring 提供的统一资源访问抽象(支持文件、URL、classpath)。
Spring Boot 核心类(扩展了解)
核心注解
引入bean对象
importSelector
import
ImportBeanDefinitionRegistrar
bean对象
@Repository
@Service
@Controller
@Bean
@conditional
@AutoWried
属性值默认是true,一定要被注入;也可以设置成reqiured=false,告诉当前类可以不用注入这个对象;
IOC 相关
@Component
声明一个类交给 Spring 容器管理(通用组件)。
@Controller
Web 层控制器(Spring MVC 专用,语义化 @Component)。
@Service
Service 层业务逻辑类(语义化 @Component)。
@Repository
DAO 层持久化类,语义化 @Component,并支持数据库异常转换。
@Autowired
按 类型 自动注入 Bean。
@Qualifier
配合 @Autowired,指定 Bean 名称,解决多个同类型 Bean 冲突。
@Value
注入配置文件中的属性值。
@Configuration
声明配置类,替代 XML 配置。
@Bean
声明一个方法的返回对象交由 Spring 管理(常用于第三方类注入)。
@Scope
指定 Bean 作用域(singleton/prototype/request/session)。
@Lazy
设置 Bean 延迟加载。
AOP / 事务相关注解
@Aspect
定义切面类。
@Before、@After、@Around、@AfterReturning、@AfterThrowing
定义方法的切入点执行时机。
spring框架设计模式
1、工厂模式
各种BeanFactory,Application创建中都用了
2、模板模式
各种BeanFactory,Application创建中都用到,中间有很多空实现,方便子类去增加方法
3、代理模式
aop的实现用的动态代理
4、策略模式
5、单例模式
bean对象默认都是单利
6、观察者模式
7、适配器模式
8、装饰者模式
实战问题
spring 通过注解开启事物方法
查询某一条数据
更新这条数据
查询这条数据
第二次查询获取的数据是咋样的? 读取的事
查询某一条数据
更新这条数据
查询这条数据
第二次查询获取的数据是咋样的? 读取的事
读取的是更新之后的
原因解释
由于事务未提交,查询还是用 同一个连接,走的是事务内的上下文视图。
所以第二次查询能查到 更新后的值(事务内可见)。
如何实现这个
MySQL InnoDB 支持 MVCC(多版本并发控制):
当前事务的修改自己可见(即使没提交)。
其他事务在你没提交前是看不到的。
springBoot
springBoot优势
1.可以以jar包的形式独立启动
2.内嵌了tomcat/jetty/Undertow服务器。
3.在spring的基础上简化了maven的配置,引入spring-boot-starter-web 依赖;
4.springBoot可以根据类路径中的jar包,类自动配置成bean;
5.有运行时的监控系统
6.快速构建项目,提高开发效率,部署效率;
7.天然与云计算集成;
8.天然的已经整合了很多第三方的框架
spring 和springboot 的区别
Spring 是一个轻量级的企业级开发框架,核心是 IOC 和 AOP,但需要繁琐的配置和依赖管理
Spring Boot 是基于 Spring 的快速开发框架,它通过自动配置、起步依赖和内嵌服务器,简化了 Spring 项目的开发过程
springBoot核心注解
@SpringBootApplication最核心注解
包含以下注解
@SpringBootConfiguration
表示是springboot的配置类
@EnableAutoConfiguration
开启自动配置注解
去mate-info/spring.factiories文件中加载需要被自动注入的java类
@ComponentScan
表示要扫描的当前包以及子包下的所有被标记成spring bean对象的java类
@importResource,@Import
手动给spring添加bean对象,导入一些第三方的配置类
@Indexed
提升@CompontentScan性能的注解
@EnableAsync
开启异步方法
@EnableScheduling
开启定时任务
springBoot自动装配大致过程
详细过程
1、springBoot启动类上面是@SpringBootApplication注解
3、这个注解中又包含了另外一个@Import注解
4、import注解又实现了ImportSelector接口的类型,
5、ImportSelector可以给spring容器中手动添加bean对象
6、所以在spring启动的时候通过ImportSelector中的方法去读取meta/info目录下面的spring.factories文件中需要被自动转配的所有配置类
7、然后再通过meate/info下的springautoconfigure-metadata.properties文件做条件过滤,过滤掉不需要被自动装配的类
8、得到最终需要被装配的类,然后加载到spring容器
1、启动类加载
运行 SpringApplication.run() → 创建 IOC 容器 ApplicationContext。
2、加载自动配置类
@EnableAutoConfiguration → 导入 AutoConfigurationImportSelector。
AutoConfigurationImportSelector 会去 META-INF/spring.factories 里找到所有 xxxAutoConfiguration 类。
3、条件匹配(@Conditional)
每个自动配置类都有条件注解,比如:
@ConditionalOnClass:某个类存在时才生效
@ConditionalOnMissingBean:只有当容器中没有某个 Bean 时才生效
4、注册 Bean
满足条件的 @Configuration 类会向容器中注入 Bean。
比如,DataSourceAutoConfiguration 会帮你自动创建 DataSource,如果你没自己配置数据源的话。
简单过程
Spring Boot 的自动装配是通过 @EnableAutoConfiguration 实现的,它会读取 META-INF/spring.factories 下的自动配置类,再结合 @Conditional 系列注解判断是否生效,最终把符合条件的 Bean 注入到 Spring 容器里,从而实现“约定大于配置,开箱即用”。
springBoot自动装配原理
https://www.bilibili.com/video/BV1TV4y157yz?p=28&vd_source=e6fc2faffd817786a7a38aeaab56c2a1
TODO
springBoot启动方式
1、通过main方法启动
2、达成jar包通过 java -jar的命令启动,或者达成war包掉到web容器中启动
3、使用maven/gradle 插件来运行
springBoot简单介绍
springBoor是基于spring创建的一个上层应用框架,14年发布1.0会比以前那种ssm,给予配置的方式效率高很多
springBoot中starter(启动器)的理解
springBoot启动的时候默认将springBoot自身的bean对象,项目中开发定义的bean对象,以及sptingBoot默认的一些bean对象加载到bean容器
starter会去读取meta-info目录下提供的一个spring.factories文件,将需要默认加载进spring容器的类进行一个读取加载操作
如果第三方的插件组件也需要在启动的时候加载进spring容器,可以自身和spring做一个整合包。但是通常springBoot已经提高了很多整合包了,整合报的命名通常都是 spring-boot-starter-xxx pom依赖
实际开发
如果想引入第三方的配置需要的步骤
1、添加spring-boot-starter-xxx的依赖包到pom文件
2、在配置文件中配置相关的需要的配置
常用的starter包
spring boot-starter-web
提供了SpringMVC+内嵌了Tbmcat容器
spring-boot-starterdata-jpa
提供了 SpringJPA和Hibernate框架整合
sprinq-boot-starter-data-redis
redis数据源整合
spring-boot-starter-solr
solr搜索
mybatis-spring-boot-starter
mybatis-springBoot整合
springBoot需要web容器
一般不需要
spring boot-starter-web
提供了SpringMVC+内嵌了Tbmcat容器
springBoot项目中如何解决跨域问题
解决方式
1、类似通过jsonp类解决跨域问题,但是支持Get方式请求
2、SpringBoot中我们可以通过WebMvcConfigurer重写addCorsMapping方法,在这个方法中添加允许进行跨域的相关请求
什么是跨域问题
1、浏览器的同源策略限制:两个页面的协议,ip地址,端口号必须要是一样的才能请求
还是为了浏览器访问数据安全
跨域就是:协议不一致,ip地址,端口中只要有一个不一致就是跨域
springBoot怎么集成第三方组件
soringBoot项目如何使用log4j
springBoot默认使用的是logback
1、先排除logback的包
2、pom文件中添加log4j依赖
4、配置log4j相关配置
通用方法
1、pom文件中引入springBoot与第三方组件的得整合启动包:spring-boot-starter-redis
2、再在配置文件中引入该组件的必须要配置的配置项
springBoot中bootstrap.yml文件作用
springBoot默认支持的属性文件
application.properties
application.xml
application.yml
application.yaml
springBoot默认是不支持这类配置文件
在springCloud环境下才支持,作用是在springBoot项目启动之前启动一个父容器;
父容器可以在springBoot容器启动之前完成一些加载初始化的操作:比如说加载配置中心的信息
springBoot中Actuator的理解
作用
健康检查(Health):查看应用及依赖服务(数据库、Redis 等)的状态
指标(Metrics):收集 JVM、内存、线程池、请求等指标
信息(Info):应用自定义信息,如版本号、环境等
日志管理(Logging):查看或调整日志级别
审计与追踪(Trace/Httptrace):记录最近请求
端点管理(Endpoint):提供 REST API 来访问以上功能
信息的监控可以在springBoot自带的springBoot admin监控平台上看到;
使用步骤
1、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、配置路径
# 访问端口
management.server.port=8081
# 根路径
management.endpoints.web.base-path=/actuator/z
# web端允许的路径
management.endpoints.web.exposure.include=*
management.server.port=8081
# 根路径
management.endpoints.web.base-path=/actuator/z
# web端允许的路径
management.endpoints.web.exposure.include=*
3、请求获取当前可用的统计接口信息
http://127.0.0.1:8081/actuator/z
/actuator/z里还有端口都是配置文件中配置的
可以得到当前所有的统计信息项目
返回请求路径信息
{
"_links":{
"self":{
"href":"http://127.0.0.1:8081/actuator/z",
"templated":false
},
"prometheus":{
"href":"http://127.0.0.1:8081/actuator/z/prometheus",
"templated":false
},
"beans":{
"href":"http://127.0.0.1:8081/actuator/z/beans",
"templated":false
},
"caches-cache":{
"href":"http://127.0.0.1:8081/actuator/z/caches/{cache}",
"templated":true
},
"caches":{
"href":"http://127.0.0.1:8081/actuator/z/caches",
"templated":false
},
"health-path":{
"href":"http://127.0.0.1:8081/actuator/z/health/{*path}",
"templated":true
},
"health":{
"href":"http://127.0.0.1:8081/actuator/z/health",
"templated":false
},
"info":{
"href":"http://127.0.0.1:8081/actuator/z/info",
"templated":false
},
"conditions":{
"href":"http://127.0.0.1:8081/actuator/z/conditions",
"templated":false
},
"configprops":{
"href":"http://127.0.0.1:8081/actuator/z/configprops",
"templated":false
},
"configprops-prefix":{
"href":"http://127.0.0.1:8081/actuator/z/configprops/{prefix}",
"templated":true
},
"env":{
"href":"http://127.0.0.1:8081/actuator/z/env",
"templated":false
},
"env-toMatch":{
"href":"http://127.0.0.1:8081/actuator/z/env/{toMatch}",
"templated":true
},
"loggers":{
"href":"http://127.0.0.1:8081/actuator/z/loggers",
"templated":false
},
"loggers-name":{
"href":"http://127.0.0.1:8081/actuator/z/loggers/{name}",
"templated":true
},
"heapdump":{
"href":"http://127.0.0.1:8081/actuator/z/heapdump",
"templated":false
},
"threaddump":{
"href":"http://127.0.0.1:8081/actuator/z/threaddump",
"templated":false
},
"metrics":{
"href":"http://127.0.0.1:8081/actuator/z/metrics",
"templated":false
},
"metrics-requiredMetricName":{
"href":"http://127.0.0.1:8081/actuator/z/metrics/{requiredMetricName}",
"templated":true
},
"scheduledtasks":{
"href":"http://127.0.0.1:8081/actuator/z/scheduledtasks",
"templated":false
},
"mappings":{
"href":"http://127.0.0.1:8081/actuator/z/mappings",
"templated":false
},
"refresh":{
"href":"http://127.0.0.1:8081/actuator/z/refresh",
"templated":false
},
"features":{
"href":"http://127.0.0.1:8081/actuator/z/features",
"templated":false
}
}
}
"_links":{
"self":{
"href":"http://127.0.0.1:8081/actuator/z",
"templated":false
},
"prometheus":{
"href":"http://127.0.0.1:8081/actuator/z/prometheus",
"templated":false
},
"beans":{
"href":"http://127.0.0.1:8081/actuator/z/beans",
"templated":false
},
"caches-cache":{
"href":"http://127.0.0.1:8081/actuator/z/caches/{cache}",
"templated":true
},
"caches":{
"href":"http://127.0.0.1:8081/actuator/z/caches",
"templated":false
},
"health-path":{
"href":"http://127.0.0.1:8081/actuator/z/health/{*path}",
"templated":true
},
"health":{
"href":"http://127.0.0.1:8081/actuator/z/health",
"templated":false
},
"info":{
"href":"http://127.0.0.1:8081/actuator/z/info",
"templated":false
},
"conditions":{
"href":"http://127.0.0.1:8081/actuator/z/conditions",
"templated":false
},
"configprops":{
"href":"http://127.0.0.1:8081/actuator/z/configprops",
"templated":false
},
"configprops-prefix":{
"href":"http://127.0.0.1:8081/actuator/z/configprops/{prefix}",
"templated":true
},
"env":{
"href":"http://127.0.0.1:8081/actuator/z/env",
"templated":false
},
"env-toMatch":{
"href":"http://127.0.0.1:8081/actuator/z/env/{toMatch}",
"templated":true
},
"loggers":{
"href":"http://127.0.0.1:8081/actuator/z/loggers",
"templated":false
},
"loggers-name":{
"href":"http://127.0.0.1:8081/actuator/z/loggers/{name}",
"templated":true
},
"heapdump":{
"href":"http://127.0.0.1:8081/actuator/z/heapdump",
"templated":false
},
"threaddump":{
"href":"http://127.0.0.1:8081/actuator/z/threaddump",
"templated":false
},
"metrics":{
"href":"http://127.0.0.1:8081/actuator/z/metrics",
"templated":false
},
"metrics-requiredMetricName":{
"href":"http://127.0.0.1:8081/actuator/z/metrics/{requiredMetricName}",
"templated":true
},
"scheduledtasks":{
"href":"http://127.0.0.1:8081/actuator/z/scheduledtasks",
"templated":false
},
"mappings":{
"href":"http://127.0.0.1:8081/actuator/z/mappings",
"templated":false
},
"refresh":{
"href":"http://127.0.0.1:8081/actuator/z/refresh",
"templated":false
},
"features":{
"href":"http://127.0.0.1:8081/actuator/z/features",
"templated":false
}
}
}
路径
http://127.0.0.1:8081/actuator/z
http://127.0.0.1:8081/actuator/z/prometheus
http://127.0.0.1:8081/actuator/z/beans
当前用哪些bean对象
http://127.0.0.1:8081/actuator/z/health
健康信息
http://127.0.0.1:8081/actuator/z/caches/{cache}
内存信息
http://127.0.0.1:8081/actuator/z/heapdump
当前对内存信息
http://127.0.0.1:8081/actuator/z/threaddump
当前线程内存信息
http://127.0.0.1:8081/actuator/z/metrics
统计信息的具体项目
http://127.0.0.1:8081/actuator/z/scheduledtasks
当前项目有哪些定时任务
http://127.0.0.1:8081/actuator/z/refresh
http://127.0.0.1:8081/actuator/z/features
springBoot 启动中会去默认加载数据库,redis这些配置吗?
自动配置这些通常都是有条件
@ConditionalOnClass → 当某个类在 classpath 中存在才生效
• @ConditionalOnMissingBean → 当容器里没有同类型 Bean 才创建
• @ConditionalOnProperty → 根据配置文件中属性决定是否加载
• @ConditionalOnMissingBean → 当容器里没有同类型 Bean 才创建
• @ConditionalOnProperty → 根据配置文件中属性决定是否加载
数据库(DataSource)
• 条件:
1. classpath 中有 JDBC 驱动或 HikariCP/Tomcat JDBC 等
2. 配置了数据库连接属性,如:
• 条件:
1. classpath 中有 JDBC 驱动或 HikariCP/Tomcat JDBC 等
2. 配置了数据库连接属性,如:
Redis
• 条件:
1. classpath 中有 spring-boot-starter-data-redis 或 Jedis/Lettuce 类
2. 配置了 Redis 连接属性,如:
• 条件:
1. classpath 中有 spring-boot-starter-data-redis 或 Jedis/Lettuce 类
2. 配置了 Redis 连接属性,如:
总结
Spring Boot 不会盲目加载数据库或 Redis,它只会:
• 当 classpath 有相关依赖
• 配置文件中有必要配置
• 自动装配条件满足时
才去初始化相关 Bean
• 优势:开箱即用,但又可通过条件控制关闭(比如 exclude 某些自动配置)
• 当 classpath 有相关依赖
• 配置文件中有必要配置
• 自动装配条件满足时
才去初始化相关 Bean
• 优势:开箱即用,但又可通过条件控制关闭(比如 exclude 某些自动配置)
spring开启特殊功能
@EnableAspectJAutoProxy
开启AspectJ自动代理支持
@EnableAsync
开启异步方法
@EnableScheduling
开启定时任务
@EnableWebMvc
开启web mvc配置
@enabletransactionmanagement
开启事物
@EnableRetry
开启方法重试功能
EnableCircuitBreaker
开启方法熔断功能
spring ,springMvc ,springBoot区别
spring和springMvc
1、spring是一个一站式轻量级的java开发框架,核心是控制反转和切面编程,针对web层,业务层,持久层等都提供了多种配置解决方案
2. springMvc是spring基础之上的一个MVC框架,主要处理web开发的路径映射和视图演染,属于spring框架中
springMvc和springBoot
1、springMvc属于一个企业WEB开发的MVC框架,涵盖面包括前端视图开发、文件配置、后台接口逻辑开发
等,XML、config等配置相对比较繁琐复杂;
等,XML、config等配置相对比较繁琐复杂;
2、springBoot框架相对于springMvc框架来说,更专注于开发微服务后台接口,不开发前端视图,同时遵循默认优于配置,简化了插件配置流程,不需要配置xml,相对springmvc,大大简化了配置流程;
总结
1、Spring框架就像一^家族,有众多衍生产品例如boot、security、jpa等等。但他们的基础都是Spring的ioc. aop等.ioc提供了依赖注入的容器,aop解决了面向横切面编程,然后在此两者的基础上实现了其他延伸产
品的高级功能;
品的高级功能;
2、springMvc主要解决WEB开发的问题,是基于Servlet的fMVC框架,通过XML配置,统T发前端视图和
后端逻辑;
后端逻辑;
3、由于Spring的配置非常复杂,各种XML、JavaConfig、servlet处理起来匕啜繁琐,为了简化开发者的使用,
从而创造性地推出了springB。。唯架,默认优于配置,简化了springMvc的配置流程;但区别于springMvc的是,
springBoot专注于单体微8艮务接口开发,和前端解耦,虽然springBoot也可以做成springMvc前后台一起开发,
但是这就有点不符合springBoot框架的初衷了 ;
从而创造性地推出了springB。。唯架,默认优于配置,简化了springMvc的配置流程;但区别于springMvc的是,
springBoot专注于单体微8艮务接口开发,和前端解耦,虽然springBoot也可以做成springMvc前后台一起开发,
但是这就有点不符合springBoot框架的初衷了 ;
spring-cloud
微服务组件
注册中心
注册中心概述
针对于动态数据,对于服务器的加入,或者删除是可以动态感知的;
注册中心核心功能
服务注册
服务提供方想注册中心发送的心跳时间和续约时间
服务发现
服务提供方想注册中心发送的心跳时间和续约时间
动态追踪服务注册信息
自我保护机制
Eureka 的自我保护机制工作
如果15分钟之内超过85%的客户端节点都没有正常的心跳信息,那么Eureka就会认为客户端和注册中心发生了网络故障,那么EURKEA就会自动进入自我保护机制
Eureka 的自我保护机制下Eureka工作情况
不再从注册列表中剔除长时间没有发送心跳的客户端
继续接受新的服务注册和服务查询,但是这些数据都不会被同步到其他的注册中心;
网络稳定之后,Eureka注册信息才会被同步到其他机器上;
Eureka 的自我保护模式是有意义
防止因为分区网络,导致心跳信息没有发送或者没有接受到信条信息,而错误的把一个正常服务的机器从服务注册列表中剔除;
健康检查
通过客户端给服务端间隔一定时间发送心跳还有发送续约信息;
注册中心好处
客户端,服务端ip地址解耦合
实现服务的动态扩容或者动态删除服务
可监控各个服务运行情况
注册中心实现
Zookeeper
eurake
工作流程
1、启动eureka服务集群
2、eureka客户端通过配置的eureka的服务ip,发送ip,端口,还有服务接口信息
3、Eureka Client 会每 30s 向 Eureka Server 发送一次心跳请求,证明客户端服务正常
4、服务调用的时候会向注册中心获取服务列表,然后从服务列表中获取具体信息,发送服务
工作机制
服务注册
服务注册调用示意图
示意图
各个服务启动时,Eureka Client都会将服务注册到Eureka Server,Eureka Server 内部有二层缓存机制来维护整个注册表
作用
Eurake client 想节点提供自身的元数据,比如 IP 地址、端口
服务续约
过程
Eureka Client 会每隔 30 秒会向eurake节点发送一次心跳来续约,告诉节点服务还在正常运行;
重要属性
服务失效时间
默认30秒
子主题
续约间隔时间
如果 Eureka Server 在 90 秒内没有收到 Eureka Client 的续约,Server 端会将实例从其注册表中删除
服务剔除
Eureka Client 和 Eureka Server 不再有心跳时,Eureka Server 会将该服务实例从服务注册列表中删除,即服务剔除
服务下线
服务关闭时候,想eurake节点发送取消请求,然后该客户端对应的注册信息就会在注册列表中被删除
获取注册列表信息
Eureka客户端从eurake服务节点上获取服务注册列表信息,通过ribbon负载均衡进行远程调用,并将服务注册列表信息缓存在本地。
重要属性
开启还是关闭eurake客户端从节点拉取注册信息
拉取注册列表时间间隔
eureka缓存
1.客户端拉服务列表,注册中心会从缓存中拿,并不每次都是从服务注册列表中获取;
服务端,客户端缓存
eureka服务端信息三级缓存
registry
实时更新
readWriteCacheMap
实时更新
readOnlyCacheMap
周期更新
客户端信息缓存
localRegionApps
upServerListZoneMap
缓存相关配置
服务端配置
客户端是从只读缓存还是从读写缓存获取配置信息
读写缓存更新只读缓存
默认30秒
清理未续约节点周期
默认60秒;间隔60秒会去清理不可用的节点信息
清理未续约节点超时时间
默认90秒;
客户端配置
服务续约周期
增量更新周期
负载均衡周期
2.客户端会缓存服务注册列表;
3.负载均衡器也会缓存服务列表
eureka高可用
eureka注册中心本身支持集群化
集群中的每一个节点都是可以堆外提供注册和服务发现功能
这点和zk的差别很大,zk在同一时间点只能是由一个主节点对外提供服务发现注册功能
集群中的每一个节点也是一个微服务,也可以做相互的注册
eureka集群中某一节点挂了,其他节点持续对外提供服务
eureka高可用集群,中注册中心都是对等的,每个注册中心都会把自己的数据同步给其他注册中心;其他注册中心在收到心跳信息的时候会判断是客户端注册信息还是注册中心注册信息,如果是客户端信息那么注册中心就把数据同步到其他注册中心,如果是注册中心的注册信息那么就不做任何操作;
自我保护策略
服务端
默认情况下,注册中心不会剔除已经挂掉的服务;认为挂掉的服务正在尝试连接注册中心
设置
eureka.server.enable-self-preservation=false
关闭该默认机制;确保注册中心可以剔除不可用实例
eureka.server.eviction-interval-timer-in-ms=5000
剔除失效服务的间隔时间
客户端
心跳时间
lease-renewal-interval-in-seconds
每间隔多久发送一次心跳时间,表示当前服务还活着
续约时间
lease-expiration-duration-in-seconds
超过这个时间没有向注册中发送心跳,那么表示我这个服务已经挂了,请把我剔除服务注册列表
子主题 6
eureka架构
zk和eurake区别
zk保证CP(一致性,容错性)
eruake是ap (可用性,容错性)
eurake 每一个节点都是平等都可以对外提供服务注册和发现,而zk只有集群中的主节点才能堆外提供服务注册和发现
nacos
配置中心
概述
系统启动需要的参数和依赖的各类外部信息;
配置中心自动刷新时限
1、配置中心server端承担起配置刷新的职责
2、提交配置出发post请求给server端的bus/refreah接口
3、server端接受到请求并发送给spring cloud bus总线
4、springcloud bus 接收到消息并通知其他连接到总线的客户端
5、其他客户端接收到通知,请求server端获取最新的配置
6、全部客户端均获取到最新的配置
配置中心如何保证数据安全
1、各个环境做到数据配置隔离
2、配置中心所有的配置信息都进行加密处理
具体实现
springCloud config
apollo
apollo由来
是携程架构部门研发的分布式配置中心
特性
1、统一管理不同环境,不同集群的配置
2、配置修改实时生效
热发布,修改配置,客户端可以在1s接收到最新的配置
3、配置版本管理
配置修改都有版本的概念,可以方便回滚到历史某个版本
4、支持灰度发布
支持发布后,配置只对部分客户端实例生效,等观察一段时间再对所有实例生效
5、发布操作审计
配置编辑,发布都有详细的管理机制以及操作日志,方便追踪问题
6、客户端配置信息监控
可以在见面上查看配置被哪些实例使用
7、提供了java和.net原生客户端
8、提供开发平台api
基础概念
配置管理维度
一级维度
应用层级维度
标识配置所属项目应用
二级维度
环境维度
区分一个应用下不同的环境
DEV
FAT
uat
pro
三级维度
集群维度
相同实力的不同分组
比如说,北京分组,上海分组,配置可能不一样
四级维度
namespace维度
类似同一个项目下针对比如说数据库,redis等等不同的配置文件
本地缓存
Apollo客户端会把从服务端获取到的配置在本地文件系统缓存一份,用于在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置,不影响应用正常运行
apollo设计图
配置更新基础示意图
大致工作流程
1、在管理平台上做配置的修改和发布
2、配置中心通知Apollp客户端有配置更新
3、apollpo客户端从配置中心拉去最新配置,更新本地配置并通知都应用
示意图
子主题
配置更新详细示意图
详细工作流程
1、客户端和服务端保持了一个长连接,能第一时间获得配置更新的推送
2、客户端还会定时从 Apollo 配置中心服务端拉取应用的最新配置
这是一个备用机制
客户端定时拉取会上报本地版本,所以一般情况下,对于定时拉取的操作,服务端都会返回 304 - Not Modified
定时频率默认为每 5 分钟拉取一次,客户端也可以通过在运行时指定 apollo.refreshInterval来覆盖,单位为分钟
3、客户端从 Apollo 配置中心服务端获取到应用的最新配置后,会保存在内存中
4、客户端会把从服务端获取到的配置在本地文件系统缓存一份,在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置
5、应用程序从 Apollo 客户端获取最新的配置、订阅配置更新通知
详细工作示意流程图
子主题
apollo整体设计
示意图
工作流程说明
1、Config Service 提供配置的读取、推送等功能,服务对象是各个微服务
2、Admin Service 提供配置的修改、发布等功能,服务对象是管理界面
3、集群部署
1、Config Service 和 Admin Service 都是多实例、无状态部署,所以需要将自己注册到 Eureka 中并保持心跳
4、服务注册与发现
1、在 Eureka 之上我们架了一层 Meta Server 用于封装Eureka的服务发现接口
2、客户端通过域名访问 Meta Server 获取Config Service服务列表(IP+Port),而后直接通过 IP+Port 访问服务,同时在 Client 侧会做 load balance 错误重试
3、Portal 通过域名访问 Meta Server 获取 Admin Service 服务列表(IP+Port),而后直接通过 IP+Port 访问服务,同时在 Portal 侧会做 load balance、错误重试
apollo相关问题
1、阿波罗如何保证配置实时更新
1、客户端和服务端的长连接保持长连接,能在第一时间获取配置更新的推送
2、客户端还会定时拉取服务端配置是否有更新
2、阿波罗如何保证可用性
1、configservice 集群部署,且都会注册到注册中心
最大程度上保证微服务和服务端配置获取通信畅通
2、admin service 集群部署
配置管理平台和服务端保持配置修改通信畅通
3、客户端会缓存配置信息到本机
当配置中心集群挂了,会从本地读取配置
4、admin sevcie 和conig service 集群工作相互不受对方影响
nacos
实现原理
springBoot 中的@Value是如何读取到 配置中心的数据?
1. 拉取远程配置(在启动时)。
子主题
步骤
1、配置拉取
2、
Apollo
拉取远程配置
启动时从服务端拉配置,写入内存。
apollo将配置信息注入到 Spring Environment。
Apollo 内部会注册 PropertySources,并且对 Environment 做 动态更新:
Spring 的 @Value 注解读取的是 Environment 的实时值,所以再次访问时获取的是最新值。
Nacos
Spring Cloud Config
服务降级熔断
相关概念
服务雪崩
demo解释
当大量的请求请求上层服务,上层服务所依赖的底层服务,在处理请求的时候,无法承受大量的请求,导致底层服务无法快速相应,导致上层服务请求堆积,导致上层服务无法快速处理请求,导致请求堆积,从而导致A服务不可用
解释
由于底层的服务某种原因,导致整个上层服务都不可用,有一种连锁反应
解决方式
服务熔断,服务降级,服务限流
服务限流
解释
单位时间内限制对服务器的访问量
作用
在高并发情况下,保护系统不被大量请求导致服务雪崩
服务熔断
解释
底层服务不可用的时候,上层服务直接不再调用这个底层服务,而直接返回一个结果;
作用
隔离上层和底层服务之间的级联影响,避免系统崩溃
服务降级
解释
服务压力激增的情况下,主动对一些服务不处理或者简单处理,来释放服务器压力,保证服务器核心功能正常运行
作用
保证整个系统核心功能呢个稳定性和可用性
服务熔断,服务降级区别
触发原因
服务熔断是调用链路上的某个服务不可以用引起的;
服务降级从整体负载考虑
目标
熔断是框架层次的处理
降级是业务层次的处理
实现方式
熔断主要是在客户端进行处理,书写兜底处理
降级需要在服务端进行兜底处理
服务降级是对整个系统资源的再次分配(区分核心服务,非核心服务)
服务熔断是服务降级的一种特殊方式,防止服务雪崩而采取的措施;
具体实现
sentinel
sentinel作用
流量控制
熔断降级
系统负载保护
Sentinel概念
资源定义
服务接口
接口中调用的其他服务
熔断降级
某个资源出现不稳定的时候,降低对该资源的调用进行限制并快速失败,避免影响到其他系统造成整个系统雪崩
规则
流量控制规则
熔断降级规则
系统自我保护规则
Sentinel工作机制
1.对资源显示定义,来标记资源
2.提供可修改规则接口
3.对资源适时统计,流量适时监控
熔断降级
熔断策略
平均响应时间
滑动窗口统计中,1秒内的平均响应时间超过了阈值,就会熔断
异常比例
滑动窗口的统计中当资源每秒的请求次数超过5个,且每秒的异常比例超过一定阈值;那么这个方法就会自动返回
异常比例范围 [0.0, 1.0],也就是0%-100%;
异常数
滑动窗口在1分钟的异常数目超过一定的阈值就会进行熔断。
降级策略
线程并发数
线程数量在某个资源上堆积了数量,那么新的请求就会被拒绝;等堆积的线程完成任务后,才开始接受新的请求;
资源相应时间
当依赖的资源出现相应时间过长,那么对该资源的访问都会直接被拒绝,等到一定的时间窗口之后再回复正常访问;
降级规则
熔断-降级区别
熔断就是直接不能访问该接口,该接口直接返回错误的执行方法;降级,一段时间之内不能再次访问这个接口,等高峰期过了才会再次访问该接口;
流量控制
流量控制角度
控制效果
直接限流
冷启动
排队
运行指标
QPS
系统负载
线程池
资源调用关系
概述
一个资源可能调用其他资源,形成一个调用链路,通过调用链路可以衍生出更多的流量控制手段
控制方式
根据调用方限流
根据调用链路入口限流:链路限流
关系资源流量控制
控制方式
保护业务线程不被耗尽,当某个资源超过一定阈值数量的线程排队的时候,对该资源的请求就会直接被拒绝,等到没有排队线程就会接受新的请求
冷启动
系统长期处于低活跃度,短期流量猛增,直接把系统拉大高水位可能直接把系统冲垮;让流量缓慢的增加,给系统一个预热时间,避免系统被冲垮;
均速器
通过漏斗算法严格控制请求通过的间隔时间
直接拒绝
当QPS超过任意规则的阈值,新的请求就会被立即拒绝,拒绝方式抛出FlowException
限流控制规则配置项
resource
限流规则作用对象
count
限流阈值
grade
限流阈值类型(QPS或者并发线程数)
limitApp
是否区分调用来源
strategy
调用关系限流策略
controlBehavior
流控控制效果(直接决绝,冷启动,均速排队)
限流规则统计项目
系统保护
系统保护规则
1.通过网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去
2.让系统的入口流量和系统的负载达到一个平衡,保证在系统能力范围之内处理最多请求;
sentinel和Hystrix对比
不同点
扩展性
sentinel扩展性强Hystrix区别
熔断降级策略
sentinel基于相应时间,异常比例,异常数量熔断降级; Hystrix只能通过异常比例来降级
限流
sentinel基于QPS支持基于调用关系的限流;Hystrix对限流支持比较有限
隔离策略
sentinel通过某一个资源被调用的并发线程数,当线程在某个资源上堆积到了一定程度新请求就会被拒绝; Hystrix每一个资源都会分配相应的线程池,通过资源对应的线程池控制
流量整形
sentinel支持预热模式,匀速器模式,预热排队模式;Hystrix不支持
控制台
sentinel控制台可以查询规则,配置规则,监控情况;Hystrix只能监控查看
系统自适应保护
sentinel支持Hystrix不支持
相同点
实时统计实现
都是通过滑动窗口来做指标统计
动态规则配置
sentinel Hystrix都支持多数据源
注解
sentinel,Hystrix都支持注解开发
hystrix
Hystrix使用
@HystrixCommand
commandKey,groupKey,thread key重点说明
commandKey
代表一类command,代表底层依赖的一个接口
groupKey
代表了某一个底层的依赖服务;这个服务可以有多个接口
逻辑上是组织起一堆的command key的调用,统计信息,成功次数,timeout次数,失败次数,可以看到某一些服务整体的访问情况
如果不配置
threadPoolKey
线程池配置
以上三者实战说明
同时配置了groupKey 和 threadPoolKey,具有相同的threadPoolKey的使用同一个线程池
如果只配置了groupKey ,那么具有相同的groupKey 的使用同一个线程池
总结
一般来说command group 是对应了一个底层服务,多个command key对应这个底层服务的多个接口,这多个接口按照 command group 共享一个线程池
如果想单独给某一个底层接口也就是某一个command key设置线程池,直接配置上threadpool key 就可以
fallbackMethod
回滚的方法名称
报错之后,执行的默认方法
commandProperties
可以配置执行的隔离策略是线程隔离,还是信号量隔离
参数设置
hystrix.command.default.execution.isolation.strategy 隔离策略,默认是Thread, 可选Thread|Semaphore
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 命令执行超时时间,默认1000ms
hystrix.command.default.execution.timeout.enabled 执行是否启用超时,默认启用true
hystrix.command.default.execution.isolation.thread.interruptOnTimeout 发生超时是是否中断,默认true
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests 最大并发请求数,默认10,该参数当使用ExecutionIsolationStrategy.SEMAPHORE策略时才有效。如果达到最大并发请求数,请求会被拒绝。理论上选择semaphore size的原则和选择thread size一致,但选用semaphore时每次执行的单元要比较小且执行速度快(ms级别),否则的话应该用thread。
emaphore应该占整个容器(tomcat)的线程池的一小部分。
threadPoolProperties
线程池相关的配置
参数设置
hystrix.threadpool.default.coreSize 并发执行的最大线程数,默认10
hystrix.threadpool.default.maxQueueSize BlockingQueue的最大队列数,当设为-1,会使用SynchronousQueue,值为正时使用LinkedBlcokingQueue。该设置只会在初始化时有效,之后不能修改threadpool的queue size,除非reinitialising thread executor。默认-1。
hystrix.threadpool.default.queueSizeRejectionThreshold 即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝。因为maxQueueSize不能被动态修改,这个参数将允许我们动态设置该值。if maxQueueSize == -1,该字段将不起作用
hystrix.threadpool.default.keepAliveTimeMinutes 如果corePoolSize和maxPoolSize设成一样(默认实现)该设置无效。如果通过plugin(https://github.com/Netflix/Hystrix/wiki/Plugins)使用自定义实现,该设置才有用,默认1.
hystrix.threadpool.default.metrics.rollingStats.timeInMilliseconds 线程池统计指标的时间,默认10000
hystrix.threadpool.default.metrics.rollingStats.numBuckets 将rolling window划分为n个buckets,默认10
ignoreExceptions
忽略一些异常,这些异常不被统计到熔断中
observableExecutionMode
定义hystrix observable command的模式;
raiseHystrixExceptions
任何不可忽略的异常都包含在HystrixRuntimeException中;
defaultFallback
默认的回调函数,该函数的函数体不能有入参,
返回值类型与@HystrixCommand修饰的函数体的返回值一致。如果指定了fallbackMethod,则fallbackMethod优先级更高。
返回值类型与@HystrixCommand修饰的函数体的返回值一致。如果指定了fallbackMethod,则fallbackMethod优先级更高。
其他参数
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests 如果并发数达到该设置值,请求会被拒绝和抛出异常并且fallback不会被调用。默认10
hystrix.command.default.fallback.enabled 当执行失败或者请求被拒绝,是否会尝试调用hystrixCommand.getFallback() 。默认true
Circuit Breaker相关的属性
hystrix.command.default.circuitBreaker.enabled 用来跟踪circuit的健康性,如果未达标则让request短路。默认true
hystrix.command.default.circuitBreaker.requestVolumeThreshold 一个rolling window内最小的请求数。如果设为20,那么当一个rolling window的时间内(比如说1个rolling window是10秒)收到19个请求,即使19个请求都失败,也不会触发circuit break。默认20
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds 触发短路的时间值,当该值设为5000时,则当触发circuit break后的5000毫秒内都会拒绝request,也就是5000毫秒后才会关闭circuit。默认5000
hystrix.command.default.circuitBreaker.errorThresholdPercentage错误比率阀值,如果错误率>=该值,circuit会被打开,并短路所有请求触发fallback。默认50
hystrix.command.default.circuitBreaker.forceOpen 强制打开熔断器,如果打开这个开关,那么拒绝所有request,默认false
hystrix.command.default.circuitBreaker.forceClosed 强制关闭熔断器 如果这个开关打开,circuit将一直关闭且忽略circuitBreaker.errorThresholdPercentage
Metrics相关参数
hystrix.command.default.metrics.rollingStats.timeInMilliseconds 设置统计的时间窗口值的,毫秒值,circuit break 的打开会根据1个rolling window的统计来计算。若rolling window被设为10000毫秒,则rolling window会被分成n个buckets,每个bucket包含success,failure,timeout,rejection的次数的统计信息。默认10000
hystrix.command.default.metrics.rollingStats.numBuckets 设置一个rolling window被划分的数量,若numBuckets=10,rolling window=10000,那么一个bucket的时间即1秒。必须符合rolling window % numberBuckets == 0。默认10
hystrix.command.default.metrics.rollingPercentile.enabled 执行时是否enable指标的计算和跟踪,默认true
hystrix.command.default.metrics.rollingPercentile.timeInMilliseconds 设置rolling percentile window的时间,默认60000
hystrix.command.default.metrics.rollingPercentile.numBuckets 设置rolling percentile window的numberBuckets。逻辑同上。默认6
hystrix.command.default.metrics.rollingPercentile.bucketSize 如果bucket size=100,window=10s,若这10s里有500次执行,只有最后100次执行会被统计到bucket里去。增加该值会增加内存开销以及排序的开销。默认100
hystrix.command.default.metrics.healthSnapshot.intervalInMilliseconds 记录health 快照(用来统计成功和错误绿)的间隔,默认500ms
Request Context 相关参数
hystrix.command.default.requestCache.enabled 默认true,需要重载getCacheKey(),返回null时不缓存
hystrix.command.default.requestLog.enabled 记录日志到HystrixRequestLog,默认true
Collapser Properties 相关参数
hystrix.collapser.default.maxRequestsInBatch 单次批处理的最大请求数,达到该数量触发批处理,默认Integer.MAX_VALUE
hystrix.collapser.default.timerDelayInMilliseconds 触发批处理的延迟,也可以为创建批处理的时间+该值,默认10
hystrix.collapser.default.requestCache.enabled 是否对HystrixCollapser.execute() and HystrixCollapser.queue()的cache,默认true
hystrix.command.default.fallback.enabled 当执行失败或者请求被拒绝,是否会尝试调用hystrixCommand.getFallback() 。默认true
Circuit Breaker相关的属性
hystrix.command.default.circuitBreaker.enabled 用来跟踪circuit的健康性,如果未达标则让request短路。默认true
hystrix.command.default.circuitBreaker.requestVolumeThreshold 一个rolling window内最小的请求数。如果设为20,那么当一个rolling window的时间内(比如说1个rolling window是10秒)收到19个请求,即使19个请求都失败,也不会触发circuit break。默认20
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds 触发短路的时间值,当该值设为5000时,则当触发circuit break后的5000毫秒内都会拒绝request,也就是5000毫秒后才会关闭circuit。默认5000
hystrix.command.default.circuitBreaker.errorThresholdPercentage错误比率阀值,如果错误率>=该值,circuit会被打开,并短路所有请求触发fallback。默认50
hystrix.command.default.circuitBreaker.forceOpen 强制打开熔断器,如果打开这个开关,那么拒绝所有request,默认false
hystrix.command.default.circuitBreaker.forceClosed 强制关闭熔断器 如果这个开关打开,circuit将一直关闭且忽略circuitBreaker.errorThresholdPercentage
Metrics相关参数
hystrix.command.default.metrics.rollingStats.timeInMilliseconds 设置统计的时间窗口值的,毫秒值,circuit break 的打开会根据1个rolling window的统计来计算。若rolling window被设为10000毫秒,则rolling window会被分成n个buckets,每个bucket包含success,failure,timeout,rejection的次数的统计信息。默认10000
hystrix.command.default.metrics.rollingStats.numBuckets 设置一个rolling window被划分的数量,若numBuckets=10,rolling window=10000,那么一个bucket的时间即1秒。必须符合rolling window % numberBuckets == 0。默认10
hystrix.command.default.metrics.rollingPercentile.enabled 执行时是否enable指标的计算和跟踪,默认true
hystrix.command.default.metrics.rollingPercentile.timeInMilliseconds 设置rolling percentile window的时间,默认60000
hystrix.command.default.metrics.rollingPercentile.numBuckets 设置rolling percentile window的numberBuckets。逻辑同上。默认6
hystrix.command.default.metrics.rollingPercentile.bucketSize 如果bucket size=100,window=10s,若这10s里有500次执行,只有最后100次执行会被统计到bucket里去。增加该值会增加内存开销以及排序的开销。默认100
hystrix.command.default.metrics.healthSnapshot.intervalInMilliseconds 记录health 快照(用来统计成功和错误绿)的间隔,默认500ms
Request Context 相关参数
hystrix.command.default.requestCache.enabled 默认true,需要重载getCacheKey(),返回null时不缓存
hystrix.command.default.requestLog.enabled 记录日志到HystrixRequestLog,默认true
Collapser Properties 相关参数
hystrix.collapser.default.maxRequestsInBatch 单次批处理的最大请求数,达到该数量触发批处理,默认Integer.MAX_VALUE
hystrix.collapser.default.timerDelayInMilliseconds 触发批处理的延迟,也可以为创建批处理的时间+该值,默认10
hystrix.collapser.default.requestCache.enabled 是否对HystrixCollapser.execute() and HystrixCollapser.queue()的cache,默认true
hystrix设计
hystrix的熔断设计
熔断请求判断机制算法:使用无锁循环队列计数,每个熔断器默认维护10个bucket,每1秒一个bucket,每个blucket记录请求的成功、失败、超时、拒绝的状态,默认错误超过50%且10秒内超过20个请求进行中断拦截。
熔断恢复:对于被熔断的请求,每隔5s允许部分请求通过,若请求都是健康的(RT<250ms)则对请求健康恢复
熔断报警:对于熔断的请求打日志,异常请求超过某些设定则报警
hystrix的隔离设计
线程池隔离
对每一个设置了线程池的资源(理解成一个接口或者一类接口,或者针对某一个底层服务的所有接口),都会开启一个专属的线程池来处理这些资源对应的请求,线程池来处理这些资源对应的请求,堆积的请求也会进入线程池对应的阻塞队列
项目在启动的时候会有一些资源消耗,但是会在大批量的请求到来的时候,可以游刃有余的处理
信号量隔离
信号量来记录当前有多少线程在运行,请求进来的时候先判断是否会超过最大的信号量(最大线程数量),如果超过那么就会丢弃最新的请求,不超过就会让信号量+1,严格控制当前正在执行的线程数量
无法应对大量的请求,大量的请求过来,就是直接放弃执行了,
对比
线程池因为有阻塞队列的原因,所以在一定程度上可以保存一分部请求,慢慢处理;但是信号量就不行,需要严格控制当前执行的线程个数
hystrix的超时机制设置
等待超时
设置任务入列最大时间
判断阻塞队列的头部任务入列时间是否大于超时时间。大于则放弃任务
运行超时
直接可以使用线程池的get方法
hystrix工作流程
熔断流程
1、当出现调用错误的时候,开起一个时间窗口(默认十秒)
2、在这个时间串口内,统计调用次数是否达到最小次数
如果没有达到,则重置统计信息,回到第一步
如果没有达到,即使请求全部失败,也回到第一步
3、如果次数达到了,统计失败占总请求的百分比阈值是否达到
如果没有达到,则重置统计数据,回到第一步
4、如果达到则跳闸
5、开起一个默认时间为5秒的活动窗口,每间隔5秒钟,让一个请求通过去访问已经跳闸的服务;
如果失败,回到第三步继续计算错误百分比
6、如果调用成功,重置断路器
简易工作流程图
流程图
Resillence4j
网关
网关概念
网关工作流程
具体实现
zuul
gateway
限流
负载均衡
熔断
Spring Cloud Gateway 底层使用了高性能的通信框架Netty
负载均衡
负载均衡概念
具体实现
Ribbon
特点
无需部署,直接嵌入客户端做为负载均衡器使用
spring cloud LoadBalance
ribbon
使用
1.调用端引入ribbon的包
注意事项
1.负载均衡默认算法是轮询
2.通过把负载均衡对象定义成bean修改负载均衡算法
负载均衡算法
1、轮询策略
按照一定的顺序依次调用服务实例
2、权重策略
根据每个服务提供者的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性也就越低
实现
刚开始使用轮询策略并开启一个计时器,每一段时间收集一次所有服务提供者的平均响应时间,然后再给每个服务提供者附上一个权重,权重越高被选中的概率也越大
3、随机策略
从服务提供者的列表中随机选择一个服务实例
4、最小连接数策略
遍历服务提供者列表,选取连接数最小的⼀个服务实例;如果有相同的最小连接数,那么会调用轮询策略进行选取
5、重试策略
可以看做是轮询策略的一种
按照轮询策略来获取服务
如果服务实力失效或者服务实例为null,指定的时间之内不断地进行重试来获取服务,如果超过指定时间依然没获取到服务实例则返回 null
6、可用性敏感策略
可用敏感性策略
先过滤掉非健康的服务实例,然后再选择连接数较小的服务实例
7、区域敏感策略
根据服务所在区域(zone)的性能和服务的可用性来选择服务实例,在没有区域的环境下,该策略和轮询策略类似
工作流程简述
1、ribbon拦截所有的远程调用
2、解析调用路径中的host,获取服务名称
3、根据服务名称获取服务实例列表
1、先从本地获取服务实例列表
2、本地不存在,那么就从注册中心拉去服务列表,缓存本地
4、根据负载均衡策略获取某一个具体的服务ip和端口
3、再通过http请求框架请求服务获取结果
工作流程示意图
示意图
负载均衡实现方式
客户端实现
ribbon
服务端实现
nginx
lvs
F5 硬件实现
客户端服务端负载均衡示意图
子主题
服务端实现负载均衡问题
1、需要服务端有强的流量控制权
2、无法满足不同调用方使用不同的负载均衡策略需求
客户端这边就可以实现这个,避免这个问题;
调用方式
两者的区别联系
区别
feign是ribbon调用方式的封装
联系
子主题
负载均衡
算法种类
轮询
随机
过滤故障,连接数超过一定阈值机器,剩下进行轮询
过滤故障机器,轮询
过滤掉故障机器,选择并发最小访问
根据平均响应时间加权选择服务
根据机器性能,可以用性选择服务
请求重试机制
具体实现
feign
使用
1.调用端引入feign包
2.调用端定义服务接口
3.用定义的服务接口调用
注意事项
1.负载均衡默认算法是轮询
配置文件中定义修改后的负载均衡算法
rest template
open feign
feign理论
简单介绍
http请求调用的轻量级框架
作用
1、简化springcloud 对远程接口开发以及调用
2、整合spring ribbon,hystrix实现接口负载均衡和短路
Feign的HTTP客户端
目前支持
HttpURLConnection
JDK自带
未实现连接池;需要自己手动实现连接池
HttpClient
封装http请求头,参数,内容,响应体,方便开发
自带Http连接池
OKHttp
OKHttp拥有共享Socket,减少对服务器请求次数
自带http连接池
默认使用
HttpURLConnection
feign和openfeign区别
OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解
OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类做负载均衡和服务调用
feign工作流程
feign接口调用流程
详细流程图
流程图
详细流程
1、本地接口A调用远程接口B
2、通过接口的动态代理实现了接口B
3、接口B读取解析springMvc相关注解,生成http请求
1、解析@FeignClient注解获取服务名称,获取请求路径
2、解析请求路径还有参数信息
3、序列化操作,非必要 ?
4、接口B将请求相关信息交给Ribbon对应的负载均衡器
1、获取去注册中心获取这个服务对应的服务列表
2、根据负载均衡算法从注册列表中选择一个
5、负载均衡器生成最终的请求地址
6、交给http组件发送请求
feign接口启动注册流程
详细流程
1、启动类启动的时候扫描启动类上的注解@EnableFeignClients
2、这个注解中@EnableFeignClients中还有一个@Import注解,这个注解引入了一个FeignClientsRegistrar类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
// 引入FeignClientsRegistrar 来扫描@FeignClient注解下的类
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {
...
}
@Target(ElementType.TYPE)
@Documented
// 引入FeignClientsRegistrar 来扫描@FeignClient注解下的类
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {
...
}
3、这个类实现了ImportBeanDefinitionRegistrar接口,也就是可以想spring容器中手动注入bean对象
**
* spring boot 启动时会自动调用 ImportBeanDefinitionRegistrar 入口方法
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata
, BeanDefinitionRegistry registry) {
// 读取 @EnableFeignClients 注解中信息
registerDefaultConfiguration(metadata, registry);
// 扫描所有@FeignClient注解的类
registerFeignClients(metadata, registry);
}
* spring boot 启动时会自动调用 ImportBeanDefinitionRegistrar 入口方法
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata
, BeanDefinitionRegistry registry) {
// 读取 @EnableFeignClients 注解中信息
registerDefaultConfiguration(metadata, registry);
// 扫描所有@FeignClient注解的类
registerFeignClients(metadata, registry);
}
4、FeignClientsRegistrar类中有一个方法registerBeanDefinitions ,做bean相关的操作
5、registerDefaultConfiguration方法,会去读取@EnableFeignClients注解;将这些信息注册到一个 BeanDefinitionRegistry 里面去
feign的一些默认配置将通过这里注册的信息中取获取
5、registerFeignClients方法中有registerFeignClients,和扫描所有@FeignClient注解的类
1、先扫描相关包路径
2、通过@FeiginClient注解信息向BeanDefinitionRegistry里面注册bean
registerFeignClients流程图
6、registerFeignClient方法构建bean
1、实际构建的FeignClientFactoryBean
详细流程图
流程图
监控中心
springBoot admin
链路追踪
sleuth
skywalking
pinpoint
微服务架构相关问题
基础概念类
什么是微服务?和单体应用相比有何优缺点?
缺点
简单
运维复杂、分布式事务难、调用链监控和调试难
详细
服务调用复杂性
网络问题
容错问题
负载问题
高并发问题
事物一致性问题
运维复杂性提高
单体服务只需要维护一个服务;
微服务需要维护很多个服务
测试复杂性提高
微服务调用链路变长了
优点
简单
优点:服务独立部署、技术栈灵活、易于扩展、按需伸缩
详细
1、服务部署灵活性提高
单体架构是每做一次修改,就必须要将单体服务进行全量的重新部署;
微服务是,修改某一块业务只需要部署这某一块业务对应的微服务就可以,发布快捷轻便;
2、技术更加灵活
单体引用对同一类型的技术栈,往往只选择一种技术栈,如果要做多个技术栈选择往往会相互影响;
而微服务可以是针对每一个拆分出来的服务做针对性的技术栈选型,而可以相互不影响;
3、应用性能得到提高
4、简化开发
单体服务
单体服务,就是所有开发都在开发一个单体服务,团队协作,分支合并要求很高;还需要团队的每个成员对整个系统都需要有一定的了解;
团队协作性要求高
每次做修改,都需要沟通团队中的相关其他开发;通知影响范围;
开发上手难度大
需要对整个系统都有一定了解
单体服务包含了各个业务代码,开发,改动起来影响范围更大
微服务
降低对团队协作性要求
一个开发组,只需要开发属于他那一块的微服务,不需要很高的团队协作性;
降低开发上手难度
快速开发只需要熟悉他那块的微服务就可以,不需要对整个系统都很了解;
5、业务边界清晰
单体服务
涉及到复合业务的时候,往往都是在其他的业务中书写相关的业务代码;业务边界,责任不够清晰;
微服务
对同一类型业务会,都已封装成对应的接口,由单独的团队或者开发来负责;业务边界清晰,责任分明
5、代码复用性
微服务还可以提高代码复用性;
单体架构和微服务架构的区别?
单体:一个应用包,所有功能放一起,部署简单但扩展难。
微服务:拆分成多个服务,灵活扩展,但需要治理体系(注册中心、配置中心、网关等)。
微服务之间如何通信?
同步:HTTP REST、gRPC、Dubbo RPC
gRPC
基于 HTTP/2 协议,支持多路复用、双向流、头部压缩。
使用 Protobuf(二进制序列化),性能比 JSON 更高。
用 Protobuf(二进制格式),体积小、性能高,但可读性差。
Dubbo
默认使用 TCP 长连接,结合自定义的二进制协议(Dubbo 协议),也可以支持 HTTP、gRPC。
更加灵活,主要用于 Java 体系。
支持多种序列化方式(Hessian2、Protobuf、JSON 等),默认 Hessian2(二进制格式)。
异步:消息队列(Kafka、RocketMQ、RabbitMQ)
微服务之间通过 HTTP 协议通信,遵循 REST 架构风格,通常使用 JSON 作为数据格式。
REST:是一种 架构风格,告诉你“该怎么设计 API”。
HTTP:才是真正的 通信协议,负责数据在客户端和服务端之间传输。
JSON/XML:是常用的数据格式,用来承载资源的数据。
RPC、gRPC、Thrift 的区别?
RPC(Remote Procedure Call,远程过程调用)
概念
RPC 是一种 通信范式,允许客户端像调用本地方法一样调用远程服务
本质:封装网络通信,让调用远程服务像本地方法一样透明
本质:封装网络通信,让调用远程服务像本地方法一样透明
特点
可以使用不同协议实现(HTTP、TCP、UDP 等)
序列化方式灵活(JSON、XML、Protobuf 等)
语言无关(取决于具体实现)
gRPC(Google RPC)
gRPC 是 Google 开源的高性能 RPC 框架
基于 HTTP/2 和 Protobuf(默认)
支持 多语言(Java、Go、Python、C++ 等)
Apache Thrift
概念
Thrift 是 Apache 开源的跨语言 RPC 框架
最初由 Facebook 开发
提供 接口定义语言(IDL) + 跨语言序列化/传输协议
微服务如何划分?
按业务领域(DDD 思想)
单一职责,独立部署,避免过度细化
微服务和 SOA 有什么区别?
SOA:面向企业级 系统集成,强调“服务复用 + 中心化”。
微服务:面向互联网 敏捷开发,强调“服务自治 + 去中心化”。
什么情况下不适合上微服务?
系统规模较小
如果是一个 简单的管理后台、企业官网、内部工具,业务逻辑不复杂。
团队规模较小
微服务强调 团队与服务一一对应(Conway 定律)。
业务模型不清晰
业务还在快速变化,领域边界不明确时,如果强行拆分服务,很容易拆错。
技术和运维能力不足
微服务需要 完善的 DevOps、自动化测试、持续集成/部署、容器化、监控告警。
对性能要求极高、延迟敏感
单体应用内部调用是 方法调用,延迟非常低。
事务一致性要求很高
微服务天然是分布式的,事务一致性需要用 分布式事务(TCC、Saga、MQ 补偿) 来保证。
微服务架构特点
一组小的服务
独立的进程
轻量级通信
基于业务能力
独立部署
无集中式管理
服务治理类
为什么需要注册中心?
动态发现服务,避免硬编码 IP/端口
支持扩容/缩容,负载均衡
微服务如何实现服务注册与发现?
通过注册中心(如 Eureka、Nacos、Zookeeper、Consul)。
Provider 启动时注册服务,Consumer 通过注册中心发现可用服务。
微服务调用如何实现负载均衡?
客户端负载均衡:Ribbon、Feign
服务端负载均衡:Nginx、Gateway、K8s Service
Eureka 和 Zookeeper 的区别?
Zookeeper:CP(强一致性,节点挂掉可能不可用)
Eureka:AP(保证可用性,短暂不一致但可继续服务)
日志
如何做 集中日志管理?(ELK、EFK)
总结
集中日志管理 = 采集 (Filebeat/Fluentd) → 传输 (Kafka/直发) → 存储 (Elasticsearch/Loki) → 展示 (Kibana/Grafana) → 告警。
详细步骤
日志采集
每个服务写日志到本地文件(Logback / Log4j2)。
通过 Agent/采集器 收集日志
Filebeat(轻量级日志收集器,常配合 ELK)
Fluentd / Fluent Bit(CNCF 项目,性能更高)
Logstash(功能强大,但资源开销大)
日志传输
采集器将日志发送到消息队列或日志存储:
Kafka(常见缓冲层,削峰填谷)
直接推送到 Elasticsearch / Loki
日志存储
Elasticsearch:全文检索能力强,查询灵活。
日志分析与展示
Kibana(可视化查询,配合 Elasticsearch)。
或者
Grafana + Loki(轻量化日志查询、告警)。
Graylog(开源日志管理平台)。
告警与联动
日志异常 → 触发告警 → 通知(钉钉、企业微信、PagerDuty)。
结合 Prometheus + Alertmanager,实现指标与日志联动。
为什么要集中日志?
微服务部署在不同节点,日志分散。
线上问题要快速定位,单机 grep 不现实。
需要全局视角:查询、聚合、分析、报警。
监控
如何实现服务监控?
Metrics 指标:Prometheus + Grafana
链路追踪:Sleuth + Zipkin / SkyWalking / Jaeger
健康检查:Actuator /health
链路追踪的作用?
跨服务调用时跟踪完整链路,定位性能瓶颈和异常
如何监控微服务的 健康状态
监控微服务的健康状态是 运维和高可用 的核心工作
常见做法包括 主动探测 + 被动监控 + 日志/指标收集
1. 应用层健康检查
目标:判断单个服务是否正常
在每个微服务中提供健康检查接口(常见 /health、/actuator/health)
使用 Spring Boot Actuator,自动提供 /actuator/health,可显示数据库、Redis、消息队列等依赖的健康情况。
可以定制检查逻辑,比如依赖的外部服务是否可用
2. 服务调用链监控
目标:判断微服务之间调用是否正常、是否有瓶颈。
3. 系统指标监控
监控内容
应用级指标:QPS、RT、错误率、线程池情况、队列堆积。
系统级指标:CPU、内存、磁盘、网络带宽。
监控工具
Prometheus + Grafana:常见组合,采集 + 可视化。
Micrometer:Spring Cloud 的指标收集库,支持接入 Prometheus、InfluxDB 等。
4. 日志监控与报警
集中日志管理:ELK(Elasticsearch + Logstash + Kibana)、EFK(Fluentd)。
异常日志报警:接入 告警系统(如钉钉/企业微信/邮件)。
5. 熔断与降级机制(被动容错)
目标:即使监控不到位,微服务也要有 自我保护
Hystrix / Resilience4j:支持熔断、降级、隔离,防止雪崩。
K8s HPA(自动扩容):CPU/请求数过高时自动扩容。
配置
微服务配置中心的作用?
集中管理配置,支持动态刷新、多环境、多租户、灰度发布
配置如何实现 动态刷新?
不同的配置中心有不同的实现方式
Nacos Config
客户端会和 Nacos Server 建立 长轮询 或 推送机制。
当配置变更时,Nacos Server 主动推送变更通知。
Apollo(携程开源)
客户端和 Apollo Server 长轮询。
配置变更时 Apollo Server 主动通知客户端拉取。
常见配置中心有哪些?
Spring Cloud Config、Apollo、Nacos、Consul KV
微服务配置如何管理?
使用配置中心(Spring Cloud Config、Apollo、Nacos)集中管理,支持动态刷新、多环境。
微服务网关
网关在微服务架构中的作用?
统一入口,路由转发
鉴权、限流、熔断、日志、跨域处理
常见实现:Spring Cloud Gateway、Zuul、Kong、Traefik
容错与高可用
微服务如何实现熔断和限流?
熔断:Hystrix、Resilience4j、Sentinel
限流:令牌桶、漏桶算法,或使用网关(Nginx/Gateway)
服务雪崩效应是什么?如何解决?
含义:一个服务不可用,导致调用它的服务也不可用,逐级放大。
解决:熔断、隔离(线程池/信号量隔离)、限流、服务降级。
如何保证微服务的高可用?
多实例部署 + 负载均衡
健康检查和自动剔除不可用节点
配置中心、注册中心的高可用(集群部署)
服务降级(返回兜底数据)
服务熔断(避免雪崩效应)
限流(防止流量突增压垮服务)
异步削峰
熔断和降级,限流区别?
熔断:服务异常/超时过多,直接切断请求
目的
防止下游服务故障或高延迟影响整体系统
类似电路熔断,遇到故障自动中断请求,防止故障扩散
类似电路熔断,遇到故障自动中断请求,防止故障扩散
原理
状态机:
闭合(Closed):正常请求,统计错误率
打开(Open):错误率超过阈值,短时间内拒绝请求
半开(Half-Open):尝试少量请求,验证服务是否恢复
当下游恢复正常后,熔断器回到闭合状态
状态机:
闭合(Closed):正常请求,统计错误率
打开(Open):错误率超过阈值,短时间内拒绝请求
半开(Half-Open):尝试少量请求,验证服务是否恢复
当下游恢复正常后,熔断器回到闭合状态
实现方式
Netflix Hystrix(Java)
Resilience4j
Spring Cloud Circuit Breaker
Netflix Hystrix(Java)
Resilience4j
Spring Cloud Circuit Breaker
降级:提供备用逻辑或默认响应
目的
当下游服务不可用或响应过慢时,主动降低功能或返回备用结果,保证系统核心功能可用
实现方式
返回默认值 / 缓存值
比如库存服务不可用时,返回最近一次缓存的库存
比如库存服务不可用时,返回最近一次缓存的库存
简化功能
比如社交应用动态加载失败,显示文字占位而非图片
比如社交应用动态加载失败,显示文字占位而非图片
静态兜底数据
提供固定提示或降级内容
提供固定提示或降级内容
限流
目的
控制系统访问流量,防止过载
保护下游服务、数据库或资源池不被压垮
控制系统访问流量,防止过载
保护下游服务、数据库或资源池不被压垮
实现方式
固定窗口计数(Fixed Window)
每个固定时间窗口允许的请求数
滑动窗口(Sliding Window)
更平滑统计请求数,防止突发流量
漏桶算法(Leaky Bucket)
请求以固定速率流入处理队列,多余请求排队或丢弃
令牌桶算法(Token Bucket)
以固定速率生成令牌,请求消耗令牌,超出速率限制流量
固定窗口计数(Fixed Window)
每个固定时间窗口允许的请求数
滑动窗口(Sliding Window)
更平滑统计请求数,防止突发流量
漏桶算法(Leaky Bucket)
请求以固定速率流入处理队列,多余请求排队或丢弃
令牌桶算法(Token Bucket)
以固定速率生成令牌,请求消耗令牌,超出速率限制流量
具体场景:秒杀系统如何防止流量冲垮服务?
做法
1. 前端限流
目的:在请求到达后端前就做流量削峰。
方式
固定窗口/滑动窗口限流:通过 Nginx、网关或中间件限制每秒请求数。
漏桶/令牌桶算法:平滑流量,防止瞬时峰值冲垮后端。
2. 请求排队 / 异步处理
目的:把瞬时大量请求缓冲,降低后端瞬时压力。
方式
消息队列:将请求放入队列,后端异步消费(Kafka、RabbitMQ、RocketMQ)。
分布式队列:每个商品有一个队列,按顺序处理请求。
好处:秒杀瞬时高峰不会直接压到数据库或库存服务。
3. 库存预减 / 内存标记
目的:减少数据库压力,防止超卖。
方式:
1. Redis 预减库存
2. 内存标记:每个商品在应用内存中维护“是否售罄”标记,售罄直接拒绝请求,避免频繁访问 Redis/DB。
好处:大幅减少 DB 访问,防止库存超卖。
4. 服务熔断与降级
目的:在系统压力过大时,快速拒绝部分请求,保护核心服务。
方式:
使用 Sentinel / Resilience4j 设置熔断规则。
对非核心功能(比如日志统计、排行榜等)进行降级处理。
好处:保证核心秒杀服务可用,不因为非核心请求宕机。
5. 缓存与 CDN
目的:降低数据库压力,提高读取性能。
方式:
秒杀商品信息、库存放入 Redis 缓存。
静态内容可通过 CDN 缓存。
好处:快速返回商品信息,减少 DB 请求量。
6. 数据库优化
分库分表:减轻单表压力。
行级锁/乐观锁:避免超卖。
批量更新:将库存更新操作批量处理,降低事务冲突。
7. 微服务架构配合
网关 + 服务注册发现 + 负载均衡:
网关限流 + 路由请求到多实例。
异步消息 + 秒杀服务 + 库存服务 + 下单服务:
请求异步排队,库存预减,订单异步生成。
监控 & 报警:
Prometheus/Grafana 实时监控 QPS、延迟、库存情况。
微服务 A 调用 B、C 服务时,如何保证调用可靠、可观察?
调用可靠性
重试(Retry)
作用:网络抖动或临时异常时重试,增加成功率
注意:
配合 指数退避(Exponential Backoff) 避免雪崩
设置最大重试次数,防止无限循环
配合 指数退避(Exponential Backoff) 避免雪崩
设置最大重试次数,防止无限循环
限流 / 降级(Rate Limit / Circuit Breaker)
限流:避免下游压力过大
熔断(Circuit Breaker):下游故障时快速失败,保护系统
降级:提供默认值或缓存数据,保证服务可用
熔断(Circuit Breaker):下游故障时快速失败,保护系统
降级:提供默认值或缓存数据,保证服务可用
异步调用 / 消息队列
对于非实时业务,可用 异步消息解耦调用
优势:
降低同步调用压力
可重试、持久化,保证最终一致性
优势:
降低同步调用压力
可重试、持久化,保证最终一致性
幂等性设计
确保同一个请求重复调用不会产生副作用
常见方法:
唯一请求 ID
数据库唯一约束
幂等操作接口
常见方法:
唯一请求 ID
数据库唯一约束
幂等操作接口
可观察性
日志(Logging)
记录调用请求、参数、返回值、异常
建议使用 结构化日志,便于搜索和分析
可结合 集中化日志系统(ELK / Loki / Graylog)
建议使用 结构化日志,便于搜索和分析
可结合 集中化日志系统(ELK / Loki / Graylog)
指标监控(Metrics)
收集调用次数、成功率、延迟、异常率
Prometheus + Grafana 是常用组合
Prometheus + Grafana 是常用组合
分布式追踪(Tracing)
跨服务调用链路可视化
常用工具:Zipkin、Jaeger、SkyWalking
利用 Trace ID 追踪请求全链路
常用工具:Zipkin、Jaeger、SkyWalking
利用 Trace ID 追踪请求全链路
健康检查
每个服务提供 /health 接口
调用方或注册中心定期探测服务健康状态
调用方或注册中心定期探测服务健康状态
微服务调用系统中网络延迟、抖动和分区容错处理方法
网络延迟
问题
请求从节点 A 发送到节点 B 的时间不可预测,可能延迟很高
高延迟可能导致服务调用超时、请求堆积
处理方法
超时设置(Timeout)
每个 RPC/HTTP 请求设置合理超时,防止长时间阻塞
设置连接超时时间,读取超时时间
异步调用
异步请求、Future/Promise、消息队列
避免同步阻塞,提高吞吐量
批量请求
将多个请求合并,减少网络往返次数
示例:数据库批量查询、RPC 批量调用
本地缓存 / 最近数据缓存
避免频繁远程调用,降低延迟对业务的影响
网络抖动
问题
网络延迟波动大,导致响应时间不稳定
对高可用系统影响更大,可能触发不必要的重试或熔断
处理方法
指数退避
重试请求时,每次延迟递增,减少对网络的瞬时压力
抖动(Jitter)策略
在退避延迟中增加随机值,避免所有客户端同时重试导致雪崩效应
负载均衡
请求分发到延迟低、负载均衡的节点
常用方式:客户端负载均衡(Ribbon)或服务端负载均衡(K8s Service / Nginx)
分区容错
问题
系统被网络分区(Partition)隔离,节点无法互相通信
CAP 定理表明:在分区发生时,需要在 一致性 和 可用性 之间做权衡
处理方法
副本机制
数据多副本存储,即使部分节点不可达,仍能提供服务
Leader / Follower 选举
利用一致性协议(Raft、Paxos)选出主节点处理写请求
保证在网络分区下仍有单一写入入口
异步写 / 最终一致性
分区时仍允许节点处理请求(可用性优先)
后续通过 副本同步 或 补偿机制 达到最终一致
降级与熔断
分区发生时,拒绝部分请求或返回默认值,保护核心服务
避免雪崩式故障传播
重试与补偿
网络恢复后,对失败请求进行重试
对不可幂等操作使用 补偿事务(TCC / Saga)
数据与事务
微服务如何处理分布式事务?
方案:
2PC(强一致性,但性能差)
TCC(Try-Confirm-Cancel)
Saga(长事务补偿机制)
消息最终一致性(MQ 事务消息)
如何保证不同微服务的数据一致性?
最终一致性(BASE 理论)
事件驱动架构(Event Sourcing)
什么是 最终一致性?
最终一致性是一种 弱一致性模型。
在分布式系统中,当一个数据被更新后,系统允许短时间内各节点数据不一致,但经过一段时间后,所有节点最终会达到一致
实现方式
异步消息/事件
补偿机制
如果一个订单系统和库存系统同时更新,怎么保证数据一致?
网关与安全
微服务网关的作用?
路由转发
统一鉴权与认证(JWT/OAuth2)
限流与熔断
日志收集
常见网关实现有哪些?
Nginx(通用负载均衡)
Spring Cloud Gateway
Kong、Zuul
K8s Ingress
什么是 OAuth2在微服务中如何应用?
OAuth2 是什么?
一种 授权框架(不是协议,也不是具体实现)。
主要解决的问题是:
用户如何把自己在某个系统里的资源,安全地授权给另一个应用访问?
微服务之间的调用也只需要经过一次校验权限
在微服务中的应用
微服务架构下,通常有很多独立的服务(订单、库存、用户、支付...)。如果没有统一的授权机制:
每个服务都得单独管理登录/鉴权,复杂而且不安全。
服务间调用可能会被伪造或越权访问。
用 OAuth2 来做统一的 认证 + 授权中心
1、引入统一的授权服务器(可以用 Keycloak、Auth0、Spring Authorization Server)。
2、用户登录时 → 授权服务器颁发 Access Token(常用 JWT 格式)。
3、前端或 API Gateway 在调用微服务时,把 Token 放到 Authorization: Bearer <token> 请求头里。
4、每个微服务接到请求时
校验 Token 是否有效(签名、过期时间、scope/权限)。
决定是否允许访问该资源。
OAuth2如何实现微服务相互调用权限合法性?
在微服务架构里,所有 Token 都是统一的授权服务器(Authorization Server)发的;这样每个服务只要会验证这个“签发方”的 Token 就行
token传递分为两种场景
转发用户的 Token
前端用户登录后拿到 Access Token(JWT)。
前端调用 订单服务时带上这个 Token。
订单服务再调用 库存服务时,把同一个 Token 转发过去。
库存服务验证、
Token 是否由授权服务器签发(签名验证)。
Token 是否过期。
Token 里的 scope / role / claim 是否允许访问库存 API。
好处:能明确知道“是哪个用户在下单”。
缺点:Token 在多个服务间传来传去,可能会暴露过多权限。
订单服务使用自己的服务 Token
授权服务器事先给每个微服务注册一个 Client ID / Secret。
订单服务调用库存服务时,先用 Client Credentials Flow 去授权服务器换一个 Token。
这个 Token 的权限是“订单服务 → 库存服务”。
库存服务验证这个 Token 的合法性后才返回结果。
好处:粒度清晰,每个服务只拿自己需要的权限。
缺点:如果需要传递用户身份信息,还要额外设计。
验证 Token 合法性的方式
本地验证(常用,性能高)
Access Token 用 JWT 格式,包含签名。
库存服务只要拿到授权服务器公开的 公钥(JWKS endpoint),就能验证签名合法性。
远程验证(集中校验,性能低一些)
库存服务向授权服务器发请求,调用 introspection endpoint(OAuth2 标准接口)。
授权服务器告诉它:这个 Token 是否有效、属于谁、scope 有哪些。
权限服务器是一台单独做权限的服务器吗?
微服务体系里,这个 认证/授权服务器(Authorization Server / Identity Provider) 一般确实是 一个独立的服务,主要负责 身份认证和权限发放,而不会混杂业务逻辑
主要做三件事情
认证(Authentication)
负责“你是谁”。
处理用户的登录、注册、验证密码、多因素认证(MFA)。
授权(Authorization)
负责“你能做什么”。
发放 Access Token / Refresh Token / ID Token。
Token 里会写明用户角色、scope、权限范围。
集中管理账号和权限
统一用户目录(User Directory)。
管理用户 → 角色 → 权限的映射关系。
提供 OAuth2 / OIDC 协议接口给微服务调用。
微服务部署与容器化
微服务一般如何部署?
Docker 容器化 + Kubernetes 编排
配合 CI/CD 流水线自动发布
基础概念
容器
封装微服务运行环境。
Docker容器只是容器实现的其中的一种方式
Docker
流行的容器引擎
功能
打包应用(build 镜像)。
运行容器(run)。
提供镜像仓库(Docker Hub)。
Kubernetes(K8s)
容器编排平台
功能:
管理成百上千个容器的部署、扩容、滚动更新。
提供服务发现、负载均衡。
监控容器健康状态,挂掉了自动拉起来。
pod
Pod 是 Kubernetes(K8s)中最小的调度单位
换句话说,K8s 在集群里分配资源、调度运行的最小对象就是 Pod。
一个 Pod 可以包含 一个或多个容器,但这些容器共享网络和存储,并且生命周期绑定在一起。
一般情况下会有一个微服务应用以及日志收集服务;不会存在两个微服务
Service
概念
Service 提供 Pod 的稳定访问入口
在 K8s 中,Pod 是 短暂的、会随调度变化而重建的
Service 通过标签选择器(Selector)将请求转发到对应 Pod 集合
Deployment
Deployment 用于 声明式管理 Pod 副本(Replica)
负责:
创建 Pod 副本
版本升级(Rolling Update)
回滚历史版本
扩缩容(scale up/down)
创建 Pod 副本
版本升级(Rolling Update)
回滚历史版本
扩缩容(scale up/down)
特点
Pod 是 Deployment 的实例,Deployment 管理 Pod 的生命周期
保证 Pod 数量满足副本数(Replica)
支持滚动更新、蓝绿发布等策略
Pod 是 Deployment 的实例,Deployment 管理 Pod 的生命周期
保证 Pod 数量满足副本数(Replica)
支持滚动更新、蓝绿发布等策略
Kubernetes 在微服务中的作用?
服务发现
负载均衡
如何实现负载均衡
K8s 自带基本负载均衡(Pod 间流量分发)。
给同一个服务的不同pod会标记成一个组
当请求打到 Service 时,K8s 会自动在组中的 Pod 之间做 负载均衡(通常是轮询)。
自动弹性伸缩
弹性伸缩的层次
Pod 级别
作用:根据应用负载动态调整 Pod 副本数。
节点级别
作用:Pod 扩容需要更多计算资源时,自动增加节点;节点闲置时自动回收。
扩缩容的是“运行 Pod 的机器”
容器资源调整
作用:动态调整 Pod 容器的 CPU / 内存请求与限制。
弹性伸缩流程
监控:HPA/VPA/CA 监控指标(CPU、内存、请求量、自定义指标)。
判断:指标超阈值 → 触发扩容,低于阈值 → 触发缩容。
执行:
HPA:增加或减少 Pod 副本数。
VPA:调整 Pod 内容器资源。
CA:增加或减少节点数量。
调度:K8s Scheduler 把新 Pod 调度到可用节点。
demo
用户访问量高峰 → CPU 使用率超过 70% → HPA 扩容 Pod 数量 3 → 5
节点资源不够 → Cluster Autoscaler 自动添加节点
高峰结束 → CPU 使用率下降 → HPA 缩容 Pod 数量 5 → 2
空闲节点 → Cluster Autoscaler 回收节点
如何实现 蓝绿发布、灰度发布、滚动更新?
滚动更新
概念
默认的 K8s Deployment 更新方式。
逐步替换 Pod:旧版本 Pod 被新版本 Pod 替换,但始终保持服务可用。
工作原理
Deployment 更新镜像或配置。
K8s 按配置(maxUnavailable、maxSurge)逐个或逐批替换 Pod
旧 Pod 健康检查通过后被删除,新 Pod 替换完成。
特点
无停机,平滑更新。
配置灵活:可以控制更新速度和并发数量。
蓝绿发布
概念
同时运行 两套环境:
蓝色:当前线上版本
绿色:新版本
流量切换一次性从蓝色切到绿色。
工作原理
部署绿色环境(新版本 Pod),与蓝色环境并行。
测试新版本健康状态。
切换流量(Service/Ingress 指向绿色 Pod)。
蓝色环境可以保留一段时间作为回滚。
特点
切换瞬间完成,停机时间几乎为 0。
回滚简单:只需切回旧版本 Service。
需要更多资源(同时保留两套环境)。
灰度发布
概念
逐步放量:新版本先分配一小部分流量,验证稳定后再逐步增加。
工作原理
部署少量新版本 Pod(Canary Pod)。
配置流量分配策略(Ingress、Service Mesh、Istio、NGINX 等)。
监控指标(错误率、响应时间)。
如果稳定 → 逐步增加新版本流量,最终替换旧版本。
出问题 → 回滚到旧版本。
特点
风险最小,适合复杂业务。
可以结合 A/B 测试。
配置复杂,需要支持流量路由的工具(Service Mesh、Ingress Controller)。
k8s 如何让微服务如何实现自动化部署?
微服务自动化部署目标
快速交付:代码提交 → 自动构建 → 测试 → 部署
稳定可靠:标准化流程,减少人为错误
零停机:通过滚动更新、蓝绿或灰度发布
弹性伸缩:部署后自动适应流量
Kubernetes 下自动化部署流程
源码管理
每个微服务单独 Git 仓库(或 mono repo)
代码 Push 或 Merge Request → 触发 CI/CD
持续集成(CI)
构建镜像
编译代码 → 单元测试 → Docker 镜像打包
推送到镜像仓库(Harbor、Docker Hub 等)
自动化测试
单元测试、集成测试、静态扫描、漏洞扫描
持续部署(CD)
更新 K8s 配置
Deployment / StatefulSet / Service / Ingress 的 YAML 或 Helm Chart
镜像版本号更新(image tag)
部署策略
滚动更新(Rolling Update)
蓝绿发布(Blue-Green Deployment)
灰度发布(Canary Deployment)
自动回滚
Deployment 健康检查失败 → 回滚到上一版本
监控与告警
热点进阶问题
CAP 理论是什么?在微服务里怎么理解?
C(一致性)、A(可用性)、P(分区容忍性),三者不可同时满足。
微服务一般选择 AP 或 CP,通过 BASE 理论(最终一致性)解决强一致性问题。
CAP 定理在微服务中的应用?
分布式系统无法同时满足一致性(C)、可用性(A)、分区容忍性(P)
注册中心选型时要权衡:
Zookeeper 偏向 CP
Eureka 偏向 AP
你在项目中如何落地微服务架构?
注册中心(Nacos/Eureka)
配置中心(Apollo/Nacos)
网关(Gateway/Nginx)
熔断/限流(Sentinel/Resilience4j)
监控(Prometheus + Grafana + Zipkin)
部署(Docker + K8s)
微服务实用性
引入微服务的时间点
什么样的组织结构更适合微服务架构
中台战略
分层
IAAS
paas层
应用
核心业务层
渠道接入
业务前台
业务中台
业务后台
服务发现模式
传统lb模式
依赖外接的负载均衡器(F5,NGINX)
主机内lb模式
在每主机上部署一个负载均衡器
进程内lb模式
负载均衡移动到应用服务内
性能好,
zuul网关
前置路由过滤器
路由过滤器
后置路由过滤器
可动态插拔
网关上设计防爬虫
路由发现体现
服务分层
服务网关
服务之间是怎么相互发现
外面流量怎么通过网关访问微服务
服务
基础服务
相互之间同步路由表
聚合服务
服务调用方式
RPC
REST
服务治理
配置集成
文档
统一异常处理
代码生成
自动生产服务端客户端
序列化
REST/RPC
安全访问控制
限流熔断
调用链埋点
Metrics
日志
负载路由
服务注册发现
后台服务集成,DB,MQ,CACHE
微服务监控系统分层监控架构
日志监控
健康检查
调用链监控
告警系统
metrics监控
子主题 6
ELK -- log监控
nagios
调用链监控选型
CAT
ZIPKIN
PINPOINT
字节码增强的方式做
子主题 4
容器
解决的问题
环境一致性问题
镜像部署问题
容器集群调度平台
容器发布
发布体系
k8s集群
微服务业务拆分维度和原则
维度(拆分方式)
1、功能维度
按照系统业务功能进行划分,例如对于电商系统,按功能维度咱们能够拆分为商品中心,订单中心,用户中心,购物车,结算等功能模块
2、状态维度
功能模块如果能够按照不一样的业务状态再进行划分,就好比电商中的优惠券,可以分成建立优惠券,领券,使用优惠券,优惠券失效
相同的业务从开始到结束的不同状态的区分
3、读写维度
按照读写压力拆分
商品中心读压力大,那么就将商品读写分成两个服务,以提高系统安全性,可用性
4、纵深维度
按照业务纵深维度,最底层的业务模块和上层的业务模块拆分开
比如说:订单需要用到商品,用户,等信息;但是用户模块,商品模块是不会用到订单信息;此时商品模块和用户模块就是相当于订单模块就是下层模块
5、AOP维度
根据访问特征,按照aop拆分
商品详情页能够分为CDN、页面渲染模块等。而CDN就是一个AOP
AKF拆分原则
概述
也就是服务拆分的一个总的指向原则
Availability(可用性)
系统要保证高可用,避免单点故障。
在拆分服务时,要确保即使某个服务不可用,其他服务依然可以正常运行。
常用方法:冗余、负载均衡、服务隔离。
K-factor(增长因子 / 可扩展性)
“K”代表可扩展性,关注如何水平扩展系统来应对用户增长。
拆分服务时,需要考虑不同模块的负载和增长模式,确保可以独立扩展。
例如:用户服务、订单服务、支付服务可以分别水平扩展。
Failure isolation(故障隔离)
当系统某部分发生故障时,要限制影响范围,不让整个系统瘫痪。
设计原则:单个服务出问题不影响其他服务(类似微服务的理念)。
微服务应用架构原则
2、前后端分离
3、无状态服务
不能在服务本地内存中缓存数据
4、无状态通讯原则
降低服务之间通讯协议沟通成本
一、服务设计原则
单一职责原则 (Single Responsibility)
每个微服务只聚焦一个清晰的业务能力,例如订单服务、库存服务、支付服务。
避免“大而全”的服务,降低耦合。
高内聚,低耦合
服务内部紧密围绕某一业务目标组织,外部依赖尽可能少。
避免跨服务强耦合、循环调用。
自治性 (Autonomy)
服务应当可以独立开发、部署、扩展、运维。
个服务升级不应强制影响其他服务。
小而轻量 (Size & Scope)
微服务不追求越小越好,而是“业务边界清晰”。
避免过度拆分,增加管理复杂度。
二、接口与通信原则
API 优先 / 契约优先 (API First / Contract First)
服务之间的通信必须通过明确的接口契约(REST/gRPC/GraphQL 等)。
避免共享数据库、绕过 API 直接访问内部数据。
无状态 (Stateless)
服务调用尽量无状态,用户状态存储在外部(Redis/Session 服务/Token)。
方便水平扩展与负载均衡。
异步优先
在可能的情况下,使用事件驱动、消息队列降低耦合,提高吞吐。
同步调用仅用于强一致或强实时需求。
三、数据与存储原则
每个服务独立数据存储 (Database per Service)
不同服务不共享数据库表,保证自治和解耦。
需要一致性时,通过 API、消息事件实现。
最终一致性优先
在分布式系统中,牺牲部分强一致性,采用补偿/对账机制保证最终一致。
避免大范围分布式事务。
四、部署与运维原则
独立部署 (Independent Deployment)
每个服务可以单独构建、发布、回滚。
配合 CI/CD 流水线实现快速上线。
自动化与容器化
服务应能在容器(Docker、K8s)中独立运行,便于扩缩容。
配置中心、服务发现、注册中心等支撑组件必不可少。
可观测性 (Observability)
服务必须具备日志、指标、链路追踪能力(Logging / Metrics / Tracing)。
方便故障定位与监控。
五、组织与团队原则
按业务能力划分团队 (Conway’s Law)
团队和服务边界对应,每个团队负责一个或多个完整的业务能力。
避免跨团队依赖过多。
DevOps 文化
团队对服务全生命周期负责(开发、测试、运维、监控)。
强调自治与快速迭代。
六、演进与治理原则
演进式架构 (Evolutionary Architecture)
微服务拆分/合并应当可以演进,不是一拆到底。
支持灰度发布、AB 测试、蓝绿部署。
容错与弹性 (Resilience)
超时、重试、限流、熔断、降级必须设计在服务调用中。
系统要能在部分失败时继续提供核心功能。
治理与标准化
统一的 API 规范、认证授权、安全策略。
服务注册发现、配置管理、版本控制要有统一机制。
微服务概论
微服务产生
微服务是有一个martin fowler大师提出来的,是一种架构风格,通过将大型单体应用划分成较小服务单元,从而降低整个系统复杂度
springCloud和springCloudalibaba都有哪些组件
spring cloud netflix
配置中心
Spring Cloud Config
注册中心
Eureka
提供了一个服务注册中心、服务发现的客户端,还有一个方便的查看所有注册的服务的界面。 所有的服务使用Eureka的服务发现客户端来将自己注册到Eureka的服务器上
远程调用
Feign
服务客户端,服务之间如果需要相互访问,可以使用RestTemplate,也可以使用Feign客户端访问
负载均衡
Ribbon
熔断降级
Hystrix
Hystrix Dashboard
提供可视化界面,监控各个服务上服务调用所花费的时间
监控和断路器
通过快速的失败,降低服务的级联报错
网关
Zuul
客户端的请求都需要先通过网关后,再请求后台服务,通过配置的路由来判断请求需要访问哪个问题,再从注册中心获取注册服务来转发请求
监控
Turbine
聚合监控平台
可以查看所有的服务实力,都聚集到统一的一个地方查看;
springCloud alibaba
注册中心-配置中心
nacos
负载均衡
Ribbon
服务调用
Feign
熔断降级
Sentinel
网关
Gateway
调用链路监控
Sleuth
分布式事物处理
Seata
springCloud
提供了构建微服务系统所需要的一组通用开发模式;以及一系列快速实现这些开发模式的工具
通常说的springCloud是指的是springCloud netflix;和springcloud cloud alibaba都是springcloud这一系列开发模式的具体实现
springcloud和dubbo区别
dubbo开始只是一个rpc调用框架,核心是解决服务调用问题,侧重也是服务调用,没有springcloud功能全面;springcloud 是一个大而且全的框架,提供了一些列的解决方案;dub
dubbo数据传输直接使用传输层的二进制传输,对象直接转成二进制数据
spring cloud 是使用应用层http协议进行传输,数据最终会转成二进制,中件会有性能消耗
soa,分布式,微服务之间的关系和区别
SOA
SOA历史
上世纪90年代出现的一个面向服务的体系结构
SOA缺点
ESB(服务总线)是单体结构,很容易出现单点故障
SOA不能解决部署速度
SOA很容易出现功能直接相互依赖
soa和微服务
soa是一种架构设计风格,是为了将单体服务拆分成一些具有特定业务目标的较小模块
微服务也是soa架构思想的一种形式
两者区别
服务通讯方式
SOA依赖消息传递协议在服务之间进行通信
数据存储
SOA类似单体服务,通常都是共享使用一个数据库
微服务,每一个微服务都有自己业务的服务
规模和范围
虽然都是较小服务组成,但是SOA服务的粒度比较粗,微服务粒度比较小
通信
微服务之间是通过与语言无关的http协议通信
SOA通过SOA上层的ESB,通过消息传递协议进行服务之间通信
松耦合和高内聚
微服务的耦合性更低
SOA耦合性更高
SOA,和微服务架构图
左边是SOA,右边是微服务
分布式和微服务
两者区别
部署方式
分布式架构,将打的系统分为多个业务模块,部署到不同机器上,通过接口进行数据交互;
微服务可以部署在同一台机器上也可以分散部署到不同的机器上
两者联系
微服务架构也算是分布式架构的一种
三者之间的联系
SOA架构,微服务架构都可以看做是分布式架构思想的一种表现
spring生态
spring-生态
springframework
springframework 是spring 里面的一个基础开源框架
spring data
提供对各种数据源操作的封装
Spring Cloud Data Flow
Spring Cloud Data Flow是用于构建数据集成和实时数据处理管道的工具包
Spring for GraphQL
spring 对图数据结构的处理
spring-cloud生态
Azure
spring cloud 为项目部署提供的一套环境
项目发布的云平台
可以为项目提供生命周期管理,监控诊断,配置管理,服务发现,CI/CD集成,蓝绿部署
Spring Cloud Alibaba
提供一整套分布式项目的各种技术解决的框架
Spring Cloud netflux
提供一整套分布式项目的各种技术解决的框架
Spring Cloud for Amazon Web Services
可简化与托管Amazon Web Services的集成
spring cloud bus
用于实现微服务之间的通信
spring cloud bus整合 java的事件处理机制和消息中间件消息的发送和接受,主要由发送端、接收端和事件组成
Spring Boot Cloud CLI
该工具为Spring Boot CLI提供了一组命令行增强功能,有助于进一步抽象和简化Spring Cloud部署
Spring Cloud Cloud Foundry
Spring Cloud for Cloudfoundry可以轻松地在Cloud Foundry(平台即服务)中运行Spring Cloud应用程序。 Cloud Foundry具有“服务”的概念,即“绑定”到应用程序的中间件,实质上为其提供包含凭据的环境变量(例如,用于服务的位置和用户名)
Spring Cloud - Cloud Foundry Service Broker
Spring Cloud Cluster
Spring Cloud Cluster提供了一组用于在分布式系统中构建“集群”功能的功能。 例如领导选举,集群状态的一致存储,全局锁和一次性令牌。
Spring Cloud Commons
Spring Cloud Commons模块是为了对微服务中的服务注册与发现、负载均衡、熔断器等功能提供一个抽象层代码,可以自定义相关基础组件的实现
Spring Cloud Config
spring的配置中心
统一管理微服务配置的一个组件,具有集中管理、不同环境不同配置、运行期间动态调整配置参数、自动刷新等功能。
参考文档
https://blog.csdn.net/u011066470/article/details/106741430
Spring Cloud Connectors
简化了云平台(如Cloud Foundry和Heroku)中连接服务和获取操作环境感知的过程,尤其适用于Spring应用程序
它是为可扩展性而设计的:您可以使用提供的云连接器之一或为您的云平台编写一个,并且您可以使用内置支持常用服务(关系数据库,MongoDB,Redis,RabbitMQ)或扩展Spring 云连接器可与您自己的服务配合使用。
SpringCloud Consul
Consul是一套开源的分布式服务发现和配置管理系统
提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网格,总之Consul提供了一种完整的服务网格解决方案
Spring Cloud Contract
为通过CDC(Customer Driven Contracts)开发基于JVM的应用提供了支持。它为TDD(测试驱动开发)提供了一种新的测试方式 - 基于接口
传统自测
示意图
Spring Cloud Contract
示意图
Spring Cloud Function
通过函数促进业务逻辑的实现
将业务逻辑的开发生命周期与任何特定运行时目标分离,以便相同的代码可以作为Web端点,流处理器或任务运行
支持无服务器提供商之间的统一编程模型,以及独立运行(本地或PaaS)的能力
在无服务器提供商上启用Spring Boot功能(自动配置,依赖注入,指标)
就像Spring一直在推广基于普通java对象(POJO)的编程模型一样,Spring Cloud Function也基于普通的函数来推广编程模型。我们指的是java.util.function包中定义的核心接口:Function,Consumer和Supplier。
Spring Cloud Gateway
网关
Spring Cloud GCP
Spring 数据是用于在众多存储技术中存储和检索 POJO 的抽象。 Spring Cloud GCP 在数据存储模式下为Google Cloud Firestore添加了 Spring Data 支持。
与谷歌的数据处理的整合
Spring Cloud Open Service Broker
Spring Cloud Open Service Broker 是一个框架,用于构建实现Open Service Broker API 的Spring Boot应用程序。
Spring Cloud Pipelines
该项目试图解决以下问题:
创建公共部署管道
传播良好的测试和部署实践
加快将功能部署到生产所需的时间
创建公共部署管道
传播良好的测试和部署实践
加快将功能部署到生产所需的时间
Schema Registry
对不同的项目统一数据编码格式
Spring Cloud Security
权限
Spring Cloud Skipper
Skipper是一种工具,允许您在多个云平台上发现应用程序并管理其生命周期。
Skipper是一个工具,允许您发现Spring Boot应用程序并管理其在多个云平台上的生命周期。您可以单独使用Skipper或将其与Continuous Integration管道集成,以帮助实现应用程序的持续部署。
Spring Cloud Sleuth
链路追踪
Spring Cloud Sleuth是对Zipkin的一个封装
Spring Cloud Stream
微服务应用构建消息驱动能力的框架
简化了消息队列的开发上手难度
目前只支持 RabbitMQ ,Kafka
Spring Cloud Task
SpringBoot应用程序提供创建短运行定时任务
Task中,我们可以灵活地动态运行任何任务,按需分配资源并在任务完成后检索结果。Tasks是Spring Cloud Data Flow中的一个基础项目,允许用户将几乎任何SpringBoot应用程序作为一个短期任务执行。
Spring Cloud Task App Starters
Spring Cloud Task Application Starters是独立的可执行应用程序,可用于按需用例,例如数据库迁移,机器学习和计划操作
特性
独立运行作为Spring Boot应用程序
编排为短暂的数据微服务
将数据微服务应用程序用作maven或docker工件
通过命令行,环境变量或YAML文件覆盖配置参数
提供基础架构以单独测试应用程序
从此版本的Spring Initializr下载为初学者
独立运行作为Spring Boot应用程序
编排为短暂的数据微服务
将数据微服务应用程序用作maven或docker工件
通过命令行,环境变量或YAML文件覆盖配置参数
提供基础架构以单独测试应用程序
从此版本的Spring Initializr下载为初学者
Spring Cloud Vault
辅助spting boot程序保护一些敏感配置信息
SpringCloud——Zookeeper
注册中心
Spring Cloud App Broker
Spring Cloud App Broker是一个用于构建Spring Boot应用程序的框架,该应用程序实现Open Service Broker API以将应用程序部署到平台。
Open Service Broker API项目允许开发人员为云本地平台(如Cloud Foundry,Kubernetes和OpenShift)中运行的应用程序提供服务。 Spring Cloud App Broker提供了一个基于Spring Boot的框架,使您能够快速创建服务代理,在配置托管服务时将应用程序和服务部署到平台。
Spring Cloud Circuit Breaker
熔断
Spring Cloud Kubernetes
Spring Cloud Kubernetes提供使用Kubernetes原生服务的Spring Cloud公共接口实现。此代码仓库中提供的项目是促进在Kubernetes中运行的Spring Cloud和Spring Boot应用程序的集成
Kubernetes就是帮助大家更快的搭建使用Kubernetes原生服务的微服务项目,并与Spring Cloud集成
Spring Cloud Kubernetes意味着我们想要将服务部署到Kubernetes集群,Spring Cloud Kubernetes为我们实现了Spring Cloud的一些接口,让我们可以快速搭建Spring Cloud微服务项目框架,并能使用Kubernetes云原生服务。
Kubernetes提供服务注册和发现、以及配置中心的实现,我们完全没有必要再自己部署一套注册中心、配置中心,因此Spring Cloud Kubernetes为我们提供使用这些原生服务的接口实现。除注册中心和配置中心之外,如果我们还想使用istio,Spring Cloud Kubernetes也提供了支持,这些无非就是解释文章开头的那句话“Spring Cloud Kubernetes提供使用Kubernetes原生服务的Spring Cloud公共接口实现”
Kubernetes提供服务注册和发现、以及配置中心的实现,我们完全没有必要再自己部署一套注册中心、配置中心,因此Spring Cloud Kubernetes为我们提供使用这些原生服务的接口实现。除注册中心和配置中心之外,如果我们还想使用istio,Spring Cloud Kubernetes也提供了支持,这些无非就是解释文章开头的那句话“Spring Cloud Kubernetes提供使用Kubernetes原生服务的Spring Cloud公共接口实现”
参考文档
https://www.likecs.com/show-203352078.html#sc=586
Spring Cloud OpenFeign
基于http请求的接口调用
netty
Netty的组件
ServerBootstrap
EventLoop
EventLoopGroup
channel
ChannelPipeline
ChannelContextHandler
netty事件类型
建立连接
连接关闭
收到消息
读完成
channel被注册到EventLoop
channel从EventLoop注销
可写状态改变
出现异常
收到一个用户自定义事件
Netty粘包拆包
粘包拆包原因
粘包拆包解决方式
固定长度的拆包器
行拆包器
分隔符拆包器
基于数据包长度的拆包器
自定义拆包方案
netty线程模型
Reactor单线程模型
Reactor多线程模型
主从Reactor多线程模型
线程池职责
接受客户端请求线程池
处理IO的线程池
netty序列化
Marshalling
Protocol Buffers
message pack
jdk自带
netty零拷贝
子主题 1
netty对象池
netty内存池
0 条评论
下一页