Skip to content

Latest commit

 

History

History
39 lines (19 loc) · 2.07 KB

59.基础实战:业务逻辑异步处理.md

File metadata and controls

39 lines (19 loc) · 2.07 KB
  1. 耗时业务异步处理

如果业务处理的时间太长,会有什么影响

通常情况下,业务逻辑的处理都会比较耗时,比如:

  • 如果是数据库操作,查询时间可能在100ms以上,甚至更慢
  • 如果设计到远程调用,可能消耗的时间在200ms甚至更久。

这样相比于Netty内部的IO操作(通常都是毫秒级)相比,两者不在一个量级上。

会造成什么问题?

如果业务处理的时间太长,就会导致子通道上的其他的IO操作发生严重的阻塞,一个EventLoop内线程会负责处理这几千个,甚至几万个IO通道,而在一个EventLoop内部线程上任务是串型的,而耗时的入站/出站越多,就会越拖慢整个线程的其他IO处理,最终导致严重的性能问题。

解决方案: EventLoop线程和业务线程互相隔离

在服务端需要隔离EventLoop(Reactor反应器)线程和业务线程。

基本的方法是,使用独立的,异步的业务线程去执行用户验证的逻辑。而不在EventLoop线程去执行用户验证的逻辑。

  • 隔离方案1: 使用独立的Netty线程组

    • 创建一个线程池组
    • 在初始化服务端通道的时候,在管道添加处理器的时候,指定线程池组 (这样处理器处理业务逻辑的时候会使用指定的线程池组,而不会使用当前的IO线程组)
  • 隔离方案2: 专门的JAVA线程池,专门用于处理耗时的任务。

Executor线程的任务队列特点

Netty Executor线程的任务队列是一个MPSC队列(多生产者单消费者队列)。

  • MPSC队列的特点是:只有EventLoop线程自己是唯一的消费者,它将遍历任务队列,逐个执行任务;其他线程只能作为生产者,它们的出/入站操作都会作为异步任务加入到任务队列。

  • 通过MPSC队列,EventLoop线程能做到确保: 同一个通道上所有的出/入站处理都是串型的,不是并行的,这样不同的handler业务处理器之间不需要进行线程的同步,这点也能节省线程之间的同步的时间。