1. 简介主要解决多线程中数据因并发产生不⼀致问题,同个线程共享数据,ThreadLocal为每⼀个线程都提供了变量的副本,使得每个线程在某时间访问到的并不是同⼀个对象,这样就隔离了多个线程对数据的数据共享,这样的结果是耗费了内存,但大大减少了线程同步所带来性能消耗,也减少了线程并发控制的复杂度。
ThreadLocal不能使用原子类型,只能使用Object类型
原理和源码
ThreadLocal中的⼀个内部类ThreadLocalMap,这个类没有实现map接口,就是⼀个普通的Java类,但是实现的类似map的功能
每个数据用Entry保存,其中的Entry继承与WeakReference,用⼀个键值对存储,键为ThreadLocal的引用。
每个线程持有⼀个ThreadLocalMap对象,每⼀个新的线程Thread都会实例化⼀个ThreadLocalMap并赋值给成员变量threadLocals,使用时若已经存在threadLocals,则直接使用已经存在的对象。
2. 3种实现2.1 ThreadLocal2.2 InheritableThreadLocalInheri ...
1. 代码
定义错误枚举
123456789@AllArgsConstructor@Getterpublic enum ErrorCodeEnum { SYSTEM_ERROR(100001, "系统异常"); private final Integer code; private final String msg;}
定义异常类
1234567891011121314/** * 业务异常 */@Datapublic class BizException extends RuntimeException { private Integer code; private String msg; public BizException(ErrorCodeEnum errorCodeEnum) { super(errorCodeEnum.getMsg()); this.code = errorCodeEnum.getCode(); this.msg ...
1. 背景消息中心的项目中,需要支持长连接推送的需求,因为目前只是内部使用,将长连接服务端和http的springBoot服务放在了一起。需要完成的需求
在Springboot中启动Netty服务端
将Netty的端口注册到Nacos上,方便前端服务通过网关连接到Netty服务端,同时Nacos本身有负载均衡的能力
Springboot服务启动的时候,同时启动Netty服务,服务关闭时,同时关闭Netty服务
2. 实现方式
与前端长连接交互使用WebSocket通信
服务端使用Netty作为服务端
Springboot启动后,通过实现ApplicationRunner接口来启动服务,ApplicationRunner会在SpringBoot服务启动完成后,执行实现的方法具体实现
public class NettyStartServer implements ApplicationRunner
获取Nacos信息,通过手动注册的方式将Netty服务注册到Nacos上
123456789// 将netty服务注册到nacosProperties properties = ...
1. 背景在项目开发过程中,需要从上下文中获取当前用户,当前租户等信息,并且在feign调用时,能把用户信息传递到下游服务,这一切的前提是用户在浏览器发起请求时携带了用户token,经过security服务验证封装,最终将用户信息放在了上下文中。
问题:在kafka异步监听事件中,由于不是用户发送的http请求,所以没有token,即使传递了token,security不会自动将用户信息封装到上下文中,所以无法获取执行的用户,SecurityUtils.getUserId()会报错
方案:
接收到用户http请求,把请求头中的用户信息拿出来,在kafka的消息头里加入用户token,租户id,用户id,等信息
消费端根据消息头把用户信息取到
根据security的规则,请求auth拿到用户信息,手动塞到上下文里,同时把token放在feign请求的线程变量里,方便传递到下游
注意:
因为kafka是一个高吞吐量的中间件,加入请求用户信息,解析用户的操作,会极大的影响性能
所以不能直接修改原始的kafka的操作,需要单独开发一套功能,需要传递用户信息才使用该功能,不用的话还是 ...
1. 背景在做消息中心的邮件模块时,反馈偶现邮件发送延迟较高的问题,可能会出现发送的邮件,几个小时后才能收到。经过排查发现是,通过API调用邮箱服务器发送邮件时比较慢,大概1~2秒发一份邮件,而且由于公司邮箱服务器的问题,经常超时。当有某个服务发送了大量邮件时,比如全员的通知邮件,会导致Kafka的发送队列长时间排队堆积,后面其他业务发送的邮件会在很长时间的排队后才能收到。针对该问题,消息中心做了邮件发送的优化。
2. 原始方案
原始方案中通过两层异步解决一次发送中多个发送渠道发送的并发问题。
邮件发送全部由单个email的TOPIC发送,当单次发送邮件数量太大,会影响其他服务的业务邮件发送时间
3. 方法优化将原来单个topic发送通道改为多条线路同时发送。
改为多条线路后也会带来其他的问题
改为多路后,只是缓解了单路带来的压力,并没有彻底解决大量发送时导致其他业务的延迟问题
通过将同一个发送账号的发送任务放在同一个队列
不同的账号走不同的通道
这样即使有一个业务发送的邮件数很多,也只会占用其中一个TOPIC,其他业务的发送任务来了,可以使用其他线路来发送
因为不确定会有多 ...
1. 问题描述2. 解决方案2.1 在本项目中通过上下文获取用户信息123456789@Resource private ResourceServerTokenServices tokenServices; private void initLocalToken(String token) { if(StrUtil.isNotBlank(token)) { OAuth2Authentication auth = tokenServices.loadAuthentication(token); SecurityContextHolder.getContext().setAuthentication(auth); } }
2.2 将token通过feign传递到下一个服务
定义一个线程变量
1234567891011121314151617181920212223242526272829303132333435import com.alibaba.ttl.Tra ...
pip## 1. anacondahttps://www.anaconda.com/下载官网的python慢,可以走淘宝的镜像源https://registry.npmmirror.com/binary.html?path=python/
命令:
123456789101112//查看conda版本conda -V //查看已有的虚拟环境conda env list//创建虚拟环境conda create -n env_name python=x.x//删除虚拟环境conda remove -n env_name --all//激活虚拟环境conda activate env_name//关闭虚拟环境conda deactivate
2. 修改conda默认的环境路径通过conda info命令查看信息,可以看到默认的路径在C盘
123envs directories : C:\Users\cmyang\.conda\envs D:\soft\Anaconda3\envs C:\Users\cmyang\Ap ...
1. 第一个网页123456789101112<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="keywords" content="html,css,js"> <meta name="description" content="前端学习网站"> <title>Title</title></head><body>Hello World</body></html>
<!DOCTYPE html>表示使用html5版本编写
meta
可以提供该网页相关信息,元数据
charset=”utf-8”,定义编码,处理中文乱码问题
name=”keywords” content ...
自定义排序
wrapper.last(" order by field(role, 'OWNER', 'ADMIN', 'EDIT', 'VIEW'), id desc")