缘由

本人从事游戏开发很多年一直都是游戏服务器端开发。

因为个人原因吧,一直在小型公司,或者叫创业型团队工作吧。这样的环境下不得不逼迫我需要什么都会,什么做。

但是自我感觉好像什么都不精通。。。。。

好了好像偏题了!

回归正题

现在公司是做手游开发,java服务器 + U3D做客户端的mmo手游,仿魔兽世界!

做软件的都知道一个蛋疼的事情,那就是线上Bug。但是做服务的人更清楚另一个蛋疼的事情,就是在线更新,不停服更新。

知道的人,想想都蛋疼,当然不知道的,那就只能自己想象了。

线上经常出问题大家都是能理解的。bug肯定是有的。做服务的同僚应该都知道,不到维护的时间是不能停止服务区更新的除非是非常重大的bug。

这里面游戏服务器更为严格,因为你无故维护,维护一次可能就会流失一批玩家。所以这一直是一个梗。

本人经过三个星期的研究和测试,最终发现一个可以解决这种一出现bug,却能在线更新,且不影响性能的触发方式。

通过这样一个方式,主程序,加数据库,通过脚本实现逻辑模块;

这样就有一个脚本的实现形式,脚本如果实现的不好,那么性能消耗就很大了。

我的做法是把逻辑部分的方法抽象出来。放到脚本去实现。通过脚本把实现脚本逻辑代码在注册会逻辑模块。

这样的做法能保证我们有逻辑模块有bug的时候及时的修改逻辑,再次注册脚本已到达热更新效果。保证服务器运行的稳定性。

我们开始吧。

首先我要说一下我这里使用的是C#语言作为讲解。java也是一样的道理。不在赘述,如果需要代码实现的可以留言!这里可能牵涉到我之前的一些文章包含的类容,比如脚本加载器,日志模块,http监听模块。

我们先创建一个控制台项目叫TestApp

在新建一个类库项目 TestApp.Scripts

基本工作已经完成了。

接下来,我们在TestApp下面新建一个类IMainManager
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;

 /**
  *
  * @author 失足程序员
  * @Blog http://www.cnblogs.com/ty408/
  * @mail 492794628@qq.com
  * @phone 13882122019
  *
  */
 namespace TestApp
 {
     /// <summary>
     ///
     /// </summary>
     public interface IMainManagerScript
     {

          void Test();

     }
 }
我们在TestApp下面新建一个类MainManager
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;

 /**
  *
  * @author 失足程序员
  * @Blog http://www.cnblogs.com/ty408/
  * @mail 492794628@qq.com
  * @phone 13882122019
  *
  */
 namespace TestApp
 {
     /// <summary>
     ///
     /// </summary>
     public class MainManager : IMainManagerScript
     {

         public static MainManager instance = new MainManager();

         public static MainManager GetInstance()
         {
             return instance;
         }

         public IMainManagerScript IScript;

         public void Test()
         {
             IScript.Test();
         }

     }
 }
接下来我们在TestApp.Scripts 新建一个文件
 using Net.Sz.Framework.Log;
 using Net.Sz.Framework.Script;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;

 /**
  *
  * @author 失足程序员
  * @Blog http://www.cnblogs.com/ty408/
  * @mail 492794628@qq.com
  * @phone 13882122019
  *
  */
 namespace TestApp.Scripts
 {
     /// <summary>
     ///
     /// </summary>
     public class MainManagerScript : BaseScript, IMainManagerScript
     {

         public void Test()
         {
             Logger.Info("我是test");
         }

         public override void InitScript()
         {
             MainManager.GetInstance().IScript = this;
             Logger.Info("MainManagerScripttest  InitScript");
         }

     }
 }
 using Net.Sz.Framework.Log;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;

 namespace TestApp
 {
     class Program
     {
         static void Main(string[] args)
         {
             //Logger.LOGCONSOLE = true;//不在控制台打印信息
             //Logger.LOGLEVEL = Logger.ENUM_LOGLEVEL.INFO;//不显示debug消息
             Logger.Info("==================Start============================");

             Net.Sz.Framework.Script.ScriptManager.GetInstance().LoadCSharpFile(new string[] { "../../../TestApp.Scripts/" });

             MainManager.GetInstance().Test();

             Logger.Info("==================End============================");
             Console.ReadLine();
         }
     }
 }

我们先尝试运行一次

也许上面的打印太乱,我们看看简洁版本的

上面我们看样看出来,功能是没有问题的。

如果你稍微注意了,或者看过我之前的文章的话,会发现我的这个脚本没有实现IBaseScript接口,而只继承了BaseScript抽象类。因为这样的脚本不需要放到脚本存储器里面,只需要执行init函数,把脚本自身反注册到主程序函数体里面!

现在就是牵涉更新的事情。

更新有一个问题,当服务一旦部署后需要更新那就是的再次执行加载脚本方法。如果你使用windows服务运行的,更新势必是一个问题。

这里我只介绍一种方式,http监听方式。

要开启http监听方式,需要一个Net.Sz.Framework.Netty.Http.IHttpHandler的实现类

 using Net.Sz.Framework.Log;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;

 /**
  *
  * @author 失足程序员
  * @Blog http://www.cnblogs.com/ty408/
  * @mail 492794628@qq.com
  * @phone 13882122019
  *
  */
 namespace TestApp
 {
     /// <summary>
     ///
     /// </summary>
     public class ReloadScriptHandler : Net.Sz.Framework.Netty.Http.IHttpHandler
     {
         public void Action(Net.Sz.Framework.Netty.Http.HttpSession session, string method, string bindpath, Dictionary<string, string> parms)
         {
             Logger.Info("收到请求");

             Net.Sz.Framework.Script.ScriptManager.GetInstance().LoadCSharpFile(new string[] { "../../../TestApp.Scripts/" });
             MainManager.GetInstance().Test();

             session.writeSuccess();
             session.AddBodyLine("OK");
             session.WriteFlush();
         }
     }
 }

接下来我们在主函数加入下面代码

            Dictionary<string, Net.Sz.Framework.Netty.Http.IHttpHandler> handlers = new Dictionary<string, IHttpHandler>();

            handlers.Add("ReloadScript", new ReloadScriptHandler());//开启对http监听,监听模块为  ReloadScript

            Net.Sz.Framework.Netty.NettyPool.GetInstance().AddHttpBind(, handlers);

运行起来,看看,

可以看出,开启了http监听,reloadscript

然后我们修改一下MainManagerScript文件的Test方法

        public void Test()
        {
            Logger.Info("我是test  修改过的版本");
        }

在浏览器输入:http://127.0.0.1:9527/reloadscript

运行时成功的。这样的架构方式,很适合的是游戏开发,某些功能块很容易出bug,如果用脚本存储器访问比较耗费性能。

这样反向注册功能块脚本到功能块,既能实现bug的热更新,也不会影响性能消耗。

如果有疑问可以留言哦。如果你觉得这纯粹是扯淡,也欢迎留言。

不要问我,逻辑部分都是源码方服务器上安全吗?难道你打包就安全了?反编译,脱壳反混淆的工具一大堆。

上面是C#版本的,如果想要源码,

或者是java源码的,可以留言哦~!

线上bug的解决方案--带来的全新架构设计的更多相关文章

  1. 线上bug分析

    昨天下午大神把组内几十号人召集在一起开Online bug分析大会,主要是针对近期线上事故从事故原因和解决方案两个维度来分析. 对金融软件来说,每一次的线上事故都有可能给公司带来重大的损失,少扣了用户 ...

  2. 「日常开发」记一次因使用Date引起的线上BUG处理

    生活中,我们需要掌控自己的时间,减少加班,提高效率:日常开发中,我们需要操作时间API,保证效率.安全.稳定.现在都2020年了,了解如何在JDK8及以后的版本中更好地操控时间就很有必要,尤其是一次线 ...

  3. 记一次线上bug排查-quartz线程调度相关

    记一次线上bug排查,与各位共同探讨. 概述:使用quartz做的定时任务,正式生产环境有个任务延迟了1小时之久才触发.在这一小时里各种排查找不出问题,直到延迟时间结束了,该任务才珊珊触发.原因主要就 ...

  4. 线上bug或故障界定及填写规范

    [线上故障与线上Bug界定] 一.线上故障: 1.  故障参照公司规范稍做调整: a)         1级故障:资讯首页或主App首页无法打开:多条业务线同时不可用:超过15分钟: b)       ...

  5. 关于线上bug

    之所以想写下线上bug,因为发觉有些公司对线上bug的处理是比较严格甚至是很苛刻,涉及到的相关人可能会因此而背黑锅. 之所以会存在这样情况,因为公司各部门都有关联,特别是用户.老板的投诉,也给公司会造 ...

  6. 程序员如何描述清楚线上bug

    案例 一个管理后台的bug,把操作记录中的操作员姓名,写成了该操作员的id.原因是修改了一个返回操作人姓名的函数,返回了操作人的id.但是还有其他地方也用这个函数,导致其他地方把姓名字段填写成了操作员 ...

  7. 听说”双11”是这么解决线上bug的

    听说"双11"是这么解决线上bug的 --Android线上热修复的使用与原理 预备知识和开发环境 Android NDK编程 AndFix浅析 Android线上热修复的原理大同 ...

  8. 记录一次线上bug

    记录一次线上bug,总的来说就是弱网和重复点击.特殊值校验的问题. 测试场景一:        在3g网络或者使页面加载速度需要两秒左右的时候,输入学号,提交学生的缴费项目,提交完一个 学生的缴费后, ...

  9. 线上BUG:MySQL死锁分析实战

    原文链接:线上BUG:MySQL死锁分析实战 1 线上告警 我们不需要关注截图中得其他信息,只要能看到打印得org.springframework.dao.DeadlockLoserDataAcces ...

随机推荐

  1. ASP.NET MVC5+EF6+EasyUI 后台管理系统(72)-微信公众平台开发-消息处理

    系列目录 前言 Senparc.Weixin.MP SDK提供了MessageHandler消息处理类 在作者的Wiki中也详细说明了如何定义这个类,下面我们来演示,消息的回复,及效果 了解Messa ...

  2. Angular企业级开发(2)-搭建Angular开发环境

    1.集成开发环境 个人或团队开发AngularJS项目时,有很多JavaScript编辑器可以选择.使用优秀的集成开发环境(Integrated Development Environment)能节省 ...

  3. ASP.NET MVC学习之母版页和自定义控件的使用

    一.母板页_Layout.cshtml类似于传统WebForm中的.master文件,起到页面整体框架重用的目地1.母板页代码预览 <!DOCTYPE html> <html> ...

  4. Div Vertical Menu ver5

    这个小功能,如果是算此次,已经是第5次修改了.可以从这里看到前4次:V1, http://www.cnblogs.com/insus/archive/2011/10/17/2215637.html V ...

  5. jQuery标准的AJAX模板

    $('#saveInformationTemplate_button').on('click', function(){ if(isEmpty($("#name").val())) ...

  6. Ubuntu安装redis并配置远程、密码以及开启php扩展

    一.前言 redis是当前流行的nosql数据库,很多网站都用它来做缓存,今天我们来安装并配置下redis 二.安装并配置redis 1.安装redis sudo apt-get install re ...

  7. How to accept Track changes in Microsoft Word 2010?

    "Track changes" is wonderful and remarkable tool of Microsoft Word 2010. The feature allow ...

  8. 通过Mono 在 Heroku 上运行 .NET 应用

    英文原文:Running .NET on Heroku 中文原文:在 Heroku 上运行 .NET 应用 自从加入了Heroku之后,我就想在这个平台上运行.NET程序.现在我很高兴向大家宣布,我们 ...

  9. mono for android Listview 里面按钮 view Button click 注册方法 并且传值给其他Activity 主要是context

    需求:为Listview的Item里面的按钮Button添加一个事件,单击按钮时通过事件传值并跳转到新的页面. 环境:mono 效果: 布局代码 主布局 <?xml version=" ...

  10. MonoDevelop 4.2.2/Mono 3.4.0 in CentOS 6.5 安装笔记

    MonoDevelop 4.2.2/Mono 3.4.0 in CentOS 6.5 安装笔记 说明 以root账户登录Linux操作系统,注意:本文中的所有命令行前面的 #> 表示命令行提示符 ...