zoukankan      html  css  js  c++  java
  • mongo源码学习(二)db.cpp之mongoDbMain方法分析

    mongo后台进程的入口:mongo/src/mongo/db/dbmain.cpp,wmain(for windows)和main函数,main函数也很简单,就是委托给db.cpp中的mongoDbMain函数来处理。

    下面的这段代码就是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;
    }

    上面的代码读起来还是没有啥太大难度,就是做了一些启动的初始化以及准备工作,然后打开监听开始接收请求。现在我还没有管每个里面是怎么具体执行,接下来我比较感兴趣的是,从客户端的请求是怎么来到入口点的。

  • 相关阅读:
    求两个数的最大公约数--简单
    输入7个人的成绩,找出大于平均成绩的值--简单
    回文--简单
    约瑟夫环--中等难度
    数组中查找最大数和次大数--简单
    Docker在云环境中的应用实践初探:优势、局限性与效能评测
    基于mongoDB的capped collection的性能优化
    微软开放技术(中国)携 CKAN 和 OData 技术引入基于 Azure 的开放数据平台
    ThreadPoolExecutor原理及使用
    通过 Azure Media Encoder 降低编码成本
  • 原文地址:https://www.cnblogs.com/tuhooo/p/9848858.html
Copyright © 2011-2022 走看看