1.添加Redis分布式锁接口,代码宏控制启动(目前非启用)
(存在问题1.由于redis异步,锁存在内容较高,加锁后影响性能较严重
2.不是每次锁都能成功)
2.添加显示接口中,openssl生成证书时间信息输出(生成证书总时间/生成证书次数)
This commit is contained in:
206
src/components/redis/rd_lock.c
Normal file
206
src/components/redis/rd_lock.c
Normal file
@@ -0,0 +1,206 @@
|
||||
/*************************************************************************
|
||||
> File Name: rd_lock.c
|
||||
> Author:
|
||||
> Mail:
|
||||
> Created Time: 2018<31><38>07<30><37>05<30><35> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 11ʱ01<30><31>39<33><39>
|
||||
************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "rd_lock.h"
|
||||
#include "rt_string.h"
|
||||
|
||||
struct rd_RedLock{
|
||||
float m_clockDriftFactor;
|
||||
sds m_unlockScript;
|
||||
int m_retryCount;
|
||||
int m_retryDelay;
|
||||
char *m_continueLockScript;
|
||||
};
|
||||
|
||||
static struct rd_RedLock redlock = {
|
||||
.m_clockDriftFactor = 0.01,
|
||||
.m_unlockScript = NULL,
|
||||
.m_retryCount = 0,
|
||||
.m_retryDelay = 0,
|
||||
.m_continueLockScript = NULL,
|
||||
};
|
||||
|
||||
struct rd_RedLock *mutx_redlock()
|
||||
{
|
||||
return &redlock;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_unique_lockid()
|
||||
{
|
||||
int i = 0;
|
||||
char *s = NULL;
|
||||
char value[10] = "0123456789";
|
||||
unsigned char buffer[20];
|
||||
|
||||
struct timeval t1;
|
||||
gettimeofday(&t1, NULL);
|
||||
srand(t1.tv_usec * t1.tv_sec);
|
||||
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
buffer[i] = value[rand() % 10];
|
||||
}
|
||||
//<2F><>ȡ20byte<74><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
s = sdsempty();
|
||||
for (i = 0; i < 20; i++) {
|
||||
s = sdscatprintf(s, "%02X", buffer[i]);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static int
|
||||
rd_lock_instance(redisContext *c, const char *resource,
|
||||
const char *val, const int ttl)
|
||||
{
|
||||
int xret = 0;
|
||||
redisReply *reply;
|
||||
|
||||
reply = (redisReply *)redisCommand(c, "set %s %s px %d nx", resource, val, ttl);
|
||||
if (NULL == reply)
|
||||
goto finish;
|
||||
|
||||
//printf("Set return: %s [null == fail, OK == success]\n", reply->str);
|
||||
|
||||
if (reply->str && STRCMP(reply->str, "OK") == 0) {
|
||||
xret = 1;
|
||||
}
|
||||
freeReplyObject(reply);
|
||||
|
||||
finish:
|
||||
return xret;
|
||||
}
|
||||
|
||||
static char **convertToSds(int count, char** args)
|
||||
{
|
||||
int j;
|
||||
char **sds = (char**)malloc(sizeof(char*)*count);
|
||||
for(j = 0; j < count; j++)
|
||||
sds[j] = sdsnew(args[j]);
|
||||
return sds;
|
||||
}
|
||||
|
||||
redisReply *rd_command_argv(redisContext *c, int argc, char **inargv)
|
||||
{
|
||||
redisReply *reply = NULL;
|
||||
|
||||
char **argv;
|
||||
argv = convertToSds(argc, inargv);
|
||||
|
||||
size_t *argvlen;
|
||||
argvlen = (size_t *)malloc(argc * sizeof(size_t));
|
||||
|
||||
for (int j = 0; j < argc; j++)
|
||||
argvlen[j] = sdslen(argv[j]);
|
||||
|
||||
reply = (redisReply *)redisCommandArgv(c, argc, (const char **)argv, argvlen);
|
||||
if (reply) {
|
||||
//printf("RedisCommandArgv return: %lld\n", reply->integer);
|
||||
}
|
||||
free(argvlen);
|
||||
sdsfreesplitres(argv, argc);
|
||||
return reply;
|
||||
}
|
||||
|
||||
int rd_mutex_unlock(struct rd_lock_scb *mtx, struct redisContext *c)
|
||||
{
|
||||
int argc = 5;
|
||||
struct rd_RedLock *redlock = mutx_redlock();
|
||||
|
||||
char *unlockScriptArgv[] = {(char*)"EVAL",
|
||||
redlock->m_unlockScript,
|
||||
(char*)"1",
|
||||
(char*)mtx->m_resource,
|
||||
(char*)mtx->m_val};
|
||||
|
||||
redisReply *reply = rd_command_argv(c, argc, unlockScriptArgv);
|
||||
if (reply) {
|
||||
freeReplyObject(reply);
|
||||
}
|
||||
|
||||
if (reply->integer){
|
||||
sdsfree(mtx->m_resource);
|
||||
sdsfree(mtx->m_val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* redis lock*/
|
||||
int rd_mutex_lock(const char *resource, const int ttl,
|
||||
struct rd_lock_scb *mtx, struct redisContext *c)
|
||||
{
|
||||
struct rd_RedLock *redlock = mutx_redlock();
|
||||
|
||||
char *val = NULL;
|
||||
int retryCount =0, xret = 0;
|
||||
|
||||
val = get_unique_lockid();
|
||||
if (!val) {
|
||||
return xret;
|
||||
}
|
||||
mtx->m_resource = sdsnew(resource);
|
||||
mtx->m_val = val;
|
||||
retryCount = redlock->m_retryCount;
|
||||
|
||||
do {
|
||||
int n = 0;
|
||||
int startTime = (int)time(NULL) * 1000;
|
||||
|
||||
if (c == NULL || c->err) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (rd_lock_instance(c, resource, val, ttl)) {
|
||||
n++;
|
||||
}
|
||||
|
||||
int drift = (ttl * redlock->m_clockDriftFactor) + 2;
|
||||
int validityTime = ttl - ((int)time(NULL) * 1000 - startTime) - drift;
|
||||
//printf("The resource validty time is %d, n is %d\n",
|
||||
// validityTime, n);
|
||||
|
||||
if (n > 0 && validityTime > 0) {
|
||||
mtx->m_validityTime = validityTime;
|
||||
xret = 1;
|
||||
goto finish;
|
||||
} else {
|
||||
printf("The resource validty time is %d, n is %d\n",
|
||||
validityTime, n);
|
||||
}
|
||||
// Wait a random delay before to retry
|
||||
int delay = rand() % redlock->m_retryDelay + floor(redlock->m_retryDelay / 2);
|
||||
printf("[Test] delay = %d\n", delay);
|
||||
usleep(delay * 1000);
|
||||
retryCount--;
|
||||
} while (retryCount > 0);
|
||||
|
||||
finish:
|
||||
return xret;
|
||||
}
|
||||
|
||||
void rd_lock_init()
|
||||
{
|
||||
struct rd_RedLock *rdlock = mutx_redlock();
|
||||
|
||||
rdlock->m_continueLockScript = sdsnew("if redis.call('get', KEYS[1]) == ARGV[1] then redis.call('del', KEYS[1]) end return redis.call('set', KEYS[1], ARGV[2], 'px', ARGV[3], 'nx')");
|
||||
rdlock->m_unlockScript = sdsnew("if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end");
|
||||
rdlock->m_retryCount = 8;
|
||||
rdlock->m_retryDelay = 10;
|
||||
rdlock->m_clockDriftFactor = 0.01;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
26
src/components/redis/rd_lock.h
Normal file
26
src/components/redis/rd_lock.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*************************************************************************
|
||||
> File Name: rd_lock.h
|
||||
> Author:
|
||||
> Mail:
|
||||
> Created Time: 2018年07月05日 星期四 11时02分03秒
|
||||
************************************************************************/
|
||||
|
||||
#ifndef _RD_LOCK_H
|
||||
#define _RD_LOCK_H
|
||||
|
||||
#include "hiredis.h"
|
||||
|
||||
struct rd_lock_scb{
|
||||
int m_validityTime;
|
||||
sds m_resource;
|
||||
sds m_val;
|
||||
};
|
||||
|
||||
void rd_lock_init();
|
||||
|
||||
int rd_mutex_lock(const char *resource, const int ttl,
|
||||
struct rd_lock_scb *mtx, struct redisContext *c);
|
||||
|
||||
int rd_mutex_unlock(struct rd_lock_scb *mtx, struct redisContext *c);
|
||||
|
||||
#endif
|
||||
40
src/components/redis/redis.mk
Normal file
40
src/components/redis/redis.mk
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
|
||||
# standard component Makefile header
|
||||
sp := $(sp).x
|
||||
dirstack_$(sp) := $(d)
|
||||
d := $(dir)
|
||||
|
||||
# component specification
|
||||
|
||||
OBJS_$(d) :=\
|
||||
$(OBJ_DIR)/rd_lock.o\
|
||||
|
||||
CFLAGS_LOCAL += -I$(d)
|
||||
$(OBJS_$(d)): CFLAGS_LOCAL := -std=gnu99 -W -Wall -Wunused-parameter -g -O3 \
|
||||
-I$(d)\
|
||||
-I$(d)/../../rt\
|
||||
-I$(d)/../../inc\
|
||||
|
||||
|
||||
# standard component Makefile rules
|
||||
|
||||
DEPS_$(d) := $(OBJS_$(d):.o=.d)
|
||||
|
||||
#LIBS_LIST := $(LIBS_LIST) $(LIBRARY)
|
||||
LIBS_LIST := $(LIBS_LIST)
|
||||
|
||||
CLEAN_LIST := $(CLEAN_LIST) $(OBJS_$(d)) $(DEPS_$(d))
|
||||
|
||||
-include $(DEPS_$(d))
|
||||
|
||||
#$(LIBRARY): $(OBJS)
|
||||
# $(MYARCHIVE)
|
||||
|
||||
$(OBJ_DIR)/%.o: $(d)/%.c
|
||||
$(COMPILE)
|
||||
|
||||
# standard component Makefile footer
|
||||
|
||||
d := $(dirstack_$(sp))
|
||||
sp := $(basename $(sp))
|
||||
Reference in New Issue
Block a user