DockerCompose 启动 open-match

news2024/11/26 16:49:38

背景介绍

open-match是Google和unity联合开源的支持实时多人匹配的框架,已有多家游戏厂商在生产环境使用,官网 https://open-match.dev/site/ 。原本我们使用的是UOS上提供的匹配能力,但是UOS目前不支持自建的Dedicated servers 集群,只能上传镜像,UOS会自动完成分配以及创建,灵活性就不是那么高了,按照open-match的官方教程,需要有k8s的环境。但是小公司就是不想要k8s,我就想单机部署,可以使用docker-compose。open-match本身的镜像build 提供了dockerfile文件。把项目clone到本地,然后在 tm中以此使用以下命令构建对用的image

tip:该方案只是启动了 core 部分要求的组件即

搭建步骤

Install with YAML | Open Match

后面的部分,需要自行探索了,现在也在学习中,欢迎交流讨论

先构建一个中间镜像base builder,然后一次构建对应的component即可,需要修改Dockerfile.cmd中的

FROM open-match-base-build as builder

为,目的是指定使用本地的version版本,否则会远程拉取镜像,网络问题会导致不成功,需要开梯子

FROM open-match-base-build:latest as builder
docker build -f .\Dockerfile.base-build -t open-match-base-build . 
docker build --build-arg IMAGE_TITLE=synchronizer -f .\Dockerfile.cmd -t open-match-synchronizer .

接着使用docker-compose.yaml 来控制启动过程,内如如下

version: '3'
services:
  open-match-backend:
    image: open-match-backend:latest
    container_name: open-match-backend
    volumes:
      - ./matchmaker_config_default.yaml:/app/matchmaker_config_default.yaml
      - ./matchmaker_config_override.yaml:/app/matchmaker_config_override.yaml
    ports:
      - "50505:50505"  # gRPC
      - "51505:51505"  # HTTP
    environment:
      API_BACKEND_HOSTNAME: "open-match-backend"
      API_BACKEND_GRPC_PORT: "50505"
      API_BACKEND_HTTP_PORT: "51505"
      REDIS_HOSTNAME: "open-match-redis"
      REDIS_PORT: "6379"
    depends_on:
      - redis

  open-match-frontend:
    image: open-match-frontend:latest
    container_name: open-match-frontend
    ports:
      - "50504:50504"  # gRPC
      - "51504:51504"  # HTTP
    volumes:
      - ./matchmaker_config_default.yaml:/app/matchmaker_config_default.yaml
      - ./matchmaker_config_override.yaml:/app/matchmaker_config_override.yaml
    environment:
      API_FRONTEND_HOSTNAME: "open-match-frontend"
      API_FRONTEND_GRPC_PORT: "50504"
      API_FRONTEND_HTTP_PORT: "51504"
      REDIS_HOSTNAME: "open-match-redis"
      REDIS_PORT: "6379"
    depends_on:
      - redis

  open-match-query:
    image: open-match-query:latest
    container_name: open-match-query
    ports:
      - "50503:50503"  # gRPC
      - "51503:51503"  # HTTP
    environment:
      API_QUERY_HOSTNAME: "open-match-query"
      API_QUERY_GRPC_PORT: "50503"
      API_QUERY_HTTP_PORT: "51503"
      REDIS_HOSTNAME: "open-match-redis"
      REDIS_PORT: "6379"
    volumes:
      - ./matchmaker_config_default.yaml:/app/matchmaker_config_default.yaml
      - ./matchmaker_config_override.yaml:/app/matchmaker_config_override.yaml
    depends_on:
      - redis

  open-match-synchronizer:
    image: open-match-synchronizer:latest
    container_name: open-match-synchronizer
    volumes:
      - ./matchmaker_config_default.yaml:/app/matchmaker_config_default.yaml
      - ./matchmaker_config_override.yaml:/app/matchmaker_config_override.yaml
    ports:
      - "50506:50506"  # gRPC
      - "51506:51506"  # HTTP
    environment:
      API_SYNCHRONIZER_HOSTNAME: "open-match-synchronizer"
      API_SYNCHRONIZER_GRPC_PORT: "50506"
      API_SYNCHRONIZER_HTTP_PORT: "51506"
      REDIS_HOSTNAME: "open-match-redis"
      REDIS_PORT: "6379"
    depends_on:
      - redis

  open-match-swaggerui:
    image: open-match-swaggerui:latest
    container_name: open-match-swaggerui
    ports:
      - "51500:51500"  # HTTP for Swagger UI
    volumes:
      - ./matchmaker_config_default.yaml:/app/matchmaker_config_default.yaml
      - ./matchmaker_config_override.yaml:/app/matchmaker_config_override.yaml
    environment:
      API_SWAGGERUI_HOSTNAME: "open-match-swaggerui"
      API_SWAGGERUI_HTTP_PORT: "51500"
    depends_on:
      - open-match-backend
      - open-match-frontend
      - open-match-query
      - open-match-synchronizer

  redis:
    image: redis:alpine
    container_name: open-match-redis
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data

volumes:
  redis-data:

matchmaker_config_default.yaml 的内容和 matchmaker_config_override.yaml的内容是一致的,目的就是override可以覆盖default中的值(猜的),这部分内容从k8s的yaml文件中copy过来,内容如下
 

logging:
  level: debug
  format: text
  rpc: false
# Open Match applies the exponential backoff strategy for its retryable gRPC calls.
# The settings below are the default backoff configuration used in Open Match.
# See https://github.com/cenkalti/backoff/blob/v3/exponential.go for detailed explanations
backoff:
  # The initial retry interval (in milliseconds)
  initialInterval: 100ms
  # maxInterval caps the maximum time elapsed for a retry interval
  maxInterval: 500ms
  # The next retry interval is multiplied by this multiplier
  multiplier: 1.5
  # Randomize the retry interval
  randFactor: 0.5
  # maxElapsedTime caps the retry time (in milliseconds)
  maxElapsedTime: 3000ms

api:
  backend:
    hostname: "open-match-backend"
    grpcport: "50505"
    httpport: "51505"
  frontend:
    hostname: "open-match-frontend"
    grpcport: "50504"
    httpport: "51504"
  query:
    hostname: "open-match-query"
    grpcport: "50503"
    httpport: "51503"
  synchronizer:
    hostname: "open-match-synchronizer"
    grpcport: "50506"
    httpport: "51506"
  swaggerui:
    hostname: "open-match-swaggerui"
    httpport: "51500"

  # Configurations for api.test and api.scale are used for testing.
  test:
    hostname: "open-match-test"
    grpcport: "50509"
    httpport: "51509"
  scale:
    httpport: "51509"

redis:
  # Open Match's default Redis setups
  hostname: open-match-redis
  # source value: open-match-core.redis.port = 6379
  port: 6379
  usePassword: false
  passwordPath: /redis-password
  pool:
    maxIdle: 200
    maxActive: 0
    idleTimeout: 0
    healthCheckTimeout: 300ms

telemetry:
  reportingPeriod: "1m"
  traceSamplingFraction: "0.01"
  zpages:
    enable: "true"
  prometheus:
    enable: "false"
    endpoint: "/metrics"
    serviceDiscovery: "true"
  stackdriverMetrics:
    enable: "false"
    gcpProjectId: "replace_with_your_project_id"
    prefix: "open_match"

然后就可以启动了

运行demo

如果要运行open-match的 demo-first-match,还要一个组件

evaluator

该组件的目的是对所有的matches进行评估,并返回得分,open-match会保留评分最高的组合,比如我们以 战力相差的相近为评估规则,假定 abc,三个玩家的战力分值分配时 10 20 25,则abc三人同时匹配在1v1的条件选,应当尽可能的选择20 25这个相近的评分,评分组件evaluator这个需要开始自行实行,通过synchronizer进行调用,open-match 提供了一个default实现 即default-evaluator,使用以下命令进行构建即可

docker build --build-arg IMAGE_TITLE=default-evaluator -f .\Dockerfile.cmd -t open-match-default-evaluator .

如果开发环境存在需要平凡需求的情况,直接ide环境启动即可,但是需要在 matchmaker_config_default.yaml中指明 evaluator的位置信息

api:
  evaluator:
    hostname: "open-match-default-evaluator"
    httpport: "5499"
    grpcport: "5498"

接着需要修改几个demo的hostname地址,一个是frontend的hostname,位置在

open-match/examples/demo/components/clients/clients.go:84

//修改前
conn, err := grpc.Dial("open-match-frontend.open-match.svc.cluster.local:50504", grpc.WithInsecure())

//修改后
conn, err := grpc.Dial("localhost:50504", grpc.WithInsecure())

另外一个是 backend的hostname

open-match/examples/demo/components/director/director.go:71

//修改前
conn, err := grpc.Dial("open-match-backend.open-match.svc.cluster.local:50505", grpc.WithInsecure())

//修改后
conn, err := grpc.Dial("localhost:50505", grpc.WithInsecure())

然后还需要部署一个组件mmf,负责判断给定的组合是否符合要求,可以直接启动 cmd/scale-mmf,或者build镜像,一样的需要修改query的hostname,位置信息如下

open-match/examples/scale/mmf/mmf.go:42

//修改前
conn, err := grpc.Dial("open-match-query.open-match.svc.cluster.local:50503", utilTesting.NewGRPCDialOptions(logger)...)

//修改后
conn, err := grpc.Dial("localhost:50503", utilTesting.NewGRPCDialOptions(logger)...)

mmf的服务地址,是由director在fetchMatches指定的,相关的代码位置在

open-match/examples/demo/components/director/director.go:82

不同版本可能会有所变化,当前提及的代码内容来源于open-match的最新master代码,2024年10月9日 

req := &pb.FetchMatchesRequest{
			Config: &pb.FunctionConfig{
				Host: "om-function.open-match-demo.svc.cluster.local",
				Port: 50502,
				Type: pb.FunctionConfig_GRPC,
			},
			Profile: &pb.MatchProfile{
				Name: "1v1",
				Pools: []*pb.Pool{
					{
						Name: "Everyone",
					},
				},
			},
		}

所以我们需要改掉这里Host所指定的值,修改为mmf的实际地址即可,最后更新docker-compose.yaml并执行 docker-compose -f docker-compose.yaml up,在cmd/demo-first-match/main.go 文件中运行main函数即可成功运行demo程序

demo程序的执行成功后会返回一个虚拟的链接地址,该链接地址由director组件返回,可以理解为在director中返回具体的dedicated server的ip地址,demo中是随机产生的代码位置在

examples/demo/components/director/director.go:132 

如果不正确可以搜索2222作为线索定位

	for _, match := range matches {
		ids := []string{}

		for _, t := range match.Tickets {
			ids = append(ids, t.Id)
		}

		req := &pb.AssignTicketsRequest{
			Assignments: []*pb.AssignmentGroup{
				{
					TicketIds: ids,
					Assignment: &pb.Assignment{
						Connection: fmt.Sprintf("%d.%d.%d.%d:2222", rand.Intn(256), rand.Intn(256), rand.Intn(256), rand.Intn(256)),
					},
				},
			},
		}

		resp, err := be.AssignTickets(ds.Ctx, req)
		if err != nil {
			panic(err)
		}

		_ = resp
	}

匹配成功后返回的链接地址

open-match对mmf,evaluator,director 提供了多种游戏场景的默认实现,可以在亦有模板的基础上结合业务进行开发,具体内容可以查看examples/scale/README.md

感觉联机几千人同时在线这种方式应该够够吧,先这样,散会

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2201886.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【万字长文】Word2Vec计算详解(一)CBOW模型

【万字长文】Word2Vec计算详解(一)CBOW模型 写在前面 本文用于记录本人学习NLP过程中,学习Word2Vec部分时的详细过程,本文与本人写的其他文章一样,旨在给出Word2Vec模型中的详细计算过程,包括每个模块的计…

LLM4Rec最新工作: 字节发布用于序列推荐的分层大模型HLLM

前几个月 Meta HSTU 点燃各大厂商对 LLM4Rec 的热情,一时间,探索推荐领域的 Scaling Law、实现推荐的 ChatGPT 时刻、取代传统推荐模型等一系列话题让人兴奋,然而理想有多丰满,现实就有多骨感,尚未有业界公开真正复刻 …

微服务架构---认识Zuul

目录 认识Zuul简单的例子 第一个Zuul程序步骤1:创建父工程zuul-1步骤2:创建HystrixController类步骤3:搭建服务消费者eureka-consumer项目(1)创建一个config包,在config包下新建配置类RestConfig&#xff0…

别再浪费时间!利用ChatGPT写作提效神器,赶紧收藏!

在信息化迅猛发展的当下,写作已成为我们日常中不可或缺的组成部分。论是在撰写报告、进行学术论文创作,还是写博客内容,写作都是我们思想和观点的核心手段。然而,写作非易事,它常需要我们付出大量的时间和精力。那么&a…

Superset SQL模板使用

使用背景 有时想让表的时间索引生效,而不是在最外层配置报表时,再套多一层时间范围。这时可以使用SQL模板 参考官方文档 https://superset.apache.org/docs/configuration/sql-templating/#:~:textSQL%20Lab%20and%20Explore%20supports%20Jinja 我…

vscode中的Code Runner配置----output中文乱码(设置默认使用cmd运行文件)、设置当前文件夹为根路径

问题描述 1. 存在中文显示异常,以及输出用Output输出的问题 解决方法: 把终端改为 cmd。如果是就不用替换了 修改RunCode的配置 完成,下面点击 run code就在cmd中运行了 2. 设置当前文件夹为根路径 code runner 的默认根路径是当前项目…

C#中Assembly3个获取路径的方法

在C#中,经常要获取路径 ,可以通过Assembly的三个重载方法来获取,如下所示这三个分别是GetCallingAssembly、GetEntryAssembly和GetExecutingAssembly。 string tmpEntryPath Assembly.GetEntryAssembly().Location;string tmpExeasmPath As…

嵌入式面试——C语言和数据结构篇(二)

本篇为C语言和数据结构篇(二) 1、关键字static的作用是什么? 答: 在C语言中,关键字static有三个明显的作用: 1>在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 2&…

深度解读数字化转型的核心驱动因素与实践指南从战略到落地

数字化转型的战略重心 在当今商业环境中,数字化转型不仅是企业提升效率的工具,更是创造竞争优势的必要条件。随着技术的飞速发展,企业在面对市场动态变化时,依赖于其数字化基础设施、数据处理能力以及对新技术的敏捷反应能力&…

嵌入式面试——FreeRTOS篇(六) 任务通知

本篇为:FreeRTOS 任务通知篇 任务通知简介 1、任务通知介绍 答: 任务通知:用来通知任务的,任务控制块中的结构体成员变量ulNotifiedValue就是这个通知值。 使用队列、信号量、事件标志组时都需要另外创建一个结构体&#xff0c…

【JAVA开源】基于Vue和SpringBoot的高校学科竞赛平台

本文项目编号 T 075 ,文末自助获取源码 \color{red}{T075,文末自助获取源码} T075,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 教…

如何使用DAMODEL进行AI开发教程

DAMODEL:DAMODEL 目前DAmodel注册并实名赠送50大洋的免费额度,搭载4090的服务器费用不到2r/h 教程: 完成注册并实名后 在此点击创建实例 选择实例配置 选择镜像,看你使用哪种dl框架 设置完毕后创建密钥并选择该密钥。 创建…

防火墙的三种工作模式:路由模式、透明模式(网桥)、混合模式

防火墙作为网络安全的核心设备之一,扮演着至关重要的角色。它不仅能够有效防御外部网络的攻击,还能保护内部网络的安全。在如今复杂多样的网络环境下,防火墙的部署和工作模式直接影响着网络安全策略的实施效果。防火墙通常可以工作在三种模式…

论文阅读笔记-Self-Attention

前言 Self-Attention能够将每个元素和当前时刻元素进行比较来确定上下文元素的重要性,这也使得它在NLP模型中表现优异。而本篇文章则是将卷积结构与Self-Attention结构进行了比较,通过 实验证明了这样的卷积结构同样有着高效的计算和足以和Self-Attention媲美的效果。本篇文…

【AAOS】Android Automotive 9模拟器源码下载及编译

源码下载 repo init -u https://android.googlesource.com/platform/manifest -b android-9.0.0_r61 repo sync -c --no-tags --no-clone-bundle 源码编译 source build/envsetup.sh lunch aosp_car_x86_64-userdebug make -j8 运行效果 emulator Home界面 MAP All apps S…

python爬虫 - 数据提取

🌈个人主页:https://blog.csdn.net/2401_86688088?typeblog 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、数据类型及其对应的提取策略 (一)文本数据 &…

网约巴士订票系统小程序的设计

管理员账户功能包括:系统首页,个人中心,管理员管理,用户管理,巴士信息管理,积分兑换管理,积分纪录管理,新闻信息管理,基础数据管理 微信端账号功能包括:系统…

国产长芯微LDC8531低功耗轨到轨输出 16 位串行输入数模转换器完全P2P替代DAC8531

描述 LDC8531是一款低功耗、单16位缓冲电压输出数模转换器(DAC)。其片上精密输出放大器允许实现轨到轨输出摆动。LDC8531使用多功能三线串行接口,其时钟频率高达30MHz,与标准SPI、QSPI、Microwire和数字信号处理器(DSP…

数据库迁移中的权限问题及解决方法——以Error 1142为例

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] &#x1f4f1…

无线领夹麦克风哪个降噪好?选购领夹麦克风需注意的五大隐藏风险

不知道大家有没有遇到这样一个情况,为什么有些视频或直播的声音听起来那么清晰,仿佛身临其境,而自己拍的视频却总是嘈杂不堪,尤其是在户外拍摄的时候,音频中更是充斥着各种各样的噪音。这种问题主要还是麦克风的原因所…