SSE
简介Server-Sent Events 服务器推送事件,简称 SSE,是一种服务端实时主动向浏览器推送消息的技术。
SSE运行在HTTP协议之上,它允许服务器以事件流(Event Stream)的形式将数据发送给客户端。客户端通过建立持久化的HTTP连接,并监听这个事件流,从而可以实时接收到服务器推送的数据。
SSE用途ChatGPT 是一个基于深度学习的大型语言模型,处理自然语言需要大量的计算资源和时间,响应速度肯定比普通的读数据库要慢的多,普通 http 接口等待时间过长,显然并不合适。对于这种单项对话场景,ChagtGPT 将先计算出的数据“推送”给用户,边计算边返回,避免用户因为等待时间过长关闭页面。而这,可以采用 SSE 技术。
SSE 可以在 Web 应用程序中实现诸如股票在线数据、日志推送、聊天室实时人数等即时数据推送功能。股票📈k线的实时变化,彩票趋势走向,以及工业数据实时监控(受限于页面的数据获取范围面)和日志推送和CI/CD工作流进度的推送等相关单向推送需求的场景。
需要注意的是,SSE 并不是适用于所有的实时推送场景。在需要高并发、高吞吐量和低延迟的 ...
logback的配置和使用
logback 简介
logback 官网:https://logback.qos.ch/
logback 由三个模块组成:
logback-core
logback-classic
logback-access
logback-core 是其它模块的基础设施,其它模块基于它构建,logback-core 提供了一些关键的通用机制。
logback-classic 的地位和作用等同于 Log4J,它也被认为是 Log4J 的一个改进版,并且它实现了简单日志门面 SLF4J;
logback-access 主要作为一个与 Servlet 容器交互的模块,比如说tomcat或者 jetty,提供一些与 HTTP 访问相关的功能。
配置文件接下来会介绍关于 logback 配置文件的配置项。
Configuration整个 logback.xml 配置文件的结构如下:
1234567891011121314151617<configuration scan="true" scanPeriod="60 seconds" debug=" ...
一致性哈希
分布式缓存对于经常使用的数据,我们一般会使用 Redis 作为缓存机制,为了实现高可用,使用了3台Redis(没有设置集群,集群至少要6台)。
使用hash算法,存储的时候根据公式 h = hash(key)%机器节点数,h 为 Redis 对应的编号,取数据的时候也根据相同的公式取,因此一定可以从存储的机器中拿到想要的数据。但是使用这种策略可能会存在以下问题:
假设有一台 Redis 服务器宕机了,此时每个 key 就要按照 h = hash(key)%(机器节点数-1) 重新计算
假设要新增一台 Redis 服务器,此时每个 key 就要按照 h = hash(key)%(机器节点数+1) 重新计算
也就是说,如果服务节点有变更,会导致缓存失效,大量的 key 需要重新计算,在这期间如果有请求进来,就会直接打到数据库上,导致缓存雪崩。
一致性哈希算法一致性哈希是讲整个哈希空间组织成一个虚拟的圆环,假设哈希函数 H 的值空间为 [0,2^32-1](哈希值是32位无符号整形)。
把服务器按照 IP 或者主机名作为关键字进行哈希,确定服务器在哈希环中的 ...
深入浅出Spring AOP
对AOP的理解AOP(Aspect-Oriented Programming:面向切面编程),它实际做的就是将业务和一些非业务进行拆解,降低彼此业务模块与非业务模块的耦合度,便于后续的扩展维护。例如权限校验、日志管理、事务处理等都可以使用AOP实现。而Spring就是基于动态代理实现AOP的。如果被代理的类有实现接口的话,就会基于JDK Proxy完成代理的创建。反之就是通过Cglib完成代理创建。
Spring AOP和AspectJ AOP的区别知道吗?
答: 其实Spring AOP属于运行时增强,基于代理(Proxying)实现的。而AspectJ AOP属于编译时增强,基于字节码操作(Bytecode Manipulation)实现的。相比之下后者比前者更成熟、更强大一些。如果在切面不多的情况下,两者差异是不大的,如果切面非常多的话,后者性能会比强者好很多。
AOP中有很多核心术语,分别是:
目标(Target): 这就被代理的对象,例如我们希望对UserService每个方法进行增强(在不动它的代码情况下增加一些非业务的动作),那么这个UserService就是目标 ...
MyBatis源码
MyBatis 执行流程首先回顾一下jdbc的执行流程。
MyBatis的执行流程也包含jdbc的执行流程,但是会做一些前置处理。
方法代理(MapperMethod)使用动态代理调用,可以看到非常熟悉的 invoke 方法,这个invoke方法就是动态代理的逻辑,method.invoke()方法就是实现代理类对原始方法的调用。
12345678910111213141516171819202122232425262728public class MapperProxy<T> implements InvocationHandler, Serializable { private static final long serialVersionUID = -6424540398559729838L; private final SqlSession sqlSession; private final Class<T> mapperInterface; private final Map<Method, MapperMethod> ...
jdbc的演变
jdbc流程
jdbc操作jdbc连接123456789101112131415161718@Testpublic void testConnection5() throws Exception {//1.加载配置文件InputStream is =ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");Properties pros = new Properties();pros.load(is);//2.读取配置信息String user = pros.getProperty("user");String password = pros.getProperty("password");String url = pros.getProperty("url");String driverClass = pros.getProperty("driverClass");//3.加载驱动 ...
自定义starter
starter介绍Spring Boot Starter是什么?
Spring Boot Starter可以被理解为一种依赖的集合,也可以看作是一个空的项目,它由pom.xml文件配置了一堆jar包的组合。
Spring Boot Starter解决了什么问题?
Spring Boot Starter解决了手动配置大量依赖项和参数的问题。在Spring Boot之前,如果要开发一个Web应用程序,需要手动添加很多依赖项,如Servlet、JSP、JSTL等,并且还需要配置很多参数,如数据源、事务管理器等。而通过使用Spring Boot Starter,开发者只需要添加一个Starter依赖,就可以轻松地集成各种不同的功能模块,而无需关心底层的配置和集成细节。
Spring Boot Starter的价值是什么?
Spring Boot Starter的价值在于它能够提高开发效率和代码质量,同时减少开发成本和复杂度。通过使用Starter,开发者可以专注于业务逻辑的实现,而不需要关心底层的配置和集成细节。另外,Starter还支持更快的迭代和部署,因为它们通常包含了一些可重用的依赖库和 ...
MySQL语句执行原理
count(*) 的实现方式在不同的MySQL引擎中,count(*)有不同的实现方式。
MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count(*)的时候会直接返回这个数,效率很高;
而InnoDB引擎就麻烦了,它执行count(*)的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。
这篇文章里讨论的是没有过滤条件的count(*),如果加了where 条件的话,MyISAM表也是不能返回得这么快的。
为什么InnoDB不跟MyISAM一样,也把数字存起来呢?
由于多版本并发控制(MVCC)的原因,InnoDB表“应该返回多少行”也是不确定的。每一行记录都要判断自己是否对这个会话可见,因此对于count(*)请求来说,InnoDB只好把数据一行一行地读出依次判断,可见的行才能够用于计算“基于这个查询”的表的总行数。
用缓存系统保存计数一般会想到使用 Redis 缓存总数,但是即使 Redis 正常工作,这个值还是逻辑上不精确的。
因为使用 Redis 存储会存在数据不一致的情况,无论是先往数据表里插入一行,然后 Redis 计数 + 1; 还是先 Redi ...
MySQL高可用
MySQL主备一致MySQL 主从复制
主库将数据库中数据的变化写入到 binlog
在从库上通过change master命令,设置主库的IP、端口、用户名、密码,以及要从哪个位置开始请求binlog,这个位置包含文件名和日志偏移量。
在从库上执行start slave命令,这时候从库会启动两个线程,就是图中的io_thread和sql_thread。其中io_thread负责与主库建立连接。
主库校验完用户名、密码后,创建一个 binlog dump 线程,开始按照从库传过来的位置来发送 binlog ,从库中的 I/O 线程负责接收
从库的 I/O 线程将接收的 binlog 写入到 relay log 中。
从库的 SQL 线程读取 relay log 同步数据本地(也就是再执行一遍 SQL )。
基于位点的主备切换把节点B设置成节点A’的从库的时候,需要执行一条change master命令:
1234567CHANGE MASTER TO MASTER_HOST=$host_name #IPMASTER_PORT=$port #端口M ...
基于Git分支模型的理解与思考
进入企业后,开发过程中为了实现多人同步协作,企业往往会有一套 git 分支规范,这和学习中遇到的分支大有不同。本文是对 git 成熟模型 A successful Git branching model 的理解和对公司约定的 git 分支规范的思考。
在实际生产开发的过程中,如果每个人都随意的创建分支,随意的提交commit,必将导致整个git仓库非常的混乱,不易于团队协作。Vincent Driessen 同学为了解决这个问题提出了 A successful Git branching model,最后形成了业内普遍采用的 git 工作流程,大家都在约定的流程内使用git,使得团队协作效率大大提高。
为什么使用Git?Git 是一个分布式版本管理工具,在多人协作的条件下高效处理任何规模的软件工程,并对项目版本、状态做环境隔离。每一个Git克隆都是一个完整的文件库,含有全部历史记录和修订追踪能力,不依赖于网络连接或中心服务器。最大特色是分支和合并操作非常快速、简便。
与SVN相比,git有以下5点优势:
版本库本地化,支持离线提交,相对独立不影响协同开发。每个开发者都拥有自己的版本 ...