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