Skip to content

ioGame 网络编程框架 17.1.45 同进程亲和性

Compare
Choose a tag to compare
@iohao iohao released this 07 Jul 03:35
· 351 commits to main since this release

主要更新

[#159] 同进程同时支持多种连接方式方式的技巧

public class MyApplication {
    ... ... 省略部分代码
    static int externalCorePort = 10100;

    public static void main(String[] args) {
        // 游戏对外服列表
        List<ExternalServer> externalServerList = listExternalServer();
        new NettyRunOne()
                .setExternalServerList(externalServerList)
                .startup();
    }

    static List<ExternalServer> listExternalServer() {
        return List.of(
                // 连接方式;WEBSOCKET
                createExternalServer(ExternalJoinEnum.WEBSOCKET)
                // 连接方式;TCP
                , createExternalServer(ExternalJoinEnum.TCP)
                // 连接方式;UDP
                , createExternalServer(ExternalJoinEnum.UDP)
        );
    }

    static ExternalServer createExternalServer(ExternalJoinEnum join) {
        int port = externalCorePort;
        port = join.cocPort(port);
        DefaultExternalServerBuilder builder = DefaultExternalServer
                .newBuilder(port)
                // 连接方式
                .externalJoinEnum(join)
                // 与 Broker (游戏网关)的连接地址
                .brokerAddress(new BrokerAddress("127.0.0.1", IoGameGlobalConfig.brokerPort));

        return builder.build();
    }
}

[#157] fix 默认心跳钩子问题

[#122] 同进程亲和性

相关文档:https://www.yuque.com/iohao/game/unp26u

简介

同进程内不同 Netty 实例通信时,是通过内存进行传输的,不需要经过网络传输,数据传输速度极快。也就是说,如果我们将游戏对外服、Broker(游戏网关)、游戏逻辑服部署在同一个进程中(也就是单体应用),那么各服务器之间是在内存中通信的。甚至可以简单的理解为在同一 JVM 中的 a 方法调用了 b 方法,b 方法调用了 c 方法。

同进程亲和性是 ioGame 的特性之一,可以让同一进程内的 Netty 实例拥有相互访问优先权。说人话就是,如果你在同一进程内启动了游戏对外服、Broker(游戏网关)、游戏逻辑服,当有请求需要处理时:

  • 即使你启动了多个 Broker(游戏网关),游戏对外服会优先将请求交给同进程内的 Broker(游戏网关)来处理。
  • 即使你启动了多个相同的游戏逻辑服,Broker(游戏网关)会优先将请求交给同进程的游戏逻辑服来处理。
  • 同样的,游戏逻辑服处理完请求后,会优先将响应交给同进程内的 Broker(游戏网关)。

部署简图

img

图中有这么几个部分,分别是:

  • 玩家,这些玩家可能连接到【1111】或【2222】进程中。
  • 【进程 3333】启动了多个公共的游戏逻辑服。
  • 【进程 1111】启动了游戏对外服、Broker(游戏网关)、游戏逻辑服[A-1、B-1]。
  • 【进程 2222】启动了游戏对外服、Broker(游戏网关)、游戏逻辑服[A-2、B-2]。

TIP:同一进程内,不同 Netty 实例之间的通信,是通过内存进行传输的,不需要经过网络传输,数据传输速度极快。

同进程亲和性指的是,优先访问同进程内的游戏逻辑服,当同进程内没有能处理请求的游戏逻辑服时,才会去其他进程或机器中查找能处理请求的游戏逻辑服;

处理流程

下面用一个场景来说明,游戏逻辑服对应的 action 数据如下:

游戏逻辑服-A 提供了路由:1-1。

游戏逻辑服-C 提供了路由:2-1。

从图中我们知道了,相同类型的【游戏逻辑服-A】启动了两台,分别在【进程 1111】和【进程 2222】中。

现在我们有一个玩家与【进程 1111】的游戏对外服建立了连接,并发起 1-1 请求;请求会被【游戏逻辑服-A-1】来处理,因为【游戏逻辑服-A-1】与玩家所在的【游戏对外服】是同一个进程内的,所以该请求会优先被【游戏逻辑服-A-1】消费;

通过同进程亲和性我们可以看出,虽然启动了两台相同类型的【游戏逻辑服-A】,但玩家的请求只会由【进程 1111】内的【游戏逻辑服-A-1】来消费,因为玩家连接的是【进程 1111】的游戏对外服。

当玩家发起 2-1 请求时,在【进程 1111】内找不到对应的游戏逻辑服来处理这个请求时,框架会将请求交给【游戏逻辑服-C-1】来处理。

使用场景

开发者可以利用同进程亲和性的特点,按照上图中的部署方式,可以让各服务器之间通过进程来做微隔离。此外,又能提供一些游戏逻辑服来处理公共业务;如一些跨服活动、跨服战...等,各种跨服业务

使用该部署方式,可做参考的游戏类型如下:

  • 滚服类型的游戏
  • RTS(Real Time Strategy)实时战略游戏,例如星际争霸、红色警戒。
  • MOBA(Multiplayer Online Battle Arena)多人在线竞技场游戏,例如英雄联盟、DOTA2。
  • ARPG(Action Role-playing Game)动作角色扮演游戏,例如暗黑破坏神、无尽之剑。
  • FPS(First-person Shooter)一人称射击游戏,例如使命召唤、绝地求生。
  • TPS(Third-person Shooter)第三人称射击游戏,例如疾速前进、战地。
  • 待补充...

小结

同进程亲和性是优先访问同进程内的游戏逻辑服,并不是说不能访问其他进程的游戏逻辑服。

特点

  • 同进程亲和性换句话说就是,除了可以优先让同进程内的逻辑服相互访问外,还能访问其他进程的逻辑服。
  • 各逻辑服在同进程内的通信,是通过内存进行传输的,不需要经过网络传输,数据传输速度极快。
  • 合理利用同进程亲和性,可以让各服务器之间通过进程来做微隔离。

最后

ioGame 的架构由三部分组成:1.游戏对外服、2.Broker(游戏网关)、3.游戏逻辑服;三者既可相互独立,又可相互融合。所以,使用 ioGame 几乎可以满足任意的部署方式,可以根据你的需求来适应不同类型的游戏,并且在 ioGame 中做这些工作是简单的。

这里为什么要特意介绍一下三者之间的组合关系呢?目的是想告诉开发者,ioGame 的架构是灵活的。同进程亲和性在以下组合会生效。

为了更简单的说明三者之间的灵活性,现在把三者用字母代替,A.游戏对外服、B.Broker(游戏网关)、C.游戏逻辑服;我们可以得出如下组合

ABC :三者在一个进程中,他们之间使用内存通信;(无需传输

AB + C :【游戏对外服和游戏网关】在一个进程中,他们之间使用内存通信;(传输一次

A + BC :【游戏网关和游戏逻辑服】在一个进程中,他们之间使用内存通信;(传输一次

通过上面的组合,我们可以看出,ioGame 架构是支持类似传统架构那样只做一次跳转,甚至可以做到零跳转,这完全取决于你们的部署方式。

上面三种组合方式,都具备同进程亲和性。同进程亲和性生效的要点只有一个,至少保证有两部分在一个进程内。