简介

  结合自身工作经历写的网络游戏服务器开发相关技术,服务器运维部署相关技术。 编写目的主要是进行服务器技术总结、分享、备忘、指令快速查找。全书总共分为开发篇、运维篇两个部分。 项目开发语言主要是Java,部分项目为Go,C#,同时涉及Shell脚本,Unity等相关技术。 本书不过多介绍理论知识,更多的是介绍实际项目中使用到的技术,框架,常用命令介绍、备忘等,相关技术会贴出官方文档或参考文档地址。

开发篇

  前两章介绍在实际开发中的两个游戏项目,架构和使用的相关技术,MMORPG项目采用分区分服架构,slots项目采用全区全服架构。 第三章介绍服务器端开发RPG游戏使用的AI技术;第四章介绍如何将Unity中的NavMesh+A*寻路算法运用于服务器;第五章介绍excel导表工具;第六章介绍服务器压测集群。

运维篇

   第一章介绍生产环境Linux参数调优,各种软件安装,环境配置;第二章介绍开发中使用的工具部署,使用;第三章介绍项目在开发、生产环境中的CI/CD;第四章介绍数据库的部署,维护,常用指令; 第五章介绍服务器、进程服务的监控与预警;第六章介绍线上运行程序的诊断,问题排查处理;第七章介绍一些其他常用组件的部署运维。

技术交流学习359135103@qq.com

MMORPG项目

  MMORPG大型多人在线角色扮演游戏,本人在实际工作中采用的分区分服架构,Java开发的多进程服务器。 此章节主要总结一下MMORPG常用的技术,服务器架构的搭建,核心功能模块的设计、编写以及怎样进行压力测试以保证承载,延迟问题。

简介

  介绍一款修仙类MMORPG手游服务器实现,游戏是分区分服,架构采用分布式多进程搭建。 客户端采用Unity开发,服务开发技术主要是Java,单服务器线上实跑真实玩家2000+,机器人压测实跑5000+。

技术选型

  服务器使用Java版本为Jdk8,未过多使用第三方组件,基本上是自己封装。 数据库MongoDB存储玩家数据,MySQL存储策划配置文件,Redis存储排行榜及部分缓存数据。 使用Git、Jenkins、Nexus搭建测试环境,持续集成,持续部署。 Github类似开源服务器框架GameServer

  • 编程:Java
  • 数据库:MongoDB、MySQL、Redis
  • 网络库:Netty、ProtoBuf
  • 项目构建:Maven
  • 开发工具:Git、Jenkins、Nexus
  • 生产环境:Centos

架构

  服务器采用多进程进行架构,客户端到网关、内部通信使用自定义TCP进行网络通信(Netty+Protobuf),后台管理系统调用查询使用HTTP协议。整体架构如下所示

服务器架构

登录服

  登录服可水平扩展,兼容了类似zookeeper的服务发现功能,游戏服、网关服启动时会向所有的登录服进行注册,同时可管理他们的运行状态。 主要功能如下:

  • 登录校验
  • 获取游戏服务器列表
  • 获取网关列表
  • 网关服、游戏服状态管理

  玩家首次打开游戏APP通过通过HTTP请求网关列表,登录服返回空闲的网关地址; APP使用返回的地址向网关进行TCP连接,然后进行登录校验,获取游戏大区列表,玩家选择登录游戏逻辑服。后续所有客户端请求TCP消息都通过网关服转发,时序图如下所示:
登录流程图

网关服

  网关服也是水平扩展的,连接登陆服、游戏逻辑服、世界服,负责各自消息的转发,主要功能如下:

  • 网络消息的转发
  • 玩家连接会话管理
  • 消息合并
  • 数据加解密
  • 数据压缩、解压缩
  • 玩家通信频率限制,IP黑名单处理

  玩家登录选择游戏服后,会在网关绑定玩家登录的游戏服连接会话,以后所有消息都转发到对应该游戏服。 网络消息转发通过为每个消息定义一个消息ID进行转发。如果消息ID是注册在游戏逻辑服,就将相应的消息转发给游戏逻辑服。

  消息合并是将游戏逻辑服同一时间同一玩家的多条返回消息合并成一个消息转发给客户端,减少网络延迟,丢包重发等。 消息合并不超过MTU,且必须设置超时时间。数据加解密使用对称加密算法RC4,创建Socket时服务器返回一个密钥字符串。 数据压缩使用Snappy进行压缩,且只对消息长度超过MTU的部分数据进行压缩。 通信频率限制,IP黑名单主要是针对非法玩家使用加速器的请求,篡改协议等做出相应的限制。

协议定义

用户到网关

  用户到网关的协议格式如下,其中消息长度第30位标识是否加密,29位标识是否压缩,后二十位表示真正的消息长度。

消息长度[4]+消息ID[4]+Protobuf字节流

网关和内部进程

  网关到内部进程服务协议增加了玩家ID,需要知道每条消息归属于那个玩家。

消息长度[4]+消息ID[4]+玩家ID[8]+Protobuf字节流

游戏服

  一个游戏服是一个独立的游戏世界,玩家所有游戏操作相关的逻辑都在游戏服进行处理。多个游戏地图场景在一个游戏服中使用多线程处理,没有按照地图进行创建进程。 核心功能模块参考下一节,主要功能模块有:

  • 武器、宠物、镶嵌、法宝、成就、称号、境界、坐骑、翅膀、时装等养成系统
  • 公会、好友、组队、邮件、聊天、师徒、结婚等社交系统
  • 背包、仓库、商城、交易、摆摊等系统
  • 野外场景、战场、副本等系统
  • AI、寻路、技能、Buff等系统
  • 活动系统

日志服

  日志服也是水平扩展的,游戏服在多个可用日志服中随机选择一个进行日志传送。 日志服主要功能是将所有收到的消息批量写入MySQL数据库,供后台系统进行处理。

充值服

  充值服也是水平扩展的,主要是功能是验证第三方充值的合法性。

核心模块

  此小节主要介绍MMORPG游戏中的关键技术、特性及注意事项,主要模块有:

  • 线程模型
  • 热更新
  • 地图战斗

线程模型

  因为服务器采用的是多进程多线程模型,因此线程模型未设计好,经常会出现各种bug和性能问题。 经过多次实践借鉴最终基于netty的线程模型进行了封装,源码可参考javaLib 。 采用n个线程对应m个队列,一个线程可绑定多个队列,一个队列可以是一个功能模块,比如公会可分配一个队列绑定到唯一的线程,如下图所示:

thread

//场景线程组
SceneLoopGroup sceneLoopGroup = new SceneTaskLoopGroup();
//全局线程组
SceneLoopGroup soleLoopGroup = new SceneTaskLoopGroup();

//注册
SceneLoop sceneLoop = soleLoopGroup.next();

//teamScene 是实现了Scene接口的TeamManager单例对象
teamScene.register(sceneLoop);
guildScene.register(sceneLoop);
...

  上面示例代码SceneTaskLoopGroup等价于Netty的NioEventLoopGroup,Scene等价于Netty的Channel。 全局所有玩家操作的对象如公会,聊天,组队等都单独创建一个独立的队列,所有玩家该功能模块的操作都丢人该队列中执行; 野外场景,副本的创建也单独创建一个队列,在同一场景、副本的玩家操作在同一队列中执行。

热更新

  热更新使用Java自带的JavaCompiler将源文件编译成class文件,然后使用ClassLoader将class文件加载到内存中, 源码及示例可参考GameServer4j 。 此方法优点是使用java原生代码,开发简单方便;缺点是只能更新部分逻辑,如数据存储实体类不能进行热更新,逻辑必须实现接口。 大致流程如下:

Script update flow

地图战斗

地图设计

  1. 地图分为野外地图、副本、战场、公会地图等,其中野外地图又按人数分多线。
  2. 每个地图都绑定一个消息队列,同一地图的玩家操作,战斗都在同一线程执行。
  3. 每个地图都有定时器进行AI、技能的定时计算。
  4. 地图划分主要有两种,一种是为了进行视野同步(九宫格)将地图分成大小相同的多个矩形格子, 另一种是四叉树划分行走面的凸多边形(快速查询地图对象所在行走面的凸多边形)。 Map divide

技能设计

  技能、AI目标筛选也只针对九宫格中的对象进行寻找,方式分为矩形,圆形,扇形等。 矩形目标筛选通过玩家朝向构建一个矩形,然后判断周围的对象是否在矩形中;圆形直接判断周围对象的距离;扇形构建多个三角形,判断周围对象是否在三角形中。 Skill target

AI、寻路

压力测试

压测结果

  • 单服务器可承载5000+
  • 同一场景地图可承载1000+对象(玩家+NPC)寻路释放技能

测试目的

  • 模拟真实玩家行为,发现服务器高并发下的问题
  • 测试服务器的承载压力
  • 分析优化网络,消息包
  • 测试各个功能模块
  • 分析技能、NPC AI,寻路等高频执行逻辑性能问题
  • 协助客户端排查性能问题,同步显示对象数,渲染性能问题

实现技术

  • Netty:网络通信
  • A星+NavMesh:玩家寻路
  • 行为树:玩家逻辑组装
  • Libgdx:图形界面显示

Slots项目

  Slots主要是针对欧美的休闲游戏,本人在实际工作中采用的微服务架构,Java+Go开发的混合型服务器。 此章节主要总结一下Slots游戏开发中常使用的技术,服务器架构的搭建,核心功能模块的设计、编写以及怎样进行压力测试以保证承载,延迟问题。

简介

  介绍一款Slots手游服务器实现,游戏是全区全服,架构采用微服务搭建。 客户端采用Unity开发,服务开发语言主要是Java和Go。

技术选型

  服务器使用Java版本为Jdk14,Go版本为1.14.3。 Java开发游戏主要功能逻辑,Go开发周边功能及工具,Unity开发内部图形化工具,shell开发CI/CD脚本。 数据库MongoDB存储玩家数据和策划配置文件,Redis存储排行榜及部分缓存数据。 使用Git、Jenkins、Nexus、Docker搭建测试环境,持续集成,持续部署。 Sentry监控代码异常,InfluxDB监控数据库、Docker、Linux主机等资源占用,Elasticsearch实现日志集中查询, Skywalking监控Java进程信息,Grafana+钉钉实现监控图形化和预警通知。 Github类似开源服务器框架GameServer4j

  • 编程:Java、Go、C#、Shell
  • 图形:Unity
  • 数据库:MongoDB、Redis
  • 网络库:Netty、ProtoBuf、Grpc
  • 开发工具:Git、Jenkins、Nexus、Gitlab、Maven
  • 生产环境:Centos、Docker、Elasticsearch、Nginx
  • 监控:Grafana、InfluxDB、Sentry、Skywalking、钉钉
  • 第三方组件:Springboot、Zookeeper

服务器架构

  服务器采用微服务进行架构,客户端到网关使用自定义TCP进行网络通信(Netty+Protobuf),内部通信使用grpc, 后台管理系统调用查询使用HTTP协议。服务配置,服务发现使用zookeeper进行管理。整体架构如下所示:

架构图

API服

  API可水平扩展,主要功能如下:

  • 注册、登录校验
  • 充值校验

  玩家首次打开游戏APP通过HTTP向Manage服获取网关列表; 客户端使用返回的地址向网关进行TCP连接;然后向Api服进行登录校验或用户注册;如果校验失败直接经网关返回客户端,否则将信息经网关再发送给大厅服请求加载玩家数据。 后续所有客户端请求TCP消息都通过网关服转发,时序图如下所示:

登录流程图

网关服

  网关服也是水平扩展的,连接API服、大厅服、Slots小游戏服,负责各自消息的转发,主要功能如下:

  • 网络消息的转发
  • 玩家连接会话管理
  • 消息合并
  • 数据加解密
  • 数据压缩、解压缩
  • 玩家通信频率限制,IP黑名单处理

  玩家登录选择游戏服后,会在网关绑定玩家登录的游戏服连接会话,以后所有消息都转发到对应该游戏服。 网络消息转发通过为每个消息定义一个消息ID进行转发。如果消息ID是注册在大厅服,就将相应的消息转发给大厅服。

  消息合并是将游戏逻辑服同一时间同一玩家的多条返回消息合并成一个消息转发给客户端,减少网络延迟,丢包重发等。 消息合并不超过MTU,且必须设置超时时间。数据加解密使用对称加密算法RC4,创建Socket时服务器返回一个密钥字符串。 数据压缩使用Snappy进行压缩,且只对消息长度超过MTU的部分数据进行压缩。 通信频率限制,IP黑名单主要是针对非法玩家使用加速器的请求,篡改协议等做出相应的限制。

协议定义

   用户到网关,网关到大厅、Slots服使用自定义TCP协议进行通信,其他服务器互联使用标准的grpc连接。

用户到网关

消息长度[4]+消息ID[4]+确认消息最小序列号[4]+消息序号[4]+Protobuf字节流

  用户到网关的协议其中消息长度第30位标识是否加密,29位标识是否压缩,后二十位表示真正的消息长度; 消息序号用来确定每个消息的唯一性,客户端自增长,确认消息序列号是客户端收到的请求消息最小序列号; 消息序号用于判断客户端重复请求,同一序号只能被后台服务器执行一次,网关会进行返回消息缓存,如果客户端请求消息序号网关有缓存,直接从缓存消息返回结果,比如断线重连; 服务器收到确认消息最小序号就将网关缓存的所有小于改序号的缓存消息清除掉,表示客户端不再需要该消息。流程图如下所示:

消息流程图

网关和内部进程

消息长度[4]+消息ID[4]+玩家ID[8]+消息序号[4]+Protobuf字节流

  网关到内部进程服务协议增加了玩家ID,需要知道每条消息归属于那个玩家。

大厅服

  大厅服是可水平扩展的有状态逻辑服务器,每个玩家登录都会在网关绑定一个大厅,同一玩家只能在同一大厅处理自身逻辑。 大厅逻辑不会涉及玩家间的交互逻辑,如公会,聊天则会转发到世界服进行逻辑处理。 核心功能模块参考下一节,大厅主要功能模块有:

  • 任务、收集、宠物、成就等养成系统
  • 好友、邮件
  • 活动

世界服

  世界服是单点有状态服务器,主要处理多个玩家有交互的逻辑,主要功能模块有:

  • 公会
  • 聊天

Slots服

  Slots服是各种slots小游戏,每个小游戏是单独的有状态微服务。 Slots服和网关采用自定义TCP协议通信,和大厅采用grpc通信。 slots服只编写游戏逻辑,公共处理逻辑调用大厅rpc。

Manage服

  Manage是无状态的HTTP服务,采用SpringBoot搭建的web框架。 可水平扩展,采用Nginx做负载均衡,内部采用grpc和所有服务进行通信。主要功能如下:

  • 客户端获取网关IP地址
  • 后台查询修改玩家信息入口
  • 服务器管理入口(加载脚本、配置、关服等)

微服务

  微服务主要采用Go语言开发,主机是解决Java进程占用内存较大问题,同时开发速度快。 微服务设计目的主要是为了分割世界服这种有状态的单点逻辑。

核心模块

  此小节主要介绍Slots游戏中的关键技术、特性及注意事项,主要模块有:

  • 线程模型
  • 热更新
  • CI/CD

线程模型

  线程模型和MMORPG线程模型模型类似,源码可参考javaLib 。 采用n个线程对应m个队列,一个线程可绑定多个队列,一个队列可以是一个功能模块,比如公会可分配一个队列绑定到唯一的线程。因为玩家操作基本无互操作,因此每个玩家都分配了一个队列,所有玩家操作都在自身队列执行,如下图所示:
线程模型

热更新

  热更新方式同MMORPG项目一致,参考MMORPG热更新

CI/CD

  因为服务器采用微服务架构,进程数上百个,因此采用Docker部署,然后结合jenkins一键部署,加快部署流程。具体搭建技术使用可参考后面的运维篇。

测试环境

  测试环境运行比较简单,直接在Jenkins中运行项目,更新流程如下:

测试更新流程

生产环境

  生产环境服务运行于Docker中,在Jenkins中启动、构建项目、镜像制作, 然后利用私有Docker Register和Docker远程命令执行一键部署。 因为服务都是有状态服务,因此不能直接杀进程,在拉取镜像后,使用后台HTTP调用关闭服务器,确保所有数据都被持久化。 具体更新流程如下:

测试更新流程

压力测试

  因测试环境没有足够的主机,只压测到最高同时在线6000人,两个网关服、两个大厅服、两个API服、两个Manage服和若干子游戏服。 HTTP后台使用Locust测试,最高并发2000QPS; 游戏因为使用TCP自定义协议,因此用Go自行写了压测集群,模拟客户端发送消息,最高5000QPS。

测试目的

  • 模拟真实玩家行为,发现服务器高并发下的问题
  • 测试服务器的承载压力
  • 分析优化网络,消息包
  • 测试各个功能模块

实现技术

  • Go:开发压测集群
  • Unity:开发压测客户端工具
  • Locust:Python实现的HTTP压测工具

人工智能

  此章节主要包含寻路系统和AI两部分,总结自己在开发MMORPG中服务器怎样实现NPC寻路和AI行为。 所有代码使用Java开发,源码参考GameAI4j , Unity NavMesh导出工具参考NavMeshDemo

参考资料

参考书籍

  • 《游戏编程算法与技巧》:人工智能章节介绍了A*、贪婪、Dijkstra等算法,导航网格,状态机。
  • 《Game AI Pro》 :专业AI文档的收集,想法、思路,网络版:http://www.gameaipro.com/

开源项目

  • libgdx :Java 游戏开发框架
  • gdx-ai :libGDX 的AI框架
  • GdxDemo3D :libGDX和gda-ai开发的寻路和AI示例。
  • recastnavigation :Recast导入关卡几何体产出导航网格,Detour在导航网格上进行路径查询。

寻路系统

  因为客户端使用的Unity,因此服务器寻路系统和客户端保持一致采用导航网格和A*算法实现。

寻路方式

多边形寻路参考PolygonNavMesh 原理:

  1. 将unity导出的数据生成凸多边形
  2. 找出所有凸多边形共享的边
  3. 使用A*算法找出起点到目标点所经过的多边形列表
  4. 使用漏斗算法找出顶点坐标

导航网格

  导航网格是一系列的凸多边形相连的网格,比路点拥有更少的数据存储,可方便实现分层寻路系统。

Unity导出NavMesh

  Unity导出NavMesh首先需在场景中烘培出寻路层NavMesh,因为服务器寻路精度要求没有客户端要求高, 因此在烘培NavMesh时并未使用关卡几何体对象进行烘培,而是美工制作了一个行走面片进行烘培,这样能有效减少导航网格的凸多边形个数,提升性能。 其次需要注意Unity是左手坐标系,服务器是基于gdx-ai 的右手坐标系,因此导出时需要将y坐标取反。 最后需要特别注意Unity生成的相邻的凸多边形顶点可能共边不共顶点,服务器创建邻接关系是需要判断是否相连。 Unity NavMesh导出工具参考NavMeshDemo ,具体步骤如下:

  1. 选中model_1_xzm,然后在Navigation中烘培行走层对象
    客户端地图

  2. 选择工具-导出服务器NavMesh,点击测试地图大小,修改地图范围
    操作窗口

  3. 点击生成NavMesh数据,将生成的json文本导入服务器寻路工具 查看
    服务器地图

总结

  1. 多边形寻路和三角形寻路由于原理相同,性能消耗差不多,由于多边形合并了三角形,速度稍微快一些;顶点寻路相比于多边形寻路慢了5~40倍
  2. 多边形寻路需要导出的寻路数据在行走层中没有额外的顶点,共边顶点坐标需要一致,顶点寻路由于由于采用阻挡区三角形顶点寻路,因此没有此限制,但是增加了额外的阻挡区数据
  3. 多边形寻路支持3D寻路,顶点寻路只能平面寻路

决策系统

  因为一直做手游,因此接触到的AI都比较简单,特别是在服务器端的AI。 在实际开发中使用了状态机和行为树两种AI,参考文章Decision Making

状态机

  状态机实现小怪这种简单AI,状态机实现简单,但是复杂AI比较乱。

行为树

  行为树实现相对较复杂的Boss AI,行为树管理相对较复杂AI更直观,但是性能消耗较多,每次需要从根节点循环检测。 在实际开发中采用了两种技术组装行为树:脚本和xml配置。脚本方便程序员组装,可热更新;xml可策划进行编辑。

Excel导表

  策划配置的Excel数值在游戏服启动时一般是需要加载到内存中,加速配置文件的读取。 因此在开发中一般都有自己的一套规则,工具,我们实现的方式是将excel读取写入到MongoDB数据库中,服务器启动从数据库中加载缓存到内存中。 参考项目game-server/game-tool, 格式设计

excel工具

压力测试

  游戏服务器开发压力测试一般用途是发现性能瓶颈点,多线程问题等。

HTTP压测

  游戏如果使用HTTP协议通信,则压力测试非常方便,有很多第三方工具可用,如Locust 。 Locust可搭建集群,然后自己编写简单Python脚本,可模拟成千上万rps并发量。

TCP压测

  因为游戏很多使用自定义协议的Tcp,没有很好用的第三方工具,因此需要自行开发压力测试客户端。 在实际项目中参考locust架构搭建了一套压测集群(go)及显示工具(unity)。主要收集指标如下所示:

1. 总的rps、消息平均延迟、流量、消息请求推送次数

统计

2.请求消息的请求次数、延迟、大小、rps

请求接口

3.推送消息的推送次数、大小、rps

推送接口

4.压测集群主机的CPU、内存、人数

工作组

Linux

  本章节主要记录基于CentosOS 7常用指令; 开发和生产环境中Linux的常用软件安装维护; 生产环境中网络,防火墙,时间等的环境调优配置。 三个小节如下:

CentOS命令参考

  主要记录常用的系统命令使用及CentOS7中的安装使用。

系统资源

  磁盘、CPU、内存、IO等常见命令使用。 游戏服务器程序可能出现死循环,定时器泄露等占用CPU;未正常释放对象占用过多的内存或者内存一直飙升等问题; 存储数据,网路请求太多,消耗IO过高等问题;日志输出太多,没有正常删除照成磁盘占满等问题。

top命令

  top命令经常用来监控linux的系统状况,常用的性能分析工具,能够实时显示系统中各个进程的各种资源占用情况。 参考地址https://blog.csdn.net/yjclsx/article/details/81508455。进入top界面安如下安静可安需求显示。

  • 1:展开每个CPU的信息
  • P:以CPU的使用资源排序显示
  • M:以内存的使用资源排序显示
  • N:以pid排序显示
  • T:由进程使用的时间累计排序显示
# 1.查看指定进程 内存,cpu等信息
top -p 2913

# 2.查看进程详细信息,具体条目说明参考 https://blog.csdn.net/weixin_40584007/article/details/88847745  
cat /proc/1308/status

dstat命令

  多功能系统资源统计生成工具 ( versatile tool for generating system resource statistics), 可提供包含 top、free、iostat、ifstat、vmstat等多个工具的功能。详细使用可参考:https://www.cnblogs.com/shoufeng/p/9739805.html

# 1.安装
yum -y install dstat

# 2.查看
dstat

iostat

  统计CPU和IO信息,详细使用可参考:https://www.cnblogs.com/architectforest/p/12628399.html

# 1.查看
iostat -xmt 1

ps命令

  查看具体进程相关信。

# 1.查询进程id
ps -ef | grep game-hall | awk '{print "kill "$2}'

文件操作

  常用地文件上传,下载,打包,日志查看操作等。游戏服务器出现bug,有时候为了方便查看日志,需要将大的日志文件进行压缩打包,然后下载到本地进行操作。

re|sz上传下载命令

  可在Xshell中快速上传,下载文件。

# 1.安装
yum -y install lrzsz

# 2.上传
rz

# 3.下载
sz [文件名]

tar解压缩

# 1.打包压缩目录
tar -czvf game_hall_20201209.tar.gz game_hall_20201209121360/

目录文件操作

# 1.删除backups目录30天之前修改的文件
find backups/ -mtime +30 -delete

系统日志

  系统日志文件含义:

  • /var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之一
  • /var/log/secure 与安全相关的日志信息
  • /var/log/maillog 与邮件相关的日志信息
  • /var/log/cron 与定时任务相关的日志信息
  • /var/log/spooler 与UUCP和news设备相关的日志信息
  • /var/log/boot.log 守护进程启动和停止相关的日志消息
# 1.显示所有日志:
journalctl

# 2.查看最后10条日志
journalctl -n 10

# 3.跟踪日志:
journalctl -f

# 4只显示冲突、告警和错误
journalctl -p err..alert

网络操作

  新服务器部署过程中需要查看两台服务器直接网络是否联通需要用ping命令; 检测网络端口是否开放,能否访问通需要使用telent命令; 在主机上下载安装包通常需要wget命令; 经常需要调用http请求进行后台管理操作需要使用curl命令。

Telnet

# 1.检查是否安装
rpm -qa | grep telnet

# 2.查看yum列表
yum list | grep telnet

# 3.安装
yum install -y telnet-server.x86_64
yum install -y telnet.x86_64

# 4.执行
telnet 192.168.1.11 80

wget

# 1.安装
yum -y install wget

curl

# 1.安装
yum -y install curl

16. wireshark

  监听服务器、客户端指定端口是否收到远端的消息包。用于网络消息包的分析。官方文档:https://www.wireshark.org/docs/wsug_html_chunked/index.html

# 1.安装
yum install wireshark wireshark-qt

# 2.服务器获取网络包
# 2.1.创建文件&添加权限
touch packet.txt
chmod o+x packet.txt

# 2.2.查看网络接口
tshark -D

# 2.3.记录
tshark -w packet.txt -i eth0 -q

# 2.4.控制台查看指定端口(非常消耗内存)
tshark -i eth0 -Y "tcp.port == 4019"
tshark -i ens5 -Y "tcp.port == 7050"

firewall-cmd

# 1.查看防火墙所有开放的端口
firewall-cmd --zone=public --list-ports
firewall-cmd --list-all
  
# 2.开放端口
firewall-cmd --zone=public --add-port=27017/tcp --permanent

# 3.生效
firewall-cmd --reload

# 4.防火墙开关,状态查看
systemctl stop firewalld
systemctl start firewalld
systemctl status firewalld

netstat

  压测时可使用该命令查看网络连接是否正常创建,释放。


# 1.查看端口
netstat -lnpt
 
# 2.查看指定端口
netstat -lnpt |grep 5672

# 3.网络状态统计信息
netstat -an | awk '/^tcp/ {++y[$NF]} END {for(w in y) print w, y[w]}'

# 4.连接数
netstat -an |grep ESTABLISHED |wc -l

# 5.每个ip连接数
netstat -nat|grep "tcp"|awk ' {print$5}'|awk -F : '{print$1}'|sort|uniq -c|sort -rn

# 6.每个ip ESTABLISHED连接数
netstat -nat|grep ESTABLISHED|awk '{print$5}'|awk -F : '{print$1}'|sort|uniq -c|sort -rn

# 7.查看指定端口的连接信息
netstat -an | grep 7050

CentOS软件安装

  一些常用软件安装,配置。

JDK安装

  JDK安装可参考下面连接,生产环境使用docker运行程序,因此可跳过安装JDK。

vim安装

# 1.安装
yum -y install vim*

tree安装

  展示目录的树形结构。

# 1.安装
yum install tree -y

# 2.展示目录
tree /data/game

CentOS环境配置

  本节主机介绍生产环境中linux内核调优,网络连接设置;时间设置,服务器部署在国外,还需要考虑时区的配置。

网络连接数限制设置

ulimit -n

参考文档:https://blog.csdn.net/hunhun1122/article/details/79391147

# 1.修改连接数,重启后生效
vim /etc/security/limits.conf
    * soft nofile 204800
    * hard nofile 204800
    * soft nproc 204800
    * hard nproc 204800
# 2.分别新建下面两个文件,并加入 如下内容
vim /etc/security/limits.d/90-nproc.conf 
    * soft nproc 204800  
    * hard nproc 204800  
vim /etc/security/limits.d/def.conf
    * soft nofile 204800  
    * hard nofile 204800  
 
# 3.临时设置连接数
ulimit -n 204800

net.core.somaxconn

参考文档:https://www.cnblogs.com/my-show-time/p/15206020.html

# 1.查看参数
sysctl -a | grep net.core.somaxconn
# 2.设置 ,在末尾添加
vim /etc/sysctl.conf
    net.core.somaxconn=32768
sysctl -p
# 3.查看
sysctl -a | grep net.core.somaxconn

网络超时设置

参考文档:https://docs.mongodb.com/v3.6/faq/diagnostics/#adjusting-the-tcp-keepalive-value

# 1.使网络超时设置10分钟,超时后检测3次,每次30秒
vim /etc/sysctl.conf
    net.ipv4.tcp_keepalive_time=600
    net.ipv4.tcp_keepalive_intvl=30
    net.ipv4.tcp_keepalive_probes=3
sysctl -p
sysctl -a | grep keepalive

常用网络设置

参考文档:https://help.aliyun.com/document_detail/41334.html

#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,
net.ipv4.tcp_keepalive_time=600
net.ipv4.tcp_keepalive_intvl=30
net.ipv4.tcp_keepalive_probes=3

#web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而nginx定义的NGX_LISTEN_BACKLOG默认为511,所以有必要调整这个值
net.core.somaxconn=32688

#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭  
net.ipv4.tcp_syncookies = 1  

#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭  
net.ipv4.tcp_tw_reuse = 1  

#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭  
net.ipv4.tcp_tw_recycle = 1

#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间  
net.ipv4.tcp_fin_timeout=30

#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_syn_backlog = 8192

#表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。
#默认为180000,改为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于 Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。
net.ipv4.tcp_max_tw_buckets = 5000

#对外连接端口范围
net.ipv4.ip_local_port_range = 10240 65000
##表示文件句柄的最大数量
fs.file-max = 102400

# 多网卡防止丢包
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0

日期时间设置

  服务器部署在国外,使用美国时间会有夏时令问题;之前服务器未同步网络时间,会存在系统时间运行一段时间跑块,导致多台主机时间不一致。因此采用如下配置:

# 1.查看系统时间
timedatectl status
date

# 2.查看可用时区
timedatectl list-timezones

# 3.设置时区
timedatectl set-timezone America/New_York

# 4.设置时间同步
timedatectl set-ntp yes

# 5.设置硬件时钟为UTC时间
timedatectl set-local-rtc 0

# 6.设置系统读取GST时区,美国纽约涉及到夏时令,会存在时间调快和调慢1小时问题
vi /etc/profile
    export TZ='GST+5'
source /etc/profile

参考文档:https://www.cnblogs.com/lei0213/p/8723106.html

主机名称设置

# 1.查看主机名
uname -n

# 2.修改主机名
hostnamectl set-hostname cd-linux-34
hostnamectl set-hostname audit

主机登录提示设置

# 1.登录linux提示主机功能
echo "正式服Gate、Login、Hall服务器..." >/etc/motd

磁盘挂载

  下面是测试服磁盘空间不足,单独给jenkins挂载一个磁盘。

# 1.查看磁盘
df -kh
fdisk -l

# 2.创建挂载目录
cd /mnt/
mkdir jenkins

# 3.挂载,及开机自动挂载
mount /dev/vdb1 /mnt/jenkins/
echo '/dev/vdb1 /mnt/jenkins ext4 defaults 0 0' >> /etc/fstab

# 4.关闭jenkins 移动目录到新位置
mv /var/lib/jenkins/ /mnt/jenkins/

# 5.创建软连接,重启jenkins
ln -s /mnt/jenkins/jenkins /var/lib
service jenkins start

用户创建及权限设置

参考文档:https://blog.51cto.com/u_14557673/2446952

# 1.创建账号
useradd -M develop
# 2.修改密码
passwd develop
    123456
    123456

开发工具

Git

安装

# 1.安装
yum install -y git

# 2.查看版本
git version

命令


# 1.添加全部&目录
git add .
git add Assets/Scripts

# 2.提交 
git commit -m "初始化提交"

# 3.推送
git push -u origin develop 

# 4.取消提交
git reset @~

常见问题

1.Git Push remote: fatal: pack exceeds maximum allowed size

  • 取消提交 git reset @~,提交少量文件,再推送
  • 如果使用gitlab,可以到管理后台修改最大推送文件限制

Gitlab

   Gitlab是开源的仓库管理系统,在Git基础上添加了Web服务,类似Github,使用非常方便,因此公司内部自行搭建了Gitlab。

gitlab命令

参考文档:https://docs.gitlab.com/ee/administration/raketasks/maintenance.html#check-gitlab-configuration

# 1.查看系统信息和gitlab信息
sudo gitlab-rake gitlab:env:info

# 2.检查配置
sudo gitlab-rake gitlab:check

# 3.数据迁移检测
sudo gitlab-rake db:migrate:status

gitlab升级

参考文档:
https://docs.gitlab.com/ee/update/plan_your_upgrade.html https://docs.gitlab.com/ee/update/package/
https://docs.gitlab.com/ee/update/index.html#upgrade-paths

# 1.查看可用版本包
yum --showduplicates list gitlab-ee

# 2.更新到指定版本,gitlab必须一步一步的更新到最新版本,中间版本不能跳过
yum install gitlab-ee-13.8.8-ee.0.el7
yum install gitlab-ee-13.12.15-ee.0.el7
yum install gitlab-ee-14.0.12-ee.0.el7
yum install gitlab-ee-14.6.2-ee.0.el7

升级错误问题:
安装官方路径 yum install gitlab-ee-14.0.12-ee.0.el7 升级到 yum install gitlab-ee-14.6.2-ee.0.el7 报错
参考文档:https://docs.gitlab.com/ee/user/admin_area/monitoring/background_migrations.html#database-migrations-failing-because-of-batched-background-migration-not-finished

# 1.重新加载配置
sudo gitlab-ctl reconfigure

# 2.重新迁移数据库
sudo gitlab-rake db:migrate

Maven

Maven安装

参考文档:https://blog.csdn.net/djrm11/article/details/106340433
setting配置 setting.xml

# 1.官网下注包上传到 data目录
tar -xzvf apache-maven-3.6.3-bin.tar.gz
  
# 2.设置环境变量,在profile末尾添加
vi /etc/profile
    MAVEN_HOME=/data/apache-maven-3.6.3
    export PATH=${MAVEN_HOME}/bin:${PATH}
source /etc/profile

# 3.设置jdk版本
cd /data/apache-maven-3.6.3/bin
vim mvn
    JAVA_HOME=/data/java/jdk-14.0.2
    
# 4.修改setting配置

Nexus

Nexus 搭建公司内部maven私有仓库,便于公司内部包的版本管理,加速获取公共包。

Nexus3 安装

参考文档:https://hub.docker.com/r/sonatype/nexus3/#notes

# 1.创建挂载目录
mkdir /data/nexus-data

# 2.运行镜像
docker run -d -p 8081:8081 --name nexus -v /data/nexus-data:/nexus-data sonatype/nexus3

常见问题

私有仓库上传snapshot jar包,项目检出snapshot jar类文件找不到问题

参考文档:https://segmentfault.com/a/1190000022068814

  1. 配置pom.xml 拉取最新jar包
<repositories>
    <repository>
        <id>public</id>
        <url>http://192.168.0.1:8081/repository/maven-public/</url>
        <snapshots>
            <!-- 始终下载最新的 snapshot 包 ,因为协议消息在其他项目,时刻改变 -->
            <updatePolicy>always</updatePolicy>
        </snapshots>
    </repository>
</repositories>

  1. jar 包运行,pom.xml设置项目打包插件
<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-jar-plugin</artifactId>
 <version>3.2.0</version>
 <configuration>
     <archive>
         <manifest>
             <addClasspath>true</addClasspath>
             <classpathPrefix>lib/</classpathPrefix>
             <mainClass>com.game.gate.GateApp</mainClass>
             <!--配置可使用快照版本-->
             <useUniqueVersions>false</useUniqueVersions>
         </manifest>
     </archive>
 </configuration>
</plugin>

maven setting.xml 镜像配置错误导致拉取不到存在的jar包问题

参考文档: https://segmentfault.com/q/1010000019941502/a-1020000019941560

 <mirror>
        <id>public</id>
        <mirrorOf>*</mirrorOf>
        <name>central repository</name>
        <url>http://192.168.0.1:80/repository/maven-public/</url>
    </mirror> 

mirrorOf 最开始配置问central,导致上传到snapshot库中的jar包无法下载,改为*问题解决

Nps

  Nps内网穿透工具,可以实现外网连接公司电脑进行办公,特别是疫情期间居家办公和线上问题处理。

搭建

参考文档:
https://blog.csdn.net/qq_41225906/article/details/125888457
https://ehang-io.github.io/nps/#/

# 1.服务器搭建
# 1.1 下载
cd /data
mkdir nps
cd nps
wget https://github.com/ehang-io/nps/releases/download/v0.26.10/linux_amd64_server.tar.gz
tar -xzvf linux_amd64_server.tar.gz
# 1.2安装,启动,关闭
./nps install
nps start
nps stop

# 2.进入网页后台进行配置,创建用户,TCP隧道

# 3.Windows 连接服务器
npc.exe -server=127.0.0.1:8024 -vkey=7fx8smcst1cp0rw3 -type=tcp
# 3.1注册服务,运行,停止
npc.exe install -server=127.0.0.1:8024 -vkey=7fx8smcst1cp0rw3 -type=tcp
npc.exe start
npc.exe stop

# 4.远程连接地址
mstsc
127.0.0.1:8888     

项目部署

Docker

  因为slots类游戏有上百个子游戏,每个子游戏都是单独的服务,如果使用传统的服务器部署一整套或更新将是恶魔般的存在,因此用docker搭建了一套自动化部署流程。

部署流程

部署流程图

环境搭建

Linux环境搭建

安装

安装参考:https://www.linuxprobe.com/install-use-docker-in-centos7.html

# 1.安装
yum install docker

# 2.查看版本号
docker version

# 3.启动
systemctl  start docker.service

# 4.开机启动
systemctl  enable docker.service

私有仓库安装

参考文档:
https://hub.docker.com/_/registry
https://docs.docker.com/registry/

docker run -d -p 5000:5000 --restart=always -v /data/registry:/var/lib/registry --name registry registry:2

配置远程访问

# 1.配置远程访问 替换如下内容,记得开放2375端口的访问权限
vi /lib/systemd/system/docker.service
    ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock -H tcp://0.0.0.0:7654

# 2.配置docker参数,添加如下内容
vi /etc/docker/daemon.json
    {
        "insecure-registries":[
            "192.168.0.1:5000"
        ],
        "registry-mirrors":[
            "https://6kx4zyno.mirror.aliyuncs.com"
        ],
        "log-driver":"json-file",
        "log-opts":{
            "max-size":"1000m",
            "max-file":"1"
        }
    }

错误处理

ln -s /usr/libexec/docker/docker-proxy-current /usr/bin/docker-proxy
ln -s /usr/libexec/docker/docker-proxy-current /usr/bin/docker-proxy
ps -aux | grep -v grep | grep docker-proxy
systemctl stop docker.service
docker rm $(docker ps -aq)
systemctl status docker.service
cd /usr/libexec/docker/
sudo ln -s docker-runc-current docker-runc 

windows docker数据盘设置

  docker 安装默认镜像目录在C盘中,使用一段时间后此文件特别大,然而电脑C盘空间太小, 因此需要将此文件移动到空间大的磁盘上。
参考文档:https://blog.csdn.net/weixin_47513022/article/details/120083726

维护

常用命令

# 1.进入容器
docker exec -it d1412927d331 /bin/sh
# 管理员进入才可编辑配置文件
docker exec -it --user root  a6882651c45b /bin/sh

# 2. 内存 cpu查看
docker stats
# 2.1 不显示名称处理方案
docker stats $(docker ps --format '{{.Names}}')

# 3.日志查看
docker logs -f 8da217c8723a

# 4.docker信息
docker info
docker container inspect 73a656d7fe44

# 5.网络
docker network ls

磁盘清理

# 1.目录磁盘占用
du -h

# 2.统计当前目录大小
du -sh ./*
du -sh /data

# 3.系统磁盘
df -h

# 4.docker查看磁盘
docker system df

# 5.清理磁盘,删除关闭的容器、无用的数据卷和网络,以及dangling镜像
docker system prune

# 6.删除所有没使用的镜像
docker system prune -a

线上问题

  • failed to retrieve docker-init version Mar 26 01:25:00 ip-172-31-62-192.us-west-2.compute.internal dockerd[1458]: time="2021-03-26T02:25:00.103411934-04:00" level=warning msg="failed to retrieve docker-init version"
      官方解释版本太老,已经不维护, 版本1.13,正式服docker需要更新,现在是17年版本了

  • Cannot connect to the Docker daemon at tcp://0.0.0.0:2375. Is the docker daemon running   因为阿里云服务器进行yum update 所有软件,导致docker版本更新到 1.41 (20.10.12)导致之前的配置失效,从新配置远程访问

  • ERROR: ZONE_CONFLICT: 'docker0' already bound to a zone
      因为阿里云服务器进行yum update 所有软件,导致docker版本更新到 1.41 (20.10.12),更新防火墙设置。 参考文档:https://www.cnblogs.com/wxbn/p/15057806.html

 # 1.检查firewall-cmd中是否存在docker zone 
 firewall-cmd --get-active-zones
 
 # 2.如果“docker”区域可用,将接口更改为 docker0(非持久化)
 sudo firewall-cmd --zone=docker --change-interface=docker0
 
 # 3.如果“docker”区域可用,请将接口更改为 docker0(持久化)
 sudo firewall-cmd --permanent --zone=docker --change-interface=docker0 
 sudo systemctl restart firewalld
 
 # 4.启动docker 
 systemctl  start  docker
 
 # 5。查看
 systemctl status docker

docker中查看 java堆栈信息

参考文档: http://t.zoukankan.com/duanxz-p-10238570.html

# 1.查看容器id
docker ps

# 2.进入docker
docker exec -it 26612c5d62a2 /bin/sh

# 3.查看java进程
jps

# 4.输出堆栈信息
jstack 1

Jenkins

安装

参考文档:
https://pkg.jenkins.io/redhat-stable/
https://www.jianshu.com/p/368685768680

# 1.安装
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key

yum install jenkins
# 2.配置启动 
vi /etc/sysconfig/jenkins
   JENKINS_PORT=40015
   JENKINS_JAVA_OPTIONS="-server -Xms1024m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m -Djava.awt.headless=true"
chkconfig jenkins on
service jenkins start
  • 错误处理:AWT is not properly configured on this server https://blog.csdn.net/qq_44959735/article/details/104363491

  • mvn 命令无法识别问题
    https://www.jianshu.com/p/993ffb82ee0e

Windows 编码设置

  进入 E:\Program Files\Jenkins 在jenkins.xml中设置启动参数 -Dfile.encoding=UTF-8

TODO 结合docker进行流程介绍

数据库

MongoDB

安装

Docker安装

参考文档:
https://www.runoob.com/docker/docker-install-mongodb.html
https://hub.docker.com/_/mongo?tab=description

 # 1. 运行镜像
docker run -itd --name mongo-3.6.23 -p 27017:27017 mongo:3.6.23 --auth

# 2. 进入容器创建账号
$ docker exec -it mongo-3.6.23 mongo admin
# 创建一个名为 admin,密码为 123456 的用户。
db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]});
# 尝试使用上面创建的用户信息进行连接。
db.auth('admin', '123456')

# 3. 连接地址
mongodb://admin:123456@192.168.0.1:27017/?authSource=admin&readPreference=primary&appname=MongoDB%20Compass&ssl=false

CentOS7 安装&配置

参考文档:
https://docs.mongodb.com/v3.6/tutorial/install-mongodb-on-red-hat/

# 1.设置安装源
vim /etc/yum.repos.d/mongodb-org-3.6.repo
    [mongodb-org-3.6]
    name=MongoDB Repository
    baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.6/x86_64/
    gpgcheck=1
    enabled=1
    gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc

# 2.安装
sudo yum install -y mongodb-org

# 3.启动
sudo systemctl start mongod

# 4.开机启动
sudo systemctl enable mongod

# 5.关闭|重启
sudo systemctl stop mongod
sudo systemctl restart mongod

# 连接
mongo --host 127.0.0.1:27017

配置 Disable Transparent Huge Pages (THP)

参考文档:https://docs.mongodb.com/v3.6/tutorial/transparent-huge-pages/

配置文件mongod.conf

参考文档: https://docs.mongodb.com/v3.6/administration/configuration/
  外网访问和密码验证,文件路径/etc/mongod.cnf,添加修改如下内容:

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0  # Listen to local interface only, comment to listen on all interfaces.
#security:
security:
  authorization: enabled

连接数设置

官方推荐设置:https://docs.mongodb.com/v3.6/reference/ulimit/#recommended-ulimit-settings

-f (file size): unlimited
-t (cpu time): unlimited
-v (virtual memory): unlimited [1]
-l (locked-in-memory size): unlimited
-n (open files): 64000
-m (memory size): unlimited [1] [2]
-u (processes/threads): 64000

每日备份

参考文档:https://www.jb51.net/article/135847.htm

# 1.创建存储目录
cd /data
mkdir mongo
mkdir backup
mkdir backup/now
mkdir backup/list

# 2.编辑脚本
vim backup.sh
    #!/bin/sh
    OUT_DIR=/data/mongo/backup/now #临时备份目录
    TAR_DIR=/data/mongo/backup/list #备份存放路径
    DATE=`date +%Y_%m_%d` #获取当前系统时间
    DB_USER=root #数据库账号
    DB_PASS=123456 #数据库密码
    DAYS=7 #DAYS=7代表删除7天前的备份,即只保留最近7天的备份
    TAR_BAK="mongo_backup_$DATE.tar.gz" #最终保存的数据库备份文件名
    cd $OUT_DIR
    rm -rf $OUT_DIR/*
    mkdir -p $OUT_DIR/$DATE
    mongodump -u $DB_USER -p $DB_PASS -o $OUT_DIR/$DATE #备份全部数据库
    tar -zcvf $TAR_DIR/$TAR_BAK $OUT_DIR/$DATE #压缩为.tar.gz格式
    find $TAR_DIR/ -mtime +$DAYS -delete #删除7天前的备份文件

# 3.添加脚本执行权限
chmod +x backup.sh

# 4.添加定时任务,每天凌晨2点30进行备份
crontab -e
  30 2 * * * sh /data/mongo/backup.sh
crontab -l

将备份数据复制到另外一台主机

参考文档:https://blog.csdn.net/gjwgjw1111/article/details/103515031 (有坑,不要在配置文件中加注释)
数据库所在服务器1 每日定时将数据推送到服务器2

备份主机2
# 1.查询rsync是否安装
rpm -qa rsync

# 2.创建备份目录
mkdir /data/mongo/backup
chown -R nobody:nobody /data/mongo/backup

# 3.编辑服务器配置文件,输入如下内容
vim /etc/rsyncd.conf
    #以下是全局配置
    log file = /var/log/rsyncd.log
    pid file = /var/run/rsyncd.pid
    lock file = /var/lock/rsyncd
    use chroot = yes
    read only = no
    [mongobackup]
       comment = sync rsync/data/mongo/backup
       path = /data/mongo/backup
       gid = root
       max connections = 10
       auth users = root
       secrets file = /etc/rsyncd.pass
       hosts allow = 172.31.49.33,127.0.0.1
       timeout = 600

# 4.创建认证文件,输入如下内容
vi /etc/rsyncd.pass
    root:123456
chmod 600 /etc/rsyncd.pass
vim /etc/xinetd.d/rsync
    service rsync
    {
            disable = no
            socket_type = stream
            wait = no
            user = root
            server = /usr/bin/rsync
            server_args = --daemon
            log_on_failure += USERID
    }

# 5.启动服务器 重启时记得删除rsyncd.pid:‘rm -rf /var/run/rsyncd.pid’
rsync --daemon --config=/etc/rsyncd.conf

# 6.开启端口,防火墙设置
sudo firewall-cmd --zone=public --add-port=873/tcp --permanent
mongodb安装端
# 1.创建账号密码
vi /etc/rsync_client.pwd
    123456
chmod 600 /etc/rsync_client.pwd

# 2.同步目录测试
rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd /data/mongo/backup/list root@172.31.55.20::mongobackup

# 3.回到 每日备份 在backup.sh中添加如下代码
rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd $TAR_DIR/$TAR_BAK root@172.31.55.20::mongobackup

自动删除备份数据

# 1.创建备份文件 redis、mongodb一样,只是路径不同
touch delete_backup.sh
chmod 754 delete_backup.sh
vim delete_backup.sh
    #!/bin/sh
    find /data/mongo/backup/ -mtime +30 -delete

# 2.删除30天前的备份文件pw
crontab -e
   30 2 * * * sh /data/mongo/delete_backup.sh
   35 2 * * * sh /data/redis/delete_backup.sh
crontab -l

命令操作

账号密码

参考文档:
https://www.jianshu.com/p/d21cdf929a2e
https://docs.mongodb.com/v3.6/tutorial/enable-authentication/

# 1.创建管理员账号
use admin
db.createUser(
  {
    user: "root",
    pwd: "123456",
    roles: [
       { role: "userAdminAnyDatabase", db: "admin" }
    ]
  }
)

# 2.登录
db.auth('root','123456')
mongo -u root -p 123456


# 3.授权
 db.grantRolesToUser(
    "root",
    [
        { role: "root", db: "admin" },
    ]
)
db.grantRolesToUser("root",[{role:"readWrite",db:"common"}])

# 4.读写权限账号
db.createUser(
  {
    user: "admin",
    pwd: "123456",
    roles: [
       { role: "readWriteAnyDatabase", db: "admin" }
    ]
  }
)
db.auth('admin','123456')

# 5.查看权限账号
db.createUser(
  {
    user: "read",
    pwd: "123456",
    roles: [
       { role: "readAnyDatabase", db: "admin" }
    ]
  }
)

# 6.数据库权限账号
db.createUser({user:"hall",pwd:"123456",roles:[{role:"readWrite",db:"game-hall"}]})

# 7.删除用户
db.dropUser("slots")

性能统计设置

参考文档:https://docs.mongodb.com/v3.6/tutorial/manage-the-database-profiler/#database-profiling-view-status

db.setProfilingLevel(1)
# 最近10条慢操作
db.system.profile.find().limit(10).sort( { ts : -1 } ).pretty()

数据备份还原

参考文档:
https://docs.mongodb.com/v3.6/tutorial/backup-and-restore-tools/
https://www.cnblogs.com/clsn/p/8244206.html

# 1.备份
cd /data/mongo/backup
mkdir 2020****
cd 2020****
mongodump --username root --password 123456
#显示备份目录大小
du -h --max-depth=1 /data/mongo/backup/    

# 2.数据还原
mongorestore --host mongodb1.example.net --port 3017 --username user --password 'pass' /opt/backup/mongodump-2013-10-24
mongorestore -h 172.31.49.33:27017 -uroot -p123456 --authenticationDatabase admin -d game-hall -c club /data/mongo/backup/now/2022_01_07/game-hall/club.bson

常用命令

# 1.查询 昵称包含指定字符串,显示指定字段
db.role.find({"nick":{$regex:"Helen"}},{nick:1,rid:1,gold:1})
db.player.find({"level":{"$gte":50}},{_id:1,nick:1,level:1})

# 2.查询所有注册人数
db.getCollection('role').find({"roleType":0}).count({})

# 3.查询平台充值总和
db.billing_order.aggregate([
   { $match: { status: 200 } },
   { $group: { _id: "$platform", total: { $sum: "$price" } } }
])

# 4.查询总注册人数
db.role.aggregate([
   { $group: { _id: "$roleType", count: { $sum: 1 } } }
])

# 5.查询最近时间段登录人数
db.role.aggregate([
   { $match: { lastLoginTime: {"$gt":ISODate("2021-01-01T00:00:01.303Z")} } },
   { $group: { _id: "$roleType", count: { $sum: 1 } } }
])
db.role.aggregate([
   { $match: { registerTime: {"$lt":ISODate("2021-01-08T00:00:01.303Z"),"$gt":ISODate("2021-01-07T00:00:01.303Z")} } },
   { $group: { _id: "$roleType", count: { $sum: 1 } } }
])

# 6.查询人数大于10的公会
db.club.aggregate([
    {$project:{memberCount:{$size:"$memberIds"}}},
    {$match:{memberCount: {$gte:10}}}
 ]).itcount()

# 7.模糊查询
{"nick":{$regex:/^.*emp.*$/i}}

# 8.删除
db.config_board.deleteMany({"type":2})

# 9.数组大小查询
{"firstEnter":true,"refreshTime":{"$gt":1646024300450},"pushCoin.levelEntries":{"$exists":true},"$where": "this.pushCoin.levelEntries.length>1" }

# 10.查看可用连接
db.serverStatus().connections

# 11.查询性能分析
db.account.find({"rid":1000037}).explain("executionStats")

# 12.创建索引
db.account.createIndex( { "accountName" : 1 } )

Redis

安装

Docker安装

参考文档: https://hub.docker.com/_/redis/?tab=description&page=1&ordering=last_updated

# 1. 创建挂载目录
cd data
mkdir redis

# 2. 拉取镜像并运行 
docker run --name redis-5.0.12 --restart=always -p 6379:6379 -v /data/redis:/data -d redis:5.0.12 redis-server --appendonly yes --requirepass 123456

CentOS7安装

参考文档:https://www.cnblogs.com/heqiuyong/p/10463334.html

  • 安装路径: /usr/local/redis
  • 配置|命令路径:/usr/local/redis/bin
  • 数据|日志路径:/data/redis
  • redis.conf 修改内容

每日备份

参考文档:https://blog.csdn.net/Junetest/article/details/104796142/

  • 脚本地址/data/redis/backup.sh
  • 日志路径:/var/spool/mail/root
 # 1.编辑脚本
 cd /data/redis
 vim backup.sh
     #! /bin/bash
     PATH=/usr/local/redis/bin:$PATH
     redis-cli -p 6379 bgsave
     date=$(date +"%Y%m%d")
     cp /data/redis/dump.rdb /data/redis/backup/dump$date.rdb
     echo " 备份完成!"
     DAYS=7
     find /data/redis/backup/ -mtime +$DAYS -delete #删除7天前的备份文件
     echo "删除7天前数据备份完成!"
 chmod +x backup.sh

# 2.添加定时任务,每天凌晨两点半备份
crontab -e
  30 2 * * * sh /data/redis/backup.sh
crontab -l

将备份数据赋值到另外一台主机

详细操作参考: mongodb备份/将备份数据赋值到另外一台主机

备份端配置
# 1.编辑服务器配置,末尾添加
vim /etc/rsyncd.conf
   #以下是全局配置
   [redisbackup]
   comment = sync rsync/data/redis/backup
   path = /data/redis/backup
   gid = root
   max connections = 10
   auth users = root
   secrets file = /etc/rsyncd.pass
   hosts allow = 172.31.49.33,127.0.0.1
   timeout = 600

 # 2.创建备份目录
mkdir /data/redis/backup
chown -R nobody:nobody /data/redis/backup

# 3.启动服务器 重启时记得删除rsyncd.pid:‘rm -rf /var/run/rsyncd.pid’
rsync --daemon --config=/etc/rsyncd.conf
redis安装端
# 1.同步目录测试
rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd /data/redis/backup root@172.31.55.20::redisbackup

# 2.回到 每日备份 在backeup.sh中添加如下代码
rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd /data/redis/backup/dump$date.rdb root@172.31.55.20::redisbackup

操作

常用系统命令

cd /usr/local/redis/bin/
# 1.查看redis状态
./redis-cli -p 6379 --stat	

# 2.查看统计最大键
./redis-cli --bigkeys -p 6379	

# 3.监控redis操作
./redis-cli -p 6379 monitor	

# 4.延迟测试
./redis-cli -p 6379 --latency	

# 5.历史延迟
./redis-cli -p 6379 --latency-history 

# 6.数据备份  https://blog.csdn.net/rentian1/article/details/93845092
./redis-cli -p 6379 --rdb /data/redis/backup/dump20201104.rdb	

性能测试

参考文档:https://redis.io/topics/benchmarks

# 1.测试
./redis-benchmark -p 6379 -q -n 100000
    PING_INLINE: 82918.74 requests per second
    PING_BULK: 81900.09 requests per second
    SET: 80128.20 requests per second
    GET: 82304.52 requests per second
    INCR: 84317.03 requests per second
    LPUSH: 78678.20 requests per second
    RPUSH: 84961.77 requests per second
    LPOP: 84388.19 requests per second
    RPOP: 83194.67 requests per second
    SADD: 85543.20 requests per second
    HSET: 84674.01 requests per second
    SPOP: 83682.01 requests per second
    LPUSH (needed to benchmark LRANGE): 82576.38 requests per second
    LRANGE_100 (first 100 elements): 48828.12 requests per second
    LRANGE_300 (first 300 elements): 24576.06 requests per second
    LRANGE_500 (first 450 elements): 18484.29 requests per second
    LRANGE_600 (first 600 elements): 15130.88 requests per second
    MSET (10 keys): 69156.30 requests per second

# 2.测试
./redis-benchmark -p 6379 -r 1000000 -n 2000000 -t get,set,lpush,lpop -P 16 -q
    SET: 547195.62 requests per second
    GET: 893655.06 requests per second
    LPUSH: 672721.12 requests per second
    LPOP: 736106.00 requests per second

# 3.测试
./redis-benchmark -p 6379 -r 1000000 -n 2000000 -t get,set,lpush,lpop -q
    SET: 83329.86 requests per second
    GET: 82736.94 requests per second
    LPUSH: 84409.55 requests per second
    LPOP: 83710.03 requests per second

Elasticsearch

  使用Elasticsearch进行集中日志查询管理;Linux主机,Docker,数据库等监控;应用程序性能,运行状态监控。

安装

1.ElasticSearch安装

参考文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.10/docker.html

# 1.拉取镜像
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.10.2

# 2.创建数据挂载目录并授权
cd /data
mkdir elasticsearch
chmod g+rwx elasticsearch
chgrp 0 elasticsearch

# 3.启动单个节点
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -v /data/elasticsearch:/usr/share/elasticsearch/data -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.10.2

# 4.测试查看信息
http://127.0.0.1:9200/_cat/nodes?v=true&pretty

2.Kibana安装

  Web查询客户端。参考文档:https://www.elastic.co/guide/en/kibana/7.10/docker.html

# 1.拉取镜像
docker pull docker.elastic.co/kibana/kibana:7.10.2

# 2.运行
docker run -d --name kibana --link elasticsearch:elasticsearch -p 5601:5601 docker.elastic.co/kibana/kibana:7.10.2

# 3.配置 
docker ps -f name=kibana
docker exec -it e431d5f8c92b /bin/sh
cd config
vi kibana.yml
# 3.1中文显示 添加如下内容
    i18n.locale: "zh-CN"

# 4.访问地址:http://127.0.0.1:5601/     

3.Filebeat安装

  使用filebeat将本地日志文件传送到Elasticsearch数据库中。 参考文档:https://www.elastic.co/guide/en/beats/filebeat/7.10/filebeat-installation-configuration.html
配置文件参考:filebeat.yml

# 1.下载运行包
cd /data/elasticsearch
curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.10.2-linux-x86_64.tar.gz
tar xzvf filebeat-7.10.2-linux-x86_64.tar.gz

# 2.连接elasticsearch
cd filebeat-7.10.2-linux-x86_64
vim filebeat.yml
    output.elasticsearch:
      hosts: ["127.0.0.1:9200"] 
    setup.kibana:
      host: "127.0.0.1:5601"
    
    - type: log
      enabled: true
      paths:
        - /var/log/*.log
        - /data/game/*/*.log

# 3.查看|使用模块
./filebeat modules list
./filebeat modules enable system
./filebeat setup -e

# 4.启动
sudo chown root filebeat.yml 
sudo chown root modules.d/system.yml 
nohup ./filebeat -e >/dev/null  &
#必须exit退出一下,不然filebeat进程运行一段时间会退出
exit

4.APM Server 安装

  监控应用程序,安装的7.10版本最大支持到Jdk11,可用Skywalking替代。
参考文档:
https://www.elastic.co/guide/en/apm/get-started/7.10/install-and-run.html
https://www.elastic.co/guide/en/apm/server/7.10/installing.html
https://www.elastic.co/guide/en/apm/server/7.10/running-on-docker.html
https://www.elastic.co/guide/en/apm/server/7.10/configuration-process.html
http://47.108.13.34:40014/app/home#/tutorial/apm
配置文件参考:hall/apm-server.yml

# 1.下载并解压缩 APM Server
curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-7.10.2-x86_64.rpm
sudo rpm -vi apm-server-7.10.2-x86_64.rpm

# 2.启动
service apm-server start

# 3.常用配置
vim apm-server.yml 
    apm-server:
      host: "0.0.0.0:8200
    kibana:
        enabled: true
        host: "127.0.0.1:5601"
    rum:
        enabled: true
        
    output.elasticsearch:
      hosts: ["127.0.0.1:9200"]

5.Heartbeat 安装

  监控引用程序是否在运行状态中,实际生产中使用较少。例如应用程序像InfluxDB写数据,结合Grafana来监控。 参考文档:https://www.elastic.co/guide/en/observability/7.10/ingest-uptime.html
配置文件参考:heartbeat.yml

# 1.下载运行包
cd /data/elasticsearch
curl -L -O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-7.10.2-linux-x86_64.tar.gz
tar xzvf heartbeat-7.10.2-linux-x86_64.tar.gz

# 2.连接elasticsearch
cd heartbeat-7.10.2-linux-x86_64
vim heartbeat.yml
    heartbeat.monitors:
    - type: http
      id: ElasticSearch
      name: ElasticSearch
      urls: ["http://127.0.0.1:9200"]
      schedule: '@every 10s'
    - type: tcp
      id: GateClient1
      name: GateClient1
      schedule: '@every 5s'
      hosts: ["127.0.0.1:2012"]
      mode: any

    output.elasticsearch:
      hosts: ["127.0.0.1:9200"] 
    setup.kibana:
      host: "127.0.0.1:5601"

# 3.查看|使用模块
./heartbeat setup -e

# 4.启动
sudo chown root heartbeat.yml 
nohup ./heartbeat -e >/dev/null  &
#必须exit退出一下,不然heartbeat进程运行一段时间会退出
exit

# 5.配置http,tcp网络监控
cd monitors.d
cp sample.http.yml.disabled register.http.yml
vim register.http.yml

6.Metricbeat安装

  监控linux服务器内存、CPU、网络、磁盘,MongoDB数据库,Docker等,可使用InfluxDB替代。 参考文档:https://www.elastic.co/guide/en/beats/metricbeat/7.10/metricbeat-installation-configuration.html

# 1.下载运行包
cd /data/elasticsearch
mkdir metricbeat
curl -L -O https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-7.10.2-linux-x86_64.tar.gz
tar xzvf metricbeat-7.10.2-linux-x86_64.tar.gz

# 2.连接elasticsearch
cd metricbeat-7.10.2-linux-x86_64
vim metricbeat.yml

    output.elasticsearch:
      hosts: ["localhost:9200"] 
    setup.kibana:
      host: "localhost:5601"
 cd modules.d
 #修改mongodb数据库连接地址用户名和密码
 vim mongodb.yml 
 

# 3.查看|使用模块(系统,docker,mongodb)
./metricbeat modules list
./metricbeat modules enable system mongodb docker
./metricbeat setup -e

# 4.启动
sudo chown root metricbeat.yml 
sudo chown root modules.d/system.yml 
sudo chown root modules.d/docker.yml 
sudo chown root modules.d/mongodb.yml 
nohup ./metricbeat -e >/dev/null  &
#必须exit退出一下,不然filebeat进程运行一段时间会退出
exit

查询

1.查询匹配的日志内容

curl -X GET "localhost:20011/filebeat-*/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "message": "国家"
    }
  }
}
'

2.kibana查询

参考文档:
https://www.jianshu.com/p/9d511ea3a49d
https://blog.csdn.net/jack1liu/article/details/102531714

  • 全词查询
    message:"正常退出游戏"

监控系统

Grafana

安装

1.运行docker镜像

docker run -d --name=grafana -p 3000:3000 grafana/grafana

2.访问地址 http://192.168.0.1:3000/ ,账号admin 密码admin
3.修改配置文件

# 1.进入docker
docker exec --user root -it a6882651c45b /bin/sh

# 2.修改默认URL地址,重启docker容器
cd config
vi defaults.ini
root_url = %(protocol)s://192.168.0.1:3000

4.钉钉监控预警通知
在钉钉群群创建Webhook如下机器人
钉钉机器人创建

复制URL到Grafana设置通知渠道 Grafana通知渠道

注意: 预警文本需要包含钉钉设置的关键字

5.安装redis数据源插件 进入docker运行命令grafana-cli plugins install redis-datasource重启服务器

InfluxDB

安装

1. InfluxDB安装

  1. docker安装命令:
 docker run -d --name influxdb -p 8086:8086 --restart=always -e TZ="America/Chicago" quay.io/influxdb/influxdb:v2.0.3 --reporting-disabled
  1. 浏览器访问:http://127.0.0.1:8086/
    账号:root 密码: 123456

2. Telegraf安装

参考地址:https://docs.influxdata.com/telegraf/v1.17/introduction/installation/
配置文件路径:/etc/telegraf/telegraf.conf

# 1.编辑安装源
cat <<EOF | sudo tee /etc/yum.repos.d/influxdb.repo
[influxdb]
name = InfluxDB Repository - RHEL \$releasever
baseurl = https://repos.influxdata.com/rhel/\$releasever/\$basearch/stable
enabled = 1
gpgcheck = 1
gpgkey = https://repos.influxdata.com/influxdb.key
EOF

# 2.安装
sudo yum install telegraf

# 3.启动
sudo systemctl start telegraf

# 4.停止(注意正式服需要停止默认服务,没有配置,开机自动启动)
systemctl stop telegraf

3. Telegraf配置

  1. 自动配置
    服务器监控,docker,redis为自动配置
    参考:https://docs.influxdata.com/influxdb/v2.0/write-data/no-code/use-telegraf/auto-config/
  2. 手动配置
    参考:https://docs.influxdata.com/influxdb/v2.0/write-data/no-code/use-telegraf/manual-config/

4. 删除数据库

参考文档:https://docs.influxdata.com/influxdb/v2.0/write-data/delete-data/

# 1.进入容器
docker exec -it 7df65a67e3ba /bin/bash
    
# 2.删除命令
influx delete --org game-aws --bucket game-server \
  --token uf6uM-veNG_RcJVXdWfloYodv3pNFMQBSHxh9br8QMg9Qsr_6aT1pif_cdCiWAZ3mU5vIEc9K_2daCtK_V9g== \
  --start '1970-01-01T00:00:00Z' \
  --stop '2021-11-14T00:00:00Z' \
  --predicate '_measurement="game_info"'

5. 数据监控

  配置文件参考: LinuxMongoDBRedisDocker

# 1.设置环境变量
export INFLUX_TOKEN=m4jOs8bnYI05Gg7bXCqdKWVOQtTzZBDJby1pMfvKgvrq_sFxxmB3KvZjGzaZ1iXw-a0KnQSkib4i5euvzQw==

# 2.启动telegraf
nohup telegraf --config http://127.0.0.1:8086/api/v2/telegrafs/07a13141c3f98000 >/dev/null  &

# 3. linux本地配置启动
nohup telegraf --config /data/telegraf/LinuxTelegraf.conf >/dev/null  &
nohup telegraf --config /data/mongo/MongodbTelegraf.conf >/dev/null  &
nohup telegraf --config /data/mongo/Rediselegraf.conf >/dev/null  &
nohup telegraf --config /data/mongo/DockerTelegraf.conf >/dev/null  &

Skywalking

  监控java 进程信息,elasticsearch apm 有类似功能,但是只支持到了jdk11。

安裝

# 1.下载
cd /data/
wget https://archive.apache.org/dist/skywalking/8.7.0/apache-skywalking-apm-es7-8.7.0.tar.gz
tar -xzvf apache-skywalking-apm-es7-8.7.0.tar.gzrm
rm -rf apache-skywalking-apm-es7-8.7.0.tar.gz

# 2.配置 数据存储为elasticsearch
cd apache-skywalking-apm-bin-es7/config
vim application.yml
    storage:
    selector: ${SW_STORAGE:elasticsearch7}
    
    elasticsearch7:
      nameSpace: ${SW_NAMESPACE:""}
      clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:127.0.0.1:9000}
      
  # 3.配置web查看端口
  cd  apache-skywalking-apm-bin-es7/webapp
  vim webapp.yml
  
      server:
        port: 9001
        
  # 4.启动
  cd apache-skywalking-apm-bin-es7/bin
  ./startup.sh

Java docker agent 配置

参考:https://blog.csdn.net/gre_999/article/details/101726367

见项目dockerfile文件和docker启动脚本

常见问题

1.谷歌浏览器不显示仪表盘数据

清除缓存,或者换个浏览器,使用Edge

Sentry

  提供错误日志查询,预警,文档参考:https://docs.sentry.io/product/

安装

  官网只看见linux docker-compose安装教程,而且对docker和docker-compose有要求,sentry服务太多,较耗内存。安装脚本下载 ,参考文档:
https://github.com/getsentry/self-hosted/releases
https://develop.sentry.dev/self-hosted/

# 1.解押及安装
mkdir /data/sentry
unzip self-hosted-22.8.0.zip
cd self-hosted-22.8.0
./install.sh

# 2.启动 访问地址:<http://127.0.0.1:9000/>
docker-compose up -d

# 3.停止
docker-compose down

诊断工具

Arthas

  进行线上Java应用问题排查。参考文档:

环境部署

# 1.运行,因为有多个java版本,需要指定路径
cd /data/java/
/data/java/jdk-14.0.2/bin/java -jar arthas-boot.jar --target-ip 0.0.0.0

命令参考

1.docker运行 arthas

docker里出现arthas无法工作的问题,是因为应用没有安装 JDK ,而是安装了 JRE

# 1.docker 运行(官方使用,实际不行,docker容器没有wget 命令)
docker exec -it  ${containerId} /bin/bash -c "wget https://arthas.aliyun.com/arthas-boot.jar && java -jar arthas-boot.jar"

# 2.使用curl 方式进行
docker exec -it bcd75 /bin/bash
curl https://arthas.aliyun.com/arthas-boot.jar --output arthas-boot.jar
java -jar arthas-boot.jar
    dashboard
    thread -all

2.仪表盘查看概要信息

dashboard

3.查看线程

  • thread -b, 找出当前阻塞其他线程的线程
  • thread –all, 显示所有匹配的线程
  • thread -n 3 3个最忙的线程
  • thread 49 显示线程id为49的堆栈信息
  • thread --state WAITING 查看等待状态的线程

4.查看内存

  • memory 查看内存信息

5.日志修改

# 1.查看指定名称日志
logger -n com.dls

# 2.修改日志级别
logger --name com.dls --level info

6.调优,性能、bug排查

# 1.查看类信息
sc -d com.dls.slots.gate.service.GateService

# 2.查看方法信息
sm -d com.dls.slots.gate.service.GateService init

# 3.查看类加载信息
classloader

# 4.监控方法执行次数和耗时
monitor -c 5 com.dls.slots.gate.tcp.user.UserTcpServerHandler channelRead

# 5.跟踪函数执行,统计耗时
trace com.dls.slots.gate.tcp.user.UserTcpServerHandler channelRead

# 6.方法调用栈
stack com.dls.slots.gate.tcp.user.UserTcpServerHandler channelRead

# 7. 查看方法返回值,参数,执行时间,是否异常等
tt -t com.dls.slots.gate.sturct.User sendToUser

三方组件

Nginx

安装

安装参考:http://nginx.org/en/linux_packages.html 配置路径:/etc/nginx/

# 1.安装前置软件
sudo yum install yum-utils
vim /etc/yum.repos.d/nginx.repo
    [nginx-stable]
    name=nginx stable repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    
    [nginx-mainline]
    name=nginx mainline repo
    baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=0
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true

# 2.安装
sudo yum install nginx

# 3.退出
nginx -s quit
service nginx stop
# 4.启动
nginx
service nginx start
# 5.重载配置
nginx -s reload
sudo systemctl reload nginx
# 6.重启
nginx -c /etc/nginx/nginx.conf

配置

文件下载

# 1.创建目录文件
mkdir /data/download
 
# 2.配置download.conf
vim download.conf
   server {
       listen       8012;
       listen  [::]:8012;
       auth_basic           "input password";
       auth_basic_user_file /etc/nginx/conf.d/password;
       location ^~ /download/ {
          #需要下载的文件存放的目录
           alias  /data/download/;
           sendfile on;
           autoindex on;  # 开启目录文件列表
           autoindex_exact_size on;  # 显示出文件的确切大小,单位是bytes
           autoindex_localtime on;  # 显示的文件时间为文件的服务器时间
           charset utf-8,gbk;  # 避免中文乱码
       }
   }
 
# 3.加载配置
nginx -s reload

常见问题

  • bind() to 0.0.0.0:XXXX failed (13: Permission denied)
# 1.查看http可访问端口
semanage port -l | grep http_port_t
# 2.设置http访问端口
semanage port -a -t http_port_t  -p tcp 8090

参考:https://blog.csdn.net/cbmljs/article/details/88574122

代理和被代理端口都需要设置

  • recv() failed (104: Connection reset by peer) while reading response header from upstream, client: game-manage 项目docker端口映射错误,导致不能访问

  • 502 no live upstreams while connecting to upstream 大厅报错,未正常返回数据,导致nginx连接耗尽
    配置 keepalive 256; 共用长链接
    参考:https://blog.csdn.net/donkeyboy001/article/details/119548514

Zookeeper

安装

Docker 安装

参考文档:https://hub.docker.com/_/zookeeper

# 1.拉取镜像并运行
docker run --name zookeeper -p 2181:2181 --restart always -d zookeeper

控制台命令

# 1.进入服务器
cd /data/apache-zookeeper-3.6.1-bin/bin

# 2.连接zookeeper
./zkCli.sh -timeout 5000 -server 127.0.0.1:2181

# 3.查看帮助命令
h

# 4.查看节点及状态
ls /
stat game

# 6.创建&获取路径数据
create /game/online/log/grpc 127.0.0.1:8305,127.0.0.1:8306
get /game/online/log/grpc

# 7.退出
quit

参数配置

最大连接数配置

  最大连接数默认每台主机最大连接60个客户端

# 1.进入目录
cd /data/apache-zookeeper-3.6.1-bin/conf

# 2.编辑
vim zoo.cfg 
    maxClientCnxns=600

# 3.重启
./zkServer.sh restart