jms及active(jdk api)的实现
在企业中,分布式的消息队列需要实现的问题:
1、不同的业务系统分别处理同一个消息(订阅发布),同一个业务系统负载处理同一类消息(队列模式)
2、消息的一致性问题,在互联网公司中一般不要求强一致性,一般要求高性能,所以只需要每次轮询消息日志或消息存储文件,重新发送未一致的问题。(公司中出现过存储文件在集群数据库上的情况,然后由于读写分离,出现了消息重复发送的故障)
3、消息重复发送问题也称为消息的幂等性:解决重复问题可以让消费者在接受到消息后查看日志或文件是否消息已经被修改状态或删除。(公司的故障中,由于读写分离,所以消息状态还没来得及被更改,重复性检测就已经检测完了数据库中文件,导致的重复性问题仍然没被解决)
4、基于消息机制建立服务总线,主业务在接受消息后通知服务总线,服务总线通知旁支服务,而不是旁支服务长时间询问主服务。
一、jms:java message service java消息服务,他不是一种协议,而是一个api,用来服务于消息中间件的api;
二、消息中间件:为了异步可靠的在两个系统结构之间(泛指两个,可以多个)进行消息传输,令项目服务化,解耦性强。例如:我们有个登录系统,如果用户登录成功返回给用户成功提示之前会调用积分增加服务,日志服务等,这样一旦其中一个服务失效可能就会延迟用户获得登陆成功提示的时间,降低用户体验,所以我们可以异步将用户登录信息传输到附加服务中,只返回用户关心的登录信息。
三、常用的消息中间件:ActiveMQ、RabbitMQ、Kafka
四、以下为active利用jdk自带的jms实现,结合spring的请点击:
结构如下:
pom.xml文件:
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.zxc.jms</groupId>
- <artifactId>jms</artifactId>
- <version>1.0-SNAPSHOT</version>
- <dependencies>
- <dependency>
- <groupId>javax.jms</groupId>
- <artifactId>javax.jms-api</artifactId>
- <version>2.0.1</version>
- </dependency>
- <dependency>
- <groupId>org.apache.activemq</groupId>
- <artifactId>activemq-core</artifactId>
- <version>5.7.0</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/log4j/log4j -->
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.17</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.7.2</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>1.7.2</version>
- </dependency>
- </dependencies>
- </project>
log4j.properties:(用的是slf4j日志)如果是idea注意一定要放在resource下,如果用的是eclipse要放在src下
- ### 设置###
- log4j.rootLogger = debug,stdout,D,E
- ### 输出信息到控制抬 ###
- log4j.appender.stdout = org.apache.log4j.ConsoleAppender
- log4j.appender.stdout.Target = System.out
- log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
- log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
- ### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
- log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
- log4j.appender.D.File = D://logs/log.log
- log4j.appender.D.Append = true
- log4j.appender.D.Threshold = DEBUG
- log4j.appender.D.layout = org.apache.log4j.PatternLayout
- log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
- ### 输出ERROR 级别以上的日志到=E://logs/error.log ###
- log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
- log4j.appender.E.File =D://logs/error.log
- log4j.appender.E.Append = true
- log4j.appender.E.Threshold = ERROR
- log4j.appender.E.layout = org.apache.log4j.PatternLayout
- log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
ActiveMQ分为两种类型:
第一种队列模式:点对点模式,一个消息生产者生产的消息存入消息队列中,然后可以有多个消费者的多个连接,这些连接基本平均分配这些消息。
第二种订阅发布模式:一定要订阅者(就是消费者)先要订阅队列,然后发布者发布消息存入队列,订阅者全部接受所有队列消息,不会均分。
第一种的队列模式:
appProducer:
- package com.zxc.jms.queue;
- import javax.jms.*;
- import org.apache.activemq.ActiveMQConnectionFactory;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class appProducer {
- private static String url = "tcp://localhost:61616";
- private static String queuename = "queue-test";
- private static Logger logger = LoggerFactory.getLogger(appProducer.class);
- public static void main(String[] args) throws JMSException {
- ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
- Connection connection = connectionFactory.createConnection();
- connection.start();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Destination destination = session.createQueue(queuename);
- MessageProducer producer = session.createProducer(destination);
- for (int i = 1; i <= 10000; i++) {
- TextMessage message = session.createTextMessage("生产者发出第" + i + "消息");
- producer.send(message);
- logger.info("生产者发出的第{}条数据", i);
- }
- connection.close();
- }
- }
appConsumer:
- package com.zxc.jms.queue;
- import javax.jms.*;
- import org.apache.activemq.ActiveMQConnectionFactory;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class appConsumer {
- private static String url = "tcp://localhost:61616";
- private static String queuename = "queue-test";
- private static Logger logger = LoggerFactory.getLogger(appProducer.class);
- public static void main(String[] args) throws JMSException {
- ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
- Connection connection = connectionFactory.createConnection();
- connection.start();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Destination destination = session.createQueue(queuename);
- MessageConsumer consumer = session.createConsumer(destination);
- consumer.setMessageListener(new MessageListener() {
- @Override
- public void onMessage(Message message) {
- TextMessage textMessage = (TextMessage) message;
- logger.info("接受者接到消息");
- }
- });
- }
- }
第二种:订阅发布模式
appProducer:
- package com.zxc.topic;
- import javax.jms.*;
- import org.apache.activemq.ActiveMQConnectionFactory;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class appProducer {
- private static final String url = "tcp://localhost:61616";
- private static final String topicName = "topic-test";
- private static final Logger logger = LoggerFactory.getLogger(appProducer.class);
- public static void main(String[] args) throws JMSException, InterruptedException {
- ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
- Connection connection = connectionFactory.createConnection();
- connection.start();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Topic topic = session.createTopic(topicName);
- MessageProducer producer = session.createProducer(topic);
- for (int i = 0; i <= 100; i++) {
- TextMessage message = session.createTextMessage("消息"+i);
- producer.send(message);
- logger.info("生产者广播第{}条消息",i);
- Thread.sleep(2000);
- }
- connection.close();
- }
- }
appConsumer:
- package com.zxc.topic;
- import javax.jms.*;
- import org.apache.activemq.ActiveMQConnectionFactory;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class appConsumer {
- private static final String url = "tcp://localhost:61616";
- private static final String topicName = "topic-test";
- private static final Logger logger = LoggerFactory.getLogger(appProducer.class);
- public static void main(String[] args) throws JMSException {
- ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
- Connection connection = connectionFactory.createConnection();
- connection.start();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Topic topic = session.createTopic(topicName);
- MessageConsumer consumer = session.createConsumer(topic);
- consumer.setMessageListener((message -> {
- TextMessage textMessage = (TextMessage) message;
- try {
- logger.info("收到消息:{}",textMessage.getText());
- } catch (JMSException e) {
- e.printStackTrace();
- }
- }));
- }
- }
jms及active(jdk api)的实现的更多相关文章
- JDK API从下载到使用
经常有人问我一些java常用类的使用方法,还有一些问某个常用类是干啥的.这些问题都是不会查询jdk api,对常用类的方法不熟悉等情况.于是,经过再三思考决定编写jdk api查询使用手册. ☆准备工 ...
- 所谓的规范以及JDK api文档的重要性
所谓的规范,就是在jee api 文档里对应的接口. 可以从jdk文档和jee文档的目录结构,接口中获取对整个编程范围的把握
- JMS 之 Active MQ的安全机制
一.认证 认证(Authentication):验证某个实体或者用户是否有权限访问受保护资源. MQ提供两种插件用于权限认证:(一).Simple authentication plug-in:直接把 ...
- Linux 下编译自己的 OpenJDK7 包括JVM和JDK API
1.首先去 这里 http://download.java.net/openjdk/jdk7/ 下载OpenJDK7的源码zip包 2. 简要介绍下OpenJDK7中的目录 hotspot: 放有Op ...
- 学会使用JDK API
api是字典,知识过了一遍之后,剩下的就是实践+百度+api了
- 为Eclipse/MyEclipse添加JDK API Document帮助文档
1.下载 Java SE Development Kit 8 Documentation . 2.启动Eclipse,Window-Preference-Java-Installed JREs: 3. ...
- JMS 之 Active MQ 消息存储
一.消息的存储方式 ActiveMQ支持JMS规范中的持久化消息与非持久化消息 持久化消息通常用于不管是否消费者在线,它们都会保证消息会被消费者消费.当消息被确认消费后,会从存储中删除 非持久化消息通 ...
- JMS 之 Active MQ 启动嵌入式Broke
一.如何启动active MQ 服务 (一).使用命令启动 /bin 目录下 ./activemq start 默认使用conf/activemq.xml 配置文件 b.[root@localhost ...
- JMS 之 Active MQ 的spring整合
一.与spring整合实现ptp的同步接收消息 pom.xml: <!-- https://mvnrepository.com/artifact/org.springframework/spri ...
随机推荐
- 前端 自定义format函数
为字符串创建format方法,用于字符串格式化 {# 前端没有字符串占位符%s的替代方法,以下是自定义字符串替换的方法,以后前端拓展方法都可以使用下面的形式 #} String.prototype. ...
- Leetcode--easy系列2
#14 Longest Common Prefix Write a function to find the longest common prefix string amongst an array ...
- webRequest
chrome.webRequest 描述: 使用 chrome.webRequest API 监控与分析流量,还可以实时地拦截.阻止或修改请求. 可用版本: 从 Chrome 17 开始支持. 权 ...
- Light OJ 1288 Subsets Forming Perfect Squares 高斯消元求矩阵的秩
题目来源:Light OJ 1288 Subsets Forming Perfect Squares 题意:给你n个数 选出一些数 他们的乘积是全然平方数 求有多少种方案 思路:每一个数分解因子 每隔 ...
- BZOJ 2435: [Noi2011]道路修建 dfs搜图
2435: [Noi2011]道路修建 Description 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他 ...
- 使用IDEA 创建 MAVEN 项目
一,项目创建 1.File---New---project 选择maven 勾选Create from archtype,找到并选择org.apache.maven.archtype ...
- SQLSERVER 链接服务器
1. 执行代码 EXEC sp_addlinkedserver @server='XLZFSqlServer', --链接服务器别名 @srvproduct='', @provider='SQLOLE ...
- 多线程与MySQL(十)
1.1 多线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合 ...
- SQL like查询条件中的通配符处理
1. SQL like对时间查询的处理方法 SQL数据表中有savetime(smalldatetime类型)字段,表中有两条记录,savetime值为:2005-3-8 12:12:00和2005- ...
- mac pro 安装 composer 失败
http://getcomposer.org/doc/00-intro.md#using-composer $ brew install josegonzalez/php/composer 出现错误: ...