前景回顾

【mq】从零开始实现 mq-01-生产者、消费者启动

【mq】从零开始实现 mq-02-如何实现生产者调用消费者?

【mq】从零开始实现 mq-03-引入 broker 中间人

【mq】从零开始实现 mq-04-启动检测与实现优化

上一节我们引入了中间人 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-启动检测与实现优化的更多相关文章

  1. ubuntu11.04启动 及虚拟文件系统

    虚拟文件系统(VFS)是由Sun microsystems公司在定义网络文件系统(NFS)时创造的.它是一种用于网络环境的分布式文件系统,是允许和操作系统使用不同的文件系统实现的接口.虚拟文件系统(V ...

  2. Android 性能优化之内存泄漏检测以及内存优化(中)

    https://blog.csdn.net/self_study/article/details/66969064 上篇博客我们写到了 Java/Android 内存的分配以及相关 GC 的详细分析, ...

  3. 理解Tomcat架构、启动流程及其性能优化

    PS:but, it's bullshit ! 备注:实话说,从文档上扒拉的,文档地址:在每一个Tomcat安装目录下,会有一个webapps文件夹,里面有一个docs文件夹,点击index.html ...

  4. website 性能检测 & 前端性能优化

    website 性能检测 & 前端性能优化 https://cdn.xgqfrms.xyz/ https://mobile.xgqfrms.xyz/ PageSpeed Insights ht ...

  5. 四大MQ比较及MQ详解

    消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之 一.当今市面上有很多主流的消息中间件,如老牌的Activ ...

  6. 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 ...

  7. 【消息队列MQ】各类MQ比较

    目录(?)[-] RabbitMQ Redis ZeroMQ ActiveMQ JafkaKafka 目前业界有很多MQ产品,我们作如下对比: RabbitMQ 是使用Erlang编写的一个开源的消息 ...

  8. U盘制作Ubuntu15.04启动盘失败

    先用ubuntu15.04光盘在已有xp的电脑上安装成功​ 随后在Ubuntu安装labview说glibc没安装​ 但是ldd --version显示是安装的新版的​ 后来怀疑是86_64的原因​ ...

  9. Ubuntu 18.04 启动root账号并授权远程登录

    Ubuntu 18.04 刚刚上市2个月,下载安装,尝尝鲜~ 安装界面看上去舒服许多, 安装的速度也较之前17.04 和16.04 都快了许多.抱歉,未截图. Ubuntu 安装完成后默认不启动roo ...

随机推荐

  1. 使用Spring框架的好处是什么?

    轻量:Spring 是轻量的,基本的版本大约2MB. 控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们. 面向切面的编程(AOP):Spring支持 ...

  2. 启动Tomcat,Idea控制台输出乱码 淇℃伅

      解决:修改 tomcat 下的conf目录下 logging.properties这个文件ava.util.logging.ConsoleHandler.encoding修改为 为 GBK 就好了 ...

  3. @Autowired 注解有什么用?

    @Autowired 可以更准确地控制应该在何处以及如何进行自动装配.此注解用于在 setter 方法,构造函数,具有任意名称或多个参数的属性或方法上自动装配bean.默认情况下,它是类型驱动的注入. ...

  4. python 保存图片被截断

    运行如下代码发现横坐标属性值被截断 plt.savefig('D:\\project\\python\\zhifangtu\\a.png') plt.show() plt.savefig('D:\\p ...

  5. python udp socket通信

    前段时间学习了一下c++的socket通信,但发现那玩意儿比较复杂还是转向python了,下面就是一个简单的udpsocket通信程序,欢迎大佬前来指正 udp聊天 import socket # 创 ...

  6. Unsafe Rust 能做什么

    在不安全的 Rust 中唯一不同的是,你可以: 对原始指针进行解引用 调用"不安全"的函数(包括 C 函数.编译器的内建指令和原始分配器. 实现"不安全"的特性 ...

  7. 创建TypeScript代码模板(NVS+Yarn+ESLint+Prettier+Husky)

    创建TypeScript代码模板(NVS+Yarn+ESLint+Prettier+Husky) Cui, Richard Chikun 本文笔者将带你在Github代码仓库创建TypeScript代 ...

  8. HTML中meta标签详解;property=og标签详解

    meta是用来在HTML文档中模拟HTTP协议的响应头报文.META标签是HTML语言HEAD区的一个辅助性标签,它位于HTML文档头部的<HEAD>标记和<TITLE>标记之 ...

  9. 前端调试利器 - Charles

    Docs 开发之 Charles 配置指南 1.下载与安装 charles-proxy-4.1.4 .dmg56.12 MB已存到云盘下载 2.激活 使用公司正版license 激活 安装证书 点击证 ...

  10. python pymysql连接数据库并创建表

    之前看菜鸟教程 #!/usr/bin/python3 import pymysql # 打开数据库连接 db = pymysql.connect("localhost"," ...