• 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/

  • 相关阅读:
    Objects类源码详解(基于jdk1.8.0_261)
    Object类源码详解(基于jdk1.8.0_261)
    Collections工具类源码详解(基于jdk1.8.0_261)
    版本控制神器——git的基本使用
    数据结构练习1~插入排序~
    求指错啊急是求幂的
    编完了个代码大家给看看还能不能精简
    关于KMP算法
    有网友建议写一个新手指南或者FAQ一类的置顶你们认为呢
    c语言新手编程错误求解
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/16515795.html
Copyright © 2020-2023  润新知