/* First argument is the config file name? */
if (argv[j][0] != ‘-’ || argv[j][1] != ‘-’) { //如果不是 --开头,那就是配置文件
configfile = argv[j];
server.configfile = getAbsolutePath(configfile);
/* Replace the config file in server.exec_argv with
- its absolute path. */
zfree(server.exec_argv[j]);
server.exec_argv[j] = zstrdup(server.configfile);
j++;
}
/* All the other options are parsed and conceptually appended to the
-
configuration file. For instance --port 6380 will generate the
-
string “port 6380\n” to be parsed after the actual file name
-
is parsed, if any. */
while(j != argc) { //读取启动配置项,并存储到一个字符串中
if (argv[j][0] == ‘-’ && argv[j][1] == ‘-’) {
/* Option name */
if (!strcmp(argv[j], “–check-rdb”)) {
/* Argument has no options, need to skip for parsing. */
j++;
continue;
}
if (sdslen(options)) options = sdscat(options,“\n”);
options = sdscat(options,argv[j]+2);
options = sdscat(options," ");
} else {
/* Option argument */
options = sdscatrepr(options,argv[j],strlen(argv[j]));
options = sdscat(options," ");
}
j++;
}
//略
resetServerSaveParams();
loadServerConfig(configfile,options); //从配置文件中加载所有配置项,见下文
sdsfree(options);
}
//略
initServer();
//略
redisSetCpuAffinity(server.server_cpulist);
aeMain(server.el);
aeDeleteEventLoop(server.el);
return 0;
}
initServerConfig
学习一下,毕竟不是每次启动都非得带上配置文件不是?
void initServerConfig(void) {
int j;
updateCachedTime(1);
getRandomHexChars(server.runid,CONFIG_RUN_ID_SIZE);
server.runid[CONFIG_RUN_ID_SIZE] = ‘\0’;
changeReplicationId();
clearReplicationId2();
server.hz = CONFIG_DEFAULT_HZ; /* Initialize it ASAP, even if it may get
updated later after loading the config.
This value may be used before the server
is initialized. */
server.timezone = getTimeZone(); /* Initialized by tzset(). */
server.configfile = NULL;
//略
/* Replication related */
server.masterauth = NULL;
server.masterhost = NULL;
server.masterport = 6379;
server.master = NULL;
//略
/* By default we want scripts to be always replicated by effects
-
(single commands executed by the script), and not by sending the
-
script to the slave / AOF. This is the new way starting from
-
Redis 5. However it is possible to revert it via redis.conf. */
server.lua_always_replicate_commands = 1;
initConfigValues();
}
loadServerConfigFromString
void loadServerConfigFromString(char *config) {
char *err = NULL;
int linenum = 0, totlines, i;
int slaveof_linenum = 0;
sds *lines;
lines = sdssplitlen(config,strlen(config),“\n”,1,&totlines);
for (i = 0; i < totlines; i++) {
sds *argv;
int argc;
linenum = i+1;
lines[i] = sdstrim(lines[i]," \t\r\n");
/* Skip comments and blank lines */
if (lines[i][0] == ‘#’ || lines[i][0] == ‘\0’) continue;
/* Split into arguments */
argv = sdssplitargs(lines[i],&argc);
if (argv == NULL) {
err = “Unbalanced quotes in configuration line”;
goto loaderr;
}
/* Skip this line if the resulting command vector is empty. */
if (argc == 0) {
sdsfreesplitres(argv,argc);
continue;
}
sdstolower(argv[0]);
/* Iterate the configs that are standard */
int match = 0;
for (standardConfig *config = configs; config->name != NULL; config++) {
if ((!strcasecmp(argv[0],config->name) ||
(config->alias && !strcasecmp(argv[0],config->alias))))
{
if (argc != 2) {
err = “wrong number of arguments”;
goto loaderr;
}
if (!config->interface.set(config->data, argv[1], 0, &err)) {
goto loaderr;
}
match = 1;
break;
}
}
if (match) {
sdsfreesplitres(argv,argc);
continue;
}
/* Execute config directives */
if (!strcasecmp(argv[0],“bind”) && argc >= 2) {
int j, addresses = argc-1;
if (addresses > CONFIG_BINDADDR_MAX) {
err = “Too many bind addresses specified”; goto loaderr;
}
/* Free old bind addresses */
for (j = 0; j < server.bindaddr_count; j++) {
zfree(server.bindaddr[j]);
}
for (j = 0; j < addresses; j++)
server.bindaddr[j] = zstrdup(argv[j+1]);
server.bindaddr_count = addresses;
} else if (!strcasecmp(argv[0],“unixsocketperm”) && argc == 2) {
errno = 0;
server.unixsocketperm = (mode_t)strtol(argv[1], NULL, 8);
if (errno || server.unixsocketperm > 0777) {
err = “Invalid socket file permissions”; goto loaderr;
}
} else if (!strcasecmp(argv[0],“save”)) {
if (argc == 3) {
int seconds = atoi(argv[1]);
int changes = atoi(argv[2]);
if (seconds < 1 || changes < 0) {
err = “Invalid save parameters”; goto loaderr;
}
appendServerSaveParams(seconds,changes);
} else if (argc == 2 && !strcasecmp(argv[1],“”)) {
resetServerSaveParams();
}
} else if (!strcasecmp(argv[0],“dir”) && argc == 2) {
if (chdir(argv[1]) == -1) {
serverLog(LL_WARNING,“Can’t chdir to ‘%s’: %s”,
argv[1], strerror(errno));
exit(1);
}
} else if (!strcasecmp(argv[0],“logfile”) && argc == 2) {
FILE *logfp;
zfree(server.logfile);
server.logfile = zstrdup(argv[1]);
if (server.logfile[0] != ‘\0’) {
/* Test if we are able to open the file. The server will not
- be able to abort just for this problem later… */
logfp = fopen(server.logfile,“a”);
if (logfp == NULL) {
err = sdscatprintf(sdsempty(),
“Can’t open the log file: %s”, strerror(errno));
goto loaderr;
}
fclose(logfp);
}
} else if (!strcasecmp(argv[0],“include”) && argc == 2) {
loadServerConfig(argv[1],NULL);
} else if ((!strcasecmp(argv[0],“client-query-buffer-limit”)) && argc == 2) {
server.client_max_querybuf_len = memtoll(argv[1],NULL);
} else if ((!strcasecmp(argv[0],“slaveof”) ||
!strcasecmp(argv[0],“replicaof”)) && argc == 3) {
slaveof_linenum = linenum;
server.masterhost = sdsnew(argv[1]);
server.masterport = atoi(argv[2]);
server.repl_state = REPL_STATE_CONNECT;
} else if (!strcasecmp(argv[0],“requirepass”) && argc == 2) {
if (strlen(argv[1]) > CONFIG_AUTHPASS_MAX_LEN) {
err = “Password is longer than CONFIG_AUTHPASS_MAX_LEN”;
goto loaderr;
}
/* The old “requirepass” directive just translates to setting
-
a password to the default user. The only thing we do
-
additionally is to remember the cleartext password in this
-
case, for backward compatibility with Redis <= 5. */
ACLSetUser(DefaultUser,“resetpass”,-1);
sds aclop = sdscatprintf(sdsempty(),“>%s”,argv[1]);
ACLSetUser(DefaultUser,aclop,sdslen(aclop));
sdsfree(aclop);
sdsfree(server.requirepass);
server.requirepass = sdsnew(argv[1]);
} else if (!strcasecmp(argv[0],“list-max-ziplist-entries”) && argc == 2){
/* DEAD OPTION */
} else if (!strcasecmp(argv[0],“list-max-ziplist-value”) && argc == 2) {
/* DEAD OPTION */
} else if (!strcasecmp(argv[0],“rename-command”) && argc == 3) {
struct redisCommand *cmd = lookupCommand(argv[1]);
int retval;
if (!cmd) {
err = “No such command in rename-command”;
goto loaderr;
}
/* If the target command name is the empty string we just
- remove it from the command table. */
retval = dictDelete(server.commands, argv[1]);
serverAssert(retval == DICT_OK);
/* Otherwise we re-add the command under a different name. */
if (sdslen(argv[2]) != 0) {
sds copy = sdsdup(argv[2]);
retval = dictAdd(server.commands, copy, cmd);
if (retval != DICT_OK) {
sdsfree(copy);
err = “Target command name already exists”; goto loaderr;
}
}
} else if (!strcasecmp(argv[0],“cluster-config-file”) && argc == 2) {
zfree(server.cluster_configfile);
server.cluster_configfile = zstrdup(argv[1]);
} else if (!strcasecmp(argv[0],“client-output-buffer-limit”) &&
argc == 5)
{
int class = getClientTypeByName(argv[1]);
unsigned long long hard, soft;
int soft_seconds;
if (class == -1 || class == CLIENT_TYPE_MASTER) {
总结
至此,文章终于到了尾声。总结一下,我们谈论了简历制作过程中需要注意的以下三个部分,并分别给出了一些建议:
- 技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;
- 项目经历:只写明星项目,描述遵循 STAR 法则;
- 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;
以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频
mp(argv[0],“client-output-buffer-limit”) &&
argc == 5)
{
int class = getClientTypeByName(argv[1]);
unsigned long long hard, soft;
int soft_seconds;
if (class == -1 || class == CLIENT_TYPE_MASTER) {
总结
至此,文章终于到了尾声。总结一下,我们谈论了简历制作过程中需要注意的以下三个部分,并分别给出了一些建议:
- 技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;
- 项目经历:只写明星项目,描述遵循 STAR 法则;
- 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;
以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频
[外链图片转存中…(img-UG8E2UEz-1714518721710)]
[外链图片转存中…(img-UWAF1KUu-1714518721710)]
[外链图片转存中…(img-4Op0aLUW-1714518721710)]