从 2 个面试题说起,第一个问题: 如果一台机器上有 10w 个定时任务,如何做到高效触发?
具体场景是:
有一个 APP 实时消息通道系统,对每个用户会维护一个 APP 到服务器的 TCP 连接,用来实时收发消息,对这个 TCP 连接,有这样一个需求:“如果连续 30s 没有请求包(例如登录,消息,keepalive 包),服务端就要将这个用户的状态置为离线”。
其中,单机 TCP 同时在线量约在 10w 级别,keepalive 请求包较分散大概 30s 一次,吞吐量约在 3000qps。
怎么做?
虚拟机是一个相对于物理机的概念,这两种机器都有代码执行能力,其区别在于物理机的执行引擎是直接建立在 CPU 处理器、指令集、操作系统和硬件层面上的。
而虚拟机的执行引擎则由自己实现,因此可以制定自己的指令集和执行引擎的结构体系,而且还可以执行一些不被硬件直接支持的指令集格式。这就是虚拟机相对于物理机的优势所在。
但是缺点也比较明显,由于多了一层虚拟指令,执行虚拟机指令后还要转化为本地机器码,所以在执行效率上,虚拟机是不如物理机的。
Java 虚拟机的字节码指令由一个字节长度的操作码(Opcode)以及紧随其后的零至多个操作数(Operands)构成。
如果忽略异常处理,那么 Java 虚拟机的解释器通过下面这个伪代码的循环即可有效工作:
我们都知道 .java
文件在执行之前会编译成 .class
文件后再执行。比如下面的代码:
产品
淘宝标准化产品,由类目+关键属性唯一确定。如:手机类目,关键属性是品牌和型号,Nokia N95就是一个产品,nokia是品牌,N95是型号。
SPU
spu=standard product unit 标准化产品单元;spu相当于一个产品,可详见产品定义。
SKU
sku=stock keeping uint(库存量单位),为保存库存控制的最小可用单位,例如一件T恤中一个SKU通常由颜色、尺码组成,如下图:
我们目前项目中使用的 redis 锁并没有续期的功能,所以在执行长时间任务时会触发 attempt to unlock '{}', not locked by current thread.
异常,解决这个问题比较正确的姿势是采用 redisson
这个客户端工具.具体介绍可以搜索最大的同性交友网站 github
.