前段时间公司里有个项目需要进行重构,目标是提高吞吐量和可用性,在这个过程中对原有的线程模型和处理逻辑进行了修改,发现有很多基础的多线程的知识已经模糊不清,如底层线程的运行情况、现有的线程池的策略和逻辑、池中线程的健康状况的监控等,这次重新回顾了一下,其中涉及大量java.util.concurrent包中的类。本文将会包含以下内容:
Java中的Thread与操作系统中的线程的关系
线程切换的各种开销
ThreadGroup存在的意义
使用线程池减少线程开销
Executor的概念
ThreadPoolExecutor中的一些具体实现
如何监控线程的健康
参考ThreadPoolExecutor来设计适合自己的线程模型
一、问题描述这个项目所在系统的软件架构(从开发到运维)基本上采用的是微服务架构,微服务很好地解决了我们系统的复杂性问题,但是随之也带来了一些问题,比如在此架构中大部分的服务都拥有自己单独的数据库,而有些(很重要的)业务需要做跨库查询。相信这种「跨库查询」的问题很多实践微服务的公司都碰到过,通常这类问题有以下几种解决方案(当然,还有更多其他的方案,这里就不一一叙述了):
严格通过服务提供的API查询。这样做的好处是将服务完全当做黑盒,可以最大限度得减少服务间的依赖与耦合关系,其次还能根据实际需求服务之间使用不同的数据库类型;缺点是则代价太大。
将关心的信息冗余到自己的库中,并提供API让其他服务来主动修改。优点是信息更新十分实时,缺点是增加了服务间的依赖。
指令与查询分离(CQRS)。将可能被其他服务关心的数据放入数据仓库(或者做成类似于物化视图、搜索引擎等),数据仓库只提供读的功能。优点是对主库不会有压力,服务只要关心实现自己的业务就好,缺点是数据的实时性会受到了挑战。
深圳市科创致远科技有限公司