zoukankan      html  css  js  c++  java
  • 线程互相组合,互相依赖,设计方法

    整理于服务器管理系统部分设计思想.

    做系统始终坚持一个原则,首先保证工期,保证系统正确运行,然后系统经过一段时间的运行,肯定会有一些新的改变,新的变化,同时系统还有一些忽略的bug都可以再第二版进行迭代,第二版的重点就是提高系统的运行效率了.第一版保证系统可用,稳定,第二版重点保持稳定,提高系统效率,同时好处是第一版完成后会给用户一定的缓冲的时间将精力放在业务流程上,而不是来找你系统的bug,培养了第一版的操作习惯,第二版会上的很顺畅.

    系统想整理的主要是四个方面

    1.线程池的设计,如题

    2.细粒度权限的设计

    3.管理脚本的设计

    4.日志的设计

    线程池的设计

       第一版的线程池设计的很简单,简单的原则是每个用户的每个任务分配一个单线程的队列

       简单说,比如我想清理10台机器的日志,清理日志是一个任务,就会给当前用户分配一个单线程的队列,对10台机器的日志清理都是顺序执行.如果一台机器清理日志需要10秒,那10台机器就用100秒

      如果画个图就是这样:

         image

    好处也是显而易见的,实现起来简单,如果需要扩展只需要按照一定的策略将线程队列扩展一下.

    这个线程池的特点是对每个用户的每个任务分配一个队列,同时有一个线程是服务于这个队列的,如果这个用户下达了10个命令,那么会下达10个线程队列,保证了任务互相的公平性.而类设计是这样的,

    一个简单的并发模型框架 http://blog.duplicatedcode.com/java%E8%AF%AD%E8%A8%80/313.html

    image

    image

    其中一个代理类封装了同步和异步的方法,通过一个简单的stack用来存放用户请求,并且有个线程模块处理队列.好处就是实现类和并发逻辑分离,随时可以剥离,业务类不需要关心并发逻辑如何,只需要将任务提交即可,是异步返回,对于特别重要的操作,有接口可以同步返回.

    以上是第一版的线程池的设计,完全达到了第一版的要求

    到第二版缺点就暴露出来了,假如有20台机器需要清理,每台机器需要10秒,那也需要200秒,所以就有了第二版.

    第二版需要解决的问题:

            1. 多线程处理       

            2.任务的互相组合(比如,清理完日志,需要重启一下某项服务,之前的设计是需要清理完毕后,在分配一个重启任务)

            3.线程的互相依赖

       这一版使用了java的并发框架来处理,所以过程就相对还算简单,首先解决第一个问题,那当然是指定任务的处理策略,比如清理10台机器可以有10个线程同时处理,但是重启10台机器就必须保证2台机器可用,所以最多起5个线程进行处理.还要计算启动一台机器需要的时间

        任务的互相组合,场景是,我指定了 清理,重启,清理 三个任务,那你需要按照 清理-重启-清理 进行 执行.顺序不能乱,下次的顺序可能又是另外一种形式,所以这里需要用一些的策略来保证每个任务的独立性.

        线程的互相依赖,这个是依托于第二点,有清理-重启-清理 三个任务,每个任务下面有10个线程,只有清理的10个线程完全完毕后,才能进行下一步操作

        综上所述,现在的设计

        任务列表,定义了清理,重启,检查等单独的命令

         继承自ThreadPoolExecutor的线程工程类,

         自定义的工厂类

    可能类图比较容易看

    image

       

    简单的逻辑是这样的:

    1.Command定义了一些单独的命令

    2.DeployThreadFactory 是自定义的工厂类,可以定义线程类的名称

    3.DeployThreadPool 线程池,继承自ThreadPoolExecutor ,用来控制线程数量,线程策略

    4.BaseCallable 类,用来实现每个命令的具体逻辑,是BakupCallable RestartCallable 的基类

    5.CallableDispatcher 润滑油类,分发类,装配器,通过一个静态的Class Map,使用代理来 完成对Callable任务的 的 初始化,并未每个任务构造线程池

    6.DeployPoolUtil 类,线程守护类,用来监控任务池,如果上一个任务池完成了,就将上一个任务池的资源释放,同时开始下一个任务池

    至此,三个问题都已经解决.下面一个图来演示当清理和重启两个任务同时到达的处理方式:

    image

  • 相关阅读:
    js == 和 === 判断原理
    react 渲染原理
    常见的HTTP状态码
    类数组和数组的区别是什么?
    如何判断一个变量是不是数组?
    typeof 是否正确判断类型? instanceof呢? instanceof 的实现原理是什么?
    前端 js data数组转tree数据结构
    Echarts 基础学习
    Vue CLI 4.0 项目搭建
    Echarts Demo
  • 原文地址:https://www.cnblogs.com/duplicatedcode/p/3224136.html
Copyright © 2011-2022 走看看