在企业中,分布式的消息队列需要实现的问题:

  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)的实现的更多相关文章

  1. JDK API从下载到使用

    经常有人问我一些java常用类的使用方法,还有一些问某个常用类是干啥的.这些问题都是不会查询jdk api,对常用类的方法不熟悉等情况.于是,经过再三思考决定编写jdk api查询使用手册. ☆准备工 ...

  2. 所谓的规范以及JDK api文档的重要性

    所谓的规范,就是在jee api 文档里对应的接口. 可以从jdk文档和jee文档的目录结构,接口中获取对整个编程范围的把握

  3. JMS 之 Active MQ的安全机制

    一.认证 认证(Authentication):验证某个实体或者用户是否有权限访问受保护资源. MQ提供两种插件用于权限认证:(一).Simple authentication plug-in:直接把 ...

  4. Linux 下编译自己的 OpenJDK7 包括JVM和JDK API

    1.首先去 这里 http://download.java.net/openjdk/jdk7/ 下载OpenJDK7的源码zip包 2. 简要介绍下OpenJDK7中的目录 hotspot: 放有Op ...

  5. 学会使用JDK API

    api是字典,知识过了一遍之后,剩下的就是实践+百度+api了

  6. 为Eclipse/MyEclipse添加JDK API Document帮助文档

    1.下载 Java SE Development Kit 8 Documentation . 2.启动Eclipse,Window-Preference-Java-Installed JREs: 3. ...

  7. JMS 之 Active MQ 消息存储

    一.消息的存储方式 ActiveMQ支持JMS规范中的持久化消息与非持久化消息 持久化消息通常用于不管是否消费者在线,它们都会保证消息会被消费者消费.当消息被确认消费后,会从存储中删除 非持久化消息通 ...

  8. JMS 之 Active MQ 启动嵌入式Broke

    一.如何启动active MQ 服务 (一).使用命令启动 /bin 目录下 ./activemq start 默认使用conf/activemq.xml 配置文件 b.[root@localhost ...

  9. JMS 之 Active MQ 的spring整合

    一.与spring整合实现ptp的同步接收消息 pom.xml: <!-- https://mvnrepository.com/artifact/org.springframework/spri ...

随机推荐

  1. maven 创建web项目出错

    错误的信息: .m2/repository/org/apache/maven/archetypes/maven-archetype-webapp/maven-metadata-central.xml ...

  2. POJ 1201 &amp; HDU1384 &amp; ZOJ 1508 Intervals(差分约束+spfa 求最长路径)

    题目链接: POJ:http://poj.org/problem?id=1201 HDU:http://acm.hdu.edu.cn/showproblem.php? pid=1384 ZOJ:htt ...

  3. MyEclipse改动内存大小

    方式一网上说的(没有測试过): 找到MyEclipse的安装文件夹,一般假设不改动的话默觉得C:\MyEclipse10.1\Genuitec\MyEclipse 10.1有一个myeclipse.i ...

  4. c# 无法加载xxx.dll 找不到指定的模块(如何指定文件夹)

    如果直接放在项目运行目录,例如bin/debug可以直接加载,但是这样比较乱. 如果在放debug里面的一个文件夹里面,有可能会报错“无法加载xxx.dll 找不到指定的模块”. 如果路径写成这样就会 ...

  5. [yueqian_scut]Android多点触控技术和应用框架

    Android多点触控技术跟Linux输入子系统紧密相关.本文将从应用的角度说明Android多点触控技术的接口和应用. 一.多点触控场景分析 网络上有关Android多点触控技术的文章多见于两点拉伸 ...

  6. h5-注册

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWYAAAIpCAIAAAAeogVlAAAgAElEQVR4nOy9W1gb6Z3/OTd7s9d7t8 ...

  7. 循环神经网络(RNN, Recurrent Neural Networks)介绍

    原文地址: http://blog.csdn.net/heyongluoyao8/article/details/48636251# 循环神经网络(RNN, Recurrent Neural Netw ...

  8. HTML文档 html,html5,css,css3

    HTML 各种标签及简单应用: http://www.w3school.com.cn 1 <p><p> 2 <br/> 3 <hr/>横线 4 < ...

  9. ASP.NET中各种缓存技术的特点及使用场景

    对于一些不经常改变却经常被request的数据,我们喜欢将它们缓存在内存.这样用户请求时先到缓存中去取,如果缓存中没有,再去数据库拿,提高响应速度.缓存一般实现在BLL,这样可以与DAL分离,更换数据 ...

  10. 关于在bootstrap的tab栏中渲染echats图表,切换tab时echats不显示问题

    在开发过程中遇到这样个问题: 利用bootstrap中的tab栏,每当点击tab栏的导航时,echats仅仅只渲染第一个tab的内容,切换tab时,echats图表不显示. 其html代码为: < ...