阿里RocketMq(TCP模式)
针对公司业务逻辑,向阿里云MQ发送指定数据,消费端根据数据来做具体的业务,分两个项目,一个生产端(Producer)、一个消费端(Consumer)
生产端通过定时任务执行sql向阿里云MQ发送数据,消费端消费指定Topic上的数据
1:定时任务列表:

2:生产端表结构:

aliasName:定时任务别名;
cronExpression:定时任务轮询规则;
jobGroup:定时任务分组;
jobName:定时任务名称;
jobTrigger:定时任务触发器;
packageUrl:定时任务扫描具体封装类;
excuteSql:扫描类中执行的获取数据的脚本;
lastPramaryKey:最后一次获取数据时最大的主键;
topic:阿里云MQ的topic;
producerId:生产端的Id;
accessKey、securityKey:账号跟秘钥
dataBaseType:操作数据库类型(公司数据库类型比较多,执行脚本时,需要根据类型来指定具体的Service)

3:Java端核心代码,定时任务扫描如下配置的任务类来向阿里云MQ发送数据
public class SendPrimaryKeyListToMqTask implements Job{
private final Logger logger = LoggerFactory.getLogger(SendPrimaryKeyListToMqTask.class);
public void execute(JobExecutionContext context) throws JobExecutionException{
JobDataMap data = context.getJobDetail().getJobDataMap();
ScheduleJob scheduleJob = (ScheduleJob)data.get("jobParam");
//最后一次获取数据时最大的主键
int lastPramaryKey = scheduleJob.getLastPramaryKey();
//执行sql
String excuteSql = scheduleJob.getExcuteSql();
excuteSql = excuteSql.replace("lastPramaryKey", String.valueOf(lastPramaryKey));
//操作数据库类型(数据库配置)
int dataBaseType = scheduleJob.getDataBaseType();
//从游戏库获取数据
LinkedList<ExcuteResultData> resultData = new LinkedList<ExcuteResultData>();
if( dataBaseType == 1 ){
GameService gameService = (GameService)SpringBeanFactory.getBean(GameService.class);
resultData = gameService.getExcuteResultData(excuteSql);
//从网站库获取数据
}else if( dataBaseType == 2 ){
SiteService siteService = (SiteService)SpringBeanFactory.getBean(SiteService.class);
resultData = siteService.getExcuteResultData(excuteSql);
}
if ( resultData.size() > 0 ){
scheduleJob.setPrimaryKeyList(resultData);
QuartzService quartzService = (QuartzService)SpringBeanFactory.getBean(QuartzService.class);
//将数据集中最大的主键更新
scheduleJob.setLastPramaryKey(resultData.getLast().getPrimaryKey());
quartzService.updateLastPramaryKey(scheduleJob);
String topic = scheduleJob.getTopic();
String producerId = scheduleJob.getProducerId();
String ak = scheduleJob.getAccessKey();
String sk = scheduleJob.getSecurityKey();
//添加日志
ScheduleJobLog scjLog = new ScheduleJobLog();
scjLog.setDataSize(resultData.size());
scjLog.setJobName(scheduleJob.getJobName());
scjLog.setTopic(topic);
int scjLogId = quartzService.addMqScheduleJobLog(scjLog);
//消费端根据此日志主键更新日志状态
scheduleJob.setScjLogId(scjLogId);
Properties properties = new Properties();
properties.put("ProducerId", producerId);
properties.put("AccessKey", ak);
properties.put("SecretKey", sk);
Producer producer = ONSFactory.createProducer(properties);
producer.start();
Message msg = new Message(topic, "PRIMARY_KEY_" + String.valueOf(scjLogId), ObjectsTranscoder.serialize(scheduleJob));
msg.setKey("PRIMARY_KEY_" + String.valueOf(scjLogId));
SendResult sendResult = producer.send(msg);
if ( ( sendResult != null ) && ( sendResult.getMessageId() != null ) ){
scjLog.setMessageId(sendResult.getMessageId());
scjLog.setStatus(2);
quartzService.updateMqScheduleJobLog(scjLog);
}
producer.shutdown();
logger.debug("=====>任务名称:" + scheduleJob.getJobName());
logger.debug("=====>发送条数:" + resultData.size());
logger.debug("=====>发送主键内容:" + resultData.toString());
}
}
}
4:消费端表结构:

5:消费端Java核心代码(通过监听器来做):
import java.util.List;
import java.util.Properties;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Consumer;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.odao.common.utils.ObjectsTranscoder;
import com.odao.entity.ScheduleJob;
import com.odao.entity.ScheduleJobLog;
import com.odao.service.consumer.ConsumerService;
import com.odao.service.message.MessageService; /**
* 阿里云游戏、网站 主键数据集消费监听器
*/
public class ConsumePrimaryKeyFromMqListener implements ServletContextListener { @Override
public void contextInitialized(ServletContextEvent sce) {
WebApplicationContext appctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
MessageService messageService = (MessageService) appctx.getBean(MessageService.class);
List<ScheduleJob> consumeList = messageService.getScheduleJobList();
for(final ScheduleJob sjc : consumeList){ String topic = sjc.getTopic();
String consumerId= sjc.getConsumerId();
String ak = sjc.getAccessKey();
String sk = sjc.getSecurityKey(); Properties properties = new Properties();
properties.put(PropertyKeyConst.ConsumerId,consumerId);
properties.put(PropertyKeyConst.AccessKey,ak);
properties.put(PropertyKeyConst.SecretKey,sk);
//properties.put(PropertyKeyConst.ONSAddr,"http://onsaddr-internal.aliyun.com:8080/rocketmq/nsaddr4client-internal"); Consumer consumer = ONSFactory.createConsumer(properties); consumer.subscribe(topic, "*", new MessageListener() {
@Override
public Action consume(Message message, ConsumeContext context) {
ScheduleJob scheduleJob = (ScheduleJob) ObjectsTranscoder.deserialize(message.getBody());
if( scheduleJob !=null ){
//更新消息状态为3:消费消息成功
ScheduleJobLog scjLog = new ScheduleJobLog();
scjLog.setStatus(3);
scjLog.setMqScheduleJobLogId(scheduleJob.getScjLogId());
messageService.updateMqScheduleJobLog(scjLog);
try {
ConsumerService consumerService = (ConsumerService) Class.forName(sjc.getImplementClass()).newInstance();
boolean isSuccess = consumerService.consume(scheduleJob.getPrimaryKeyList());
if(isSuccess){
//更新消息状态为4:业务逻辑处理成功
scjLog.setStatus(4);
messageService.updateMqScheduleJobLog(scjLog);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return Action.CommitMessage;
}
}); consumer.start();
}
} @Override
public void contextDestroyed(ServletContextEvent sce) { }
}
阿里RocketMq(TCP模式)的更多相关文章
- 【运维技术】CentOS7上从零开始安装阿里RocketMQ版本:release-4.0.1【亲测哈哈】
CentOS7上从零开始安装阿里RocketMQ版本:release-4.0.1[亲测哈哈] 安装git # 更新包 $ yum update # 安装git $ yum install git # ...
- (转)阿里 RocketMQ 安装与简介
原文:阿里 RocketMQ 安装与简介 一.简介 官方简介: l RocketMQ是一款分布式.队列模型的消息中间件,具有以下特点: l 能够保证严格的消息顺序 l 提供丰富的消息拉取模式 l ...
- 阿里RocketMq试用记录+简单的Spring集成
CSDN学院招募微信小程序讲师啦 程序猿全指南,让[移动开发]更简单! [观点]移动原生App开发 PK HTML 5开发 云端应用征文大赛,秀绝招,赢无人机! 阿里RocketMq试用记录+简单的S ...
- keepalived绑定单播地址、非抢占模式及LVS的TCP模式的高可用
背景:keepalived默认是组播地址进行播放,且默认地址是224.0.0.18,如果配置多个keepalived主机,会导致虚拟IP地址存在冲突问题,这种问题怎么解决呢? 解决办法:就是将keep ...
- RabbitMQ,Apache的ActiveMQ,阿里RocketMQ,Kafka,ZeroMQ,MetaMQ,Redis也可实现消息队列,RabbitMQ的应用场景以及基本原理介绍,RabbitMQ基础知识详解,RabbitMQ布曙
消息队列及常见消息队列介绍 2017-10-10 09:35操作系统/客户端/人脸识别 一.消息队列(MQ)概述 消息队列(Message Queue),是分布式系统中重要的组件,其通用的使用场景可以 ...
- Alibaba(阿里) RocketMQ入门实例
摘自:码友18年(www.mayou18.com) what is rocketMQ? RocketMQ作为一款分布式的消息中间件(阿里的说法是不遵循任何规范的,所以不能完全用JMS的那一套东西来看它 ...
- 阿里 RocketMQ 安装与简介
一.简介 官方简介: l RocketMQ是一款分布式.队列模型的消息中间件,具有以下特点: l 能够保证严格的消息顺序 l 提供丰富的消息拉取模式 l 高效的订阅者水平扩展能力 l 实时的 ...
- UDP模式与TCP模式的区别
1.TCP有连接状态,而UDP没有. 2.TCP应用层使用无需考虑包的大小及发送情况,而UDP需要. 3.TCP中IP包大小的决定者是Socket,而UDP为应用层.
- (转)阿里RocketMQ Quick Start
转:http://blog.csdn.net/a19881029/article/details/34446629 RocketMQ单机支持1万以上的持久化队列,前提是足够的内存.硬盘空间,过期数据数 ...
随机推荐
- mpvue——Error: EPERM: operation not permitted
报错 $ npm run build > mpvue@ build D:\wamp\www\webpack\mpvue\my-project > node build/build.js w ...
- Codeforces1065F Up and Down the Tree 【树形DP】
推荐一道联赛练习题. 题目分析: 你考虑进入一个子树就可能上不来了,如果上得来的话就把能上来的全捡完然后走一个上不来的,所以这就是个基本的DP套路. 代码: #include<bits/stdc ...
- CH2401 送礼物(算竞进阶习题)
双向dfs 数据不是很大,但是如果直接暴搜的话2^45肯定过不了的.. 所以想到乱搞!!要让程序跑的更快,肯定要减下搜索树的规模,再加上这道题双搜的暗示比较明显(逃),所以就来乱搞+双搜求解 所以先从 ...
- 【XSY2472】string KMP 期望DP
题目大意 给定一个由且仅由字符'H','T'构成的字符串\(S\). 给定一个最初为空的字符串\(T\) ,每次随机地在\(T\)的末尾添加'H'或者'T'. 问当\(S\)为\(T\)的后缀时, ...
- bzoj 1067: [SCOI2007]降雨量 (离散化+线段树)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1067 思路: 毒瘤题,写的自闭,改了一晚上,注意要理清题目的逻辑 x小于等于y,x,y之间的 ...
- 【CF981D】Bookshelves(贪心,动态规划)
[CF981D]Bookshelves(贪心,动态规划) 题面 洛谷 Codeforces 给定一个长度为\(n\)的数列,把他们划分成\(k\)段,使得每段的和的结构按位与起来最大. 题解 从高位往 ...
- Balanced Sequence HDU - 6299(杭电多校1 B)
题目说要n个字符串串内随意组合以后将这些串放在一起,然后求最长的括号匹配的长度,并不要求是连续的 因为不需要是连续的,所以可以先把已经匹配好的括号加入到答案里面去,先把这些删掉,以为并不影响结果,然后 ...
- centos7/rhel7安装较高版本ruby2.2/2.3/2.4+
环境需求: 在Centos7.3中,通过yum安装ruby的版本是2.0.0,但是如果有些应用需要高版本的ruby环境,比如2.2,2.3,2.4...那就有点麻烦了,譬如:我准备使用redis官方给 ...
- 在MacOS上使用gdb(cgdb)调试Golang程序
如果你在MacOS上使用GDB工具载入Golang程序时无法载入,这篇文章可以解决.本文不具体介绍调试的方法,网上的文章太多了就不赘述了. cgdb使用的是gdb的内核,方法和原理试用本文. 问题分析 ...
- B1018. 锤子剪刀布
大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示: 现给出两人的交锋记录,请统计双方的胜.平.负次数,并且给出双方分别出什么手势的胜算最大. 输入格式: 输入第1行给出正整数N( ...