Diablo项目总结(包含线程池(countDownLatch)、EventBus、长轮询、一致性hash)

详见本地项目 diablo-new,总结文本 yiReadMe:

注:yiReadMe 是我自己看项目过程中的一些记录,方便回忆项目以及需要借鉴的代码的java文件
1.此项目核心:使用的配置更新即响应,通过 EventBus 事件总线来实现即时响应,
  具体使用见 EventDispatcher.java 以及 PullingSupport.java 中的长轮询及其实现(url 在 ClientApis中)
  长轮询其实就是前端对某个需要进行长轮询的接口设置 timeout,后端在这个超时时间内进行定时轮询(1s一次查询),
  或者使用本项目中的 EventBus 的响应事件,进行响应,一定要开启异步响应:AsyncContext.startSync()才可

2.定时任务线程框架及其使用,详情在 PullingSupport.java中,SchedualExecutorService
    如:单次定时:
         longPullingScheduler = Executors.newScheduledThreadPool(1, new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r);
                    t.setDaemon(true);
                    t.setName("DIABLO-PULLING-WORKER");
                    return t;
                }
            });

     Future pullingTimeoutFuture;
         pullingTimeoutFuture = longPullingScheduler.schedule(new Runnable() {
                        public void run() {
                            stopPulling();
                        }
                    }, serverKeepPullingTimeout, TimeUnit.SECONDS);

         线程任务执行:
          longPullingScheduler.submit(new LongPullingTask(client, pullingConfigs, asyncContext));
         定时任务取消:
         pullingTimeoutFuture.cancel();

3.线程池的使用在 ServerServiceImpl.java中:如
    private static final ExecutorService executor =
            Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r);
                    t.setName("SERVER-SERVICE-WORKER");
                    t.setDaemon(true);
                    return t;
                }
            });

        for (final String server : servers){
            //直接使用线程池, Runnable 未经封装
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    notifyServer(server, ServerUris.NOTIFY_CONFIG_UPDATED, params);
                }
            });
        }

      以及重试机制:成功返回true,失败捕获异常并休眠
      RETRY_TIMES

4.线程池以及倒计时器 CountDownLatch 的使用在 ServerServiceImpl.java中
  final CountDownLatch latch = new CountDownLatch(servers.size());
        for (final String server : servers){
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        String clientCount = requestServer(server, ServerUris.SERVER_CLIENT_COUNT, null);
                        clientCountMap.put(server, Integer.parseInt(clientCount));
                    } catch (Exception e){
                        Logs.error("failed to request server({})'s client count, cause: {}",
                                server, Throwables.getStackTraceAsString(e));
                    }
                    //线程执行,使用等待
                    latch.countDown();
                }
            });
        }

        try {
            latch.await();
        } catch (InterruptedException e) {
            // ignore
            Logs.error("failed to wait on latch, cause: {}", Throwables.getStackTraceAsString(e));
        }


5.分布式下的 一致性哈希 实现 见 Ketama.java,为了解决分布不均的问题,引入虚拟节点的概念,
  一个真实节点对应多个虚拟节点,如果各个服务器的硬件差不多,需要等分负载,那么只要使用相同的虚拟节点即可。
  如果为了解决服务器性能差异,而需要给不同服务不同负载,那么只要把不同服务的 虚拟节点数量设置不一致即可

你可能感兴趣的:(梦想架构师)