线程模型

SmartFoxServer 2x在多线程环境中运行所有扩展。在扩展功能上有两个独立的线程池:扩展控制器和事件管理器。前一个实体负责处理客户端请求,而后负责调度服务器事件,如用户登录、用户连接断开等。由于多个线程可以在Extension代码上同时运行,因此我们需要确保正确处理对共享状态的访问。标准的JDK的并发集合和锁定功能提供了强大的工具,多数情况下这应该很容易解决。

下图展示了扩展功能的基本线程结构:

网络消息发送到服务器,服务器又将请求派发到内部API(为了简单起见而没有在图中显示)或扩展管理器。此外,服务器事件也会被创建并派发到扩展管理器。

SFS2X API大部分时间都在处理并发:主SFSAPI类提供的所有调用都是线程安全的,包括游戏API和好友列表 API。但是有一些例外:例如,SFSObject和SFSArray不是线程安全的。由于这些对象主要用于数据传输,所以它们通常不被多个线程所抵触。在任何情况下,javadoc会指定哪个对象需要特别注意线程安全性。

调整线程池:

有些情况下,我们可能需要重新调整一个或两个线程池的大小,当我们拥有一个强大的多核CPU的时候;又或者当扩展代码运行缓慢,如HTTP调用或大量的数据库访问。

Extension控制器线程池可以在服务器配置器的Admin工具里调整大小。服务器事件在Admin工具中没有公开,可以从代码中调整大小,通常在扩展的init()方法中,例如:

1
2
3
4
5
6
@Override
public void init()
{
    // Resize to 5 threads
    SmartFoxServer.getInstance().getEventManager().setThreadPoolSize(5);
}

注意事项:

  在处理许多可能长时间持有线程(例如数据库查询、后端HTTP调用)的并发客户端请求时,你需要微调扩展线程的数量。

  在处理可能长时间持有线程的服务器事件(例如调用数据库的自定义登录)时,你需要微调EventManager管理器线程的数量。

没有具体的调整线程数目的设置规则,但是我们建议用小增量(例如从2个线程到5个线程,然后8个等等)进行实验。线程对于JVM来说是一种昂贵的资源,必须谨慎地使用。通过一个小测试和JVM监控工具(例如JConsole,VisualVM),您将能够找到合适的设置。