游戏服务器监控的设计与实现(三)

系统信息采集方面,选择使用Sigar的第三方库。

对于Sigar做一个简单的梳理。

服务器监控,一方面要对游戏服务器的数据进行采集,另一方面也要对游戏服务器所在的系统信息进行采集。我打算使用sigar来获取系统信息的采集工作。其Demo非常完整,并且跨平台支持,本身对于.net,C++,php,python,java,perl,ruby都是支持的,为以后的扩展和更改留有很多的余地。

sigar网址:https://support.hyperic.com/display/SIGAR/Home;jsessionid=93D9F25FC4BE420D102F15793F9EF0E1

sigar本身是带log4j的日志框架

sigar的Java实现主要还是调用本地的库,所以需要根据不同的平台引入相应的本地库。例如windows平台,就应当在构建工程的时候设置NativeLib:sigar-x86-winnt.dll、sigar-x86-winnt.lib、sigar-amd64-winnt

并引入sigar.jar,看一个官方获取系统信息的代码:

/*
 * Copyright (c) 2006-2009 Hyperic, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.hyperic.sigar.cmd;

import java.io.File;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.UnknownHostException;

import org.hyperic.sigar.OperatingSystem;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.SigarLoader;

import org.hyperic.sigar.win32.LocaleInfo;

/**
 * Display Sigar, java and system version information.
 */
public class Version extends SigarCommandBase {

    public Version(Shell shell) {
        super(shell);
    }

    public Version() {
        super();
    }

    public String getUsageShort() {
        return "Display sigar and system version info";
    }

    private static String getHostName() {
        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            return "unknown";
        }
    }

    private static void printNativeInfo(PrintStream os) {
        String version =
            "java=" + Sigar.VERSION_STRING +
            ", native=" + Sigar.NATIVE_VERSION_STRING;
        String build =
            "java=" + Sigar.BUILD_DATE +
            ", native=" + Sigar.NATIVE_BUILD_DATE;
        String scm =
            "java=" + Sigar.SCM_REVISION +
            ", native=" + Sigar.NATIVE_SCM_REVISION;
        String archlib =
            SigarLoader.getNativeLibraryName();

        os.println("Sigar version......." + version);
        os.println("Build date.........." + build);
        os.println("SCM rev............." + scm);
        String host = getHostName();
        String fqdn;
        Sigar sigar = new Sigar();
        try {
            File lib = sigar.getNativeLibrary();
            if (lib != null) {
                archlib = lib.getName();
            }
            fqdn = sigar.getFQDN();
        } catch (SigarException e) {
            fqdn = "unknown";
        } finally {
            sigar.close();
        }

        os.println("Archlib............." + archlib);

        os.println("Current fqdn........" + fqdn);
        if (!fqdn.equals(host)) {
            os.println("Hostname............" + host);
        }        

        if (SigarLoader.IS_WIN32) {
            LocaleInfo info = new LocaleInfo();
            os.println("Language............" + info);
            os.println("Perflib lang id....." +
                       info.getPerflibLangId());
        }
    }

    public static void printInfo(PrintStream os) {
        try {
            printNativeInfo(os);
        } catch (UnsatisfiedLinkError e) {
            os.println("*******ERROR******* " + e);
        }

        os.println("Current user........" +
                   System.getProperty("user.name"));
        os.println("");

        OperatingSystem sys = OperatingSystem.getInstance();
        os.println("OS description......" + sys.getDescription());
        os.println("OS name............." + sys.getName());
        os.println("OS arch............." + sys.getArch());
        os.println("OS machine.........." + sys.getMachine());
        os.println("OS version.........." + sys.getVersion());
        os.println("OS patch level......" + sys.getPatchLevel());
        os.println("OS vendor..........." + sys.getVendor());
        os.println("OS vendor version..." + sys.getVendorVersion());
        if (sys.getVendorCodeName() != null) {
            os.println("OS code name........" + sys.getVendorCodeName());
        }
        os.println("OS data model......." + sys.getDataModel());
        os.println("OS cpu endian......." + sys.getCpuEndian());

        os.println("Java vm version....." +
                   System.getProperty("java.vm.version"));
        os.println("Java vm vendor......" +
                System.getProperty("java.vm.vendor"));
        os.println("Java home..........." +
                System.getProperty("java.home"));
    }

    public void output(String[] args) {
        printInfo(this.out);
    }

    public static void main(String[] args) throws Exception {
        new Version().processCommand(args);
    }
}

其他的信息获取也类似,均是采用单例的方式,但是在一些时候获取并不方便,需要我们根据具体的情况做一些上层的封装。但是已经很便捷了。并且sigar本身对于输出格式是可以进行设置,例如CPU相关信息的的百分制的方式。

private void output(CpuPerc cpu) {
        println("User Time....." + CpuPerc.format(cpu.getUser()));
        println("Sys Time......" + CpuPerc.format(cpu.getSys()));
        println("Idle Time....." + CpuPerc.format(cpu.getIdle()));
        println("Wait Time....." + CpuPerc.format(cpu.getWait()));
        println("Nice Time....." + CpuPerc.format(cpu.getNice()));
        println("Combined......" + CpuPerc.format(cpu.getCombined()));
        println("Irq Time......" + CpuPerc.format(cpu.getIrq()));
        if (SigarLoader.IS_LINUX) {
            println("SoftIrq Time.." + CpuPerc.format(cpu.getSoftIrq()));
            println("Stolen Time...." + CpuPerc.format(cpu.getStolen()));
        }
        println("");
    }

并且Java的库主要是根据shell命令来进行区分的,非常的容易辨识,除此之外,官方Java例子还对Shell命令的跨平台进行了统一,带有官方Demo有兴趣可以去看下,但是已经不是下面提到的目录了,而是bingings/java/examples/Shell.java。

sigar本身的稳定性而言,应该不用过多的质疑。以下是一些项目使用了sigar采集系统信息的项目,足见其稳定性。

时间: 2024-10-09 03:52:33

游戏服务器监控的设计与实现(三)的相关文章

游戏服务器监控的设计与实现(一)

监控本来是为了方便运维维护游戏服务器,当服务器出现异常时能够及时提醒,并能够监视服务器的一些相关情况.然而需求是在不断变更的.这句话一点都没错,写这个工具的时候尤其如此了. 需求迭代,出现的很多情况开始都没有考虑清楚.对于需求做如下的罗列. 迭代一: 刚开始,运维说的比较简单,只要在服务器的机器上面写一个监控,能够监控服务器挂没挂,能够在挂的时候给邮箱发一封邮件.不就是一个监控工具嘛,简单!只要写个工具在,同一个物理主机上跟着服务器一起启动一个就行了,一旦服务器挂掉就能告警发送邮件,并且应运维要

游戏服务器监控的设计与实现(二)

结合上一次的拓扑结构,大部分游戏服务器采用C++实现,如果监控亦采用C++来做,在分布式上.web操作上.网络通讯.邮件功能上都得从底层重头开始构建封装并且并不便捷,需求又是不断向前迭代的,由于要保证一定的热部署和跨平台的特性(一些库是为了复用,需要兼顾平台特性),加之C++语言本身特点,开发效率反而会降低.加之本人对于C++熟悉程度不高,对于一些第三方库的不了解很难做一个合理化的选择和封装来确保稳定性,因此这个监控主要采用了Java语言实现. 系统实现目标: 实现游戏服务器的必要信息监控,统计

H5十人牛牛架设游戏服务器架构: 内核设计

H5十人牛牛架设游戏服务器查看(aqiulian.com),内核设计分析Q_212303635:接下来讲解一下内核模块分析.内核的几个组件被设计成Service,也就是说这几个模块都要实现如下接口: 图1  IService接口 Start方法用来启动服务. Stop 方法用来关闭服务. IsService 方法用于查询当前服务是否正在工作. 内核中的几个Service都不能够直接创建,Applications在使用这些Service的时候首先要得到一个IServiceMgr的实例,这被实现成了

我是如何设计游戏服务器架构的

前言 现在游戏市场分为,pc端,移动端,浏览器端,而已移动端和浏览器端最为接近.都是短平快的特殊模式,不断的开服,合服,换皮.如此滚雪球! 那么在游戏服务器架构的设计方面肯定是以简单,快捷,节约成本来设计的. 来我们看一张图: 这个呢是我了解到,并且在使用的方式,而PC端的游戏服务器而言,往往是大量的数据处理和大量的人在线,一般地图也是无缝地图的完整世界观,所以不同的程序都是独立的进程并且在不同的server中运行! 而浏览器端和移动终端,在上面就说过了,它主要是不断的开服,合服,开服,合服,那

关于游戏服务器中缓存的设计方案的讨论

(只针对游戏服务器中的热数据)游戏服务器的缓存设计总体大概有三种类型:进程内缓存--如java的ehcahe. 进程内缓存--使用会话session Cache,通过语言的基础类型和基础的集合框架来定制 .分布式缓存-- 如redis ,memcahced. 这三种类型各有个的好处,根据不同的应用场景,可以单独使用,也可以相互结合处理. 通过三方框架来做进程内缓存,和定制session cache,在一定程度上有着快而且高效的显著效果,但是不利于做分布式,使用分布式缓存 在一定程度上会造成IO上

常见游戏服务器业务逻辑和模板

0. 背景 服务器框架设计者,如果设计的好,考虑到了这几种情况,无论是对于游戏服务器逻辑清晰度,还是对于写业务逻辑的程序员来说,是非常友好的.游戏服务器业务逻辑写多了,一个游戏策划提出的需求归纳到服务器业务逻辑开发上面,也就无非几种情况需要处理. 1. 业务逻辑模板 下面给出代码模板,无论何种语言开发,大体都类似. -- 数据结构 -- tbPlayer 常见字段 tbPlayer = { dSocketId = 0, time_rec = { -- 常见时间 birth = 0, login

教你从头写游戏服务器框架

本文由云+社区发表 作者:韩伟 前言 大概已经有差不多一年没写技术文章了,原因是今年投入了一些具体游戏项目的开发.这些新的游戏项目,比较接近独立游戏的开发方式.我觉得公司的"祖传"服务器框架技术不太适合,所以从头写了一个游戏服务器端的框架,以便获得更好的开发效率和灵活性.现在项目将近上线,有时间就想总结一下,这样一个游戏服务器框架的设计和实现过程. 这个框架的基本运行环境是 Linux ,采用 C++ 编写.为了能在各种环境上运行和使用,所以采用了 gcc 4.8 这个"古老

棋牌游戏服务器架构设计

转载自:简书一位同行的文章 一,棋牌类服务器的特点 1,棋牌类不分区不分服 一般来说,棋牌游戏都是不分区不分服的.所以棋牌类服务器要满足随着用户量的增加而扩展的需要. 2,房间模式 即在同一局游戏中就是在同一个房间中,同一个房间中的人可以接收到其他人的消息. 3,每个房间的操作必须是顺序性 这个特性类似与一般游戏的回合制,每个玩家的操作都是有顺序性的. 二,需要解决的技术点 1,数据共享 因为棋牌类游戏不分区不分服,我们在设计服务器的时候,是按世界服的思想去设计,即服务器是一个n多台物理机的集群

FPS游戏服务器设计的问题 【转】

一.追溯 去gameloft笔试,有一个题目是说: 叫你去设计一个FPS(第一人称射击游戏),你是要用TCP呢还是要用UDP,说明理由 . 二.学习 这是两篇网上找到的文章,写非常不错. 当时笔试的时候自己没想到这么全,但大概想法都是一致的,摘录下来再学习一下. 1.网络游戏程序员须知 UDP vs TCP 作者:[email protected] 首发链接:http://blog.csdn.net/rellikt/archive/2010/08/21/5829020.aspx 这篇教程让我们就