blob: 045a32a97d03ef8d81d8e08ed0759a43bf940acb [file]
/**
* Copyright (C) 2013 suwenkuang ,hooligan_520@qq.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Common.h"
#include "SendCallback.h"
#include "DefaultMQProducer.h"
using namespace rmq;
long long g_lastUpdateTime = 0;
volatile long long g_cnt_total = 0;
volatile long long g_cnt_last = 0;
volatile long long g_cnt_succ = 0;
volatile long long g_cnt_fail = 0;
void Usage(const char* program)
{
printf("Usage:%s ip:port [-g group] [-t topic] [-n count] [-s size] [-w logpath]\n", program);
printf("\t -g group\n");
printf("\t -t topic\n");
printf("\t -n message count\n");
printf("\t -s message size \n");
printf("\t -w log path\n");
}
class SampleSendCallback : public SendCallback {
public:
SampleSendCallback()
{
}
virtual ~SampleSendCallback()
{
}
int count()
{
long long now = MyUtil::getNowMs();
long long old = g_lastUpdateTime;
long long total = g_cnt_succ + g_cnt_fail;
if ((now - old) >= 1000)
{
if (__sync_bool_compare_and_swap(&g_lastUpdateTime, old, now))
{
long long time = now - old;
int tps = (int)((total - g_cnt_last) * 1.0 / time * 1000.0);
g_cnt_last = total;
MYDEBUG("[producer]succ: %lld, fail: %lld, TPS: %d\n",
g_cnt_succ, g_cnt_fail, tps);
}
}
}
void onSuccess(SendResult& sendResult)
{
int cnt = __sync_fetch_and_add(&g_cnt_total, 1);
__sync_fetch_and_add(&g_cnt_succ, 1);
MYLOG("[%d]|succ|%s\n", cnt, sendResult.toString().c_str());
}
void onException(MQException& e)
{
int cnt = __sync_fetch_and_add(&g_cnt_total, 1);
__sync_fetch_and_add(&g_cnt_fail, 1);
MYLOG("[%d]|fail|%s\n", cnt, e.what());
}
};
int main(int argc, char *argv[]) {
if (argc < 2)
{
Usage(argv[0]);
return 0;
}
std::string namesrv = argv[1];
std::string group = "pg_test_group";
std::string topic = "topic_test";
int size = 32;
int count = 1000;
for (int i=2; i< argc; i++)
{
if (strcmp(argv[i],"-g")==0)
{
if (i+1 < argc)
{
group = argv[i+1];
i++;
}
else
{
Usage(argv[0]);
return 0;
}
}
else if (strcmp(argv[i],"-t")==0)
{
if (i+1 < argc)
{
topic = argv[i+1];
i++;
}
else
{
Usage(argv[0]);
return 0;
}
}
else if (strcmp(argv[i],"-n")==0)
{
if (i+1 < argc)
{
count = atoi(argv[i+1]);
i++;
}
else
{
Usage(argv[0]);
return 0;
}
}
else if (strcmp(argv[i],"-s")==0)
{
if (i+1 < argc)
{
size = atoi(argv[i+1]);
i++;
}
else
{
Usage(argv[0]);
return 0;
}
}
else if (strcmp(argv[i],"-w")==0)
{
if (i+1 < argc)
{
MyUtil::initLog(argv[i+1]);
i++;
}
else
{
Usage(argv[0]);
return 0;
}
}
else
{
Usage(argv[0]);
return 0;
}
}
// init client api log, here is not necessary, need to debug the api need to be initialized, you can consider comment it
// Here only the default print warning, error log, the log will be rolling by day, if you need to modify the log level, please set the environment variable, export ROCKETMQ_LOGLEVEL = loglevel
// The log level is as follows:
// 0 - close the log
// 1 - write error log
// 2 - write error, warning log
// 3 - write error, warning, info log
// 4 - write errors, warnings, info, debug logs
RocketMQUtil::initLog("/tmp/rocketmq_producer.log");
RMQ_DEBUG("producer.new: %s", "pg_CppClient");
DefaultMQProducer producer("pg_CppClient");
RMQ_DEBUG("producer.setNamesrvAddr: %s", namesrv.c_str());
producer.setNamesrvAddr(namesrv);
RMQ_DEBUG("producer.start");
producer.start();
std::string tags[] = { "TagA", "TagB", "TagC", "TagD", "TagE" };
int nNow = time(NULL);
char key[64];
char value[1024];
std::string str;
for (int i = 0; i < size; i += 8)
{
str.append("hello baby");
}
TimeCount tcTotal;
tcTotal.begin();
for (int i = 0; i < count; i++)
{
try
{
snprintf(key, sizeof(key), "KEY_%d_%d", nNow, i);
snprintf(value, sizeof(value), "%011d_%s", i, str.c_str());
Message msg(topic,// topic
tags[i % 5],// tag
key,// key
value,// body
strlen(value)+1
);
// Send messages asynchronously
SampleSendCallback* pSendCallback = new SampleSendCallback();
producer.send(msg, pSendCallback);
}
catch (MQClientException& e)
{
std::cout << e << std::endl;
__sync_fetch_and_add(&g_cnt_fail, 1);
MyUtil::msleep(3000);
}
}
while (1)
{
if ((g_cnt_succ + g_cnt_fail) >= count)
{
break;
}
}
tcTotal.end();
printf("statsics: succ=%d, fail=%d, total_cost=%ds, tps=%d, avg=%dms\n",
g_cnt_succ, g_cnt_fail, tcTotal.countSec(),
(int)((double)count/((double)tcTotal.countUsec()/1000/1000)), tcTotal.countMsec()/count);
producer.shutdown();
return 0;
}