技术笔记:Mina框架(实战详解)

简介: 技术笔记:Mina框架(实战详解)

Apache Mina Server 是一个网络通信应用框架,为开发高性能和高可用性的网络应用程序提供了非常便利的框架。


特点:异步的NIO框架,将UDP当成"面向连接"的协议


一、组件管理


Mina的底层依赖的主要是Java NIO库,上层提供的是基于事件的异步接口


(1)IoService(最底层【起点】)


作用:隐藏底层IO的细节,对上提供统一的基于事件的异步IO接口


IOSocketAcceptor和IOSocketChannel,分别对应TCP协议下的服务端和客户端的IOService,low-level IO经过IOService层后变成IO Event


(2)IoProcessor


作用:负责检查是否有数据在通道上读写


IoProcessor 负责调用注册在IoService 上的过滤器,并在过滤器链之后调用IoHandler


(3)IoFilter(拦截器【关键】)


作用:日志输出、黑名单过滤、数据的编码(write 方向)与解码(read 方向)等功能


(4)IoHandler(业务逻辑处理【终点】)


作用:接收、发送数据


每个IoService都需要指定一个IoHandler


(5)IoSession


作用:是对底层连接(服务器与客户端的特定连接,该连接由服务器地址、端口以及客户端地址、端口来决定)的封装


二、服务端流程:


1、通过SocketAcceptor 同客户端建立连接;


2、连接建立之后 I/O的读写交给了I/O Processor线程,I/O Processor是多线程的;


3、通过I/O Processor 读取的数据经过IoFilterChain里所有配置的IoFilter,IoFilter进行消息的过滤,格式的转换,在这个层面可以制定一些自定义的协议;


4、最后IoFilter将数据交给 Handler 进行业务处理,完成了整个读取的过程;


写入过程也是类似,只是刚好倒过来,通过IoSession.write 写出数据,然后Handler进行写入的业务处理,处理完成后交给IoFilterChain,进行消息过滤和协议的转换,最后通过 I/O Processor 将数据写出到 socket 通道


三、服务端代码实现


1、编写IoService(主要功能:设置过滤器,设置handler,绑定端口)


public class MinaServer {


private static Logger logger = Logger.getLogger(MinaServer.class);


public static void main(String【】 args) {


Configuration config = Configuration.getInstance();


try {


config.readConfiguration();


config.initDataSource();


config.initServiceDef();


// 启动FTP读文件,PE积分后台执行


//此处为内部逻辑,通过FTP读取文件,跳过


} catch (Exception e1) {


e1.printStackTrace();


System.exit(1);


}


try {


config.initInterfaceConfig();


// 启动接口调用互斥map维护线程


InterfaceBusThread interfaceBusThread = new InterfaceBusThread();


interfaceBusThread.start();


} catch (Exception e) {


logger.info("InterfaceBus error!", e);


}


NioSocketAcceptor acceptor = null; // 创建连接


try {


// 创建一个非阻塞的server端的Socket


acceptor = new NioSocketAcceptor(Runtime.getRuntime()


.availableProcessors() + 1);// ioprocesser线程数,一般为cpu数量+1


// 建立工作线程池


Executor threadPool = Executors.newFixedThreadPool(Constant.threadCount);// 设置20个handler线程


// 解决在LINUX服务器上kill掉了,但是端口仍然被占用,要过一段时间才能释放


acceptor.setReuseAddress(true);


// 添加消息过滤器


acceptor.getFilterChain().addLast("codec",


new ProtocolCodecFilter(new XMLObjectCodecFactory()));


//


// 设置服务器能够接收的最大连接数


acceptor.setBacklog(Constant.maxSocketConn);


acceptor.getFilterChain().addLast("executor",


new ExecutorFilter(threadPool));


// 设置读取数据的缓冲区大小


acceptor.getSessionConfig().setReadBufferSize(2048);


// 读写通道10秒内无操作进入空闲状态


acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);


// 绑定逻辑处理器


acceptor.setHandler(new MinaServerHandler()); // 添加业务处理


// 绑定端口


acceptor.bind(new InetSocketAddress(Constant.minaServerPort));


logger.info("server start success... port:"


+ Constant.minaServerPort);


} catch (Exception e) {


logger.error("server start error....", e);


e.printStackTrace();


System.exit(1);


}


}


}


2、编写过滤器(即上面代码的添加消息过滤器,这里使用了Mina自带的换行符编解码器工厂,注意:要在acceptor.bind()方法之前执行)


3、编写IoHandler


public class MinaServerHandler extends IoHandlerAdapter {


private final static Logger log = LoggerFactory.getLogger(TCPServerHandler.class);


@Override


public void messageReceived(IoSession session, Object message) throws Exception {


//业务代码在这里编写处理


String str = message.toString();


System.out.println("The message received is 【" + str + "】");


if (str.endsWith("quit")) {


session.close(true);


return;


}


}


@Override


public void sessionCreated(IoSession session) throws Exception {


//代码效果参考:http://hnjlyzjd.com/xl/wz_24761.html

System.out.println("server session created");

super.sessionCreated(session);


}


@Override


public void sessionOpened(IoSession session) throws Exception {


System.out.println("server session Opened");


super.sessionOpened(session);


}


@Override


public void sessionClosed(IoSession session) throws Exception {


System.out.println("server session Closed");


super.sessionClosed(session);


}


}


4、将IoHandler 注册到IoService(即上面代码的绑定逻辑处理器,注意:要在acceptor.bind()方法之前执行)


5、运行MinaServer中的main 方法,可以看到控制台一直处于阻塞状态,等待客户端连接


四、Maven的pom.xml配置


org.apache.mina


//代码效果参考:http://hnjlyzjd.com/xl/wz_24759.html

mina-core

2.0.7


org.apache.mina


mina-integration-spring


1.1.7


五、测试类(模拟客户端请求)


public class AutoTest {


private final static String IP = "localhost";


private final static int PORT = 9002;


public static void main(String【】 args) {


String msg = "testEquityInsertRevequityinsertrev


13632599010120130620";


System.out.println("testEquityInsertRev request msg:"+msg);


System.out.println("testEquityInsertRev response msg:"+testApi(msg));


}


博客园:


Copyright ?2018 不是植物


【转载文章务必保留出处和署名,谢谢!】

相关文章
|
7月前
|
XML Java 数据库连接
谈谈Java反射:从入门到实践,再到原理
谈谈Java反射:从入门到实践,再到原理
136 0
|
缓存 Java
认真阅读完这篇文章熟练掌握阿里巴巴规范创建Java线程池
认真阅读完这篇文章熟练掌握阿里巴巴规范创建Java线程池
821 0
|
4月前
|
Java 应用服务中间件 Linux
(九)Java网络编程无冕之王-这回把大名鼎鼎的Netty框架一网打尽!
现如今的开发环境中,分布式/微服务架构大行其道,而分布式/微服务的根基在于网络编程,而Netty恰恰是Java网络编程领域的无冕之王。Netty这个框架相信大家定然听说过,其在Java网络编程中的地位,好比JavaEE中的Spring。
176 3
|
6月前
|
XML 缓存 Java
大厂面试攻略:Spring框架核心要点精讲
Java SPI (Service Provider Interface) 是一种服务发现机制,允许在运行时动态加载和发现服务提供者。在数据库驱动加载中,SPI使得数据库驱动能够自动识别和注册,而无需显式加载。 Spring 是一个广泛应用的轻量级框架,核心功能包括依赖注入(DI)和面向切面编程(AOP)。不使用Spring时,开发人员需要手动管理对象的创建和依赖关系,使用Servlet等基础组件完成Web开发,以及手动处理JDBC操作。Spring通过管理Bean的生命周期和依赖关系,简化了企业级应用的开发,降低了代码的侵入性。
87 1
大厂面试攻略:Spring框架核心要点精讲
|
7月前
|
程序员 Python
类的设计奥秘:从代码到架构的科普全解
类的设计奥秘:从代码到架构的科普全解
99 2
|
7月前
|
存储 前端开发 搜索推荐
【数据结构入门精讲 | 第六篇】队列知识点及考研408、企业面试练习
【数据结构入门精讲 | 第六篇】队列知识点及考研408、企业面试练习
264 0
|
负载均衡 网络协议 Dubbo
卷起来了!手把手带你写一个中高级程序员必会的分布式RPC框架
什么是RPC? 远程服务调用 官方:一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的思想 通俗一点:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样。 市面上常见的rpc框架:dobbo,springCloud,gRPC...
直击灵魂!美团大牛手撸并发原理笔记,由浅入深剖析JDK源码
并发编程这四个字想必大家最近都在网上看到过有很多的帖子在讨论。我们都知道并发编程可选择的方式有多进程、多线程和多协程。在Java中,并发就是多线程模式。而多线程编程也一直是一个被广泛而深入讨论的领域。如果遇到复杂的多线程编程场景,大多数情况下我们就需要站在巨人的肩膀上利用并发编程框架——JDK Concurrent包来解决相关线程问题。
|
存储 缓存 前端开发
Web性能优化_知识点精讲
延迟和宽带 WebWorker 关键渲染路径 React 应用中的优化处理 利用React-Profiler提升应用性能 从 URL 输入到页面加载整过程分析 SPA 提速 SPA: SEO
175 0
Web性能优化_知识点精讲
面试官:小伙子我们先来唠唠并发编程的几大核心知识点
并发编程算是Java的一个难点,经常做业务相关的程序员基本上用不到juc的包,但是这些知识点十分重要,所以不管在哪里,时刻保持学习真的很重要。