Redis源碼分析系列六:initserver中

server.db = zmalloc(sizeof(redisDb)*server.dbnum);
 //開闢緩衝區 redis

listenToPort(server.port,server.ipfd,&server.ipfd_count); dom

顯然這個函數是監聽端口 socket

跟蹤這個函數,進入,發現最終是掉用_anetTcpServer函數。 ide

下面是_anetTcpServer函數的解析。 函數


static int _anetTcpServer(char *err, int port, char *bindaddr, int af)
{

    int s, rv;
    char _port[6];  /* strlen("65535") */
 //監聽端口
 
    struct addrinfo hints;
 //.ai_family = AF_INET;
    //.ai_socktype = SOCK_STREAM;
    //.ai_flags = AI_PASSIVE;
   
    struct addrinfo *servinfo;
 struct addrinfo *p;

  oop

    snprintf(_port,6,"%d",port);

 
    memset(&hints,0,sizeof(hints));
 
    hints.ai_family = af;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;    /* No effect if bindaddr != NULL */

  優化

    if ((rv = getaddrinfo(bindaddr,_port,&hints,&servinfo)) != 0) {
        anetSetError(err, "%s", gai_strerror(rv));
        return ANET_ERR;
  //獲取解析的信息鏈表
    }
 
    for (p = servinfo; p != NULL; p = p->ai_next)
 {
        if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1)
            continue;
  //建立一個socket

   this

        if (af == AF_INET6 && anetV6Only(err,s) == ANET_ERR) goto error;

        if (anetSetReuseAddr(err,s) == ANET_ERR) goto error;
  //設置socket重用

  
  
        if (anetListen(err,s,p->ai_addr,p->ai_addrlen) == ANET_ERR) goto error;
  //bind & listen
        goto end;
    }
    if (p == NULL) {
        anetSetError(err, "unable to bind socket");
        goto error;
    } spa

error:
    s = ANET_ERR;
end:
    freeaddrinfo(servinfo);
    return s;
}
總結:實現了socket,bind,listen並對socket設置了一些優化措施,好比設置passive,重用等。 .net

成功的socket存於server.ipfd,個數由server.ipfd_count指示。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~

下面的代碼

/* Open the listening Unix domain socket. */
    if (server.unixsocket != NULL) {
        unlink(server.unixsocket); /* don't care if this fails */
        server.sofd = anetUnixServer(server.neterr,server.unixsocket,server.unixsocketperm);
        if (server.sofd == ANET_ERR) {
            redisLog(REDIS_WARNING, "Opening socket: %s", server.neterr);
            exit(1);
        }
    }

用於創建unix 域socket

剛纔特地看了配置文件

# Specify the path for the unix socket that will be used to listen for
# incoming connections. There is no default, so Redis will not listen
# on a unix socket when not specified.
#
# unixsocket /tmp/redis.sock
# unixsocketperm 755

我認爲這裏沒有使用domain socket.因此忽略不計。

/* Abort if there are no listening sockets at all. */
    if (server.ipfd_count == 0 && server.sofd < 0) {
        redisLog(REDIS_WARNING, "Configured to not listen anywhere, exiting.");
        exit(1);
    }

這個只是檢查而已,繼續往下看。

而後接下來的幾行代碼採用了dictCreate,還記得以前說過的模板麼?

我找到了個人模板,而後替換幾個參數,讓若干變量得以順利初始化。

listSetFreeMethod(server.pubsub_patterns,freePubsubPattern);

設置server.pubsub_patterns->free = freePubsubPattern

listSetMatchMethod(server.pubsub_patterns,listMatchPubsubPattern);

設置 server.pubsub_patterns->match = listMatchPubsubPattern

 

剩下的若干初始化就很簡單,不用多說,代碼以下:

    server.cronloops = 0;     server.rdb_child_pid = -1;     server.aof_child_pid = -1;     aofRewriteBufferReset();     server.aof_buf = sdsempty();     server.lastsave = time(NULL); /* At startup we consider the DB saved. */     server.lastbgsave_try = 0;    /* At startup we never tried to BGSAVE. */     server.rdb_save_time_last = -1;     server.rdb_save_time_start = -1;     server.dirty = 0;     server.stat_numcommands = 0;     server.stat_numconnections = 0;     server.stat_expiredkeys = 0;     server.stat_evictedkeys = 0;     server.stat_starttime = time(NULL);     server.stat_keyspace_misses = 0;     server.stat_keyspace_hits = 0;     server.stat_peak_memory = 0;     server.stat_fork_time = 0;     server.stat_rejected_conn = 0;     server.stat_sync_full = 0;     server.stat_sync_partial_ok = 0;     server.stat_sync_partial_err = 0;     memset(server.ops_sec_samples,0,sizeof(server.ops_sec_samples));     server.ops_sec_idx = 0;     server.ops_sec_last_sample_time = mstime();     server.ops_sec_last_sample_ops = 0;     server.unixtime = time(NULL);     server.mstime = mstime();     server.lastbgsave_status = REDIS_OK;     server.repl_good_slaves_count = 0;
相關文章
相關標籤/搜索