限流的设计方案
1、固定窗口
固定窗口的起始时间和结束时间,在固定时间段内允许要求的请求数量访问,超过则拒绝;当固定时间段结束后,再重新开始下一个时间段进行计数。
2、滑动窗口
滑动窗口就是一个在移动的固定窗口设置的时间窗口的起始和结束时间是不断变化的,时间差值不变,允许的请求数量不变。
3、令牌桶
调用接口之前,需要拥有指定个令牌。限流器每秒会产生X个令牌放入令牌桶,调用接口需要去令牌桶里面拿令牌。如果令牌被其它请求拿完了,那么自然而然,当前请求就调用不到指定的接口。
rabbimq的常用模式
1、simple 点对点
2、work 一对多
3、fanout 交换机
4、routing 路由交换机
5、topic 路由规则交换机
1,2示例代码:
SimpleConfig
package com.dzy.mq.common.config;
import com.dzy.mq.common.constants.RabbitMqConstants;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SimpleQueueConfig {
@Bean
public Queue simpleQueue() {
return new Queue(RabbitMqConstants.MQ_SIMPLE_QUEUE, RabbitMqConstants.DURABLE);
}
/**
* 将对象转换成json字符串
* */
@Bean
public MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(messageConverter());
return rabbitTemplate;
}
}
WorkConfig
package com.dzy.mq.common.config;
import com.dzy.mq.common.constants.RabbitMqConstants;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WorkQueueConfig {
@Bean
public Queue workQueue(){
return new Queue(RabbitMqConstants.MQ_WORK_QUEUE, RabbitMqConstants.DURABLE);
}
@Bean
public Queue registerQueue(){
return new Queue(RabbitMqConstants.MQ_REGISTER_WORK_QUEUE, RabbitMqConstants.DURABLE);
}
/**
* 将对象转换成json字符串
*/
@Bean
public MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(messageConverter());
return rabbitTemplate;
}
}
RabbitMqConstants
package com.dzy.mq.common.constants;
public interface RabbitMqConstants {
String MQ_SIMPLE_QUEUE = "mq_simple_queue"; // 简单队列名称
String MQ_WORK_QUEUE = "mq_work_queue"; // 工作队列名称
String MQ_REGISTER_WORK_QUEUE = "mq_register_work_queue"; // 工作队列名称
boolean DURABLE = true;
}
Service
package com.dzy.mq.producer.service.impl;
import com.dzy.mq.common.constants.RabbitMqConstants;
import com.dzy.mq.common.entity.User;
import com.dzy.mq.producer.service.IProducerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class ProducerServiceImpl implements IProducerService {
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
public void simpleQueueSend(String msg) {
rabbitTemplate.convertAndSend(RabbitMqConstants.MQ_SIMPLE_QUEUE,msg);
log.debug("[生产者模块:]向{}发送一条信息-->{}",RabbitMqConstants.MQ_SIMPLE_QUEUE, msg);
}
@Override
public void simpleQueueUserSend(User user) {
rabbitTemplate.convertAndSend(RabbitMqConstants.MQ_SIMPLE_QUEUE,user);
log.debug("[生产者模块:]向{}发送一个对象信息-->{}",RabbitMqConstants.MQ_SIMPLE_QUEUE, user);
}
@Override
public void workQueueUserSend(User user) {
rabbitTemplate.convertAndSend(RabbitMqConstants.MQ_WORK_QUEUE,user);
log.debug("[生产者模块:]向{}发送一个对象信息-->{}",RabbitMqConstants.MQ_WORK_QUEUE, user);
}
@Override
public void register(User user) {
rabbitTemplate.convertAndSend(RabbitMqConstants.MQ_REGISTER_WORK_QUEUE,user);
log.debug("[生产者模块:]向{}发送一个对象信息-->{}",RabbitMqConstants.MQ_REGISTER_WORK_QUEUE, user);
}
}
3,5示例代码:
RabbitMQConfig
package com.dzy.bm.common.config;
import com.dzy.bm.common.RabbitMqConstants;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
@Bean
public Queue mailQueue() {
return new Queue(RabbitMqConstants.MQ_MAIL_QUEUE, RabbitMqConstants.durable, RabbitMqConstants.exclusive, RabbitMqConstants.autoDelete);
}
@Bean
public Queue messageQueue() {
return new Queue(RabbitMqConstants.MQ_MESSAGE_QUEUE, RabbitMqConstants.durable, RabbitMqConstants.exclusive, RabbitMqConstants.autoDelete);
}
@Bean
public Queue topicQueueX() {
return new Queue(RabbitMqConstants.MQ_TOPIC_QUEUE_X, RabbitMqConstants.durable, RabbitMqConstants.exclusive, RabbitMqConstants.autoDelete);
}
@Bean
public Queue topicQueueY() {
return new Queue(RabbitMqConstants.MQ_TOPIC_QUEUE_Y, RabbitMqConstants.durable, RabbitMqConstants.exclusive, RabbitMqConstants.autoDelete);
}
/**
* 交换机(Exchange)
*/
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange(RabbitMqConstants.MQ_FANOUT_EXCHANGE, RabbitMqConstants.durable, RabbitMqConstants.autoDelete);
}
/**
* Topic交换机
* @return
* */
@Bean
public TopicExchange myTopicExchange() {
return new TopicExchange(RabbitMqConstants.MQ_TOPIC_EXCHANGE, RabbitMqConstants.durable, RabbitMqConstants.autoDelete);
}
@Bean
public Binding topicXBinding(){
return BindingBuilder.bind(topicQueueX())
.to(myTopicExchange())
.with("topic.xxx");
}
@Bean
public Binding topicYBinding(){
return BindingBuilder.bind(topicQueueY())
.to(myTopicExchange())
.with("topic.*");
}
@Bean
public Binding mailBing() {
return BindingBuilder.bind(mailQueue()).to(fanoutExchange());
}
@Bean
public Binding messageBing() {
return BindingBuilder.bind(messageQueue()).to(fanoutExchange());
}
}
RabbitMqConstants
package com.dzy.bm.common;
public interface RabbitMqConstants {
String MQ_MAIL_QUEUE = "mq_mail_queue";
String MQ_MESSAGE_QUEUE = "mq_message_queue";
String MQ_TOPIC_QUEUE_X= "mq_topic_queue_x";
String MQ_TOPIC_QUEUE_Y= "mq_topic_queue_y";
String MQ_FANOUT_EXCHANGE = "mq_fanout_exchange"; // 交换机
String MQ_TOPIC_EXCHANGE = "mq_my_topic_exchange";
//参数
boolean durable = true;
boolean exclusive = false;
boolean autoDelete = false;
}
Service
package com.dzy.bm.user.service.impl;
import com.dzy.bm.common.RabbitMqConstants;
import com.dzy.bm.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class UserServiceImpl implements IUserService {
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
public void sendCode(String msg) {
rabbitTemplate.convertAndSend(RabbitMqConstants.MQ_FANOUT_EXCHANGE,
"routingKey.fanout", msg);
log.debug("[生产者:]发送一条信息:{}", msg);
}
@Override
public void sendTopic(String msg) {
rabbitTemplate.convertAndSend(RabbitMqConstants.MQ_TOPIC_EXCHANGE,
"topic.yyy", msg);
log.debug("[生产者:]发送一条信息:{}", msg);
}
}