springboot项目地址:https://github.com/spring-projects/spring-boot
查看springboot版本信息地址:https://github.com/spring-projects/spring-boot/releases
spring-cloud项目地址:https://github.com/spring-projects/spring-cloud
查看spring-cloud版本信息地址:https://github.com/spring-projects/spring-cloud/wiki
查看spring-cloud-springboot相应的版本:https://spring.io/projects/spring-cloud#overview
更详细之间的依赖关系查看地址:https://start.spring.io/actuator/info
alibaba github地址 : https://github.com/alibaba
版本查看地址 : https://github.com/alibaba/nacos/releases
Eureka自我保护模式是应对网络异常的一种保护方式,
总结:服务不可用,eureka不会立刻清除掉,依旧会对该服务信息进行保存
属于CAP的AP
C:即一致性,访问所有的节点得到的数据应该是一样的。注意,这里的一致性指的是强一致性,也就是数据更新完,访问任何节点看到的数据完全一致,要和弱一致性,最终一致性区分开来。
A:即可用性,所有的节点都保持高可用性。注意,这里的高可用还包括不能出现延迟,比如如果节点B由于等待数据同步而阻塞请求,那么节点B就不满足高可用性。
P:即分区容忍性,这里的分区是指网络意义上的分区。由于网络是不可靠的,所有节点之间很可能出现无法通讯的情况,在节点不能通信时,要保证系统可以继续正常服务。
Ribbon:客户端负载均衡和服务端调用
OpenFeign:调用默认超时时间为1秒钟
#openFeign默认封装了ribbon
ribbon:
#常指的是建立连接所用的时间,适用于网络正常的情况下,两端连接所用的时间
ReadTimeout: 6000
#建它连接后从服务需读取到可用资源所用的时间
ConnectTimeout: 6000
openFeign日志级别:
NONE:默认的,不显示任何日志;
BASIC:仅记录请求方法、URL、响应状态码及执行时间;
HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;
FULL:除了HEADERS中定X的信息之外,还有请求和应的正及元数据.
Gateway 三大核心概念
Route(路由),Predicate(断言),Filter(过滤)
Redis:
缓存穿透:查询一个用不存在的数据,解决:查询不存在数据时,也存一个null到缓存,并设置一个过期时间
缓存雪崩:同一时刻大面积key同时失效,解决:生成key过期时间时,给每个key加 1-5分钟随机过期时间
缓存击穿:一个key刚好失效,同时又有很多个请求直达数据库,到时数据库奔溃,解决:加锁,只让一个人请求数据库,其他人等待,其他人获取到锁,查询缓存
初始化线程的4中方法:
1.继承Thread(不推荐直接使用)
2.实现Runnable(不推荐直接使用)
3.Callable接口 + FutrueTask(可以拿到返回结果,和处理异常)(不推荐直接使用)
4.线程池(推荐【把所有的异步任务都提交给线程池执行】)
线程池(高并发中达到资源控制):为什么要使用线程池,在业务中以前new Thread()每次进来都要创建一个,最终会把资源耗尽,系统崩溃,
创建线程池方式:
1.创建一个固定的线程池:Executors.newFixedThreadPool(10);注意:一个系统中最好有一到二个线程池,每个异步任务,都提交给线程池让他自己去执行
方式1,和方式2,主进程无法获取线程的运算结果,不适合当前场景·
方式3,主进程可以获取线程的运算结果,但是不利于控制服务器中的线程资源。可以导致服务器资源耗尽。方式
方式4,通过如下两种方式初始化线程池
总结区别:
1、2不能得到返回值,3可以获取返回值
1、2、3都不能控制资源
4可以控制资剂,性能稳定
Callable/FutureTask 和 runable 区别 ,Callable有返回值 可以抛出异常
案例(线上部署过):结合3,4
//建议手动创建线程池
ExecutorService threadPoolExecutor= Executors.newFixedThreadPool(10);
Future<GoodsDetailsModel> goodsDetailsModelT= threadPoolExecutor.threadPoolExecutor().submit(()->{
//自己的业务处理等。。。
GoodsDetailsModel goodsDetailsModel = api.goodsDetails(itemDetailReq, new MemberModel());
return goodsDetailsModel;
});
//阻塞直到得到请求参数
GoodsDetailsModel goodsDetailsModel = goodsDetailsModelT.get();
自定义线程池:
/**
* 七大参数
* corePoolSize:核心线程数【一直存在(除非设置了allowCoreThreadTimeOut)】,线程池,创建完以后准备就绪的线程数量,
* maximumPoolSize 最大线程数【非核心线程池,受时间(keepAliveTime)限制】
* keepAliveTime 存活时间,当最大线程数 > 核心线程数 ,释放空闲线程(注:核心线程是一直不会释放的,释放的是超过核心线程数量的线程)
* unit {keepAliveTime}参数的时间单位
* workQueue 阻塞队列,如果任务很多,超过了设置的最大线程数,就会放到这个队列里面
* threadFactory 线程的创建工厂【一般默认,也可以自定义】
* handler 如果队列满了,按照我们指定的拒绝策略执行任务 RejectedExecutionHandler
*
* 执行顺序
* 1,线程池创建,准备好【核心线程数】的线程,准备接受任务
* 1.1,当【核心线程】满了,就将再进来的任务放到阻塞队列里面,空闲的【核心线程】就会自己获取队列里任务去执行
* 1.2,当队列满了,就会去创建新的线程,但只能开到设置的【最大线程数】
* 1.3,当设置的【最大线程数】也满了,就用设置的RejectedExecutionHandler拒绝任务
* 1.4,当【最大线程数】都执行完成,有很多空闲,在指定的时间keaAliveTime以后,释放【最大线程数 - 核心线程数】这些线程
*
* new LinkedBlockingDeque<>()默认是Integer的最大值(0x7fffffff),可能会导致内存不够,推荐根据系统压测得到的队列长度new LinkedBlockingDeque<>(10000)
*
*
* Executors.newCachedThreadPool() 【核心线程】为0,所有的都可以回收
* Executors.newFixedThreadPool() 固定大小,core-maxs都不可回收
* Executors.newScheduledThreadPool() 定时任务的线程池.
* Executors.newSingleThreadExecutor() 单线程的线程池,后台从队列里面获职任务,挨个执行
**/
ThreadPoolExecutor executor = new ThreadPoolExecutor(
40,
200,
10,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(10000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
CompletableFuture异步调用
停更解释:http://www.likecs.com/show-111462.html
截止2020-2月最新的,Nacos支持AP和CP模式的切换
熔断,降级,限流
什么是熔断:
A服务调用B服务,B服务可能因为网络或者其他原因,导致A服务请求B服务接口时间过长,这样我们就可以将B端开(A不再请求B),凡调用B接口直接返回降级(自定义)的数据,这样B就不会影响到A
什么是降级:
网站处于流量高峰期,服务器压力巨大,根据当前业务情况,对一些不太重要的资源进行有策略的降级,停止服务,所有的调用直接返回降级数据(自定义比如返回错误页面呀),以缓解服务器的压力
相同点
1、为了保证集群大部分服务的可用性和可靠性,防止崩溃,牺牲小我
2、用户最终都是体验到某个功能不可用,
不同点
1、炼断是被调用方故障,触发的系统主动规则
2、降级是基于全局考虑,停止一些正常服务,释放资源
什么是限流:
对打入服务的请求流量进行控制,使服务能够承担不超过自己能力的流量压力
Sentinel: https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
/**
* 验证字符串内容是否包含下列非法字符<br>
* `~!#%^&*=+\\|{};:'\",<>/?○●★☆☉♀♂※¤╬の〆
*
* @param content
* 字符串内容
* @return true 代表包含非法字符,false 代表不包含非法字符。
*/
public static boolean validateLegalString(String content) {
String illegal = "`~!#%^&*=+\\|{};:'\",<>/?○●★☆☉♀♂※¤╬の〆";
boolean flag = false;
L1: for (int i = 0; i < content.length(); i++) {
for (int j = 0; j < illegal.length(); j++) {
if (content.charAt(i) == illegal.charAt(j)) {
//isLegalChar = content.charAt(i);
flag = true;
break L1;
}
}
}
return flag;
}