通过Netty通信,采集设备现场GPS数据,并存放在redis服务器。

主程序代码如下:

/*
 /*
 * CopyRight (c) 2013 北京软秀科技有限公司www.inforwms.com 保留所有权利。 * mail:[email protected]
 */
 */
package com.softshow.product.digi;

import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.InvalidPropertiesFormatException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
import org.jboss.netty.util.internal.ConcurrentHashMap;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.softshow.product.cache.DataCache;
import com.softshow.product.db.DatabaseDataManager;
import com.softshow.product.handler.IdentifyChannelDecoder;
import com.softshow.product.handler.InitInfoChannelDecoder;
import com.softshow.product.helper.DateUtils;
import com.softshow.product.helper.GlobalTimer;
import com.softshow.product.helper.HttpClientHelper;
import com.softshow.product.helper.Log;
import com.softshow.product.model.CarInfo;
import com.softshow.product.timer.AutoUpgradTimer;
import com.softshow.product.timer.AutoOrderTimer;
import com.softshow.product.timer.WSAutoOrderTimer;

/**
 * 服务统一管理
 * @author <a href="mailto:[email protected]">meslog</a>
 * @version 1.0.0.2013-10-22
 *
 */
public class ServerManager {
	private final String cfgPath = "/server.cfg";
	private final List<TrackerServer> serverList = new LinkedList<TrackerServer>();
	private final static ConcurrentMap<Integer,TrackerServer> trackerServerMap = new ConcurrentHashMap<Integer,TrackerServer>();//lizhao

	public static ConcurrentMap<Integer,TrackerServer> getTrackerServerMap(){//lizhao
		return trackerServerMap;
	}

	public void addTrackerServer(TrackerServer trackerServer) {
		serverList.add(trackerServer);
	}

	private boolean loggerEnabled;

	public boolean isLoggerEnabled() {
		return loggerEnabled;
	}

	private static DataManager dataManager;

	public static DataManager getDataManager() {
		return dataManager;
	}

	private static Properties properties;

	public Properties getProperties() {
		return properties;
	}

	private static JedisConnectionFactory redisFactory;

	public static JedisConnectionFactory getRedisFactory() {
		return redisFactory;
	}

	/**
	 * 初始化日志、缓存、数据库和Netty服务
	 */
	public void init() throws IOException, ClassNotFoundException, SQLException {
		loadProperties();//加载配置,初始化常量

		initLogger(properties);//初始化日志

		dataManager = new DatabaseDataManager(properties);//初始化数据库连接
		Log.info(Constants.SERVER_MAIN, "**database connection initialized......**");

		redisFactory = initRedis(properties);//初始化redis缓存
		initDataCache();//加载redis缓存
		Log.info(Constants.SERVER_MAIN, "**redis load compeleted......**");

		initELSServer("fourfaith");//初始化Netty服务
	}

	private void loadProperties() throws InvalidPropertiesFormatException, IOException{
		//加载配置文件
		properties = new Properties();
		InputStream in = getClass().getResourceAsStream(cfgPath);
		properties.loadFromXML(in);
		in.close();

		//打印版本信息
		Constants.VERSION_CODE = properties.getProperty("connection.version");
		Log.info(Constants.SERVER_MAIN, "===============================system version:["+Constants.VERSION_CODE+"]");

		//初始化常量
		initConstant(properties);
	}

	/**
	 * 每天定时清理缓存数据
	 */
	private void scheduleDailyGpsCache() {
		final RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
		redisTemplate.setConnectionFactory(redisFactory);
		redisTemplate.setKeySerializer(new StringRedisSerializer());
		redisTemplate.afterPropertiesSet();
		Timer timer = new java.util.Timer(true);
		final List<CarInfo> carList = DataCache.getAllCar();
		TimerTask task = new TimerTask() {
			public void run() {
				for (CarInfo car : carList) {
					redisTemplate.delete(Constants.CACHE.TODAY_GPS_COLLECTION_PREFIX + "." + car.getId());
				}
			}
		};
		timer.scheduleAtFixedRate(task, DateUtils.getTomorrowTimeByHour(0), 24 * 60 * 60 * 1000);
	}

	private JedisConnectionFactory initRedis(Properties prop) {
		redisFactory = new JedisConnectionFactory();
		redisFactory.setUsePool(true);
		redisFactory.setPort(Integer.parseInt(prop.getProperty("redis.port")));
		redisFactory.setHostName(prop.getProperty("redis.serverUrl"));
		redisFactory.setDatabase(Integer.parseInt(prop.getProperty("redis.database")));
		redisFactory.afterPropertiesSet();
		return redisFactory;
	}

	/**
	 * 启动Netty服务和相关定时线程
	 */
	public void start() {
		//启动Netty Server
		for (Object server : serverList) {
			((TrackerServer) server).start();
		}

		//启动定时器
		startTimer();
	}

	/**
	 * Stop
	 */
	public void stop() {
		for (Object server : serverList) {
			((TrackerServer) server).stop();
		}

		// Release resources
		GlobalChannelFactory.release();
		GlobalTimer.release();
		try {
			redisFactory.destroy();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Destroy
	 */
	public void destroy() {
		serverList.clear();
	}

	/**
	 * Initialize logger
	 */
	private void initLogger(Properties properties) throws IOException {
		loggerEnabled = Boolean.valueOf(properties.getProperty("logger.enable"));

		if (loggerEnabled) {
			String serverMainName = properties.getProperty("logger.servermain");
			initLog(serverMainName,Constants.SERVER_MAIN);
			String serverGpsName = properties.getProperty("logger.servergps");
			initLog(serverGpsName,Constants.GPS_LOGGER_SERVER);
			String serverHeartName = properties.getProperty("logger.serverheart");
			initLog(serverHeartName,Constants.HEART_LOGGER_SERVER);

		}
	}

	/**
	 * 初始化常量
	 * @param properties
	 * @throws IOException
	 */
	private void initConstant(Properties props) throws IOException {
		String webPrefix = "http://" + props.getProperty("webIP");
		String ctx = props.getProperty("webContext");
		if(ctx!=null && ctx.trim().length()>0){
			webPrefix += "/"+ctx;
		}
		Constants.query_Order_url = webPrefix + Constants.query_Order_url;
		Constants.setRange_url = webPrefix + Constants.setRange_url;
		Constants.getDeviceParameter_url = webPrefix + Constants.getDeviceParameter_url;

		HttpClientHelper.MapbarAPIAddr = props.getProperty("mapBarAPIAddress");
	}

	private boolean isProtocolEnabled(Properties properties, String protocol) {
		String enabled = properties.getProperty(protocol + ".enable");
		if (enabled != null) {
			return Boolean.valueOf(enabled);
		}
		return false;
	}

	private void initServer(String protocol) throws SQLException {//lizhao
		if (isProtocolEnabled(properties, protocol)) {
			TrackerServer trackerServer = new TrackerServer(this, new ServerBootstrap(), protocol) {
				@Override
				protected void addSpecificHandlers(ChannelPipeline pipeline) {
					//进行了编码和解码.之前的handler处理字节,之后的handler处理字符串。顺序不可乱。
					pipeline.addLast("stringDecoder", new StringDecoder());
					pipeline.addLast("stringEncoder", new StringEncoder());
					pipeline.addLast("identifyDeviceDecoder", new IdentifyChannelDecoder(ServerManager.this));
					pipeline.addLast("initInfoChannelDecoder", new InitInfoChannelDecoder(ServerManager.this));
				}
			};
			trackerServerMap.put(trackerServer.getPort(), trackerServer);
			serverList.add(trackerServer);
		}
	}

	/**
	 *
	 * Description:启动时初始化数据缓存
	 */
	private void initDataCache() {
		new DataCache(dataManager);
	}

	/**
	 * 初始化日志
	 * @param name
	 * @param sgin
	 * @throws IOException
	 */
	private void initLog(String name,String sgin)throws IOException{
		if (name != null) {
			FileHandler file = new FileHandler(name,500 * 1024 * 1024, 10, true);
			// Simple formatter
			file.setFormatter(new Formatter() {
				private final String LINE_SEPARATOR = System.getProperty("line.separator", "\n");
				private final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				@Override
				public String format(LogRecord record) {
					StringBuffer line = new StringBuffer();
					dateFormat.format(new Date(record.getMillis()), line, new FieldPosition(0));
					line.append(" ");
					line.append(record.getSourceClassName());
					line.append(".");
					line.append(record.getSourceMethodName());
					line.append(" ");
					line.append(record.getLevel().getName());
					line.append(": ");
					line.append(formatMessage(record));
					line.append(LINE_SEPARATOR);
					return line.toString();
				}
			});
			Log.getLogger(sgin).addHandler(file);//文件输出
			Log.getLogger(sgin).addHandler(new ConsoleHandler());//控制台输出
		}
	}

	/**
	 * 启动定时任务
	 * @param dataManager
	 */
	public void startTimer(){
		// webservice定时获取订单
		ScheduledExecutorService executorWSOrder = Executors.newScheduledThreadPool(1);
		executorWSOrder.scheduleWithFixedDelay(new WSAutoRecieveOrderTimer(dataManager), 10, 300, TimeUnit.SECONDS);
		Log.info(Constants.SERVER_MAIN, "**Timer[receive order] running per 300s......**");

		// 定时订单
		ScheduledExecutorService deliverOrder = Executors.newScheduledThreadPool(2);
		deliverOrder.scheduleWithFixedDelay(new AutoSendOrderTimer(dataManager), 10, 180, TimeUnit.SECONDS);
		Log.info(Constants.SERVER_MAIN, "**Timer[auto send order] running per 180s......**");

		// GPS缓存定时清理
		scheduleDailyGpsCache();
		Log.info(Constants.SERVER_MAIN, "**Timer[GPS data cleaner] running per day......**");

		// 定时检查升级是否超时
		ScheduledExecutorService deviceUpgrade = Executors.newScheduledThreadPool(3);
		deviceUpgrade.scheduleWithFixedDelay(new AutoCheckUpgradTimer(dataManager), 20, 60, TimeUnit.SECONDS);
		Log.info(Constants.SERVER_MAIN, "**Timer[auto check upgrade device] running per 60s......**");

	}

}
时间: 2024-10-31 20:35:57

通过Netty通信,采集设备现场GPS数据,并存放在redis服务器。的相关文章

百万级运维心得一:Mongodb和Redis数据不能放在同一个服务器

百万级运维经验一:Mongodb和Redis数据不能放在同一个服务器 一开始时,为了省服务器,把Mongodb和Redis放在一个服务器上.网站每到高峰期都特别卡,还经常出现502.找了很久的原因,发现硬盘的写数据很大,IOPS也很高,排查了很多原因都没找到.然后再仔细研究监控,发现写硬盘的操作很有规律,每隔几分钟就有一次频繁的写硬盘,联想到Redis同步数据到硬盘的间隔就是几分钟,所以开始怀疑是Redis引起的.于是加了一台服务器,把Redis单独放在那里,发现网站瞬间快了,502问题也不再出

百万级运维经验一:Mongodb和Redis数据不能放在同一个服务器

一开始时,为了省服务器,把Mongodb和Redis放在一个服务器上.网站每到高峰期都特别卡,还经常出现502.找了很久的原因,发现硬盘的写数据很大,IOPS也很高,排查了很多原因都没找到.然后再仔细研究监控,发现写硬盘的操作很有规律,每隔几分钟就有一次频繁的写硬盘,联想到Redis同步数据到硬盘的间隔就是几分钟,所以开始怀疑是Redis引起的.于是加了一台服务器,把Redis单独放在那里,发现网站瞬间快了,502问题也不再出现了,真是痛苦的经验啊.至于,把Mongodb和Redis放在同一个服

Mongodb和Redis数据不能放在同一个服务器

一开始时,为了省服务器,把Mongodb和Redis放在一个服务器上.网站每到高峰期都特别卡,还经常出现502.找下原因,发现硬盘的写数据很大,IOPS也很高,然后再仔细研究监控,发现写硬盘的操作很有规律,每隔几分钟就有一次频繁的写硬盘,联想到Redis同步数据到硬盘的间隔就是几分钟,所以开始怀疑是Redis引起的. 于是加了一台服务器,把Redis单独放在那里,发现网站瞬间快了,502问题也不再出现了.至于,把Mongodb和Redis放在同一个服务器不同硬盘的方案,我没测试过,估计应该也会对

使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置)

原文:使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置) 在上一篇中说到了Silverlight下的Socket通信,在最后的时候说到本篇将会结合地图.下面就来看看本文实现的功能: Silverlight 与服务器利用Socket通讯,实时从服务器获取数据(本文中的数据是地理坐标),由于没有GPS,所以本文在服务器写了一个构造新坐标的函数(本文是一个三角函数),然后利用Timer组件,实时调用,得到新的坐标,并将新的坐标发送给客户端,客户端接收到发

GPS数据读取与处理

转自:http://www.cnblogs.com/emouse/archive/2013/05/29/3105745.html GPS模块简介 SiRF芯片在2004年发布的最新的第三代芯片SiRFstar III(GSW 3.0/3.1),使得民用GPS芯片在性能方面登上了一个顶峰,灵敏度比以前的产品大为提升.这一芯片通过采用20万次/频率的相关器提高了灵敏度,冷开机/暖开机/热开机的时间分别达到42s/38s/8s,可以同时追踪20个卫星信道.是目前市场上应用最为广泛,同时性价比也非常高的

可穿戴设备让“大数据”如虎添翼

“大数据”是近年来在国内外都越来越火的一个词.不管你是否真的懂,和人聊天时不能拿“新媒体”.“大数据”作谈资,那就弱爆了. 不过,正如它更多仍是一种谈资,大多数中国人对“大数据”仍然停留在一知半解的状态.国内对大数据真正的应用展开缓慢,而与之相应的批评也如国外一般纷至沓来. 从某种程度上说,“大数据”不是一个新的概念.历史学家黄仁宇曾指出古代中国缺少数目字管理 ——其言下之意是,在欧洲,人们已经更早地通过数字了解和管理 政治.经济.商业等各项事务.即便进入当代社会,这一核心思维并无真正的改变.当

气象采集设备_自动气象站

气象采集设备_自动气象站是一种便携式地面气象观测设备,由湿度.温度.数据采集器.压力传感器.辐射防护罩和支架构成.可采集.处理温度.湿度.压力等气象数据,具有RS422或RS485接口,并能实时通信.该设备精度高.时效快.使用方便,是一种适合现代气象保障需要的监测设备. 气象采集设备_自动气象站是“自动化”气象采集设备的一个模型,可以自动采集监测点的各种气象参数数据,通过一定的数据传输方式传输到服务器,供用户查看. 智能气象站是一种能够自动监测和存储气象数据的设备,主要由传感器.采集器.通信接口

GPS数据解析

1.摘要 GPS模块使用串口通信,那么它的的数据处理本质上还是串口通信处理,只是GPS模块的输出的有其特定的格式,需要字符串处理逻辑来解析其含义.如何高效的处理从GPS模块接收到的数据帧,是GPS驱动设计的重点,本文使用状态机的思想来处理GPS输出的串口数据流,相对于定时从串口环形bufer取数据包然后依次解析有更高的实时性并且单片机负荷更低. 2. GPS数据协议简介 常用的GPS模块大多采用NMEA-0183 协议,目前业已成了GPS导航设备统一的RTCM(Radio Technical C

如何采集移动App的数据?

原文作者:西安鲲之鹏 原文链接:http://www.site-digger.com/html/articles/20121221/45.html 移动App是越来越火,各种各样的应用如雨后春笋般出现. 下面给大家分享一下如何采集移动App的数据. 移动App实际上还是通过HTTP协议与服务器进行交互的,我们只要分析出接口地址及参数的含义,就能像采集普通网站那样采集App的数据. 1)先将要分析的App安装到手机上.2)通过数据线将手机连接到PC.连接方式选择"Internet传输(通过电脑将电