【mq】从零开始实现 mq-04-启动检测与实现优化
前景回顾
【mq】从零开始实现 mq-02-如何实现生产者调用消费者?
【mq】从零开始实现 mq-03-引入 broker 中间人
上一节我们引入了中间人 broker,让消息的生产者和消费者解耦。
这一节我们对初始化代码进行优化,便于后期拓展维护。

生产者启动优化
启动实现
整体实现调整如下:
@Override
public synchronized void run() {
this.paramCheck();
// 启动服务端
log.info("MQ 生产者开始启动客户端 GROUP: {}, PORT: {}, brokerAddress: {}",
groupName, port, brokerAddress);
try {
//channel future
this.channelFutureList = ChannelFutureUtils.initChannelFutureList(brokerAddress,
initChannelHandler(), check);
// register to broker
this.registerToBroker();
// 标识为可用
enableFlag = true;
log.info("MQ 生产者启动完成");
} catch (Exception e) {
log.error("MQ 生产者启动遇到异常", e);
throw new MqException(ProducerRespCode.RPC_INIT_FAILED);
}
}
看起来是不是比起原来清爽很多呢?
但是复杂性只会转移,不会消失。
答案就是封装到 initChannelFutureList 中去了。
initChannelFutureList
因为这里是生产者、消费者都会用到。
所以我们先放在统一的工具类中,实现本身和以前大同小异。
/**
* 初始化列表
* @param brokerAddress 地址
* @param channelHandler 处理类
* @param check 是否检测可用性
* @return 结果
* @since 0.0.4
*/
public static List<RpcChannelFuture> initChannelFutureList(final String brokerAddress,
final ChannelHandler channelHandler,
final boolean check) {
List<RpcAddress> addressList = InnerAddressUtils.initAddressList(brokerAddress);
List<RpcChannelFuture> list = new ArrayList<>();
for(RpcAddress rpcAddress : addressList) {
try {
final String address = rpcAddress.getAddress();
final int port = rpcAddress.getPort();
EventLoopGroup workerGroup = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
ChannelFuture channelFuture = bootstrap.group(workerGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE, true)
.handler(new ChannelInitializer<Channel>(){
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline()
.addLast(new LoggingHandler(LogLevel.INFO))
.addLast(channelHandler);
}
})
.connect(address, port)
.syncUninterruptibly();
log.info("启动客户端完成,监听 address: {}, port:{}", address, port);
RpcChannelFuture rpcChannelFuture = new RpcChannelFuture();
rpcChannelFuture.setChannelFuture(channelFuture);
rpcChannelFuture.setAddress(address);
rpcChannelFuture.setPort(port);
rpcChannelFuture.setWeight(rpcAddress.getWeight());
list.add(rpcChannelFuture);
} catch (Exception exception) {
log.error("注册到 broker 服务端异常", exception);
if(check) {
throw new MqException(MqCommonRespCode.REGISTER_TO_BROKER_FAILED);
}
}
}
if(check
&& CollectionUtil.isEmpty(list)) {
log.error("check=true 且可用列表为空,启动失败。");
throw new MqException(MqCommonRespCode.REGISTER_TO_BROKER_FAILED);
}
return list;
}
这里的 check 为了避免 2 种情况:
(1)某一个 broker 不可用
(2)没有可用的 broker 信息。
消费者启动优化
消费者连接 broker 和生产者是类似的。
这里只是放一下实现,不做更多的赘述。
@Override
public void run() {
// 启动服务端
log.info("MQ 消费者开始启动服务端 groupName: {}, brokerAddress: {}",
groupName, brokerAddress);
//1. 参数校验
this.paramCheck();
try {
//channel future
this.channelFutureList = ChannelFutureUtils.initChannelFutureList(brokerAddress,
initChannelHandler(),
check);
// register to broker
this.registerToBroker();
// 标识为可用
enableFlag = true;
log.info("MQ 消费者启动完成");
} catch (Exception e) {
log.error("MQ 消费者启动异常", e);
throw new MqException(ConsumerRespCode.RPC_INIT_FAILED);
}
}
小结
这一小节的内容特别简单,对初始化部分做了优化,便于后期维护拓展。
希望本文对你有所帮助,如果喜欢,欢迎点赞收藏转发一波。
我是老马,期待与你的下次重逢。
开源地址
The message queue in java.(java 简易版本 mq 实现) https://github.com/houbb/mq
拓展阅读
rpc-从零开始实现 rpc https://github.com/houbb/rpc
【mq】从零开始实现 mq-04-启动检测与实现优化的更多相关文章
- ubuntu11.04启动 及虚拟文件系统
虚拟文件系统(VFS)是由Sun microsystems公司在定义网络文件系统(NFS)时创造的.它是一种用于网络环境的分布式文件系统,是允许和操作系统使用不同的文件系统实现的接口.虚拟文件系统(V ...
- Android 性能优化之内存泄漏检测以及内存优化(中)
https://blog.csdn.net/self_study/article/details/66969064 上篇博客我们写到了 Java/Android 内存的分配以及相关 GC 的详细分析, ...
- 理解Tomcat架构、启动流程及其性能优化
PS:but, it's bullshit ! 备注:实话说,从文档上扒拉的,文档地址:在每一个Tomcat安装目录下,会有一个webapps文件夹,里面有一个docs文件夹,点击index.html ...
- website 性能检测 & 前端性能优化
website 性能检测 & 前端性能优化 https://cdn.xgqfrms.xyz/ https://mobile.xgqfrms.xyz/ PageSpeed Insights ht ...
- 四大MQ比较及MQ详解
消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之 一.当今市面上有很多主流的消息中间件,如老牌的Activ ...
- Ubuntu 16.04 启动错误 "a start job is running for hold until boot process finishes up"
老司机也差点翻船... 升级16.04的时候,将默认启动管理器(default display manager)选为gm3(gnome3)了(应该使用默认的lightgm)如果改成gm3,好像是nvi ...
- 【消息队列MQ】各类MQ比较
目录(?)[-] RabbitMQ Redis ZeroMQ ActiveMQ JafkaKafka 目前业界有很多MQ产品,我们作如下对比: RabbitMQ 是使用Erlang编写的一个开源的消息 ...
- U盘制作Ubuntu15.04启动盘失败
先用ubuntu15.04光盘在已有xp的电脑上安装成功 随后在Ubuntu安装labview说glibc没安装 但是ldd --version显示是安装的新版的 后来怀疑是86_64的原因 ...
- Ubuntu 18.04 启动root账号并授权远程登录
Ubuntu 18.04 刚刚上市2个月,下载安装,尝尝鲜~ 安装界面看上去舒服许多, 安装的速度也较之前17.04 和16.04 都快了许多.抱歉,未截图. Ubuntu 安装完成后默认不启动roo ...
随机推荐
- ConcurrentHashMap 的并发度是什么 ?
ConcurrentHashMap 的并发度就是 segment 的大小,默认为 16,这意味着最多同时可以有 16 条线程操作 ConcurrentHashMap,这也是ConcurrentHash ...
- Java如何声明变量?JS如何声明变量?
Java采用强类型变量检查,像C语言一样.所有变量在编译之前必须声明,而且不能使用没有赋值的变量.例如:int x;x=1234;char y='F';其中X=1234说明是一个整数,Y='F'说明是 ...
- Mock 或 Stub 有什么区别?
存根 一个有助于运行测试的虚拟对象. 在某些可以硬编码的条件下提供固定行为. 永远不会测试存根的任何其他行为. 例如,对于空堆栈,您可以创建一个只为 empty()方法返回 true 的存根.因此, ...
- 14_Nonlinear Basic Feedback Stabilization_非线性系统稳定性设计
非线性系统线性化的方式:泰勒展开近似线性化(2_线性化_泰勒级数_泰勒公式_Linearization).反馈线性化,本文使用的是反馈线性化 从图中可知道输入u非常大达到了900多,所以直接使用u消去 ...
- jquery+html5实现单张图片上传预览
js: if (window.File && window.FileReader && window.FileList && window.Blob){ ...
- H5: 表单验证失败的提示语
前言 前端的童鞋在写页面时, 都不可避免的总会踩到表单验证这个坑. 这时候, 我们就要跪了, 因为要写一堆js来检查. 但是自从H5出现后, 很多常见的表达验证, 它都已经帮我们实现了, 让我 ...
- h5页面跳转小程序
2020年以前, 只能通过 web-view内嵌h5跳转小程序,现在 可以直接跳了!!!!!! 官方文档:https://developers.weixin.qq.com/doc/offiacco ...
- 将PHPMailer整合到ThinkPHP 3.2 中实现SMTP发送邮件
本内容转载出处:http://my.oschina.net/BearCatYN/blog/299192 并对以下内容做了一处说明. ThinkPHP没有邮件发送的功能,于是,我就想了想,就将PHPMa ...
- IP和静态路由技术概述
1. IP地址的构成 IP地址:32比特的二进制数字,通常采用点分十进制方式表示. IP地址由两部分组成. 网络号码字段(Net-id)用于区分不同的网络.网络号码字段的前几位成为类别字段(又称为类别 ...
- 使用Socket实现HttpServer(三)
使用Socket实现HttpServer(三) 这一章继续对我们的服务器进行优化,引入 NIO package com.fengsir.network.step4; import java.io.IO ...