异步队列的实现。

如下图所示

REDIS 最新评论 redis实现评论_List

 

 

这里的异步实现,采用redis作为单向的任务队列,将事件通过序列存入redis队列,通过反序列化将其发送给事件消费者。

事件消费者,通过一个EventHandler接口,来处理不同的事件。

public interface EventHandler{
//用来处理事件
doHandle(EventModel model);

//返回可以处理的事件的类型
List<EventType>getsupportedTypes();

}

事件分发器通过向jedisqueue lpush事件,consumer 从jedisqueue中brpop被序列化的事件,并反序列交给从applicationContext中获取的Eventhandler的实现类去实现点赞,或者评论。

public enum EventType{
LIKE(0);
COMMENT(1);
LOGIN(3);
MAIL(3);
private int value;
EventType(int value){this.val=value;}
public int getValue(){return value;}
}
 
 
public calss EeventModel{
private EvrntTypr tpe
private int actorId;//事件触发者
privtae entityId;//触发对象 评论的id  
private int entityType;//评论的类型  实体的类型和id
private int entityOwnerId;//接收事件
 
private Map<String ,String> exts=new Hashmap<String,String>();
//get 和set函数
}
@Service
//事件的入口,统一发事件
Blpop   Brpop
public class EventProducer{
@Autowired
JedisAdapter jedisAdapter;
//将事件放入队列
public boolean firEvent(EventModel eventmodel){
try{
 String json =JSONOBJECT.toJSONString(eventModel);//将事件对象序列化存放在redis中
String key=ReidsKeyutil.getEventQueueKey();
JedisAdapter.lpush(key,json);//事件推入队列
return true;
}catche(Exception e){
return false;
}
}
}
public interface EventHandler{
//用来处理事件
doHandle(EventModel model);//处理事件

//返回可以处理的事件的类型
List<EventType>getsupportedTypes();//注册自己  表名对哪些事件关注

}

@Service
class EventConsumer implements InitilizinfBean
, ApplicationContextAware
{//进行初始化 通过Spring的上下文
//分发事件
private Map<EventType,List<Evenethandler>> config=new hashMapp<>();
private ApplicationContext applicationContext;
@Override
public void aferpropertiesSet() throws Exception{
Map<String, EventHandler> beans = applicationContext.getBeansOfType(EventHandler.class);
if (beans != null) {
    for (Map.Entry<String, EventHandler> entry : beans.entrySet()) {
        List<EventType> eventTypes = entry.getValue().getSupportEventTypes();

        for (EventType type : eventTypes) {
            if (!config.containsKey(type)) {
                config.put(type, new ArrayList<EventHandler>());
            }
            config.get(type).add(entry.getValue());
        }
    }
}
//使用线程一直去取队列
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        while(true) {
            String key = RedisKeyUtil.getEventQueueKey();
            List<String> events = jedisAdapter.brpop(0, key);//从尾部取

            for (String message : events) {
                if (message.equals(key)) {
                    continue;
                }

                EventModel eventModel = JSON.parseObject(message, EventModel.class);
                if (!config.containsKey(eventModel.getType())) {
                    logger.error("不能识别的事件");
                    continue;
                }

                for (EventHandler handler : config.get(eventModel.getType())) {
                    handler.doHandle(eventModel);
                }
            }
        }
    }
});
thread.start();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
}
}

知识渊博的小可爱