Redis에는 pubsub 기능이있어 사용이 불편하고 내 요구 사항을 충족하지 못하는 것 같아서 Redis 용 타사 모듈을 개발할 계획입니다. 키가 시간 초과되면 RocketMQ에 자동으로 시간 초과 키를 알려줍니다. RocketMQ 소비자는 메시지를 소비하고 응답하고 있습니다. 비즈니스 로직 처리.
가장 먼저 할 일은 github에서 RocketMQ의 C ++ 클라이언트 소스 코드를 다운로드하는 것입니다.
https://github.com/apache/rocketmq-client-cpp
그런 다음 컴파일하면 컴파일이 일반적으로 원활하고 오류가 발생합니다.
<pbin.v2 / libs / iostreams / build / gcc-4.8.5 / release / link-static / runtime 부족에 대한 libboost_iostreams.a
bzip2 패키지를 설치하십시오 : yum install bzip2-devel
다음 단계는 Redis 모듈을 개발하는 것입니다.
모듈도 매우 간단합니다. 방금 코드를 직접 게시했습니다.
#define REDISMODULE_EXPERIMENTAL_API
#include "../../redismodule.h"
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <unistd.h>
#include <memory.h>
#include "CProducer.h"
#include "CCommon.h"
#include "CMessage.h"
#include "CSendResult.h"
static CProducer *producer = NULL;
static char* MQAddr = NULL;
static char* MQTopic = NULL;
static char* MQTag = NULL;
static int SendTOMQ (RedisModuleCtx *ctx, const char* expirekey)
{
CMessage *msg = CreateMessage(MQTopic);
SetMessageTags(msg, MQTag);
SetMessageKeys(msg, expirekey);
CSendResult result;
SetMessageBody(msg, "Redis Key Timeout\n");
SendMessageSync(producer, msg, &result);
if (result.sendStatus == E_SEND_OK) {
printf ("Notify MQ successn: %s\n", expirekey);
return REDISMODULE_OK;
}
else {
printf ("Notify MQ fail: %s\n", expirekey);
return RedisModule_ReplyWithError(ctx,"Send to MQ fail\n");
}
}
//int (*RedisModuleNotificationFunc)(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key);
extern "C" int KeyExpireEventCallback (RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key)
{
REDISMODULE_NOT_USED(type);
REDISMODULE_NOT_USED(event);
size_t keylen = 0;
const char *expireKey = RedisModule_StringPtrLen(key, &keylen);
printf ("RocketmqMoudle callback exe: %s\n", expireKey);
//const char* topic = "FOREGROUND_CONSUMER";//
//const char* tag = "EXPIRE";//
if (MQAddr == NULL || MQTopic == NULL || MQTag == NULL) {
return RedisModule_ReplyWithError(ctx,"You haven't set the parameters of MQ yet.");
}
return SendTOMQ(ctx, expireKey);
}
extern "C" int PublishKey(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
if (argc != 2)
return RedisModule_WrongArity(ctx);
const char *expirekey = RedisModule_StringPtrLen(argv[1], NULL);
return SendTOMQ (ctx, expirekey);
}
/*
write readonly admin deny-oom deny-script allow-loading pubsub random allow-stale no-monitor fast getkeys-api no-cluster
*/
extern "C" int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
if (RedisModule_Init(ctx,"rocketmq",1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
size_t len;
/* Log the list of parameters passing loading the module. */
for (int j = 0; j < argc; j++) {
const char *s = RedisModule_StringPtrLen(argv[j], &len);
printf("Module loaded with ARGV[%d] = %s\n", j, s);
}
if (argc != 3) {
return RedisModule_WrongArity(ctx);
}
MQAddr = strdup(RedisModule_StringPtrLen(argv[0], &len));
MQTopic = strdup(RedisModule_StringPtrLen(argv[1], &len));
MQTag = strdup(RedisModule_StringPtrLen(argv[2], &len));
if (RedisModule_CreateCommand(ctx,"rocketmq.pubfun", PublishKey,"readonly",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
RedisModule_SubscribeToKeyspaceEvents (ctx, REDISMODULE_NOTIFY_EXPIRED, KeyExpireEventCallback);
producer = CreateProducer("redis_producer");
SetProducerNameServerAddress(producer, MQAddr);
if (StartProducer(producer)) {
printf("Module loaded StartProducer fail\n");
return REDISMODULE_ERR;
}
return REDISMODULE_OK;
}
# Compile flags for linux / osx
SHOBJ_CFLAGS ?= -W -Wall -fno-common -g -ggdb -std=c99 -O2
SHOBJ_LDFLAGS ?= -shared
M_R_FLAGS = -Wall -Wno-deprecated -fPIC -fno-strict-aliasing -O3 -DNDEBUG
M_D_FLAGS = -Wno-deprecated -fPIC -fno-strict-aliasing -O0 -DDEBUG
M_INCLUDES = -I/root/rocketmq-client-cpp-master/bin/include -I/root/rocketmq-client-cpp-master/bin/include/jsoncpp -I/root/rocketmq-client-cpp-master/include
LIBPATH = -L/root/rocketmq-client-cpp-master/bin
LDFLAGS = -lrocketmq
.SUFFIXES: .c .so .xo .o
all: rocketmq.so
.cpp.xo:
$(CC) -I. $(CFLAGS) $(SHOBJ_CFLAGS) $(M_D_FLAGS) $(M_INCLUDES) $(LIBPATH) -fPIC -c $< -o $@
rocketmq.xo: ../../redismodule.h
rocketmq.so: rocketmq.xo
$(LD) -o $@ $< $(SHOBJ_LDFLAGS) $(LDFLAGS) $(LIBS) -lc
clean:
rm -rf *.xo *.so
모듈 개발에서주의해야 할 작은 부분 : RedisModule_OnLoad 함수에서 실행되는 첫 번째 함수는 RedisModule_Init이어야합니다. 그렇지 않으면 segmentfalt를보고합니다.
다음 단계는 redis.conf 구성 파일을 구성하는 것입니다.
줄 추가 :
loadmodule /opt/redis-unstable/src/modules/rocketmq.so RocketMQ IP 및 TOPIC을 TAG 포팅
라인 수정 :
알림 키 공간 이벤트 Ex
Kafka 알림 메시지, MQTT 알림 메시지를 개발하거나 타사 모듈을 사용하여 스파이크 비즈니스 로직 또는 분산 잠금 관련 비즈니스 로직을 수행 할 수도 있습니다.