为什么要用消息

一、消息的作用

异步、解耦、流量削峰、日志收集、事务最终一致性

1.1 异步

1.2 解耦

只关心通知,不关心处理

1.3 流量削峰

将短时间高并发的请求持久化,然后逐步处理,从而削平高峰期的并发流量

1.4 日志收集

利用消息队列产品在接收和持久化消息方面的高性能,引入快速接收日志消息,避免写入日志时的某些故障导致业务系统访问阻塞、请求延迟等

1.5 事务最终一致性

分布式事务的规范———XA。

XA定义了全局事务管理器局部资源管理器之间的接口。XA接口是双向的系统接口,在事务管理器及一个或多个资源管理器之间形成通信桥梁。XA引入的事务管理器充全局事务中的协调者的角色。事务管理器控制着全局事务,管理事务生命周期,并协调资源,资源管理器负责控制和管理实际资源

二、消息队列的功能特点

一个典型意义上的消息队列,至少需要包含消息的发送,接收,暂存功能

除了上述功能,实际消息队列还要能处理消息堆积、消息持久化、可靠投递、消息重复、严格有序、集群等问题

三、设计一个简单的消息队列

package com.wisely.spring_boot_starter_hello;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * 消息处理中心类
 * @author Administrator
 *
 */
public class Broker {
	//队列存储消息的最大数量
	private final static int MAX_SIZE = 3;
	
	//保存消息数据的容器
	private static ArrayBlockingQueue<String> messageQueue = new ArrayBlockingQueue<String>(MAX_SIZE);
	
	//生产消息
	public static void produce(String msg){
		if(messageQueue.offer(msg)){//offer(E e) 方法是用来插入指定的元素到此优先级队列。
			System.out.println("成功向消息处理中心投递消息:"+msg+",当前缓存的消息数量是:"+messageQueue.size());
		}else{
			System.out.println("消息处理中心内暂存的消息达到最大负荷,不能继续放入消息!");
		}
		System.out.println("=================");
	}
	
	//消费消息
	public static String consume() {
		String msg = messageQueue.poll();//返回队列中的首个元素
		if(msg != null){
			//消费条件满足情况,从消费容器中取出一条消息
			System.out.println("已经消费消息:"+msg+",当前暂存的消息数量是:"+messageQueue.size());
		}else{
			System.out.println("消息处理中心内没有消息可供消费");
		}
		System.out.println("=================");
		return msg;
	}
	
}
package com.wisely.spring_boot_starter_hello;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import javafx.scene.layout.Border;

public class BrokerServer implements Runnable {

	public static int SERVICE_PORT = 9999;
	
	private final Socket socket ;
	
	public BrokerServer(Socket socket){
		this.socket = socket;
	}
	
	@Override
	public void run() {
			BufferedReader in;
			try {
				in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				PrintWriter out = new PrintWriter(socket.getOutputStream());
				while(true){
					String str = in.readLine();
					if(str == null){
						continue;
					}
					
					System.out.println("接收到原始数据:"+str);
					
					if(str.equals("CONSUME")){//要消费一条消息
						//从消息队列中消费一条数据
						String message = Broker.consume();
						out.println(message);
						out.flush();
					}else{
						//其他情况都表示生产消息放到消息队列中
						Broker.produce(str);
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
	}
	
	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(SERVICE_PORT);
		while(true){
			BrokerServer brokerServer = new BrokerServer(server.accept());
			new Thread(brokerServer).start();
		}
	}
}
package com.wisely.spring_boot_starter_hello;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 客户端访问
 * @author Administrator
 *
 */
public class MqClient {
	
	//生产消息
	public static void produce(String message) throws Exception{
		Socket socket = new Socket(InetAddress.getLocalHost(),BrokerServer.SERVICE_PORT);
		PrintWriter out = new PrintWriter(socket.getOutputStream());
		out.println(message);
		out.flush();
	}
	
	//消费消息
	public static String consume() throws Exception{
		Socket socket = new Socket(InetAddress.getLocalHost(),BrokerServer.SERVICE_PORT);
		BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		PrintWriter out = new PrintWriter(socket.getOutputStream());
		//先向消息队列发送CONSUME表示消费
		out.println("CONSUME");
		out.flush();
		//再从消息队列获取一条消息
		String message = in.readLine();
		return message;
	}
}
package com.wisely.spring_boot_starter_hello;

public class ProduceClient {
	public static void main(String[] args) throws Exception {
		MqClient client = new MqClient();
		client.produce("hello world");
	}
}
package com.wisely.spring_boot_starter_hello;

public class ConsumeClient {
	public static void main(String[] args) throws Exception {
		MqClient client = new MqClient();
		String message = client.consume();
		System.out.println("获取的消息为:"+message);
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鹏哥哥啊Aaaa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值