guava servicemanager 集成guice 使用

实例代码

  • servicemanager
public class MyServiceManagerProvider implements Provider<ServiceManager> {
   // 此处初始化一个AbstractService 实际上是多余的, ServiceManager 自带一个NoOpService
    @Inject
    Set<Service> services = Sets.<Service>newHashSet(new AbstractService() {
        @Override
        protected void doStart() {
        }
 
        @Override
        protected void doStop() {
 
        }
    });
 
    @Override
    public ServiceManager get() {
        return new ServiceManager(services);
    }
}
  • 注册
public class BootstrapModule extends AbstractModule {
 
    @Override
    protected void configure() {
        Multibinder<Service> serviceMultibinderBinder = Multibinder.newSetBinder(binder(), Service.class);
        serviceMultibinderBinder.addBinding().to(ServiceA.class);
        serviceMultibinderBinder.addBinding().to(ServiceB.class);
        bind(ServiceManager.class).toProvider(MyServiceManagerProvider.class).asEagerSingleton();;
    }
}
  • 使用
@Singleton
public class Init {
    @Inject
    private  ServiceManager serviceManager;
    public ServiceManager start(){
        return serviceManager.startAsync();
    }
}
  • 启动
 public static void main(String[] args) throws InterruptedException {
        Injector injector = Guice.createInjector(new BootstrapModule());
        Init init=  injector.getInstance(Init.class);
        ServiceManager serviceManager = init.start();
        serviceManager.servicesByState().get(Service.State.RUNNING).stream().forEach(service -> System.out.println(service.isRunning()));
        Thread.sleep(10000);
        serviceManager.stopAsync();
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                serviceManager.awaitStopped(10, TimeUnit.SECONDS);
            } catch (TimeoutException e) {
                throw new RuntimeException(e);
            }
        }));
    }
 
 

service 类型

 

 

使用中的一些问题

一般我们实现AbstractIdleService,对于定时任务实现AbstractScheduledService以及AbstractExecutionThreadService(单线程模式)
对于直接实现AbstractService的服务,需要自定编写线程管理服务,否则运行效果会不符合实际预期
参考实现

 
public class ServiceC extends AbstractService {
    @Override
    protected void doStart() {
        MoreExecutors.directExecutor().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("servicec do starting");
                    notifyStarted();
                } catch (Throwable t) {
                    notifyFailed(t);
                }
            }
        });
    }
 
    @Override
    protected void doStop() {
        MoreExecutors.directExecutor().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("serviceb do stoping");
                    notifyStopped();
                } catch (Throwable t) {
                    notifyFailed(t);
                }
            }
        });
    }

AbstractExecutionThreadService实际上的效果是执行之后如果状态是runing 的可以自己处理,比如循环数据处理,如果running 部分很快结束了,然后执行也就执行了

private final Service delegate =
      new AbstractService() {
        @Override
        protected final void doStart() {
          Executor executor =
              MoreExecutors.renamingDecorator(
                  executor(),
                  new Supplier<String>() {
                    @Override
                    public String get() {
                      return serviceName();
                    }
                  });
          executor.execute(
              new Runnable() {
                @Override
                public void run() {
                  try {
                    startUp();
                    notifyStarted();
                    // If stopAsync() is called while starting we may be in the STOPPING state in
                    // which case we should skip right down to shutdown.
                    if (isRunning()) {
                      // 一般我们都是在isRunning 中进行业务处理
                      try {
                        AbstractExecutionThreadService.this.run();
                      } catch (Throwable t) {
                        try {
                          shutDown();
                        } catch (Exception ignored) {
                          // TODO(lukes): if guava ever moves to java7, this would be a good
                          // candidate for a suppressed exception, or maybe we could generalize
                          // Closer.Suppressor
                          logger.log(
                              Level.WARNING,
                              "Error while attempting to shut down the service after failure.",
                              ignored);
                        }
                        notifyFailed(t);
                        return;
                      }
                    }
 
                    shutDown();
                    notifyStopped();
                  } catch (Throwable t) {
                    notifyFailed(t);
                  }
                }
              });
        }

参考使用

public class ServiceD extends AbstractExecutionThreadService {
    @Override
    protected void run() throws Exception {
        System.out.println("ServiceD waitting to running");
       // 此处也可能是一个循环,或者基于信号量
        if(isRunning()){
            System.out.println("ServiceD running");
        }
    }
 
    @Override
    protected void shutDown() throws Exception {
        super.shutDown();
        System.out.println("ServiceD shutdown");
    }
 
    @Override
    protected void startUp() throws Exception {
        super.startUp();
        System.out.println("ServiceD startUp");
    }
 
    @Override
    protected void triggerShutdown() {
        super.triggerShutdown();
        System.out.println("ServiceD triggerShutdown");
    }
}

graylog 的实现

 

 

说明

对于复杂服务状态管理我们基于guava servicemanager 是一个不错的选择,比如graylog 的service 就比较依赖servicemanager,对于我们进行服务管理是一个很不错的选择,值得使用

参考资料

https://github.com/google/guava/wiki/ServiceExplained

posted on 2022-10-18 19:20  荣锋亮  阅读(111)  评论(0编辑  收藏  举报

导航