创建Channel
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
class ChannelStore {
private static final Logger LOGGER = LoggerFactory.getLogger(ChannelStore.class);
private final Queue<Channel> idleQueue = new ConcurrentLinkedQueue<>();
private final Connection connection;
ChannelStore(Connection connection) {
this.connection = connection;
}
public Channel createChannel() {
Channel channel = null;
try {
channel = connection.createChannel();
return channel;
}
catch (Exception e) {
LOGGER.warn(e.getMessage(), e);
}
return channel;
}
Channel borrow() {
Channel channel;
do {
channel = idleQueue.poll();
if (channel == null) {
channel = createChannel();
if (channel != null) {
idleQueue.offer(channel);
}
channel = idleQueue.poll();
}
else {
if (!channel.isOpen()) {
LOGGER.error("rabbitmq channel 已经关闭,丢弃");
channel = null;
}
}
}
while (channel == null);
return channel;
}
void returnBack(Channel channel) {
if (channel != null) {
idleQueue.offer(channel);
}
}
}
---
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.ShutdownSignalException;
public abstract class AbstractConsumer implements Consumer {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractConsumer .class);
@Override
public void handleConsumeOk(String consumerTag) {
LOGGER.info("handleConsumeOk: {}", consumerTag);
}
@Override
public void handleCancelOk(String consumerTag) {
LOGGER.info("handleCancelOk: {}", consumerTag);
}
@Override
public void handleCancel(String consumerTag) {
LOGGER.info("handleCancel: {}", consumerTag);
}
@Override
public void handleShutdownSignal(String consumerTag, ShutdownSignalException sig) {
LOGGER.info("handleShutdownSignal: {}", consumerTag, sig);
}
@Override
public void handleRecoverOk(String consumerTag) {
LOGGER.info("handleRecoverOk: {}", consumerTag);
}
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) {
try {
rabbitmqDataHandle(consumerTag, envelope.getExchange(), envelope.getRoutingKey(), body);
}
catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
public abstract void rabbitmqDataHandle(String consumerTag, String exchange, String routingKey, byte[] body)
throws Exception;
}
---
import java.io.IOException;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class RabbitmqClient {
private static final Logger LOGGER = LoggerFactory.getLogger(RabbitmqClient.class);
private static ChannelStore channelStore;
public static void start(String uri, String threadNamePrefix) {
channelStore = new ChannelStore(init(uri, threadNamePrefix));
}
public static boolean createExchange(String exchange, BuiltinExchangeType exchangeType, boolean durable,
boolean autoDelete) {
boolean result = false;
Channel channel = null;
try {
channel = channelStore.borrow();
channel.exchangeDeclare(exchange, exchangeType, durable, autoDelete, null);
result = true;
}
catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
finally {
channelStore.returnBack(channel);
}
return result;
}
public static boolean send(String exchange, String routingKey, byte[] body) {
boolean result = false;
Channel channel = null;
try {
channel = channelStore.borrow();
channel.basicPublish(exchange, routingKey, null, body);
result = true;
}
catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
finally {
channelStore.returnBack(channel);
}
return result;
}
public static void bindConsumer(String exchange, String queueName, String routingKey, boolean durable,
boolean exclusive, boolean autoDelete, AbstractRiskConsumer callback) throws IOException {
Channel channel = channelStore.borrow();
channel.queueDeclare(queueName, durable, exclusive, autoDelete, null);
String consumerTagAssociated = channel.basicConsume(queueName, true, callback);
channel.queueBind(queueName, exchange, routingKey);
LOGGER.info("declare consume:{},{}", queueName, consumerTagAssociated);
}
private static Connection init(String uri, String threadNamePrefix) {
try {
ConnectionFactory factory = new ConnectionFactory();
factory.setUri(uri);
factory.setThreadFactory(new ThreadFactory() {
private AtomicInteger threadCount = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread th = new Thread(r,
String.join("_", threadNamePrefix, Integer.toString(threadCount.incrementAndGet())));
th.setDaemon(true);
return th;
}
});
return factory.newConnection();
}
catch (Exception e) {
LOGGER.error(e.getMessage(), e);
throw new RiskException(e);
}
}
}
---
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
@SpringBootApplication
public class A implements CommandLineRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(A.class);
public static void main(String[] args) throws UnsupportedEncodingException {
if (args == null || args.length != 3) {
// 第一个参数为循环测试次数
// 第二个参数为线程数
// 第三个参数为每个线程执行风控次数
args = new String[] { "100", "1", "50" };
}
SpringApplication.run(App.class, args);
}
@Override
public void run(String... args) throws Exception {
StartParam startParam = new StartParam();
startParam.setAppId("etrading");
startParam.setRabbitmqThreadNamePrefix("RiskOrder");
startParam.setRabbitmqUrl("amqp://admin:admin123456@192.168.193.1:5672/%2F");
SdkService.init(startParam);
do {
}while(!SdkService.isReady());
for (int i = 0; i < Integer.parseInt(args[0]); i++) {
final AtomicLong count = new AtomicLong();
final AtomicLong totals = new AtomicLong();
int threadCount = Integer.parseInt(args[1]);
CountDownLatch latch = new CountDownLatch(threadCount);
for (int j = 0; j < threadCount; j++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < Integer.parseInt(args[2]); i++) {
try {
long start = System.nanoTime();
//业务逻辑
totals.addAndGet(System.nanoTime() - start);
count.incrementAndGet();
}
catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
latch.countDown();
}
}).start();
}
latch.await();
LOGGER.info("循环测试第[{}]次,执行次数[{}]:平均{}us", i + 1, count.get(), totals.get() / count.get() / 1000);
}
SdkService.stopSdk();
}
}
---
import com.erayt.risksdk.rabbitmq.AbstractRiskConsumer;
import com.erayt.risksdk.rabbitmq.RabbitmqClient;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.rabbitmq.client.BuiltinExchangeType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class SdkService {
private static final Logger LOGGER = LoggerFactory.getLogger(SdkService.class);
private static Gson GSON = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
private static final AtomicBoolean init = new AtomicBoolean(false);
public static void init(StartParam startParam) throws Exception {
String mqUri = startParam.getRabbitmqUrl();
String threadNamePrefix = startParam.getRabbitmqThreadNamePrefix();
{
//启动mq
RabbitmqClient.start(mqUri, threadNamePrefix);
//创建交换机
RabbitmqClient.createExchange(MqConstant.ORDER_EXCHANGE, BuiltinExchangeType.DIRECT, true, false);
RabbitmqClient.createExchange(MqConstant.USED_EXCHANGE, BuiltinExchangeType.DIRECT, true, false);
RabbitmqClient.createExchange(MqConstant.RELEASE_EXCHANGE, BuiltinExchangeType.DIRECT, true, false);
RabbitmqClient.createExchange(MqConstant.HEARTBEAT_EXCHANGE, BuiltinExchangeType.DIRECT, true,
false);
{
{
//创建交换机
RabbitmqClient.createExchange(MqConstant.LOGIN_ACK_EXCHANGE, BuiltinExchangeType.DIRECT,
false, true);
//绑定消费者
RabbitmqClient.bindConsumer(MqConstant.LOGIN_ACK_EXCHANGE,
String.join("_", MqConstant.LOGIN_ACK_EXCHANGE, data), data, false, true, true,
new AbstractRiskConsumer() {
@Override
public void rabbitmqDataHandle(String consumerTag, String exchange, String routingKey,
byte[] body) throws Exception {
String data = new String(body, StandardCharsets.UTF_8);
LOGGER.debug("consumerTag: {}, exchange: {}, routingKey:{}, data: {}", consumerTag,
exchange, routingKey, data);
Map<String, String> initData = GSON.fromJson(data,
new TypeToken<Map<String, String>>() {
}.getType());
JedisClient.init(initData.get("NODES"), initData.get("USERNAME"),
initData.get("PASSWORD"));
for (Map.Entry<String, String> entry : initData.entrySet()) {
String key = entry.getKey();
if (!key.contains("LUA")) {
continue;
}
JedisClient.addLua(key, entry.getValue());
}
{
rskSdk = GSON.fromJson(initData.getOrDefault("sdk", "{}"),
new TypeToken<RskSdk>() {
}.getType());
}
}
});
}
{
RabbitmqClient.createExchange(MqConstant.BASIC_DATA, BuiltinExchangeType.DIRECT, false,
true);
RabbitmqClient.bindConsumer(MqConstant.BASIC_DATA,
String.join("_", MqConstant.BASIC_DATA, data), data, false, true, true,
new AbstractRiskConsumer() {
@Override
public void rabbitmqDataHandle(String consumerTag, String exchange, String routingKey,
byte[] body) throws Exception {
init.set(false);
String data = new String(body, StandardCharsets.UTF_8);
LOGGER.debug("consumerTag: {}, exchange: {}, routingKey:{}, data: {}", consumerTag,
exchange, routingKey, data);
init.set(true);
}
});
}
}
}
}
/**
* 是否初始化完成
* @return
*/
public static boolean isReady() {
return init.get();
}
private SdkService() {
}
public static void stopSdk() {
init.set(false);
}
}
---
class B {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private ObjectMapper objectMapper;
public void handle001(Event event) throws Exception {
//发消息
rabbitTemplate.convertAndSend(MqConstant.LOGIN_ACK_EXCHANGE, data,
objectMapper.writeValueAsString(initData));
}
}