mongo源碼學習(二)db.cpp之mongoDbMain方法分析

mongo後臺進程的入口:mongo/src/mongo/db/dbmain.cpp,wmain(for windows)和main函數,main函數也很簡單,就是委託給db.cpp中的mongoDbMain函數來處理。windows

下面的這段代碼就是db.cpp:mongoDbMain的執行過程:服務器

int mongoDbMain(int argc, char* argv[], char** envp) {
    // 註冊進程關閉時候執行的任務
    registerShutdownTask(shutdownTask);
    // 設置信號處理器, 好比kill -9 [mongo的pid]
    setupSignalHandlers();
    // srand函數是隨機數發生器的初始化函數。原型:void srand(unsigned int seed);srand和rand()配合使用產生僞隨機數序列。
    srand(static_cast<unsigned>(curTimeMicros64()));
    // 執行全局初始化
    Status status = mongo::runGlobalInitializers(argc, argv, envp);
    // 判斷初始化執行是否成功
    if (!status.isOK()) {
        // 初始化執行失敗了, 打日誌, 程序退出
        severe(LogComponent::kControl) << "Failed global initialization: " << status;
        quickExit(EXIT_FAILURE);
    }

    try {
        // 設置全局的服務上下文, 上下文這個東西真的是腦袋疼, 姑且看成一個存放變量的容器吧
        setGlobalServiceContext(ServiceContext::make());
    } catch (...) {
        auto cause = exceptionToStatus();
        severe(LogComponent::kControl) << "Failed to create service context: " << redact(cause);
        quickExit(EXIT_FAILURE);
    }

    // 獲取全局服務的上下文
    auto service = getGlobalServiceContext();
    // 設置Replication, replication是複製的意思
    setUpReplication(service);
    // 設置服務的入口點, 客戶端對服務器的訪問走的是入口點
    service->setServiceEntryPoint(std::make_unique<ServiceEntryPointMongod>(service));

    // 這個不知道是什麼意思
    ErrorExtraInfo::invariantHaveAllParsers();
    // 啓動時的配置動做, argv就是咱們啓動mongo時候的配置參數
    startupConfigActions(std::vector<std::string>(argv, argv + argc));
    cmdline_utils::censorArgvArray(argc, argv);

    // 初始化服務的全局狀態
    if (!initializeServerGlobalState(service))
        quickExit(EXIT_FAILURE);

    // Per SERVER-7434, startSignalProcessingThread must run after any forks (i.e.
    // initializeServerGlobalState) and before the creation of any other threads
    // 啓動信號處理進行, 上面的官方註釋說的是這個函數的執行有前後順序
    startSignalProcessingThread();

#if defined(_WIN32)
    if (ntservice::shouldStartService()) {
        ntservice::startService();
        // exits directly and so never reaches here either.
    }
#endif

    // 執行啓動的測試, 我猜的是檢查啓動是否有啥異常
    StartupTest::runTests();
    // 初始化以及監聽, 前面都是一些準備動做, 這裏是真的要開始監聽了, 監聽成功就能夠接受請求, 而後處理各類CRUD, 執行各類命令了
    ExitCode exitCode = initAndListen(serverGlobalParams.port);
    exitCleanly(exitCode);
    return 0;
}

上面的代碼讀起來仍是沒有啥太大難度,就是作了一些啓動的初始化以及準備工做,而後打開監聽開始接收請求。如今我尚未管每一個裏面是怎麼具體執行,接下來我比較感興趣的是,從客戶端的請求是怎麼來到入口點的。函數

相關文章
相關標籤/搜索