akka.io的基本用法

2024-06-18 04:08
文章标签 用法 基本 io akka

本文主要是介绍akka.io的基本用法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

akka.io的api已经非常非常简单了, 实在很难挑剔.  如果用它来做单进程的游戏服务器, 基本上分成三个步骤就可以完成了.


1. akka.io的环境初始化, 包括了tcp extension的初始化. 

2. 绑定一个端口, 并将这个端口上的事件交给某个actor处理, 如连接到来事件.

3. 有连接到来时将其指派给某个业务actor处理, 接下来这个业务actor就负责自己身上的所有事件了, 如消息到来事件.

-------------------------------------------------------

1.  环境初始化.

/** 服务器启动. */
public final static boolean init()
{try{AkMgr.sys = ActorSystem.create();TcpExt ext = Tcp.get(AkMgr.sys);ActorRef ref = ext.manager();//ActorRef srv = AkMgr.sys.actorOf(Props.create(Srv.class), Srv.class.getName());InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 20001);ref.tell(TcpMessage.bind(srv, addr, 0x10000, AkMgr.setOpt(), false), srv);return true;} catch (Exception e){Log.error(Log.trace(e));return false;}
}


/** 服务器端口套接字选项. */
private static final List<Inet.SocketOption> setOpt()
{List<Inet.SocketOption> options = new ArrayList<Inet.SocketOption>();options.add(TcpSO.reuseAddress(true));options.add(TcpSO.sendBufferSize(0x400 * 10));options.add(TcpSO.receiveBufferSize(0x400 * 10));return options;
}

tcp的选项似乎有点奇怪, 在bind的时候指定, 然后它们将被应用到所有的连接上去. 换句话说, 是统一指定的. 并且只提供了下面几个选项(版本是2.3.7)

没有看到linger. timeout什么的.  看来akka觉得我们不需要其它的. 事实上通过测试结果来看, 也确实如此. 连接所关联的actor在stop的时候, 

立即就被销毁了. 也没有看到tcp缓冲区残留等待, time_wait状态, 换句话说, 连接上的关闭是暴力的. 如果想延迟关闭, 你可能得单独处理.



2. 监听端口事件处理actor.

上面的Srv就是负责处理监听端口上的事件类了, onReceive函数中重要的事件就是Tcp.Connected了, 它表示了一个连接到来.

public void onReceive(Object msg) throws Exception
{try{if (msg instanceof Tcp.Bound)this.boundEvn((Bound) msg);else if (msg instanceof Tcp.Connected)this.connEvn((Tcp.Connected) msg, getSender());else{Log.error("it`s an unexpected message: %s\n", msg);this.unhandled(msg);}} catch (Exception e){Log.error(Log.trace(e));}
}


3. 当连接到来的时候, 将业务actor Peer注册到连接上就可以了.

/** 连接到来事件. */
private void connEvn(Tcp.Connected msg, ActorRef sender)
{if (Log.isTrace())Log.trace("got a connection from peer: %s\n", msg.remoteAddress());ActorRef peer = AkMgr.actorOf(Props.create(Peer.class, sender, msg.remoteAddress())); /* 构造一个peer. */this.getSender().tell(TcpMessage.register(peer), this.getSelf()); /* 连接上的事件交予peer处理. */
}

下面是Peer类的消息入口,  可能的事件在Tcp.*中都有定义.  包括了报文送达, 连接断开, 和这里没有处理的send过载等事件.

/** 消息入口. */
public void onReceive(Object msg) throws Exception
{if (msg instanceof Tcp.Received)this.datEvn((Tcp.Received) msg);else if (msg instanceof Tcp.ErrorClosed)this.disEvn((Tcp.ErrorClosed) msg);elseLog.error("it`s an unexpected message: %s\n", msg.getClass().getName());
}

这里有一个值得怀疑的地方是, 每个Tcp.Received消息是无法控制的. 相当于只要tcp缓冲区中有数据, akka就会把它拿出来, 以Tcp.Received的形式扔到应用上

来.由应用自己去decode消息流.  因为消息流是无边界的, 那么应用自己需要额外开辟一段内存来去缓存不完整的消息.

因此在注册一个Peer到连接上的时候(TcpMessage.register(peer)), 如果能让应用指定一个缓冲区是不是更好呢?  这样应用层和akka可以共同操作这片区域, 

从而减少来回的copy呢?


4. 关于性能. 

akka.io的性能是非常好的.  在10000个连接, 15000条消息/s, 8Mbytes/s的压力下. 占用了一个i5 4核cpu的120%, 也就是一个cpu多一点点.  gc也比较少,  内存的使用也很稳定.


这篇关于akka.io的基本用法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1071265

相关文章

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

java之Objects.nonNull用法代码解读

《java之Objects.nonNull用法代码解读》:本文主要介绍java之Objects.nonNull用法代码,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录Java之Objects.nonwww.chinasem.cnNull用法代码Objects.nonN

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

JavaScript Array.from及其相关用法详解(示例演示)

《JavaScriptArray.from及其相关用法详解(示例演示)》Array.from方法是ES6引入的一个静态方法,用于从类数组对象或可迭代对象创建一个新的数组实例,本文将详细介绍Array... 目录一、Array.from 方法概述1. 方法介绍2. 示例演示二、结合实际场景的使用1. 初始化二

一文带你了解SpringBoot中启动参数的各种用法

《一文带你了解SpringBoot中启动参数的各种用法》在使用SpringBoot开发应用时,我们通常需要根据不同的环境或特定需求调整启动参数,那么,SpringBoot提供了哪些方式来配置这些启动参... 目录一、启动参数的常见传递方式二、通过命令行参数传递启动参数三、使用 application.pro

SpringBoot整合MybatisPlus的基本应用指南

《SpringBoot整合MybatisPlus的基本应用指南》MyBatis-Plus,简称MP,是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,下面小编就来和大家介绍一下... 目录一、MyBATisPlus简介二、SpringBoot整合MybatisPlus1、创建数据库和

关于@RequestParam的主要用法详解

《关于@RequestParam的主要用法详解》:本文主要介绍关于@RequestParam的主要用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 基本用法2. 默认值3. 可选参数4. 绑定到对象5. 绑定到集合或数组6. 绑定到 Map7. 处理复杂类

SQL中的CASE WHEN用法小结

《SQL中的CASEWHEN用法小结》文章详细介绍了SQL中的CASEWHEN函数及其用法,包括简单CASEWHEN和CASEWHEN条件表达式两种形式,并通过多个实际场景展示了如何使用CASEWH... 目录一、简单CASE WHEN函数:二、CASE WHEN条件表达式函数三、常用场景场景1:不同状态展

Linux find 命令完全指南及核心用法

《Linuxfind命令完全指南及核心用法》find是Linux系统最强大的文件搜索工具,支持嵌套遍历、条件筛选、执行动作,下面给大家介绍Linuxfind命令完全指南,感兴趣的朋友一起看看吧... 目录一、基础搜索模式1. 按文件名搜索(精确/模糊匹配)2. 排除指定目录/文件二、根据文件类型筛选三、时间

Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)

《Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)》:本文主要介绍Java导入、导出excel的相关资料,讲解了使用Java和ApachePOI库将数据导出为Excel文件,包括... 目录前言一、引入Apache POI依赖二、用法&步骤2.1 创建Excel的元素2.3 样式和字体2.