8.14-8.20
SonarQube
简介
- SonarQube是一个开源的静态代码分析工具,根据不同语言的规则,对代码进行扫描,扫描出潜在的问题并提供修改方案。
- SonarQube除了支持自有的规则外,还可以通过插件的方式,支持CheckStyle、FindBugs、PMD等其他代码质量分析工具的规则
- 除了搭建SonarQube服务器,还可以在IDEA编辑器,安装SonarLint插件对代码进行扫描
管理问题
可以点进去问题查看单个问题的详情,点击为何是问题?查看修改建议
对问题可以标记为:
- 不会修复:代表检测出的问题不需要解决
- 误判:代表系统误判
标记上述两种标记后,下次扫描就会自动略过。
项目详情
质量阈
只有配置了管理质量阈的用户,才可以编辑质量阈。
可以自定义编辑质量阈的条件,比如Bugs > 0 & 漏洞 > 0…
满足任一条件则质量阈状态为错误,否则为正常
问题
安全热点
不一定是问题,需要审核确认是否为安全漏洞
指标
Yapi
前后端分离的痛点:
- 文档缺失,输入输出没有预期,或与预期不符。
- 文档老旧,不够全面,如文档中的接口已失效,有用的接口不放在文档里。
- 前端开发依赖于后端接口数据,需要与后端接口联调才能获得数据展示,拖慢了开发进度。
- 难以使用常规文本文档工具,对项目中所用到的接口进行管理。
接口问题:
- 接口的字段更新了
- 接口的路由更新了
- 接口返回了未预期的值
- 接口返回由于某种原因被删除了
所以要使用接口文档管理工具-YApi
接口基本管理
请求参数
- 请求Body:http 请求 body 部分。如果http请求方式是 post, put 等请求方式时会有req_body 部分。req_body_type有4种,分别是 form, json, file 和 raw 。
- Query参数:接口 url 的查询字符串参数,可以通过拖动来交换参数位置。
- Headers: http 请求头字段。
返回数据
两种形式:JSON和RAW
导入导出
导入:
- 普通模式(normal):不导入已存在的接口;
- 智能合并(good):已存在的接口,将合并返回数据的response,适用于导入了 swagger 数据,保留对数据结构的改动;
- 完全覆盖(mergin):不保留旧数据,完全使用新数据,适用于接口定义完全交给后端定义。
默认导入方式为normal
导出:
项目 -> 数据管理,选择需要导出的数据方式,一共有三种导出方式,html,markdown,json。然后点击导出按钮,将会下载数据文件。
自动化测试
通过添加测试集合,完善测试用例,接口的入参和对RESPONSE
断言,即可实现对接口的自动化测试
二次开发注意事项:
- 将package.json中 “eslint-plugin-react” 的版本限制为7.1.0版本
- 安装cross env 并修改脚本中
NODE_ENV=
为cross-env NODE_ENV=
- 在ykit.config.js中针对
swagger-client
添加对应babel-loader
。 - /server中后端程序修改后重新启动即可生效。
Quartz、XXL-JOB
定时任务
- 定时任务:在规定的时间触发执行某个任务。
- 定时任务框架(Java):使用Java语言编写的定时任务工具包(函数的集合)。
- 作用:让程序在指定的时间触发执行某个动作。
Quartz
Quartz是一个开源的任务调度框架,用于在Java应用程序中实现作业调度。
功能特点:
- 方便:完全由Java编写,对Java工程师使用友好。
- 灵活的任务调度:可以按照指定的时间表执行任务,也可以根据配置的规则,进行重复执行任务。
- 支持多种类型的触发器:简单触发器、Cron触发器、日历触发器。
- 可靠性和持久性:支持作业和触发器配置持久化到数据库中。
- 分布式和集群支持:支持分布式和集群模式,解决高可用问题。
核心组件:
作业(Job):需要执行的任务
触发器(Trigger):定义作业何时执行的规则
- 简单触发器(SimpleTrigger):简单触发器允许在指定的时间间隔内重复执行作业。
- Cron触发器(CronTrigger):允许使用Cron表达式定义更复杂的执行规则
- 日历触发器(CalendarTrigger):可以排除指定的日期或时间段,控制作业的执行
调度器(Scheduler):管理作业和触发器的注册和执行,调度器可以启动、暂停、停止作业的运行,并负责将作业分配给合适的执行线程。
XXL-JOB
XXL-JOB是一个分布式任务调度平台。
主要特性
- 可视化管理页面,可配置、管理、监控定时任务。
- 调度中心HA,调度组件支持集群部署,可保证调度中心HA
- 分布式任务调度,通过分片广播能力,支持大数据量任务的分布式调度执行
- 丰富的路由策略,执行器集群部署时提供丰富的路由策略
核心组件:
调度中心HA:
1 | 负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦, |
执行器:负责接收调度请求并执行任务逻辑,执行器专注于任务的执行。
CRON表达式
Cron(Command Run On)表达式是一种用于指定任务在某个时间点或周期性执行的字符串表达式。
数据库运维
定义
数据库运维服务是指用户数据库开展的软件安装、配置优化、备份策略选择及实施、数据恢复、数据迁移、故障排除、预防性巡检等一系列服务。
日志框架与应用
日志框架与日志门面:
- 日志框架
- JUL(Java Util Log )是Java官方提供的日志库,使用的并不是非常广泛,性能较低。
- Log4j是一个基于Java的日志记录工具。
- Logback与Log4j是同一作者作品,完美继承了Log4j的优点并补足了Log4j的不足。
- Log4j2是apache开发的一款Log4j的升级产品,并且不兼容Log4j
- 日志门面:主要有JCL 、Slf4j
1 | 是门面模式的一个应用。可以抽象的理解为java的接口,日志框架可以理解为接口的具体实现。 |
Logback介绍:
是SpringBoot内置的日志处理框架。
日志级别
等级从低到高分别是TRACE < DEBUG < INFO < WARN < ERROR,高级别日志会覆盖低级别日志(配置INFO级别的日志,那么TRACE和DEBUG级别的日志不会显示)
- Trace:是追踪,就是程序推进一下,你就可以写个trace输出,所以trace应该会特别多
- Debug:指出细粒度信息事件对调试应用程序是非常有帮助的
- Info:消息在粗粒度级别上突出强调应用程序的运行过程
- Warn:输出警告及warn以下级别的日志
- Error:输出错误信息日志
配置文件
命名:
Spring Boot官方推荐优先使用带有-spring
的文件名作为你的日志配置(如使用logback-spring.xml
,而不是logback.xml
,两者都存在会默认读取前者)
configuration
- scan : 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
- scanPeriod : 设置监测配置文件是否有修改的时间间隔,默认单位是毫秒。只有当scan为true时,此属性才生效。默认的时间间隔为1分钟。
- debug : 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
1 | <configuration scan = "true" scanPeriod="10 seconds" debug="false"> |
property:自定义变量,使用时格式为${LOG_PATH}
1 | <property name="LOG_PATH" value="./logs" /> |
appender
appender是 <configuration>
的子节点,是负责写日志的组件,该标签负责以适当的格式将日志记录事件输出到适当的输出设备。
1 | <!--name: appender名称; class: appender类的全限定名 --> |
常用appender类型:
- RollingFileAppender: 滚动记录地把日志输出到文件, 也就是可以支持日志文件按文件大小拆分,或者按日期拆分
- ConsoleAppender: 把日志打印到控制台
- FileAppender: 把日志输出到文件
- 还有一些不常用的appender类型:
ServerSocketAppender
-网络传输日志事件、SSLServerSocketAppender
-增加SSL加密验证、SMTPAppender
-将日志进行邮件发送
logger
用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>
1 | <!--name: 用于指定受此logger约束的一个包或类 |
1 | additivity的属性为true/false,它是子Logger 是否继承父Logger 的输出源(appender) 的标志位。具体说, |
root
根元素,只有一个level属性,也是<root>
可以包含零个或多个<appender-ref>
元素
1 | <root level="INFO"> |
Logback与Log4j
上面说过Logback完美继承了Log4j,所以Logback基础使用方面与Log4j相同,如日志等级、三大组件等等
Logback本质上是一个优化后的Log4j,但相比于Log4j有太多的有点,官方列举Logback具有以下几点优势:
- 更快的实施:Logback重写了Log4j内部实现,在关键路径提升了十倍速度,减少了内存损耗。
- 更广泛的测试:Logback比Log4j进行了更长时间、更高级别的测试。
- 与SLF4J的完美结合
- 更广泛的文档:Logback具有更详细并且不断更新的文档。
- Logback从0.9.22版本开始同时支持XML与Groovy语法的配置文件
- Logback可以自动扫描并加载修改后的配置文件,并且不启用新的线程资源
- Logback通过对于maxHistory属性的设置可以自动删除旧的日志文件
- Logback的RollingFileAppender可以异步的对旧的日志文档进行压缩
中间件
介绍
什么是中间件?
中间件是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的
为什么用中间件?
中间件屏蔽了底层操作系统的复杂性,使程序开发人员面对一个简单而统一的开发环境,减少程序设计的复杂性,将注意力集中在自己的业务上,不必再为程序在不同系统软件上的移植而重复工作,从而大大减少了技术上的负担。中间件带给应用新系统的,不只是开发的简便,开发周期的缩短,也减少了系统的维护、运行和管理的工作量,还减少了计算机总体费用的投入。
特点
- 满足大量应用的需要 ;
- 运行于多种硬件和OS平台 ;
- 支持分布式计算,提供跨网络、硬件和OS平台的透明性的应用或服务的交互功能 ;
- 支持标准的协议 ;
- 支持标准的接口。
分类
- 数据访问中间件
- 远程过程调用中间件
- 消息中间件
- 交易中间件
- 对象中间件等
Redis
简介
- Redis是完全开源免费的,是一个高性能的key-value数据库
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,Z-set,hash等数据结构的存储
- Redis支持数据的备份,即master-slave模式的数据备份
优点
- 性能极高—-Redis读的速度是110000次/s,写的速度是81000次/s
- 丰富的数据类型—-Redis支持Strings,Lists,Hashes,Sets及Ordered Sets数据类型操作
- Redis的所有操作都是原子性的
- Redis还支持publish/subscribe通知,key过期等等特性
- Redis是用C语言写的,一般来说C语言实现的程序执行速度相对更快
- Redis使用了单线程架构,预防了多线程可能产生的竞争问题,6.0以后开始支持多线程方式
- Redis客户端支持Java、PHP、Python、C/C++、C#、node.js多种语言
使用场景
缓存:
1 | 缓存机制几乎在所有的大型网站都有使用,合理地使用缓存不仅可以加快数据的访问速度,而且能够有效地降低 |
排行榜类的应用,取TOP N操作,比如按顶的次数排序
1 | 比如按照热度、发布时间排名,按照各种复杂维度计算出的排行榜, |
计数器应用
1 | 比如播放量,浏览次数。如果并发量很大对于传统关系型数据的性能是一种挑战 |
Pub/Sub构建消息队列
1 | 消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务解耦、非实时业务削峰等特性 |
其它方面
1 | 存储关系:比如社交关系,比如Tag等 |
数据结构
- String:可以用于用来存储用户信息、分布式锁等应用场景
- List:底层实现是链表,适用于队列、栈和秒杀等场景
- Set:字符串Set,无序不可重复,适用于用户签到、网站访问统计、用户关注标签、好友推荐、猜奖、随机数生成等业务场景
- ZSet:字符串Set,有序且不可重复,根据Score来排序。底层使用散列表和跳表来实现,所以读取中间部分数据也很快。可以用于排行榜、延迟队列等场景
- Bitmaps:底层存储的是一种二进制格式的数据。在一些特定场景下,用该类型能够极大的减少存储空间,因为存储的数据只能是0和1。如:统计签到人数、点赞人数等场景。
- HypefLogLog:实际是一种字符串类型的数据结构。使用该类型最大的好处就是减少空间、但是也存在一定的误差率。该类型也是不允许同一个key存在重复元素。该类型也支持合并多个key的值。
- GEO: GEO类型是一种存储地理信息的数据格式,基于该数据特点。可以用在一些距离计算、附近推荐等业务场景。
- Stream: Stream类型是Redis在5.0之后版本新增的一种数据结构。该数据结构主要用户消息队列的场景。Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。
淘汰策略
volatile-lru(least recently used):在设置过期时间的数据中淘汰最少使用的数据。
volatile-lfu(least frequently used):在设置过期时间的数据中淘汰使用频率最低的数据
volatile-random:在设置过期时间的数据中淘汰任意随机数据。
volatile-ttl(shorter time to live):在设置过期时间的数据中淘汰最早过期的数据。
- allkeys-lru:在所有的数据中淘汰最少使用的数据。
- allkeys-lfu:在所有的数据中淘汰使用使用频率最低的数据。
- allkeys-random:在所有的数据中随机淘汰数据。
- noeviction:默认策略,不淘汰数据,新增或者修改数据会抛异常,但是读操作正常进行,不受影响
过期删除策略
- 定时删除:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。对内存友好,但是会占用大量的cpu资源去处理过期的数据,从而影响缓存的响应时间与吞吐量
- 惰性删除:只有当访问一个key时,才会判断该key是否已过期,过期则清除。对cpu友好,但是极端情况可能存在大量过期的key没有再次被访问,占用大量内存。
- 定期删除:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。一个折中的方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
Redis默认的删除策略是定期删除和惰性删除相结合
缓存雪崩
- 大量缓存同时过期,使得大量读请求都未命中缓存,大量的访问数据库,可能会使数据库崩溃。
- redis故障,导致缓存失效,大量请求访问数据库,可能会使数据库崩溃。
缓存击穿
我们的业务通常会有几个数据会被频繁地访问,比如秒杀活动,这类被频地访问的数据被称为热点数据。
热点资源过期导致缓存失效,大量请求访问数据库,可能会使数据库崩溃。
缓存穿透
当发生缓存雪崩或击穿时,数据库中还是保存了应用要访问的数据,一旦缓存恢复相对应的数据,就可以减轻数据库的压力,而缓存穿透就不一样了。用户想访问的数据既不在缓存中,也不在数据库中,没办法构建缓存数据,数据库压力骤增
上述三种问题的结局方案:https://blog.csdn.net/qq_34827674/article/details/123463175
消息队列
介绍
MQ(message queue)消息队列,也叫消息中间件。消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能,成为异步RPC(Remote Procedure Call,远程过程调用协议)的主要手段之一。它是类似于数据库一样需要独立部署在服务器上的一种应用,提供接口给其他系统调用。
举例场景:快递,服务端就是快递小哥,客户端就是我们,MQ就相当于是菜鸟驿站、蜂巢等
作用
- 系统解耦:MQ连接的系统之间没有直接的调用关系,只是通过消息传递,故系统侵入性不强,耦合度低。
- 异步通信:消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。对于一些非必须及时处理的业务,通过消息队列可以优化系统响应时间。提升系统性能。
- 流量削峰:使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
- 数据采集:分布式系统产生的海量数据流,如:业务日志、监控数据、用户行为等,针对这些数据流进行实时或批量采集汇总,然后进行大数据分析是当前互联网的必备技术,通过消息队列完成此类数据收集是最好的选择。
RabbitMQ
RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。
名词概念
- Server:又称为Broker。接收客户端连接,实现AMQP的服务器实体。
- Connection:连接,应用程序与Broker的网络连接。
- Channel:信道,几乎所有的操作都在Channel中进行,Channel是进行消息读写的通道。客户端可建立多个Channel,每个Channel代表一个会话任务。
- Message:消息。服务器和应用程序之间传递的数据,本质上就是一段数据,由Properties和Body组成。
- Exchange:交换机。接收消息,根据路由键转发消息到绑定的队列。
- Binding:Exchange和Queue之间的虚拟连接,binding中可以包含routing key。
- Routing key:一个虚拟地址,虚拟机可用它来确定如何路由一个特定消息。
- Queue:也称为Message Queue,消息队列,保存消息并将它们转发给消费者。
- Virtual Host:其实是一个虚拟概念。类似于权限控制组,一个Virtual Host里面可以有若干个Exchange和Queue,可以用来隔离Exchange和Queue。同一个Virtual Host里面不能有相同名称的Exchange和Queue。但是权限控制的最小粒度是Virtual Host。
工作模式-发布订阅模式
- 每个消费者监听自己的队列
- 生产者将消息发给broker,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收到消息(广播)
工作模式-路由模式
生产者将消息发送给direct交换器,队列和交换器之间由一个路由key绑定,生产者发送消息时会指定路由key,交换机会把消息发布到对应key的队列上,接着监听该队列消费者的消费信息。
工作模式-Topic模式
上面的路由模式是根据key进行完整匹配(完全相等才发送消息),这里采用通配符来进行模糊匹配。
符号#
代表匹配多个词,符号*
代表匹配一个词
Kafka
Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于hadoop的批处理系统、低延迟的实时系统、storm/Spark流式处理引擎,web/nginx日志、访问日志,消息服务等等,用scala语言编写,Linkedin于2010年贡献给了Apache基金会并成为顶级开源 项目。
特点
- 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒
- 可扩展性:kafka集群支持热扩展
- 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失
- 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
- 高并发:支持数千个客户端同时读写
应用场景
- 日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、Hbase、Solr等
- 消息系统:解耦和生产者和消费者、缓存消息等。
- 用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。
- 运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。
- 流式处理:比如spark streaming和storm事件源
基本概念
Broker:
Kafka集群包含一个或多个服务器,这种服务器被称为broker。broker不维护数据的消费状态,直接使用磁盘进行消息存储,线性读写,速度快:避免了数据在JVM内存和系统内存之间的复制,减少耗性能的创建对象和垃圾回收
Cluster Controller
若干个 Broker 组成一个 集群,其中集群内某个 Broker 会成为集群控制器,它负责管理集群,包括分配Partition到 Broker、监控 Broker 故障等
Producer
负责发布消息到Kafka broker。producer 采用推(push)模式将消息发布到 broker,每条消息都被追加(append)到Partition(patition)中,属于顺序写磁盘(顺序写磁盘效率比随机写内存要高,保障 Kafka 吞吐率)
Consumer
消息消费者,向Kafka broker读取消息的客户端,consumer从broker拉取(pull)数据并进行处理Topic
Producer
将消息发送到特定的主题,Consumer 通过订阅特定的 Topic(主题) 来消费消息;同一个主题的消息可能存储在不同的节点(实际上是其对应的传输通道—Partition可以分布在不同的节点上),但是消费者不用关心具体的存储位置;一个主题的消息可以对应多个Partition,即使用多个Partition传输该主题的消息
Partition
在集群内,一个Partition由一个 Broker 负责,这个 Broker 也称为这个Partition的 Leader;当然一个Partition可以被复制到多个 Broker 上来实现冗余,这样当存在 Broker 故障时可以将其Partition重新分配到其他 Broker 来负责
Kafka为什么那么块
- 顺序读写
- 零拷贝
- 分区
- 批量发送
- 数据压缩