graylog server 模块说明一 入口简单说明

通过graylog 的入口我们可以了解到graylog 的运行机制

入口代码

graylog2-server/src/main/java/org/graylog2/bootstrap/Main.java

简单说明

入口出基于了spi 查找开发的模块
参考代码

 
public static void main(String[] args) {
        final CliBuilder<CliCommand> builder = Cli.<CliCommand>builder("graylog")
                .withDescription("Open source, centralized log management")
                .withDefaultCommand(CliCommandHelp.class)
                .withCommands(ImmutableSet.of(
                        ShowVersion.class,
                        CliCommandHelp.class));
 
        // add rest from classpath
        // 通过spi 查找依赖
        final ServiceLoader<CliCommandsProvider> commandsProviders = ServiceLoader.load(CliCommandsProvider.class);
        for (CliCommandsProvider provider : commandsProviders) {
            provider.addTopLevelCommandsOrGroups(builder);
        }
 
        final Cli<CliCommand> cli = builder.build();
        final Runnable command = cli.parse(args);
 
        command.run();
}

spi 配置

 

 


从上图可以看出,核心是Server ,同时也包含了一个迁移的cli (MigrateCmd 继承子Server,同时也基于了Migration 契约定义了如何进行系统的升级操作)

server 处理

graylog2-server/src/main/java/org/graylog2/commands/Server.java
Server 继承了ServerBootstrap 参考图

 

 


核心部分是startCommand 方法
参考处理

 
protected void startCommand() {
        final AuditEventSender auditEventSender = injector.getInstance(AuditEventSender.class);
        final NodeId nodeId = injector.getInstance(NodeId.class);
        final String systemInformation = Tools.getSystemInformation();
        final Map<String, Object> auditEventContext = ImmutableMap.of(
                "version", version.toString(),
                "java", systemInformation,
                "node_id", nodeId.toString()
        );
        auditEventSender.success(AuditActor.system(nodeId), NODE_STARTUP_INITIATE, auditEventContext);
 
        final OS os = OS.getOs();
 
        LOG.info("Graylog {} {} starting up", commandName, version);
        LOG.info("JRE: {}", systemInformation);
        LOG.info("Deployment: {}", configuration.getInstallationSource());
        LOG.info("OS: {}", os.getPlatformName());
        LOG.info("Arch: {}", os.getArch());
 
        try {
           // 对于迁移进行了而外的判断  
            if (configuration.isLeader() && configuration.runMigrations()) {
                runMigrations();
            }
        } catch (Exception e) {
            LOG.warn("Exception while running migrations", e);
            System.exit(1);
        }
 
        final ServerStatus serverStatus = injector.getInstance(ServerStatus.class);
        serverStatus.initialize();
        // 注册node 节点,也是比较重要的
        startNodeRegistration(injector);
 
        final ActivityWriter activityWriter;
        final ServiceManager serviceManager; // 使用guava 进行服务状态管理,是一个不错的guava 服务管理使用案例,其他组件都是service 实现,了解dremio 的话,dremio 也使用了service 管理模式,但是是自己实现的,没有使用guava
        final Service leaderElectionService; // leader 选举,graylog 包含了一个master 角色
        try {
            activityWriter = injector.getInstance(ActivityWriter.class);
            serviceManager = injector.getInstance(ServiceManager.class);
            leaderElectionService = injector.getInstance(Key.get(Service.class, Names.named("LeaderElectionService")));
        } catch (ProvisionException e) {
            LOG.error("Guice error", e);
            annotateProvisionException(e);
            auditEventSender.failure(AuditActor.system(nodeId), NODE_STARTUP_INITIATE, auditEventContext);
            System.exit(-1);
            return;
        } catch (Exception e) {
            LOG.error("Unexpected exception", e);
            auditEventSender.failure(AuditActor.system(nodeId), NODE_STARTUP_INITIATE, auditEventContext);
            System.exit(-1);
            return;
        }
 
        Runtime.getRuntime().addShutdownHook(new Thread(injector.getInstance(shutdownHook())));
 
        // propagate default size to input plugins
        MessageInput.setDefaultRecvBufferSize(configuration.getUdpRecvBufferSizes());
 
        // Start services.
        final ServiceManagerListener serviceManagerListener = injector.getInstance(ServiceManagerListener.class);
        serviceManager.addListener(serviceManagerListener, MoreExecutors.directExecutor());
        try {
            leaderElectionService.startAsync().awaitRunning();
            serviceManager.startAsync().awaitHealthy();
        } catch (Exception e) {
            try {
                serviceManager.stopAsync().awaitStopped(configuration.getShutdownTimeout(), TimeUnit.MILLISECONDS);
            } catch (TimeoutException timeoutException) {
                LOG.error("Unable to shutdown properly on time. {}", serviceManager.servicesByState());
            }
            LOG.error("Graylog startup failed. Exiting. Exception was:", e);
            auditEventSender.failure(AuditActor.system(nodeId), NODE_STARTUP_INITIATE, auditEventContext);
            System.exit(-1);
        }
        LOG.info("Services started, startup times in ms: {}", serviceManager.startupTimes());
 
        activityWriter.write(new Activity("Started up.", Main.class));
        LOG.info("Graylog " + commandName + " up and running.");
        auditEventSender.success(AuditActor.system(nodeId), NODE_STARTUP_COMPLETE, auditEventContext);
 
        // Block forever.
        try {
            Thread.currentThread().join();
        } catch (InterruptedException e) {
            return;
        }
    }
 
 

leader 服务,包含了静态以及自动选举,以及方便测试的,大家日常使用静态的比较多(目前已经废弃了),如果真的需要ha 方法,使用自动会更好
自动的基于了锁进行处理,锁使用了mongo cluster_locks 集合处理

 

 


官方建议配置

 
@Parameter(value = "leader_election_mode", converter = LeaderElectionMode.Converter.class)
private LeaderElectionMode leaderElectionMode = LeaderElectionMode.STATIC; // 实际推荐使用动态,基于mongo 的锁处理,
 
@Parameter(value = "leader_election_lock_polling_interval", converter = JavaDurationConverter.class)
private java.time.Duration leaderElectionLockPollingInterval = AutomaticLeaderElectionService.DEFAULT_POLLING_INTERVAL;
说明

以上是一个简单的graylog 启动入口说明,graylog 的组件还是比较多的,设计上模块化很清晰,学习起来难度不大,ioc 部分使用了guice以及
hk2,web api 以及了glassfish jersey 框架
同时graylog 的Migration 设计还是比较巧妙的,很值得借鉴学习,自模块实现参考图,后续介绍

 

 

参考资料

https://github.com/Graylog2/graylog2-server
graylog2-server/src/main/java/org/graylog2/Configuration.java
https://javaee.github.io/hk2/

posted on 2022-07-24 22:56  荣锋亮  阅读(303)  评论(0编辑  收藏  举报

导航