Go EASY游戏框架 之 RPC Guide 03

1 Overview

easy解决服务端通信问题,同样使用了RPC技术。easy使用的ETCD+GRPC,直接将它们打包组合在了一起。随着服务发现的成熟,稳定,简单,若是不用,甚至你也并不需要RPC来分解你的架构。

GRPC 有默认resovler 解决服务发现的方案,只需要完成resolver,watch等,可以轻易实现,RPC的负载均衡。只不过这种只适合,对服务器ID信息等不敏感,比如说数据服务,和业务服务。不关心是哪台服务器完成的,只要数据处理完即可。

在游戏的应用场景中,登陆你可能使用的http,进入游戏用的游戏服务器,那么登陆服务需要知道用户在哪台游戏服务器中,使用token判定登陆,传输用户信息等走RPC通道,需要明确知道是哪台服务器。默认的服务发现就不满足我们的需求了。因此我们需要改造下,将游戏的这种具有耦合性质的负载也要支持才行。

2 传送门

go get github.com/slclub/easy/rpc

  • rpc/etcd  ETCD简单封装
  • rpc/cgrpc. GRPC 原生服务发现的封装实现,以及指定方式负载的服务发现

测试项目地址:github.com/slclub/easy/examples/rpc

3 传输协议编码Protobuf

我们直接使用grpc官网的helloworld。我们简单点直接上proto文件的描述语言。致于protoc等工具,以及go的依赖proto就不详细赘述了


syntax = "proto3";

option go_package = "google.golang.org/grpc/examples/helloworld/helloworld";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

4 GRPC服务端

4.1 helloworld 接口


// server is used to implement helloworld.GreeterServer.
type hello struct {
	helloworld.UnimplementedGreeterServer
}

// SayHello implements helloworld.GreeterServer
func (s *hello) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
	log.Info("Received: %v", in.GetName())
	return &helloworld.HelloReply{Message: "Hello " + in.GetName()}, nil
}

SayHello接口会自动依据protobuf 生成的helloworld_grpc.pb.go 文件代码去接收客户端来的请求。

4.2 ETCD client初始化

etcd.NewWithOption(option.OptionWith(nil).Default(
		option.OptionFunc(func() (string, any) {
			return "Endpoints", strings.Split(etcdAddr, ";")
		})),
	)

etcdAddr 是 用分号链接起来的,etcd的监听地址字符串。ETCD 在整个服务发现体系仅仅需要这理论的一行代码足够了。演示项目我们没有配置账号和密码。实际项目需要主要服务安全。

4.3  服务端grpc 

  • 第一部分grpc初始化
  • 第二部分proto接口注册
  • 第三部分就一个函数调用Serv启动服务监听
// New 一个rpc 监听服务
	server := cgrpc.NewServer(option.OptionWith(&cgrpc.Config{
		PathName:  "server1",
		Addr:      serverAddr,
		Namespace: namespace,
		//TTL:       15,
	}).Default(
		option.DEFAULT_IGNORE_ZERO,
		option.OptionFunc(func() (string, any) {
			return "ID", "abluo"
		}),
		option.OptionFunc(func() (string, any) {
			return "AddrToClient", "127.0.0.1:18080"
		}),
	))

	// 绑定业务接口到 rpc服务
	// 可以被多次使用RegisterService,我们用的append
	server.RegisterService(
		func(server *grpc.Server) {
			helloworld.RegisterGreeterServer(server, &hello{})
		},
	)

	// 监听;如果您有主监听,那么可以用go 并发运行
	server.Serv()

其中AddrToClient 是针对游戏服务提供给游戏客户端的监听地址,对于grpc来说不是必须的。这里仅仅是从顺便使用grpc 的服务端注册到ETCD中,完成游戏端的服务发现。可以做到任何游戏服不停服的扩展性,动态添加或减少服务端的机器。

这里我们可以发现使用option.Assignment初始化的优势,演示代码的时候不需要写完整的配置参数,还能人为控制的保证参数的默认值。处理默认值都是统一的格式,流程化代码。

当然option.Assignment是有局限性的,仅仅适合服务类的对象,或者仅仅LoadOnce的逻辑部分使用。在业务代码不建议使用,因使用了reflect反射会性能低下。

4.4 grpc客户端

  • ETCD初始化;
  • grpc.Client初始化;
  • Client启动我们分开了,多了一行启动过程,一个函数调用Start();
  • handle 绑定调用接口proto;
  • client.Wait() 为测试而生的函数,实际项目中用不到;
  • client.Close() 不严谨的情况可以不用,严谨的话,在项目工程服务关闭后调用;
	// plan2 using the default value setting function.
	etcd.NewWithOption(option.OptionWith(nil).Default(
		option.OptionFunc(func() (string, any) {
			return "Endpoints", strings.Split(etcdAddr, ";")
		}),
	))

	client := cgrpc.NewClient(option.OptionWith(&struct {
		PathName  string
		Namespace string
	}{"server1", namespace}))

	client.Start()

	// do your things
	handle(client.ClientConn)
	// just for test
	client.Wait()

	// close
	client.Close()

5 启动

为了启动测试命令随时可以手敲,笔者没有将ETCD,GRPC地址通过flag传递给应用工程。直接写到代码里了。运行前,请下修改代码中的监听地址变量的值。

5.1 启动服务端

$  cd 到 examples/rpc/server 

go build && ./server

5.2 启动客户端

$  cd 到 examples/rpc/client

go build && ./client

6 Output

首先双方通信正常OK。

启动服务后,笔者模拟,任意一端崩掉用(CTRL+C),再启动崩掉的端,整体服务立刻回复正常。

其他的测试情况就不一一再往这上面粘贴了。

服务端

断开gprc服务端再启动

客户端

7 总结

构建一个完整架构的游戏服务器,仅仅靠服务发现,rpc等虽然还不足够。但是这么简单的实现服务端通信,还是让人很愉快。后续再有其他的服务组件,我们可以一一加入进去。同时给出测试项目。

go讲究毕竟是精简,笔者也不是弄个大杂烩,而是设计好package,需要什么我们就用什么。虽说做不到EASY在手天下我有,但是弄一个小体系,还是能节省我们很多项目时间。

最后欢迎大家互相交流学习,有好东西互相分享下。有兴趣的通许可以通过传送门去github,给EASY来个小小的star。因压力测试还不到位,不全,所以笔者一直没有发布一个Stable版本,希望大家谅解。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

产品入门第二讲:Axure产品元件库的使用

📚📚 🏅我是默,一个在CSDN分享笔记的博主。📚📚 ​​​​ 🌟在这里,我要推荐给大家我的专栏《Axure》。🎯🎯 🚀无论你是编程小白,还是…

西南科技大学数字电子技术实验六(智力竞赛抢答器的设计及FPGA实现)预习报告

一、计算/设计过程 说明:本实验是验证性实验,计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程,越详细越好。用公式输入法完成相关公式内容,不得贴手写图片。(注意:从抽象公式直接得出结…

【Azure 架构师学习笔记】- Azure Databricks (3) - 再次认识DataBricks

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (2) -集群 前言 在对Databricks有了初步了解之后,如果要深入使用则需要对其进行更深层次的了解。 Databricks ADB 是一个统一的…

jdk+zookeeper+kafka 搭建kafka集群

环境资源包: jdk-8u341-linux-x64.tar.gz kafka_2.12-2.2.0.tgz zookeeper-3.4.14.tar.gz 一、安装jdk 因为kafka需要Java环境,所以优先配置jdk环境,若已经配置了java环境,此步骤可以忽略 [rootVM-120-2-centos ~]# tar -xvf j…

在Node.js中使用MongoDB连接数据库、创建集合

本文主要介绍在Node.js中使用MongoDB连接数据库、创建集合的方法。 目录 连接数据库使用原生驱动程序连接MongoDB数据库使用Mongoose连接MongoDB数据库 创建集合使用mongodb驱动程序 连接数据库 在Node.js中使用MongoDB连接数据库有两种方式:使用原生驱动程序和使用…

Redis持久化AOF详解

基础面试题 什么是AOF AOF(Append-Only File)用于将Redis服务器收到的写操作追加到日志文件,通过该机制可以保证服务器重启后依然可以依靠日志文件恢复数据。 它的工作过程大抵分为以下几步: 收到客户端的写入命令(例如SET、DE…

Hadoop学习总结(Hive的安装)

Hive的安装模式分为3种,分别是嵌入模式、本地模式、远程模式。 (1)嵌入模式:使用内嵌的 Derby 数据库存储元数据,这种方式是 Hive 的默认安装方式,配置简单,但是一次只能连接一个客户端&#xf…

2023.12.14 hive sql的聚合增强函数 grouping set

目录 1.建库建表 2.需求 3.使用union all来完成需求 4.聚合函数增强 grouping set 5.聚合增强函数cube ,rollup 6.rollup翻滚 7.聚合函数增强 -- grouping判断 1.建库建表 -- 建库 create database if not exists test; use test; -- 建表 create table test.t_cookie(month …

目标检测检测精度

在一个数据集检测中,会产生四类检测结果:TP、TN 、FP 、FN: T ——true 表示正确 F——false 表示错误 P—— positive 表示积极的,看成正例 N——negative 表示消极的,看成负例 我的理解:后面为预测结…

智能优化算法应用:基于象群算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于象群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于象群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.象群算法4.实验参数设定5.算法结果6.参考文献7.MA…

C_10练习题答案

一、单项选择题(本大题共 20小题,每小题 2分,共 40分。在每小题给出的四个备选项中,选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) 1,结构化程序由三种基本结构组成,三种基本结构组成的算法是(A) A.可以完成任何复杂的任务 B.只能完成部分复杂的任务…

【数据结构和算法】压缩字符串

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一:双指针 三、代码 3.1 方法一:双指针 四、复杂度分析 前言 这是力扣…

计网Lesson9 - 链路协议和网络概述

文章目录 数据链路层协议Ethernet V2标准Ethernet V2帧格式Ethernet V2帧长度标准以太网帧 MAC 帧协议 PPP 协议PPP 概述PPP 帧 网络层网络层的设计选择 数据链路层协议 Ethernet V2标准 Ethernet V2帧格式 以太网帧格式说明: 6 6 6 字节目标地址 6 6 6 字节源地…

docker核心原理——unionfs、namespace、cgroup

docker 核心原理 docker的核心原理其实就是cgroupnamespaceunionfs 组合实现的隔离机制,资源控制等。 隔离机制 在容器进程启动之前重新挂载它的整个根⽬录“/”,⽤来为容器提供隔离后的执⾏环境⽂件系统通过Linux Namespace 创建隔离,决…

论文阅读:MonetDB/X100: Hyper-Pipelining Query Execution

目录 Abstract 1 Introduction 1.1 Outline 2 How CPU Work Abstract 在决策支持、OLAP和多媒体检索等计算密集型应用领域,数据库系统往往只能在现代cpu上实现较低的IPC(每周期指令)效率。本文首先以TPC-H基准为重点,深入研究了这种情况发生的原因。…

Debian 系统镜像下载

最近在看一些网络相关的文章需要用到 debian 11.x 的系统网上找了好多都发下载,在官网看一下 有个 11.8 的版本我无法下载,提示被最新的 debian-12.4.0 所代替,于是找到了这个链接 Index of /cdimage/unofficial/non-free/cd-including-fi…

计算机毕业设计 基于Web的城市旅游网站的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

【已解决】ModuleNotFoundError: No module named ‘tensorflow‘

问题描述 Traceback (most recent call last): File "dataset_tool.py", line 16, in <module> import tensorflow as tf ModuleNotFoundError: No module named tensorflow 如果直接pip install tensorflow&#xff0c;还会报错 解决办法 方法一 pip i…

MSF学习

之前的渗透测试中 其实很少用到 cs msf 但是在实际内网的时候 可以发现 msf cs 都是很好用的 所以现在我来学习一下 msf的使用方法 kali自带msf https://www.cnblogs.com/bmjoker/p/10051014.html 使用 msfconsole 启动即可 首先就是最正常的木马生成 所以这里其实只需…

hive聚合函数之JOIN原理及案例

1.数据准备 原始数据 创建dept.txt文件&#xff0c;并赋值如下内容&#xff0c;上传HDFS。 部门编号 部门名称 部门位置id 10 行政部 1700 20 财务部 1800 30 教学部 1900 40 销售部 1700创建emp.txt文件&#xff0c;并赋值如下内容&#xff0c;上传HDFS。 员工编号 姓名 岗…