啓動流程:
Main函數參數: server -f graylog.conf.example
主要框架:com.github.rvesse.airline,主要將shell命令參數和java類綁定,根據傳參獲取對應類的實例,final Runnable command = cli.parse(args);
然後啓動實例,由於啓動參數是sever,綁定的類是org.graylog2.commands.server
[i]啓動server實例
Server類層級如下:
運行run啓動該實例,run的邏輯如下
初始化日誌
//初始化日誌 默認是info
final Level logLevel = setupLogger();
獲取plug module,主要有三個
獲取config module, 有14個。
//初始化pid文件及netty io.netty.native.workdir配置
獲取config module
獲取config module ,其實就是所有的配置類添加NamedConfigParametersModule容器
創建上下文
系統自動注入上面獲取的plugn module 和 config module, 使用的是google的guice 依賴注入框架。框架具體看我的博客:
依賴注入的類實在是太多,看來項目複雜度還不小,以後有時間可以仔細看看注入的類。
Guice常見上下文,也就是injector容器,創建所有入住類的實例,並保存在injector,後面需要實例,直接可以通過injector獲取
GenericInitializerBindings
啓動jmx
啓動jmxreporter 暴露服務運行metrics, metrics主要使用了
com.codahale.metrics;
啓動service
這個地方使用了google的Guava Service框架,這個框架到處都用,個人覺得是java常用組件的升級版本。
具體代碼如下
@Override
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();
final ServerStatus serverStatus = injector.getInstance(ServerStatus.class);
//初始化server狀態爲starting
serverStatus.initialize();
//
startNodeRegistration(injector);
final ActivityWriter activityWriter;
final ServiceManager serviceManager;
try {
activityWriter = injector.getInstance(ActivityWriter.class);
serviceManager = injector.getInstance(ServiceManager.class);
} 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);
try {
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;
} }
至此,整個server服務完全啓動,後面可以分析每個具體service了。