并发编程实践
# 并发编程实践
# 1.生产者消费者模式
- 创建第三者——阻塞队列,实现生产者消费者解耦。
- 使用多个生产者线程生产数据,多个消费线程消费数据。
在不同场景下,可以设计相应的生产者消费者模型:
- 长连接服务器模式:多段多线程生产消费。同时消费者处理消息时,处理失败可以重复发送回队列。
- 总队列:存储所有客户端的消息。
- 单个分发线程:负责将总任务队列中的所有的任务取出,并散列发给对应索引的子任务队列。
- 多个消费线程:每个子任务队列对应一个消费者线程处理任务。处理失败可以重新将任务发送回总队列。
- 线程池:利用线程池替代上述的任务阻塞队列+消费者。生产者直接将任务丢入线程池,效率高,不需要先存再取。
# 2.线上问题定位
- Linux命令行下,使用TOP命令查看每个进程的情况。在COMMAND为java那行即为java进程的性能数据。
- top命令:
- top -1:查看每个CPU性能数据,利用率如果显示100%,可能写了一个死循环。
- top -H:查看每个线程的性能数据,存在几种情况:
- 利用率100%死循环:使用jstat查看GC,或者将线程dump。
- 某个线程一直在TOP10位置,性能有问题。
# 3.性能测试
启动线程池,多个线程通过执行“调用接口”的任务,对服务器上的接口进行压测。
查看有多少个机器连接到当前主机的端口:
netstat -nat | grep 端口号 -c
1
查看系统内存情况
cat /prov/meminfo
1
# 4.异步任务池
线程池存在的问题:①运行线程池的程序重启之后,会导致任务丢失。②线程池只能处理本机任务
每台机器配置一个任务池,一个任务池中有多个线程池,执行的任务的流程如下:
- 任意一台机器线程池接受到到任务后,首先将任务保存到全局统一的数据库当中。
- 某台机器的任务池从数据库当中取出任务并执行。
关于任务的存储,细节如下:
- 存储任务时,需要保存任务的状态、变量等等信息,保证任何机器拿到该任务都能执行成功。资源和变量的访问需要存储到全局的共享资源地址。
- 不同线程池对应处理不同优先级、不同响应时间的任务。
编辑 (opens new window)
上次更新: 2023/12/15, 15:49:57