java编写简单消息队列,实现高德坐标变形服务

20 篇文章 0 订阅
5 篇文章 0 订阅

1. 应用背景

项目中需要对GPS原始坐标进行高德坐标变形,GPS坐标一直在新增,为了保证服务的稳定性,采用了简单的消息队列进行处理。

设定定时任务,每次将待变形的坐标数据保存至待变形消息队列,然后变形服务去这个队列中取数据,将变形后的结果存入已变形消息队列,更新服务进入这个队列取数据,更新数据库。

备注:近5个月坐标转化量
2015年12月,日平均坐标量约6.16万
2015年11月,日平均坐标量约6.38万
2015年10月,日平均坐标量约3.71万
2015年09月,日平均坐标量约5.81万
2015年08月,日平均坐标量约7.40万

2. 消息队列

package com.autonavi.messagequeue;

import java.util.LinkedList;
import java.util.NoSuchElementException;

/**
 * @note 消息队列FIFO
 */
public class MessageQueue<T> {

    private int theMaxSizeOfQueue = 5000;

    /**
     * @param 1-锁定;0-可执行
     */
    private int theLockStatusOfQueue = 1;

    private LinkedList<T> msgList = new LinkedList<T>();

    /**
     * @param void
     * @return t or null
     */
    public T getMsg(){
        T t;
        try{
            t = msgList.getFirst();
            removeMsg();
        }catch(NoSuchElementException e){
            return null;
        }

        return t;
    }

    /**
     * @param t
     * @return true-添加成功;false-队列已满,需等候
     */
    public boolean addMsg(T t){
        boolean res = false;

        if(lockStatusMsg() == false){           
            lockMsg();          
            int size = sizeMsg();           
            if(size < theMaxSizeOfQueue){
                msgList.addLast(t);                     
                res = true;
            }else{              
                res = false;
            }       
        }else{
            res = false;
        }

        unlockMsg();
        return res;
    }

    /**
     * @param t
     * @return true-删除成功;false-空队列
     */
    public boolean removeMsg(){
        boolean res = false;

        if(lockStatusMsg() == false){   
            T t;
            lockMsg();  
            try{
                t = msgList.removeFirst();
            }catch(NoSuchElementException e){
                res = false;
                t = null;
            }

            if(t != null){
                res = true;
            }else{
                res = false;
            }
        }

        unlockMsg();
        return res;
    }

    public int sizeMsg(){
        return msgList.size();
    }

    /**
     * @param 锁定状态
     */
    public boolean lockStatusMsg(){
        if(theLockStatusOfQueue == 1){
            return true;
        }else{
            return false;
        }       
    }

    /**
     * @param 锁定
     */
    public void lockMsg(){
        theLockStatusOfQueue = 1;
    }

    /**
     * @param 解锁
     */
    public void unlockMsg(){
        theLockStatusOfQueue = 0;
    }

}

3. 定时任务

package com.autonavi.task;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.autonavi.constants.Constant;
import com.autonavi.dao.impl.mapper.CarPositionMapper;
import com.autonavi.domain.Coordinate;
import com.autonavi.messagequeue.MessageQueue;
import com.autonavi.method.DataChange;
import com.autonavi.method.DataQuery;
import com.autonavi.method.DataUpdate;

/**
 * <p>Author: 
 * <p>Date: 15-12-24
 * <p>Version: 2.0
 * <p>note: 4个定时计划: 数据查询,数据变形,数据更新,日志记录
 * @param <msgQueue>
 */
@Component
public class ScheduledTasks {

    @SuppressWarnings("unused")
    @Autowired
    private CarPositionMapper carPositionMapper;

    private static final Logger logger = LoggerFactory.getLogger(ScheduledTasks.class);
    // 队列1:存储待变形数据
    MessageQueue<Coordinate> msgQueue_in = new MessageQueue<Coordinate>();
    // 队列2:存储已变形数据
    MessageQueue<Coordinate> msgQueue_out = new MessageQueue<Coordinate>();

    /**
     * <p>note: 1
     * <p>note: 数据查询业务
     * @param <msgQueue_1>
     */
    @Scheduled(cron="0 0/10 0-23 * * ?") 
    public void executeDataQueryTask() {

        long startTime = System.currentTimeMillis();
        logger.info("ScheduledTasks-executeDataChangeTask: 待变形队列-入队:start");

        Coordinate coor = null;
        List<Coordinate> list = DataQuery.query();
        int size = 0;
        if(list != null){
            size = list.size();
        }

        if(size > 0){
            for(int i=0;i<size;i++){
                coor = list.get(i);
                msgQueue_in.addMsg(coor);                           
            }
        }

        long endTime = System.currentTimeMillis();
        logger.info("ScheduledTasks-executeDataQueryTask: 待变形队列-入队:"+msgQueue_in.sizeMsg()); 
        logger.info("ScheduledTasks-executeDataChangeTask: 待变形队列-入队:end,耗时:"+(endTime-startTime)+"ms");
    }

    /**
     * <p>note: 2
     * <p>note: 数据变形业务
     */
    @Scheduled(cron="0 0/3 0-23 * * ?") 
    public void executeDataChangeTask() {

        long startTime = System.currentTimeMillis();
        logger.info("ScheduledTasks-executeDataChangeTask: 已变形队列-入队:start");

        List<Coordinate> list = new ArrayList<Coordinate>();
        List<Coordinate> list_return = null;

        int size = msgQueue_in.sizeMsg();
        int current_times = 0;
        if(size < Constant.DEAL_MAX_TIMES){
            current_times = size;
        }else{
            current_times = Constant.DEAL_MAX_TIMES;
        }

        for(int i=0;i<current_times;i++){

             Coordinate coor = msgQueue_in.getMsg();
             list.add(coor);        
        }

        if(list != null && list.size() != 0){
            list_return = DataChange.change(list);
        }

        if(list_return != null && list_return.size() != 0){
            for(int j=0;j<list_return.size();j++){
                msgQueue_out.addMsg(list_return.get(j));
            }
        }
        long endTime = System.currentTimeMillis();      
        // System.out.println("消息队列2:入队"+msgQueue_out.sizeMsg());  
        logger.info("ScheduledTasks-executeDataChangeTask: 已变形队列-入队:"+msgQueue_out.sizeMsg()); 
        logger.info("ScheduledTasks-executeDataChangeTask: 已变形队列-入队:end,耗时:"+(endTime-startTime)+"ms");
    }

    /**
     * <p>note: 3
     * <p>note: 数据更新业务
     */
    @Scheduled(cron="0 0/3 0-23 * * ?") 
    public void executeDataUpdateTask() {

        long startTime = System.currentTimeMillis();
        logger.info("ScheduledTasks-executeDataChangeTask: 已变形队列-出队:start");

        List<Coordinate> list = new ArrayList<Coordinate>();
        Integer counts = 0;

        int size = msgQueue_out.sizeMsg();
        int current_times = 0;
        if(size < Constant.DEAL_MAX_TIMES){
            current_times = size;
        }else{
            current_times = Constant.DEAL_MAX_TIMES;
        }

        for(int i=0;i<current_times;i++){

         Coordinate coor = msgQueue_out.getMsg();
         list.add(coor);        
        }

        if(list != null && list.size() != 0){
            counts = DataUpdate.update(list);
        }
        long endTime = System.currentTimeMillis();   
        // System.out.println("ScheduledTasks-executeDataUpdateTask: 已变形数量-消息出队:"+msgQueue_in.sizeMsg());  
        logger.info("ScheduledTasks-executeDataChangeTask: 已变形队列-出队:"+counts);
        logger.info("ScheduledTasks-executeDataChangeTask: 已变形队列-出队:end,耗时:"+(endTime-startTime)+"ms");
    }

    /**
     * <p>note: 4
     * <p>note: 消息队列日志
     */
    @Scheduled(cron="0 0/10 0-23 * * ?") 
    public void executeDataQueueTask() {
        int msgQueue_in_size = msgQueue_in.sizeMsg();
        int msgQueue_out_size = msgQueue_out.sizeMsg();     
        logger.info("ScheduledTasks-executeDataQueueTask: 待变形队列-数据量:"+msgQueue_in_size); 
        logger.info("ScheduledTasks-executeDataQueueTask: 已变形队列-数据量:"+msgQueue_out_size);       
    }
}

4. 实现说明

目前,还是一个单线程息消息队列,后续会实现多线程消息队列。仅供大伙参考。如需项目代码,请留言。

5. 最终效果

坐标变形结果都挺好。服务运行也挺稳定。

这里写图片描述

这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值