项目描述1_spi

文章详细介绍了MQTT协议的使用,包括设备报警状态判断和指标信息的处理。还探讨了分布式事务的处理,如乐观锁、XXL-JOB分片广播。此外,重点讲述了InfluxDB的时间序列数据库特性和使用,以及Redis在存储设备信息和实现沉默周期告警机制中的应用。还涵盖了SpringSecurityOAuth的用户认证授权、WebHook监控设备在线状态以及MyBatis的二级缓存和事务管理。最后,提到了数据库优化、分页查询、限流策略以及HTTP与HTTPS的区别。
摘要由CSDN通过智能技术生成

学成在线- 6分片上传,8xxl-job
课程模块开发 分布式事务,消息表
spring-security oauth 用户认证授权 学成在线
学成在线认证授权 一些代码

MQTT协议介绍-------需要掌握

黑马分布式事物

框架学习 - 若依 / RuoYi-Vue-Plus
统一数据权限
若依数据权限使用
数据权限表结构

2.xxl-job 分片广播

1 2 3 4 4个执行器。
4个执行器和调度中心网络通信。
网络问题。
只有 1 2 2个执行器,那么 3 4的任务在 1 和2 执行器执行了。

乐观锁 status 0 待处理 1 处理成功 2处理失败 3处理中
行锁 处理。

//t.id=2, 并且t.status=0or 3, and 失败次数<3
update process t set t.ststus=3 where t.id=2 and (t.status=2 or t.status=0)
and t.failcount<3; update 行锁。

3.解析设备上传指标报文,进行设备报警状态判断

eqm 接收设备报文信息。

  1. 解析设备信息。
    1.1 获取上报的,设备id 和 设备对应的指标参数信息。(温度,湿度,电压)
  2. 根据设置的报警阈值,验证上传的报文数据信息是否需要报警,引入沉默周期。进行多端推送。
  3. 保存设备信息,引入redis,hash,key device, key1 device id ,value deviceinfo
  4. 保存设备上传的数据信息到influx db 中。 用于展示报警日志。
    数据插入和检索的数据库。
    4.1 infolux db 时间序列数据库
    持续高并发写入,不需要更新。
    数据压缩存储。
    低延时查询

database 数据库
measurement 数据库的表
point 表中的行。
point 字段 时间戳(time) 标签(tag) 数据 (fileds)

point属性含义
time数据记录的时间,主索引,默认自动生成,相当于每行数据都具备的列
tags相当于有索引的列。tag中存储的值的类型是字符串类型
fieldsvalue值,没有索引的列。field中存储的值得类型:字符串、浮点数(Double)、整数、布尔型。一个field value总是和一个timestamp相关联
  1. 指标透传(设备的指标信息),传递到其他服务,进行业务逻辑处理。

3.1 订阅所有指标配置的主题

3.1.1 报文格式

{
 "sn":"123456", // 设备编号
 "temp":1.2, //温度
 "humi":50 // 湿度
}

指标配置表
3

l 报警配置表,设置报警阈值,循环报警n次,选择沉默周期。(离线报警,温度、湿度、电压等参数报警。)
3

保存设备信息

引入redis 查询设备信息,保存设备id 是否报警,报警级别,是否在线。

3.2 达到报警状态后,进行透传(外部系统)

3.3 web hook 监控设备是否在线

3

通过emqx 中的web hook,在emqx 配置文件配置设备断连接口路径。 ,设备断开连接,执行回调函数,发送到服务器。

根据设备id 设置设备的 online status

3.4 通过emqx 代理订阅解决精准操控每个设备

emqx服务器配置代理主题,客户端连接上emqx就可以通过配置%c(客户端id),设备即可通过代理订阅方式,订阅主题。设备通过指定的主题发送客户端id到emqx。后台订阅主题,将客户端信息,和设备信息绑定。

4. influx db 保存设备报文信息。

【InfluxDB V1.8】介绍与使用分析,性能对比Mysql

influx db 主要用来存储一些时间序列的数据。(按时间维度索引的数据)

物联网设备发送过来的报文指标信息,存入influx db中
设备很多,传输过来的报文也很多。

  1. 高并发写入,不需要更新。
  2. 数据压缩存储。
  3. 低延时查询。
InfuxDB中的概念传统数据库概念
database数据库
measurement数据库中的表
point表中的行

Point是由时间戳(time)、标签(tags)、数据(fields)三部分组成,具体的含义如下:

point属性含义
time数据记录的时间,主索引,默认自动生成,相当于每行数据都具备的列
tags相当于有索引的列。tag中存储的值的类型是字符串类型 如果需要检索就 是tags
fieldsvalue值,没有索引的列。field中存储的值得类型:字符串、浮点数(Double)、整数、布尔型。一个field value总是和一个timestamp相关联 如果查询是就是这个值,就用fields

3

上面的截图展示了在名字是test的measurement存储的一些数据,我们可以通过常规的sql语句查询到这些数据。这些测试数据是在一定时间内产生的温度指标数据,其中每行数据包含了具体产生的时间(time)、是否告警(alarm)、设备编号(deviceId)、告警级别(level)、指标名称(quotaName)、数值单位(unit)、指标数值(value)。

其中value列就是filed,里面存储的是Integer;time列是每条记录产生的时间;其余列都是tag,存储的数据都是字符串。

# hostname=server01 是索引列,继续添加索引列就使用逗号。 service 也是tag列
insert disk_free,hostname_ss1,service=app value=2222i
insert disk_free,hostname=server01 value=442221834240i 

# tags 不用加引号,因为只能是字符串。
insert disk_free,hostname=server01 value=442221834240i,sv="aaaa"
sv 是filed类型,加引号,要识别是field 的字符串类型

其中 disk_free 就是表名,hostname是索引(tag),value=xx是记录值(field),记录值可以有多个,系统自带追加时间戳

4.1 influx db 存储引擎

retention policy 存储策略。 保存数据的时间
shard 分片

  • Cache 缓存
  • WAL 写优化的存储格式,持久化
  • TSM file
  • Compactor

存储目录

influxdb的数据存储有三个目录,分别是meta、wal、data:

  • meta 用于存储数据库的一些元数据,meta 目录下有一个 meta.db 文件;
  • wal 目录存放预写日志文件,以 .wal 结尾; 用于写的
  • data 目录存放实际存储的数据文件,以 .tsm 结尾。 用于查询的

4.2 influx db 保存设备的上报信息

s

设备通过eqm x 上报设备报文数据,服务端接收数据保存到influx db中。

4.3 通过influx db 查询设备的报文信息

4.4 设备详情信息查询 influx db+mysql

3

跨数据库的查询。 查询mysql 数据库设备信息, 和influxdb 的设备的报文参数信息。
通过逻辑组织。

  1. 先查询设备信息
  2. 再for 查询每个设备信息,deviceid对应的最新的指标信息(温度,电压 ,湿度)。

last 函数 获取 最新指标值。

5.设备报表分析

5.1 设备状态统计 饼图

5.2 异常告警趋势表 折线图 使用time() 函数。

这里需要说明的是:

在要执行的sql里的group by分组里使用了InfluxDB的time时间函数

  • group by time(1m):按每分钟进行分组汇总
  • group by time(1h):按每小时进行分组汇总
  • groupby time(1d):按每天进行分组汇总

之后配合select中的count函数就可以获取到具体时间维度里汇总里的总数了,这样就能获取到我们想要的汇总数据了。

InfluxDB除了会根据sql语句返回pointValue也会同时返回每一条数据对应的time时间列。

3

5.3 柱状图 报警 top 10

top() 函数

6. 保存设备经纬度 redis geo

6.1 设备上报gps 信息存储到redis 中

6.2 沉默周期 redis 实现

告警透传,同样的告警,在沉默周期内不在重复提示告警。
redis 实现
String 类型,key 为设备id,过期时间为5minutes,存在就不再进行告警。

7. 报警离线设备前端推送 通过emqx web hook 监控设备在线

EMQ的webHook来实现实现设备断网监控,并更新设备状态。
webhook由emqx_web_hook插件提供的,将EMQ X中的钩子事件(连接,断开)通知到某个Web服务的功能

告警信息推送到emqx,前端订阅消费。

7.1 mybatis 整合redis 二级缓存

设备信息,设备指标信息。

8. 项目亮点

8.1 功能模块

  1. 报警沉默周期

8.2 项目亮点

  1. 使用策略模式、工厂模式优化接收设备上报数据。注解

9 oauth 密码模式

9.1 认证流程

3
4

执行流程:

1、用户登录,请求认证服务

2、认证服务认证通过,生成 jwt 令牌,将 jwt 令牌及相关信息写入 Redis,并且将身份令牌写入 cookie

3、用户访问资源页面,带着 cookie 到网关

4、网关从 cookie 获取 token,并查询 Redis 校验 token,如果 token 不存在则拒绝访问,否则放行

5、用户退出,请求认证服务,清除 redis 中的 token,并且删除 cookie 中的 token

使用 redis 存储用户的身份令牌有以下作用:

1、实现用户退出注销功能,服务端清除令牌后,即使客户端请求携带 token 也是无效的。

2、由于 jwt 令牌过长,不宜存储在cookie中,所以将jwt的 身份令牌 存储在 redis,客户端请求服务端时附带这个 身份令牌,服务端根据身份令牌到 redis 中取出身份令牌对应的 jwt 令牌。

9.2 网关功能

  1. 路由转发
  2. jwt认证
  3. 白名单

10. 最终数据一致性 分布式事物

本地消息表+任务调度方式。实现分布式事物最终数据一致性。

10.1 熔断降级

熔断是当下游服务异常时一种保护系统的手段,降级是熔断后上游服务处理熔断的方法。
3

10.2 消息可靠性、幂等性、消息堆积。

消息可靠性、幂等性、消息堆积。

10.3 基于spring 事物的扩展

spring 事物原理
一个方法上加了@transaction注解,执行方法时,开启事物。
开启事物的时候,创建数据库连接,

编写可靠事物代码。
通过spring 声明式事务,多种情况下会失效。

  1. 方法内调用。没有经过bean 的代理无法aop增强,进行事物控制。
  2. 在方法里面启动异步线程,异步线程拿到的连接和主线程拿到的连接不是同一个。所以控制不了异步线程的事物。
  3. 发送
    锁释放,没提交。导致事物失效,提交事务后,在释放锁。
    // demo
/**
 * @author hyp
 * @date 2023/5/24
 */
public class TransactionDemo {
    @Transactional
    public void doTx() {
        // start tx

        //当前上下文事物执行完后,执行下面回调方法
        TransactionUtils.doAfterTransaction(() -> {
            //send mq rpc
        });

        // end tx
    }
}

// 工具类

/**
 * 本地事物提交后 回方法工具类
 * TranscationSynazation
 * @author hyp
 * @date 2023/5/24
 */
public class TransactionUtils {
    public static void doAfterTransaction(Runnable runnable){
        //判断当前上下文是否由事物激活
        if(TransactionSynchronizationManager.isActualTransactionActive()){
            // 注册当前事务上下文同步器
            TransactionSynchronizationManager.registerSynchronization(new TransactionCompletion(runnable));
        }
    }

}
class TransactionCompletion implements TransactionSynchronization{
    private Runnable runnable;

    public TransactionCompletion(Runnable runnable) {
        this.runnable = runnable;
    }

    /**
     *  int STATUS_COMMITTED = 0;
     *     int STATUS_ROLLED_BACK = 1;
     *     int STATUS_UNKNOWN = 2;
     * @param status 事物状态
     */
    @Override
    public void afterCompletion(int status) {
        if(status==TransactionSynchronization.STATUS_COMMITTED){
            // 事物成功提交后才执行回
            //回调函数,
            runnable.run();
        }
    }
}

10.4 多线程导入 控制事物

多线程控制事物
Java多线程批量操作,居然有人不做事务控制?–好掘金

10.5 分片上传

10.5.1 文件分片

  1. 先把整个大文件md5生成,检查是是否已经上传过。(MD5 文件)
    判断数据库有,文件服务器有才不上传。

  2. 对分块文件上传前检查 是否存在 文件服务器目录**(md5前2位/md5 3-4位/md5名 目录)** md5 前4位 做2个子目录 ,chunk 存 分块 (接口 MD5,分块文件 序号)
    3

  3. 上传分块 (MD5 ,分块序号,分块文件)

  4. 合并文件 (MD5 ,分块总数,文件名称)
    合并文件
    校验文件服务器合并后的MD5 和上传的MD5是否一致
    文件信息入库
    清除分块文件

10.6 上传文件事物失效

在上传文件到文件存储服务器后,准备把文件信息入库。
非事物方法 直接调用事物方法( 并不是以代理对象调用)
upload方法 调用了本类的 信息入库的方法,upload方法没有事物,导致 信息入库方法的事物失效。

10.6.1 事物失效

  1. 调用事物方法,把异常捕获了,导致事物失效
  2. 非事物方法调用 事物方法
  3. 非public 方法
  4. rollbackFor 回滚异常 和 抛出异常不匹配

10.6.2 mybatis 分页插件原理

首先分页参数放在ThreadLocal中,拦截执行的sql,根据数据库的类型添加对应的sql语句。
计算出了 total总条数,pageNum当前第几页,pageSize 等数据。

10.6.3 #{} 和${} 的区别

#{} 是一个占位符,解析为SQL时,会将形参变量的值取出,并自动给其添加引号。
${} 解析为SQL时,将形参变量的值直接取出,直接拼接显示在SQL中
常见的使用${}的情况:

1.当sql中表名是从参数中取的情况

2.order by排序语句中,因为order by 后边必须跟字段名,这个字段名不能带引号,如果带引号会被识别会字符串,而不是字段。

10.6.3 插件原理

MyBatis有四大核心对象:
(1)ParameterHandler:处理SQL的参数对象
(2)ResultSetHandler:处理SQL的返回结果集
(3)StatementHandler:数据库的处理对象,用于执行SQL语句
(4)Executor:MyBatis的执行器,用于执行增删改查操作
Mybatis插件原理就是:使用动态代理对以上四个目标对象进行包装,然后再有针对性的进行拦截,其生命周期分为包装和拦截。
3
3
如何编写插件
在这里插入图片描述

10.7 脱敏操作

改造了以前写的数据脱敏插件,更好用了

11 京东云技术文章

-------------------------------------------优化-、限流------------------------
接口优化的常见方案实战总结
高并发场景下常见的限流算法及方案介绍

常见的限流算法分析以及手写实现(计数器、漏斗、令牌桶)

-----------------线上问题--------------
线上问题处理案例:出乎意料的数据库连接池 | 京东云技术团队

Redis缓存的主要异常及解决方案

------------------mybatis---------

源码学习之MyBatis的底层查询原理 | 京东云技术团队

Mybatis的parameterType造成线程阻塞问题分析 | 京东云技术团队

------------------------------------并发编程------

ReentrantLock源码解析 | 京东云技术团队

关于并发编程与线程安全的思考与实践 | 京东云技术团队–synchronized

架构师日记-从代码到设计的性能优化指南 | 京东云技术团队
JAVA多线程并发编程-避坑指南

rt下降40%?程序并行优化六步法 | 京东云技术团队
------------------------------模式-----------------------
1分钟学会、3分钟上手、5分钟应用,快速上手责任链框架详解 | 京东云技术团队

烂怂if-else代码优化方案 | 京东云技术团队

---------------------------返回结果----------------------
一站式统一返回值封装、异常处理、异常错误码解决方案—最强的Sping Boot接口优雅响应处理器 | 京东云技术团队

如何优雅的处理异常

--------------------------------jvm-------------------------------
线上FullGC问题排查实践——手把手教你排查线上问题

浅析JVM GC配置指南 | 京东云技术团队
谈JVM参数GC线程数ParallelGCThreads合理性设置

jvm中类和对象定义存储基础知识 | 京东云技术团队

源码剖析JVM类加载机制

从原理聊JVM(一):染色标记和垃圾回收算法

“堆内存持续占用高 且 ygc回收效果不佳” 排查处理实践–概念可以看看

---------------------------------事务、幂等--------------------

幂等设计详解 | 京东云技术团队

如何实现数据库读一致性 | 京东云技术团队

如何在微服务下保证事务的一致性 | 京东云技术团队

多级缓存
基于Spring Cache实现Caffeine、jimDB多级缓存实战
服务端应用多级缓存架构方案 | 京东云技术团队

---------------------------------------redis---------------------------
Redis缓存高可用集群

学习下Redis内存模型

缓存空间优化实践
Redis数据结构(一)-Redis的数据存储及String类型的实现
京东云开发者|Redis数据结构(二)-List、Hash、Set及Sorted Set的结构实现
一文搞懂Redis

—=-------------------------mysql------------------------
「案例回顾」一次较波折的MySQL调优 | 京东云技术团队
MySQL之InnoDB存储结构 | 京东物流技术团队
一文了解MySQL中的多版本并发控制
一文带你搞懂如何优化慢SQL
记录一次数据库CPU被打满的排查过程
这个 MySQL bug 99% 的人会踩坑!

MySQL性能优化浅析及线上案例 案例 索引

深入理解MySQL索引底层数据结构

-----------------------------jwt oauth------------
【实践篇】教你玩转JWT认证—从一个优惠券聊起 | 京东云技术团队

11.x vivo 文章

容易忽视的细节:Log4j 配置导致的零点接口严重超时

12 观察者模式、策略模式

12.1 观察者模式

多个对象间,存在一对多的依赖关系,当一个对象的状态发生关系时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时候又被称为发布订阅模式, spring 事件机制。

观察者模式可以有任意多个观察者对象同时监听一个对象。监听某个对象的叫观察者(Observer)被监听的对象叫被观察者(Subject) 。被观察者对象在内容或状态发生改变时,会通知所有观察者,使它们能自动更新自己的信息。

12.2 观察者模式、动态策略路由

不同事件业务触发的情况下,会去通知用户邮件、短信、推送等。不同的事件,不同的业务场景下,可能时不同的推送组合,通知用户。
首先就是通过 不同业务场景 if else 判断 应该调用哪几个。

改进:
通过观察者模式,让事件的发生和通知分开处理,在代码上进行解耦。
接着,关于每种业务场景,有哪几种通知,又抽取了策略模式的接口,动态的组合每一种业务需要对应哪些通知类型。后期更灵活之后,把业务,通知组合可以放到配置中心区,达到的效果,如果需要新增业务,只需要改一下配置中心的配置,就能够组合不同的通知的模式。进行通知。 从而更加解耦,更有扩展性。

通过温度,湿度,电压,获取对应的level。根据level,通过策略模式在map中获取发送消息组合的list。
遍历所有发送消息实现类,判断是否在以上获取到的消息组合集合中。

12.3 通过 自定义注解、工厂模式+策略模式,进行项目接收mqtt消息代码解耦,提高扩展性。

每一个需要处理消息的类只需要添加@ProcessType注解,并实现MsgHandler接口即可。@ProcessType是一个自定义注解,用于指定消息协议名称
实现ApplicationContextAware,获取容器对象。根据beanClass 获取实现了msghandler接口的类。并获取类上注解对应的value 值,把注解对应的value 值 和对象存入到map中。
在 process方法中,根据设备上报的主题获取相对应的处理对象。

12.4 使用redis

12.5 通过本地消息表+Rabbitmq+xxl-job方式,保证添加考试计划事物的最终一致性。

新增考试计划。
1.发送消息到设备服务,保存设备的阻断频段。并进行频段的下发。

设计理念:

  1. 确认生产者一定要将数据投递到MQ服务器中,采用本地事务消息、定时任务、消息确认机制。

  2. MQ消费者消息能够正确消费消息,采用手动ACK模式、方法幂等性、重试机制。

  3. 始终不能消费的消息进行人工通知处理

面试 还需要答出其他处理方案, 二阶段提交,TCC 最大努力通知,Saga 事物
3
3

rabbitmq 发布确认机制。

RabbitMQ 高级:分布式事务详解案例——可靠生产(二)----长文。
消息中间件MQ-基于RabbitMQ分布式事务处理–网易课
分布式事务:基于rabbitmq可靠消息最终一致性–图
Rabbitmq实现多系统间的分布式事务,保证数据一致性—实验代码

rocketmq 消息 分布式事物 基本原理

3

12.6 mqtt vs http

mqtt 以数据为中心,而http是以文本为中心。http 是应用于服务端、客户端请求响应协议。mqtt 是轻量级的(将数据作为二进制字节数组传输)和发布订阅的模型。适用于资源受限的设备,有助于节省带宽。
发布订阅模式,可以进行解耦。(发布者和订阅者的解耦)不需要直接建立联系,无需等待。

  1. 功能简洁,低功耗。
  2. 发布订阅模式。
  3. 传输量低,节省带宽,提高传输效率。

http 使用使用受限。

  1. 实现成本高,实时性差。(设备主动服务器发送数据,只能应用于数据采集,服务端无法主动发消息给客户端)
  2. 安全性不高 http 是明文协议。https。
  3. 设备受限。 需要实现http协议,XML/JSON数据格式的解析。

mqtt 优势

  1. 低协议开销、低功耗、数百万设备连接、推送通知。

http 协议

文本传输协议,无状态的,请求、响应方式运行的协议。
报文格式

起始行

  • 请求:get /index.html HTTP/1.1
    • (method、空格、uri、空格、version、换行)
    • get/post
    • 版本号
  • 响应: HTTP/1.1 200 ok
    • 版本号 空格 状态码 Reason

头部字段集合

  • 请求头
  • 响应头

空行

消息正文

tcp 三次握手 四次挥手

Syn 同步位,

  • sync =1 表示一个连接请求
    ACK 确认位,
  • ACK=1 确认有效
  • ACK=0 确认无效
    ack 确认号。
  • ack 对方发送序号+1
    seq 序号
tcp 三次握手

第一次:客户端发送 同步位Syn=1,seq=x(x是随机的)发送给客户端。
第二次:服务器发送 Syn=1,ACK=1,ack=x+1, seq=y(服务器随机生成)
第三次:客户端 ACK=1,ack=y+1, seq=x+1
可以进行数据传送。

为什么需要三次
三次握手会产生 Syn洪泛攻击

Syn 洪泛攻击是在osi 的第四层,传输层。
例用三次握手,攻击者发送TCP SYN,syn是tcp 三次握手中的第一个数据包。而当服务器发送ACK后,攻击者就不对其进行再确认,那这个TCP连接就会处于挂起状态。即办连接状态。服务器收不到 确认的确认,还会重复发送ACK给攻击者,服务器上有大量的挂起TCP连接,消耗CPU和内存。

防火墙技术,
负载均衡,限流。缓存。

四次挥手

FIN=1 断开连接,客户端停止向服务端发送数据

  1. 客户端主动发起关闭请求。FIN=1,seq=u
  2. 服务端收到,接着向客户端发送 ACK=1,ack=u+1,seq=v(服务端生成v) 半关闭。服务端还可以向客户端发送数据。
  3. 服务器发送客户端关闭。 FIN=1,ACK=1,ack=u+1,seq=w
  4. 客户端给服务端响应 ACK=1,ack=w+1,seq= u+1(中途客户端没有向服务端发送数据)

HTTP 与 HTTPS 有哪些区别?

HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。

HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。

两者的默认端口不一样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443。

HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

http头有哪些

content-type(mimetype、application/json)、content-length 请求内容的长度、cookie、
connection 表示是否是持久连接,http 1.1 默认持久连接 。
Authorization http 授权证书
host

HTTPS 解决了 HTTP 的哪些问题?

HTTP 由于是明文传输,所以安全上存在以下三个风险:

窃听风险,比如通信链路上可以获取通信内容,用户号容易没。
篡改风险,比如强制植入垃圾广告,视觉污染,用户眼容易瞎。
冒充风险,比如冒充淘宝网站,用户钱容易没。

HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议
HTTPS 是如何解决上面的三个风险的?

  • 混合加密的方式实现信息的机密性,解决了窃听的风险。
  • 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险。
  • 将服务器公钥放入到数字证书中,解决了冒充的风险。

http 1.0 1.1 2.0 区别

  1. HTTP/1.0、HTTP/1.1、HTTP/2、HTTP/3演变
    详解HTTP协议版本(HTTP/1.0、1.1、2.0、3.0区别)
  • HTTP/1.1相比HTTP/1.0性能上的改进:
  1. 使用TCP长连接的方式改善了HTTP/1.0短连接造成性能开销
  2. 支持管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间

实际上 HTTP/1.1 管道化技术不是默认开启,而且浏览器基本都没有支持,所以后面所有文章讨论 HTTP/1.1 都是建立在没有使用管道化的前提。大家知道有这个功能,但是没有被使用就行了

解释:
举例来说,客户端需要请求两个资源。以前的做法是,在同一个 TCP 连接里面,先发送 A 请求,然后等待服务器做出回应,收到后再发出 B 请求。那么,管道机制则是允许浏览器同时发出 A 请求和 B 请求,
3
但是服务器必须按照接收请求的顺序发送对这些管道化请求的响应

如果服务端在处理 A 请求时耗时比较长,那么后续的请求的处理都会被阻塞住这称为「队头堵塞」。

所以,HTTP/1.1 管道解决了请求的队头阻塞但是没有解决响应的队头阻塞

  • HTTP/1.1 自身的性能瓶颈:
  1. 请求/响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩Body的部分
  2. 发送冗长的首部。每次互相发送相同的首部造成的浪费较多
  3. 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞(服务端队头阻塞)
  4. 没有请求优先级控制
  5. 请求只能从客户端开始,服务器只能被动响应

HTTP/2协议是基于HTTPS的,所以HTTP/2的安全性是有保障的。

  • HTTP/2相比HTTP/1.1性能上的改进:

针对不同的 HTTP 请求用独一无二的 Stream ID 来区分,接收端可以通过 Stream ID 有序组装成 HTTP 消息,不同 Stream 的帧是可以乱序发送的,因此可以并发不同的 Stream ,也就是 HTTP/2 可以并行交错地发送请求和响应

HTTP/2解决了用流和分帧的方式HTTP的队头阻塞问题。

  1. HTTP/2·会压缩头(Header),如果你同时发送多个请求,他们的头是一样的或者是相似的,那么协议会帮你消除重复的部分。

  2. HTTP/2不再像HTTP/1.1里的纯文本的报文,而是全面采用了二进制格式。头信息和数据体都是二进制,并且统称为帧(frame):头信息帧和数据帧。

  3. HTTP/2的连接可以并发多个请求(多路复用),而不用按照顺序一一对应。移除了HTTP/1.1中的串行请求,不需要排队等待,不会再出现「队头阻塞」问题。

    比如:在一个TCP连接里,服务器收到了客户端A和B的两个请求,如果发现A处理过程非常耗时,于是就回应A请求已经处理好的部分,接着回应B请求,完成后,再回应A请求剩下的部分。

  4. 服务器推送,HTTP/2在一定程度上改善了传统的「请求-应答」工作模式,服务不再是被动地响应,也可以主动向客户端发送消息。

    比如:在浏览器刚请求HTML的时候,就提前把可能用到的JS、CSS文件等静态资源主动发给客户端,减少延时的等待,也就是服务器推送(Server Push,也叫Cache Push)

  • http2 队头阻塞-

HTTP/2 通过 Stream 的并发能力,解决了 HTTP/1 队头阻塞的问题,看似很完美了,但是 HTTP/2 还是存在“队头阻塞”的问题,只不过问题不是在 HTTP 这一层面,而是在 TCP 这一层。

HTTP/2 是基于 TCP 协议来传输数据的,TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且连续的,这样内核才会将缓冲区里的数据返回给 HTTP 应用,那么当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核缓冲区里,只有等到这 1 个字节数据到达时,HTTP/2 应用层才能从内核中拿到数据,这就是 HTTP/2 队头阻塞问题。
3
图中发送方发送了很多个 packet,每个 packet 都有自己的序号,你可以认为是 TCP 的序列号,其中 packet 3 在网络中丢失了即使 packet 4-6 被接收方收到后由于内核中的 TCP 数据不是连续的,于是接收方的应用层就无法从内核中读取到,只有等到 packet 3 重传后,接收方的应用层才可以从内核中读取到数据,这就是 HTTP/2 的队头阻塞问题,是在 TCP 层面发生的。

  • HTTP/2有哪些缺陷?HTTP/3做了哪些优化?
  1. HTTP/3 把HTTP下层的TCP协议改成了UDP
    UDP 发送是不管顺序,也不管丢包的,所以不会出现像 HTTP/2 队头阻塞的问题。大家都知道 UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输。

HTTP/2解决了用流和分帧的方式HTTP的队头阻塞问题。
HTTP/3解决了用UDP+QUIC解决了TCP队头阻塞的问题。

12.7 多级缓存

数据量较大,不可能全放入缓存,引入缓存过期策略。(惰性删除定时每隔100ms,删除一小部分过期的key,2.调用get 方法 主动删除)

问题描述

基于Spring Cache实现Caffeine、jimDB多级缓存实战
服务端应用多级缓存架构方案 | 京东云技术团队
----------aa-------
spring cache实现二级缓存(Caffeine+Redis)
SpringBoot Cache使用Caffeine + Redis 支持多级缓存—以上两个类似,pig项目
---------aaa--------------
SpringCache + Caffeine + Redis整合本地缓存为分布式缓存

spring cache
springcache本身并没有提供缓存的实现,但是他提供了一套的接口、代码规范、配置、注解等,这样很容易就可以整合各种缓存,springcache主要包含了两个核心的接口来统一管理缓存相关的实现。分别是:

  • org.springframework.cache.Cache 定义了通用缓存操作的接口
  • org.springframework.cache.CacheManager 是一个spring的缓存管理器,主要用于管理不同的缓存
实现步骤
  1. 定义缓存的配置文件
  2. 实现Cache 接口
  3. 实现CacheManager接口
  4. 增加spring boot配置类
  • 获取缓存数据
    先查一级本地缓存,不存在查二级redis 缓存,二级存在,更新本地缓存。
    当一级缓存 二级缓存都不存在。
    通过双检锁的机制查询db,并先把结果放入redis,再发布事件清除各个机器本地缓存key,接着存放当前缓存到本地机器的本地缓存。

  • 新增数据
    也是先加入到redis,
    接着发布消息,清除各个机器本地缓存为xx的key,
    接着存key value 到当前服务的本地缓存中。

  • 清除
    先清除 redis ,发布事件让其他机器清除本地缓存为xx的key,再清除 本地缓存xx的key。
    先清除redis中缓存数据,然后清除caffeine中的缓存,避免短时间内如果先清除caffeine缓存后其他请求会再从redis里加载到caffeine中

13 深度分页

0.看前须知:B+树非节点为索引,叶子节点为行记录。查找时先定位内存页中的主键值,再定位硬盘中的行记录(即回表记一次I/O)。
1.单库单表设计,深度分页时,需要offset的行数很大如1000(offset不会利用到索引),B+树需要遍历扫描1000行的行记录,才知道offset1000在哪里。
2.聚集索引优化:在子查询中查找出目标行号的ID (非叶子节点可走主键索引!),在主查询中联合子查询的ID查询记录(再次使用主键索引!),
写法如: SELECT table1.id,table1.xxx,table1.yyy INNER JOIN ( SELECT id from table1 LIMIT 1000,20 ) AS table2 ON table1.id = table2.id;
3.分库分表优化:
3.1 目标表分片情况,所有分片都需要查询目标长度的记录,放到内存中重新排序。比如要分2片查三页,P片Q片各查3页共六页到内存,排序后返回前三页,缺点是内存占用和排序效率。
3.2 游标归并情况,每个分片都查 目标数/分片数 条记录,使用游标对记录值进行大小比较,然后构建有序记录。缺点是有精度问题。
4. 减少单表深度的方案:合理建表、冷热分离、分库分表
5. 控制请求的方案:避免跳转深度分表、限制最大分页数

14 spi

spi 是jdk内置的基于接口的动态扩展点的实现,定义一个标准的接口。第三方库实现这个接口,程序在运行的时候,根据配置信息,动态加载第三方的实现类,从而完成功能的动态扩展机制。

spi 是jdk 内置的基于接口的动态扩展点的实现。
作用:

  1. 把标准d的定义 和接口实现分离,在模块化开发中很好的实现了解耦。
  2. 实现功能的扩展,更好的满足定制化的需求。
    定义一个标准的接口,第三方库实现这个接口,程序在运行的时候,根据配置信息,动态加载第三方实现的类,从而完成功能的动态扩展机制。
    例如:
    在java sdk中 提供了一个数据库驱动接口,Driver接口,java里面并没有提供接口的的实现,由第三方实现。
    spi 通过ServiceLoader 类解析classpath 或者jar 包 中META-INF/services/目录下的 以接口全限定类名的文件。并加载该文件中指定的接口实现类。

1
3

自己项目
3

3
3

jdbc 打破双亲委派机制 加载驱动

加载DriverManager 类的时候,将driver 添加到list 中,加载DriverManager 使用的是引导类加载器(根加载器)。但是加载 h2Driver,mysqlDriver 的时候使用系统类加载器。

spi 只是iter 了没加到list 中,怎么可以?
因为驱动内部static{} 代码块内部 已经 load() 注册了。
3

双亲委派可见性

启动类加载器作为应用程序类加载器的上级,启动类加载器加载的类 对应用程序类加载器是可见的。

然而应用程序类加载器加载的类对启动类加载器却是不可见的。

这是由 classloader 加载模型中的可见性(visibility)决定的可见性原则允许子类加载器查看父ClassLoader加载的所有类,但父类加载器看不到子类加载器的类。

双亲委派模型的妥协

–java.sql.DriverManager通过扫包的方式拿到指定的实现类,完成 DriverManager的初始化。

但是,根据可见性原则,·java.sql.DriverManager是启动类加载器负责的,根据双亲委派的可见性原则,启动类加载器加载的 DriverManager 是不可能拿到系统应用类加载器加载的实现类 。

为了解决这个困境,Java的设计团队只好引入了一个不太优雅的设计:线程上下文类加载器 (Thread Context ClassLoader)。

这个类加载器可以通过java.lang.Thread类的setContext-ClassLoader()方法进行设置,如果创建线程时还未设置,它将会从父线程中继承一个,如果在应用程序的全局范围内都没有设置过的话,那这个类加载器默认就是应用程序类加载器。

通过这个类加载器可以实现功能,但也正是因为如此,双亲委派模型的可见性原则就被破坏了,但这也是无可奈何的事情,所以只能说是妥协~

Spi 接口 解耦

15 数据库索引 java 日志

MySQL为什么varchar字段用数字查无法命中索引,而int字段用字符串查却能命中?

总结
MySQL查询中,当字符串和数字做比较时,会触发隐式类型转换,转换规则是将字符串转换成数字。

当索引字段是字符串类型,输入参数是数值类型时,会将字段转换成数值类型再进行查找,也就是对索引字段做了函数操作,破坏了索引的有序性,因此无法使用索引。
当索引字段是数值类型,输参数是字符串类型时,会将输入参数转换成数值类型再进行查找,对等号后面的输入参数进行函数操作,并不影响索引字段的有序性,因此可以使用索引。

问题&优化归集

记一次通过优化日志解决高并发服务性能瓶颈问题
彻底搞清楚MySQL字符编码不一致造成索引失效的问题 文章1

【MySQL】表字段字符集不同导致的索引失效问题 超集 条件查询

15.1 left join on后面 加条件 与 where后面加条件的区别

left join on后面 加条件 与 where后面加条件的区别

15.2 order by limit 重复

mysql order by+limit数据重复问题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值