昨天,我“收到”了一个定时炸弹,当然也是爆炸了我才知道,原来我也有定时炸弹,说起来很杯具,是这我下半年“收到”的第二个定时炸弹;好了,下面我就介绍下我这定时炸弹,希望大家能减少定时炸弹
第一定时炸弹:炸弹的具体时间忘记了,大概是7月26号左右,记得爆炸的前一天晚上8点多,游戏实时在线人数一下子跌了200人,然后又好了;这时我也收到了电话,第一时间就怀疑是不是重启了,查了,结果不是,这时感觉会有问题,但又不知道问题出现在哪,所以心里也有些担忧,第二天下午3点多,终于爆炸了,游戏挂了,最后在同事的帮忙下手动启动游戏才发现数据库挂了(岩机),最后查到了,是数据库没有索引造成的,所以长时间造成CPU100%而导致的岩机,然后重起数据库机器,第一时间将索引加上就可以了,同时也去检查了其他机器索引是否存在。这个炸弹是我没有严格按照装游戏程序(少了加索引该步骤)造成的,真是杯具啊;从埋下定时炸弹到炸弹大概有一个星期的时间,从此,我也要严格要求自己之后不能再犯同样的错误了。
第二定时炸弹:爆炸时间,昨天下午3点多,又是下午3点多,我觉得这不是巧合,可能是那时候玩家多点,也就是说,它可能前几天就差一点点快爆炸了,只是差了点点,爆炸的第一时间,我想很大可能是数据库,所以就直接锁定在数据库机器,发现是数据库机器岩机了,所以马上重起,之后就检查索引,晕啊,配置表的索引不见了,但数据表和日志表索引依然存在,一时间想不明白,但时间紧迫,先能让游戏能玩是当前最重要的问题,所以就加索引,启动游戏程序,恢复正常了;之后问了同事,才知道,索引是导入没有索引的配置造成的,那为什么会没有了呢?现在是知道了,首先,这配置是从内网传出去,传到测试服,所以测试服也是没有,测试服再到正式服,所以第一步错了,所以到最后也是没有了,再说一下,因为游戏的配置表是经常要更新的,所以每次更新都必须要检查索引(没有索引往往是新建了库,却没有加造成的,而内网是共用的,不一定能保证每次都是有索引),这个定时炸弹过了两个多月(快三个月)才发生爆炸,所以还是自己没有检查清楚造成的,自己也很伤心,还犯了这样的错误!
经过上面两个定时炸弹,我想,管理是一门艺术,我可能不太合适做管理,做技术还可以,好了,不扯了,下面直接进入我们讨论的话题。
游戏服务器有哪些服务嗯 ,先看下代码就知道有哪些常用服务了,之后再一个个地讲解 (注:这里讲的是小型网页游戏)
ChatSocket.cpp 启动文件(不要受这个Chat命名影响)
//============================================================================
// Name : ChatSocket.cpp
// Author : Huang
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <string>
#include "ServerSocket.h"
#include "../base/Exception.h"
#include "Clients.h"
#include "../util/JSONObject.h"
#include "ServerHandler.h"
#include "../util/StringFormat.h"
#include "../config/ServerConfig.h"
#include "mongo/client/dbclient.h"
#include "../util/Config.h"
#include "../consts/Mongodb.h"
#ifndef assert
#define assert(x) MMONGO_assert(x)
#endif
using namespace gateway;
using namespace std;
using namespace util;
using namespace config;
using namespace mongo;
using namespace base;
using namespace consts;
// 初始化配置
void InitConfig();
// 初始化Action
void InitAction();
// 连接数据库
void InitMongoDB();
// 启动定时器
void TimerStart();
// 启动队列
void QueueStart();
// 启动Http服务
void HttpStart();
// 启动Socket服务
void ServerStart();
int main(int argc, char* argv[]) {
try{
//运行需要的参数,参数为配置文件位置]
for (int i = 0; i < argc; i++) {
// 暂时不做处理
}
InitConfig();
InitAction();
InitMongoDB();
TimerStart();
QueueStart();
HttpStart();
ServerStart();
}catch(Exception e){
cout << e.DisplayMsg() << endl;
}
cout << "Server is end!" << endl;
return 0;
}
void InitConfig() {
ServerConfig::Init("configs/server.cfg");
cout << "InitConfig success......ok!" << endl;
}
void InitAction() {
ServerHandler::initClassHandlerMap();
cout << "InitAction success......ok!" << endl;
}
void InitMongoDB() {
Mongodb::Init();
cout << "ConnectDB success......ok!" << endl;
}
void ServerStart() {
cout << "ServerStart Running......ok!" << endl;
ServerSocket server(ServerConfig::GetServerPort());
server.Accept();
}
void TimerStart() {
cout << "TimerStart success......ok!" << endl;
}
void QueueStart() {
cout << "QueueStart success......ok!" << endl;
}
void HttpStart() {
}
这个程序我是还没有写完的,我想如果等我全部写完了,再写博客来介绍来大家,不但看起来累,而且我也没有太多激情来写了,其实写程序重要的是思想,代码不重要,
这里可以看到有数据库(同步)、定时器、队列、Http和Socket服务,当然还有其他服务,目前我就先介绍这几个
数据库同步服务:定时检查内存中的数据,判断数据是否需要同步到数据库,为什么要定时同步呢?呵呵,在游戏里,数据库你可以把它看作是一个游戏数据的一个备份,游戏数据的获取和修改是直接操作内存的,速度很快,所以定时同步是做备份用,同时也减与数据的IO问题,因为直接操作内存,所以会存在数据安全问题,这个问题我留到《内存&线程安全》文章再讨论了,内存中的数据是从数据库加载下来,过程大概是这样 :访问内存,内存中存在就直接返回 ,不存在,到数据库上加载下来,并放入内存中去,然后返回数据,关于从数据库加载数据到内存方面的知识点也留到《内存&线程安全》文章再讲解了。所以数据库同步服务是同步内存数据到数据库的服务
定时器服务:这个在游戏中用得很多,主要分为两种,1、到某个时间点,如是2012-10-28 23:23:03秒执行,像游戏中开启某日某时活动;2、从某个时间开始,每隔x分钟执行一次,比如每5分钟给不满血的玩家加血;像JAVA它本身就提供有定时器的类(TimeTask),非常好用,直接拿来用即可。如果要自己写怎么办呢?好,首先我们要理解它是怎么做到定时执行的,呵呵,很容易想到,不停地在判断时间是不是指定的时间,是就执行,不错,定时器就是这样做的,所以要开发 一个定时器,就是必须创建一个新的线程,然后再不停地判断时间对不对,当然设计这个东西,一定要考虑到性能问题,还有sleep时间也要根据参数做最优的设计,实现定时器这代码怎么写我就不说,想知道的,google一下会有很多答案的,呵呵,我也没有写过。
队列服务:为什么叫队列服务呢,我叫某某服务不行吗?之所以用到队列二字,那是因为它就是以队列形式去执行的,队列是先进先出的,所以叫队列服务再合适不过了,好了,这个一般应用在有CD需求的功能上,比如:升级操作后,会有一个CD,说在20秒内不能再次,还有是触发某件事后,每隔一段时间执行一次,比如采矿,拿 下矿后,每分钟获得x个矿产,关于队列的实现,我简单说一下,队列它包括几个属性:创建时间,结束时间,执行时间,每隔多少时间再执行一次,要执行的方法,额外参数,关于队列的代码实现我留到《队列讲解与实现》文章中介绍了
Http服务:这个服务在游戏中也很重要,是通过http方式进行与游戏通信或管理的,比如:后台(网页版)管理游戏,重起,禁止玩家聊天等一系统的操作都是要通过http服务进行,这也通常称为游戏的API,在这里比较重点的是安全问题,因为开通了http服务,这代表任何人都可以通过http方式给游戏发信息,所以这里一定要认证是不是合法的管理信息,否则都拒绝
Socket服务:简单点就是游戏服务,是服务于前端请求,这里不必要做什么安全认证,只要请求的uid能在内存(或数据库中找到数据,那它就是合法用户),所以这个就介绍到这里了
在这篇文章里, 主要说我经过的定时炸弹和游戏有哪些服务,如果大家还有哪一点不明白的,可以发邮件给我:huangzuduan@126.com