Redis 모듈 개발, Redis는 RocketMQ 클라이언트를 트리거하여 메시지를 게시합니다.

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 알림 메시지를 개발하거나 타사 모듈을 사용하여 스파이크 비즈니스 로직 또는 분산 잠금 관련 비즈니스 로직을 수행 할 수도 있습니다.

추천

출처blog.csdn.net/langeldep/article/details/85692948