项目描述1

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

黑马分布式事物

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

1. 设备故障 描述 负载均衡 消费消息

  1. 负载均衡的策共享队列模式订阅EMQ中的售货机状态消息,当设备为故障状态的时候,创建一个自动维修工单。

2.xxl-job 分片广播

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

eqm 接收设备报文信息。

  1. 解析设备信息。
  2. 保存报文信息
  3. 保存设备信息
  4. 指标透传(设备的指标信息),传递到其他服务,进行业务逻辑处理。

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

3

l
3

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

3.3 web hook 监控设备是否在线

项目描述1_第1张图片

通过emqx 中的web hook ,设备断开连接,执行回调函数,发送到服务器。

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

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

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

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

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

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

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

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

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

项目描述1_第2张图片

上面的截图展示了在名字是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 保存设备的上报信息

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

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

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

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时间列。

项目描述1_第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 认证流程

项目描述1_第4张图片
项目描述1_第5张图片

执行流程:

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 熔断降级

熔断是当下游服务异常时一种保护系统的手段,降级是熔断后上游服务处理熔断的方法。
项目描述1_第6张图片

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 多线程导入 控制事物

多线程控制事物

10.5 分片上传

10.5.1 文件分片

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

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

  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 后边必须跟字段名,这个字段名不能带引号,如果带引号会被识别会字符串,而不是字段。

11 京东云技术文章

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

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

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

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

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

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

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

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

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

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

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

如何优雅的处理异常

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

谈JVM参数GC线程数ParallelGCThreads合理性设置

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

源码剖析JVM类加载机制

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

线上FullGC问题排查实践——手把手教你排查线上问题
------------事务、幂等--------------------
幂等设计详解 | 京东云技术团队

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

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

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

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

-----mysql-----------
一文了解MySQL中的多版本并发控制
一文带你搞懂如何优化慢SQL
记录一次数据库CPU被打满的排查过程
这个 MySQL bug 99% 的人会踩坑!
MySQL性能优化浅析及线上案例
深入理解MySQL索引底层数据结构


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

12 观察者模式、策略模式

12.1 观察者模式

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

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

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

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

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

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

12.4 通过redis,Zset数据结构,定时任务,解决了处理设备上报故障状态接口运行效率低下,查询逻辑复杂问题。使得总体接口性能提升20%,使用 Set 结构来防止缓存中存放重复订单

(1)使用redis来保存每个人的工单数据,每次创建工单在redis里使用原子增,不用考虑锁。这样得到每日最低工单人员的查询可以做到对数据库零查询。

(2)使用redis的ZSet可以实现数据的自动排序,无需手动排序,再次提升了程序的运行效率,降低了代码的复杂度。

(3)key的规则,以固定字符串(前缀)+时间+区域+工单类别(运营/运维)为大key,以人员id做小key,过期时间为2天。

(4)redis工单数列表初始化,由xxl-job负责处理,每日下午生成第2天的工单数列表。

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

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(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

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/1.1相比HTTP/1.0性能上的改进:
  1. 使用TCP长连接的方式改善了HTTP/1.0短连接造成性能开销
  2. 支持管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间
  • HTTP/1.1 自身的性能瓶颈:
  1. 请求/响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩Body的部分
  2. 发送冗长的首部。每次互相发送相同的首部造成的浪费较多
  3. 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞
  4. 没有请求优先级控制
  5. 请求只能从客户端开始,服务器只能被动响应

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

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

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

  3. HTTP/2的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。客户端还可以指定数据流的优先级。

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

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

  5. 服务器推送,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 队头阻塞问题。

  • HTTP/2有哪些缺陷?HTTP/3做了哪些优化?
  1. HTTP/3 把HTTP下层的TCP协议改成了UDP

你可能感兴趣的:(java,学习,java,开发语言)