1.添加Redis分布式锁接口,代码宏控制启动(目前非启用)

(存在问题1.由于redis异步,锁存在内容较高,加锁后影响性能较严重
          2.不是每次锁都能成功)
2.添加显示接口中,openssl生成证书时间信息输出(生成证书总时间/生成证书次数)
This commit is contained in:
fengweihao
2018-07-09 14:32:41 +08:00
parent d02f57e5ee
commit 6a98d2a041
11 changed files with 381 additions and 50 deletions

View 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;
}

View 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

View 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))