精华内容
下载资源
问答
  • 一、服务器端功能要求 1, 服务器程序运行在实验室Linux服务器(需要开端口找我)或同一个树莓派上(不需要开端口); 2, 通过命令行指定监听的端口; 3, 程序放到后台运行,并通过syslog记录程序的运行出错、调试...

    Part2 服务器

    一、服务器端功能要求

    1, 服务器程序运行在PC端服务器(需要开端口)或同一个树莓派上(不需要开端口);
    2, 通过命令行指定监听的端口;
    3, 程序放到后台运行,并通过syslog记录程序的运行出错、调试日志;
    4, 程序能够捕捉kill信号正常退出;
    5, 服务器要支持多个客户端并发访问;
    6, 服务器收到每个客户端的数据都解析后保存到数据库中,接收到的数据格式为: “ID/时间/温度”,如RPI0001/2019-01-
    05 11:40:30/30.0C”。

    二、功能分析

    1、服务器端前几条功能要求与客户端基本一致,这里不再赘述;
    2、服务器并发访问即需要用到多进程、多线程、IO多路复用(select、poll、epoll),这里,我选择多进程进行socket编程;
    3、服务器将接收到的数据保存至数据库中,这里选择sqlite3这种轻型数据库(适用于嵌入式领域,占用资源很少),关于数据库的具体使用方法将在下一篇博客中详细介绍;

    三、模块代码

    代码(receive_temper.c)如下:
    (服务器端代码未拆分成多个.c文件,所以看起来十分冗杂)

    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <signal.h>
    #include <string.h>
    #include <errno.h>
    #include <getopt.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include "sqlite3.h"
    
    #define BACKLOG 13
    
    //函数声明,打印帮助信息;捕捉信号并结束程序
    void print_usage(char *progname);
    void sig_stop(int signum);
    
    //定义一个全局变量g_stop ,与sig_stop()函数配合,达到结束程序的目的
    int g_stop = 0;
    
    int main(int argc, char *argv[])
    {
        int                     rv;
        int                     ret;
        int                     opt;
        int                     idx;
        int                     port;
        int                     log_fd;
        int                     ch = 1;
        int                     daemon_run = 0;
        int                     ser_fd = -1;
        int                     cli_fd = -1;
        pid_t                   pid = -1;
        struct sockaddr_in      ser_addr;
        struct sockaddr_in      cli_addr;
        socklen_t               cliaddr_len = 20;
    	/*命令行参数解析
    		deamon:程序后台运行
    		port:指定服务器开设端口
    		help:打印帮助信息
    	*/	
        struct option            opts[] = { 
                {"daemon", no_argument, NULL, 'd'}, 
                {"port", required_argument, NULL, 'p'}, 
                {"help", no_argument, NULL, 'h'}, 
                {NULL, 0, NULL, 0}
        }; 
        while ((opt = getopt_long(argc, argv, "dp:h", opts, &idx)) != -1)
        {
            switch(opt)
            { 
                case 'd':
                    daemon_run = 1; 
                    break;
                case 'p':
                    port = atoi(optarg); //将字符串形式的端口号转换成整型
                    break; 
                case 'h':
                    print_usage(argv[0]);	//打印帮助信息
                    return 0;
            }
        } 
    
    	//判断是否指定端口或正确端口
        if (!port)
        {
            print_usage(argv[0]);
            return 0;
        }
    
        if (daemon_run)
        {
            printf("Program %s is running at the background now\n", argv[0]);
            
            //建立日志系统
            log_fd = open("receive_temper.log",  O_CREAT|O_RDWR, 0666);
            if (log_fd < 0)
            {
                printf("Open the logfile failure : %s\n", strerror(errno));
                return 0;
            }
    
    		//标准输出、标准出错重定向
            dup2(log_fd, STDOUT_FILENO);
            dup2(log_fd, STDERR_FILENO);
    
    		//程序后台运行
            if ((daemon(1, 1)) < 0)
            {
                printf("Deamon failure : %s\n", strerror(errno));
                return 0;
            }
        }
    
    	//安装SIGUSR1信号
        signal(SIGUSR1, sig_stop);
    
    	//创建socket_fd,以供后续使用
    	//第一个参数为协议域,这里使用AF_INET(32位ipv4地址、16位端口)
    	//第二个参数为type,指定socket类型,这里使用SOCK_STREAM
    	//第三个参数为指定协议,当其为0时,自动选择与type类型相对应的默认协议
        ser_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (ser_fd < 0)
        {
            printf("Creat socket failure:%s\n", strerror(errno));
            return 0;
        }
        printf("Creat the ser_fd[%d]!\n",ser_fd);
    
    	//设置服务器地址信息
        memset(&ser_addr, 0, sizeof(ser_addr));
        ser_addr.sin_family = AF_INET;		
        ser_addr.sin_port = htons(port);		//调用htons(),将端口号由主机字节序转变成网络字节序
         //设置服务器IP地址(INADDR_ANY,代表监听所有IP),并调用htonl(0,将其由主机字节序转变成网络字节序
        ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    	//解决服务器程序停止后立刻运行,出现(端口)被占用的问题
        setsockopt(ser_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&ch, sizeof(ch));
    
    	//绑定服务器地址(IP+端口),用于提供服务
        rv = bind(ser_fd, (struct sockaddr *)&ser_addr, sizeof(ser_addr));
        if (rv < 0)
        {
            printf("Bind server's port failure:%s\n", strerror(errno));
            return 0;
        }
        printf("The port[%d] has been bind by this server!\n",port);
    
    	//调用listen(),将主动类型的socket套接字变为被动类型(等待客户端连接)
    	//第一个参数为sockfd,指定所要监听的socket套接字,用于接收外部请求
    	//第二个参数为backlog, TCP连接是一个过程,内核会在进程空间中维护一个连接队列以跟踪与服务器建立连接但还未着手处理的连接
        listen(ser_fd, BACKLOG);
    
        while (!g_stop)
        {
        	//接受来自客户端的请求,并创建一个cli_fd与客户端进行连接
            cli_fd = accept(ser_fd, (struct sockaddr *)&cli_addr, &cliaddr_len);
            if (cli_fd < 0)
            {
                printf("Accept the request from client failure:%s\n", strerror(errno));
                continue;
            }
    
            pid = fork();		//调用fork(),实现多进程
            if (pid < 0)
            {
                printf("Creat child process failure:%s.\n", strerror(errno));
                continue;
            }
            else if (pid > 0)
            {
                close(cli_fd);	//父进程关闭cli_fd,保留ser_fd,等待与其他客户端连接
                continue;
            }
            else if (pid == 0)
            {
            	close(ser_fd);		//子进程关闭ser_fd,保留cli_fd,保持与客户端连接
            	
                int         a;
                int         len;
                char        *sn;
                char        *cut;
                char        *temp; 
                char        buf[512];
                char        *datetime;
                char        *zErrMsg = NULL;
                char        sql1[128];
                //描述创建数据库中表的信息
                char        *sql = "create table if not exists temperature(sn char(10), datetime char(50), temperature  char(10))";		
                sqlite3     *db = NULL;
    
    			//调用sqlite3_open(),打开.db数据库文件。若没有,则创建
                len = sqlite3_open("temper.db",&db); 
                if (len)
                {
                    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
                    sqlite3_close(db);
                    exit(1);
                } 
                else
                {
                   printf("You have opened a sqlite3 database named temper.db successfully!\n");
                }
    
    			//创建temperature表,用来存放来自客户端的数据
                ret = sqlite3_exec(db, sql, 0, 0, &zErrMsg);
                if (ret != SQLITE_OK)
                {
                    sqlite3_close(db);
                    printf("Creat table failure \n");
                    return 0;
                }
                printf("Create table successfully!\n");
                printf("Child process start to communicate with client by cli_fd[%d]...\n", cli_fd);
                printf("Now ready to connect the client and recive message from client...\n");
                printf("\n");
                         
                while (1)		//设置while循环,持续接收来自客户端的信息
                {
                    memset(buf, 0, sizeof(buf));
                    
                    a = read(cli_fd, buf, sizeof(buf));		//从buf中读数据(客户端写入)
                    if (a < 0)		//返回值小于零,则表示接收数据出错
                    {
                        printf("Read information from client failure:%s\n", strerror(errno));
                        close(cli_fd);
                        exit(0);
                    }
                    else if (a == 0)		//返回值等于0,则表示客户端主动断开连接
                    {
                        printf("The connection with client has broken!\n");
                        close(cli_fd);
                        exit(0);
                    }
                    else		//返回值大于零,则表示接收数据成功
                    {
                        printf("The message recived from client[%s,%d] is \"%s\"\n",
                               inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port), buf);
                        //对接收到的数据进行分割操作,便于存储至数据库
                        cut = strtok(buf, "/");
                        if (cut != NULL)
                        {
                            sn = cut;
                            //printf("%s\n", sn);
                            if ((cut = strtok(NULL, "/")) != NULL)
                            {
                                datetime = cut;
                                //printf("%s\n", datetime);
                                if ((cut = strtok(NULL, "/")) != NULL)
                                {
                                    temp = cut;
                                    //printf("%s\n", temp);
                                }
                            }
                        }
                                     
                        snprintf(sql1, 128, "insert into temperature values('%s', '%s', '%s');", 
                                 sn, datetime, temp);
                        sql1[127] = '\0';
                        printf("%s\n", sql1);
                        //将数据存储至temperature表中
                        ret = sqlite3_exec(db, sql1, 0 , 0, &zErrMsg);
                        if (ret != SQLITE_OK)
                        {
                            sqlite3_close(db);
                            printf("insert data failure ; %s!\n", zErrMsg);
                            return 0;
                        }
                        printf("insert data successfully!\n");
                        printf("\n");
                    }
                }
            }
        }
        close(ser_fd);
    
        return 0;
    }
    
    //打印帮助信息函数
    void print_usage(char *progname)
    {
        printf("-d(--daemon):let program run in the background.\n"); 
        printf("-p(--port):enter server port.\n");
        printf("-h(--help):print this help information.\n"); 
        
        return ;
    }
    
    //回调函数sig_stop()
    void sig_stop(int signum)
    {
        if (SIGUSR1 == signum)		/判断捕捉到信号是否为SIGUSR1 
        {
            g_stop = 1;		//g_stop为1,while(!g_stop)循环结束,程序关闭
        }
    
        return ;
    }
    

    另注:
           1、服务器端代码是在PC端linux服务器下编写,进行域名解析时得到的时服务器的公网IP,故须在服务器连接的路由器下开设相应的端口,以供客户端正常连接!
           2、程序执行结果会在下篇博客中与sqlite3数据库的基本使用一起介绍!
           3、本程序是存在一定的bug,倘若多个客户端同时连接服务器,即会同时操作同一个数据库文件,而多个进程间互不干扰,则会出现相关问题,我会在接下来的博客中,介绍多进程、多线程、IO多路复用的相关知识,其中会提到锁的概念!

    展开全文
  • 公司的服务器需要实时监控,而且当用户空间已经满了,操作失败,或者出现程序Exception的时候就需要实时提醒,便于网管和程序员调式,这样就把这个实时监控系统分为了两部分,   第一部分:实时系统监控(cpu利用...

    转自:http://kakaluyi.iteye.com/blog/228636

    公司的服务器需要实时监控,而且当用户空间已经满了,操作失败,或者出现程序Exception的时候就需要实时提醒,便于网管和程序员调式,这样就把这个实时监控系统分为了两部分,

     

    第一部分:实时系统监控(cpu利用率,cpu温度,总内存大小,已使用内存大小)

    第二部分:实时告警

    由于无刷新实时性,所以只能使用Ajax,这里没有用到任何ajax框架,因为调用比较简单

    大家知道,由于java的先天不足,对底层系统的调用和操作一般用jni来完成,特别是cpu温度,你在window下是打死用命令行是得不到的, 但由于我们的服务器系统是linux,所以可以不调用jni完全用java的方式来得到系统信息,这里用到了runtime的exec()函数,通过解析 本地命令调用的结果来查询本地信息,

    这里要感谢公司同事qinkun推荐ecsun兄的这篇文章http://papa.iteye.com/blog/220532

     

    Java代码  收藏代码
    1. * 取得linux系统下的cpu、内存信息   
    2. *   
    3. * */   
    4. public   final   class  LinuxSystemTool   
    5. {   
    6. /**   
    7. * get memory by used info   
    8.  
    9. * @return int[] result   
    10. * result.length==4;int[0]=MemTotal;int[1]=MemFree;int[2]=SwapTotal;int[3]=SwapFree;   
    11. * @throws IOException   
    12. * @throws InterruptedException   
    13. */    
    14. public   static   int [] getMemInfo()  throws  IOException, InterruptedException   
    15. {   
    16. File file = new  File( "/proc/meminfo" );   
    17. BufferedReader br = new  BufferedReader( new  InputStreamReader(   
    18. new  FileInputStream(file)));   
    19. int [] result =  new   int [ 4 ];   
    20. String str = null ;   
    21. StringTokenizer token = null ;   
    22. while ((str = br.readLine()) !=  null )   
    23. {   
    24. token = new  StringTokenizer(str);   
    25. if (!token.hasMoreTokens())   
    26. continue ;   
    27.   
    28. str = token.nextToken();   
    29. if (!token.hasMoreTokens())   
    30. continue ;   
    31.   
    32. if (str.equalsIgnoreCase( "MemTotal:" ))   
    33. result[0 ] = Integer.parseInt(token.nextToken());   
    34. else   if (str.equalsIgnoreCase( "MemFree:" ))   
    35. result[1 ] = Integer.parseInt(token.nextToken());   
    36. else   if (str.equalsIgnoreCase( "SwapTotal:" ))   
    37. result[2 ] = Integer.parseInt(token.nextToken());   
    38. else   if (str.equalsIgnoreCase( "SwapFree:" ))   
    39. result[3 ] = Integer.parseInt(token.nextToken());   
    40. }   
    41.   
    42. return  result;   
    43. }   
    44.   
    45. /**   
    46. * get memory by used info   
    47.  
    48. * @return float efficiency   
    49. * @throws IOException   
    50. * @throws InterruptedException   
    51. */    
    52. public   static   float  getCpuInfo()  throws  IOException, InterruptedException   
    53. {   
    54. File file = new  File( "/proc/stat" );   
    55. BufferedReader br = new  BufferedReader( new  InputStreamReader(   
    56. new  FileInputStream(file)));   
    57. StringTokenizer token = new  StringTokenizer(br.readLine());   
    58. token.nextToken();   
    59. int  user1 = Integer.parseInt(token.nextToken());   
    60. int  nice1 = Integer.parseInt(token.nextToken());   
    61. int  sys1 = Integer.parseInt(token.nextToken());   
    62. int  idle1 = Integer.parseInt(token.nextToken());   
    63.   
    64. Thread.sleep(1000 );   
    65.   
    66. br = new  BufferedReader(   
    67. new  InputStreamReader( new  FileInputStream(file)));   
    68. token = new  StringTokenizer(br.readLine());   
    69. token.nextToken();   
    70. int  user2 = Integer.parseInt(token.nextToken());   
    71. int  nice2 = Integer.parseInt(token.nextToken());   
    72. int  sys2 = Integer.parseInt(token.nextToken());   
    73. int  idle2 = Integer.parseInt(token.nextToken());   
    74.   
    75. return  ( float )((user2 + sys2 + nice2) - (user1 + sys1 + nice1)) / ( float )((user2 + nice2 + sys2 + idle2) - (user1 + nice1 + sys1 + idle1));   
    76. }   
    77. }   

     

    这里的两个方法,解释一下,

    方法1文件"/proc/meminfo"里面包含的就是内存的信息,还包括了swap的信息。例如:

    $ cat /proc/meminfo

    total: used: free: shared: buffers: cached:
    Mem: 1057009664 851668992 205340672 0 67616768 367820800
    Swap: 2146787328 164429824 1982357504
    MemTotal: 1032236 kB
    MemFree: 200528 kB
    MemShared: 0 kB
    这样可以用截取字符串的方法,来得到linux内存信息.

    方法2在文件"/proc/stat"里面就包含了CPU的信息。每一个CPU的每一tick用在什么地方都在这个文件里面记着。后面的数字含义分 别是: user、nice、sys、idle、iowait。有些版本的kernel没有iowait这一项。这些数值表示从开机到现在,CPU的每tick用 在了哪里。例如:

    cpu0 256279030 0 11832528 1637168262

    就是cpu0从开机到现在有 256279030 tick用在了user消耗,11832528用在了sys消耗。所以如果想计算单位时间(例如1s)里面CPU的负载,那只需要计算1秒前后数值的差除以每一秒的tick数量就可以了。

    ok这样还剩下cpu温度,怎么做呢

    发现了一个文件"cat /proc/acpi/thermal_zone/THM/temperature";可以返回本机的linux温度,

    大概是这样的:temperature:            68C

    但不是每台linux机器都有这个THM你要确定你的linux加载了这个THM才能使用这个文件,这样就用InputStreamReader(new FileInputStream(new File("/proc/acpi/thermal_zone/THM/temperature")), 去读取这个文件,后面的相信大家一定会做了吧,就是把内容读出来,然后分割字符串去得到这个68。ok,系统基本信息全部完成,然后ok现在就只有一件事就是用Ajax去调用这个类来得到 基本信息,然后返回到页面上,Ajax的用法就不赘言了。

     

    下面是系统监控的效果,大概是Ajax每几秒去linux下去取一次系统信息,然后显示在jsp页面上,以下是效果。

     

     

     

     

    到这里第一部分系统监控部分已经完成,现在开始完成实时告警部分,分析需求

    1温度和cpu超过额定值需要告警

    2用户操作系统失败,用户存储空间不足也需要告警,还有我们公司的业务操作失败告警,如果发生Exception也只能告警,当然要把异常的堆栈的 信息保存在数据库里,我就这样设计如果用户在操作中触发了这些错误,则保存在数据库的告警表里,然后实时监控的再取出来这些信息。

    3告警是要实时的那么要怎么从告警表里查到当前以后的数据呢,一开始想到用当前时间,在当前时间加上Ajax发送时间间隔,select * from warnlist where date>new Date()+AjaxTime这种形式,后来发现时间是很不正确的,网络延迟,程序处理时间,(cpu信息用了sleep函数),等等你常常会发现有些 告警信息被无情的放过,而有的时候有重复数据,这样我想到了用id,每次进入告警系统先查询到最大的告警id,然后保存在session中,然后ajax 从数据库里取告警信息的时候都查这个id之后的数据(就是进入监控系统后的最新数据),然后session再保存新的最大id,下次ajax取还是从这个 session中取最大id,这样信息就可以当ajax取的时候都保证是最新的,而且没有重复,very good!就这样做了

    这样设计了一张告警处理表

    Sql代码  收藏代码
    1. CREATE   TABLE  `warnlist` (  
    2.   `Id` bigint (20)  NOT   NULL  auto_increment,  
    3.   `warnleave` tinyint(2) NOT   NULL   default   '0' ,//告警级别:告警的严重程度  
    4.   `fromguy` varchar (20)  NOT   NULL ,//属于哪个用户哪个组织的告警  
    5.   `warncontent` varchar (100)  NOT   NULL ,//告警内容,比如cpu使用率超过80%  
    6.   `aviliablevalue` varchar (12)  default   NULL ,//允许值 比如85%  
    7.   `warnvalue` varchar (12)  default   NULL ,//告警值 80  
    8.   `warntime` datetime NOT   NULL ,//告警时间  
    9.   `stackinfo` varchar (255)  default   NULL ,//异常的堆栈信息  
    10.   `dealwith` tinyint(2) NOT   NULL   default   '0' ,//处理结果  
    11.   `version` int (11)  default   NULL ,//version  
    12.   `organizerID` varchar (20)  default   NULL ,//组织id  
    13.   `des` varchar (255)  default   NULL ,  
    14.   PRIMARY   KEY   (`Id`)  
    15. ) ENGINE=InnoDB DEFAULT  CHARSET=utf8;  

     

    假设我ajax从系统取信息后,那么要写个逻辑,if(cpuTempature>75C)or if(cpuUserd>80%)则写入数据库,然后再查询大于上一次发送Ajax数据库的最大id的告警信息(这期间如果发生的以下错误一并查 出:用户存储空间不足,还有我们公司的业务操作失败告警,Exception等),循环插入一个xml解析类中,大概形式是这样的Ajax返回这个 xml,供页面提取信息

    Xml代码  收藏代码
    1. < response >   
    2. < cpuUsed > 67 </ cpuUsed >   
    3. < cpuTemp > 76 < cpuTemp >   
    4. < Memory > 1023422 </ Memory >   
    5. < freeMemory > 43244 </ freeMemory >   
    6. < wannlist >   
    7. < warnid > 2 </ warnid >   
    8. < warncontent > 系统存储空间不足 </ warncontent >   
    9. < fromguy > kakaluyi </ fromguy >   
    10. ..............  
    11. </ wanrlist >   
    12. < warnlist >   
    13. < warnid > 3 </ warnid >   
    14. < warncontent > cpu温度过高 </ warncontent >   
    15. < fromguy > 系统 </ fromguy >   
    16. < orgid > 系统 </ orgid >   
    17. < warnvalue > 78 </ warnvalue >   
    18. .............  
    19. </ warnlist >   
    20. ........  
    21.   
    22. </ response >   

     

    系统信息的显示代码,就是关联上面那个图片的:

    Html代码  收藏代码
    1. var  cpuUsed = req .responseXML.getElementsByTagName('cpuUsed')[0].firstChild.nodeValue;  
    2. var totalMemory = req .responseXML.getElementsByTagName('totalMemory')[0].firstChild.nodeValue;  
    3. var freeMemory = req .responseXML.getElementsByTagName('freeMemory')[0].firstChild.nodeValue;  
    4. var cpuTemp = req .responseXML.getElementsByTagName('cpuTemp')[0].firstChild.nodeValue;  
    5. $('cpuUsed').innerHTML = cpuUsed ;  
    6. $('totalMemory').innerHTML = totalMemory ;  
    7. $('freeMemory').innerHTML = freeMemory ;  
    8. $('cpuTemp').innerHTML = cpuTemp ;  
    9.   
    10. //jsp  
    11. < tr >   
    12. < td   class = "label"   width = "20%" >   
    13. 服务器CPU使用率:</ td >   
    14. < td   class = "text" >   
    15. < font   color = "#FF0000"   size = "+2" > < label   id = "cpuUsed" > </ label >   
    16. </ font >   <  告警预定阀值: 80%  >   
    17. </ td >   
    18. </ tr >   
    19.  .........  

    然后就是页面展现的问题了这里我用了dom节点的增删,一个页面保持50条记录,如果超过50条则删除以前的节点,代码为:

     

     

    Js代码  收藏代码
    1. var  length=req.responseXML.getElementsByTagName( 'warnlist' ).length;  
    2. if (length>0)  
    3. {  
    4. var  trlength=document.getElementsByTagName( 'table' )[4].childNodes[0].childNodes.length;  
    5.   
    6. if (trlength+length-1>50) //如果大于50条,则查找告警列表的table,得到   
    7. 告警信息的子节点,然后删除多余的最早的告警信息  
    8. {  
    9. var  tbody=document.getElementsByTagName( 'table' )[4].childNodes[0];  
    10. for ( var  i=1;i<trlength+length-50;i++)  
    11. {  
    12. var  tr=tbody.childNodes[i];  
    13. tr.parentNode.removeChild(tr);  
    14.   
    15. }  

     

    然后插入新的告警信息,

    Js代码  收藏代码
    1. for ( var  i=0;i<length;i++)  
    2. {  
    3. var  onewarnlist=req.responseXML.getElementsByTagName( 'warnlist' )[i].childNodes;  
    4. if (onewarnlist[0].firstChild.nodeValue==0)  
    5. {  
    6. var  leave= "企业级告警" ;  
    7. }  
    8. else  {  
    9. var  leave= "运营商级告警" ;  
    10. }  
    11. var  from=onewarnlist[1].firstChild.nodeValue;  
    12. var  warncontent=onewarnlist[2].firstChild.nodeValue;  
    13. var  aviliablevalue=onewarnlist[3].firstChild.nodeValue;  
    14. var  warnvalue=onewarnlist[4].firstChild.nodeValue;  
    15. var  warntime=onewarnlist[5].firstChild.nodeValue;  
    16. var  id=onewarnlist[8].firstChild.nodeValue;  
    17. if (onewarnlist[6].firstChild.nodeValue==0)  
    18. {  
    19. var  dealwith= "未处理"  ;  
    20. }  
    21. else  {  
    22. var  dealwith= "<font color='red'>已处理</font>" ;  
    23. }  
    24. var  table=document.getElementById( 'warntable' );  
    25. var  tr=document.createElement( 'tr' );  
    26.  if (x%2==1)  
    27. {  
    28. tr.style.backgroundColor="#BFD3F9"   
    29. }  
    30. else {  
    31. tr.style.backgroundColor="#FBFCEB"   
    32. }  
    33. x++;  
    34. table.appendChild(tr);  
    35. var  td=document.createElement( 'td' );  
    36. td.className ='listText' ;  
    37. td.innerHTML =x;  
    38. tr.appendChild(td);  
    39. var  td1=document.createElement( 'td' );  
    40. td1.className ='listText' ;  
    41. td1.innerHTML = leave;  
    42. tr.appendChild(td1);  
    43. var  td2=document.createElement( 'td' );  
    44. td2.className ='listText' ;  
    45. td2.innerHTML = from;  
    46. tr.appendChild(td2);  
    47. var  td3=document.createElement( 'td' );  
    48. td3.className ='listText' ;  
    49. td3.innerHTML = warncontent;  
    50. tr.appendChild(td3);6  
    51. var  td4=document.createElement( 'td' );  
    52. td4.className ='listText' ;  
    53. td4.innerHTML = aviliablevalue;  
    54. tr.appendChild(td4);  
    55. var  td5=document.createElement( 'td' );  
    56. td5.className ='listText' ;  
    57. td5.innerHTML = '<font color="#FF0000">' +warnvalue+ '</font>' ;  
    58. tr.appendChild(td5);  
    59. var  td6=document.createElement( 'td' );  
    60. td6.className ='listText' ;  
    61. td6.innerHTML = warntime;  
    62. tr.appendChild(td6);  
    63. var  td7=document.createElement( 'td' );  
    64. td7.className ='listText' ;  
    65. td7.innerHTML = dealwith;  
    66. tr.appendChild(td7);  
    67. var  td8=document.createElement( 'td' );  
    68. td8.className ='listText' ;  
    69. td8.innerHTML = id;  
    70. tr.appendChild(td8);  
    71.    }  

     

    ok,一切大功告成,以下是最终效果

    展开全文
  • 在数据中心里,最常见的就是机架式服务器,在机架服务器中,服务器被做成1U、2U高塞进机箱内,在狭小的空间里有大量的硬件高速运行,且服务器一般要求24小时不间断工作,散发的热量非常大。那么,怎样才能有效降低...
  • 企业环境中对机房温度要求很高,特别是现代企业中分布在全球各个地方的办公室及工厂,服务器24小时都要提供服务,所以远程能自动监控机房的温度是很有必要的,当监控到机房温度高于设定的警报值时,温度计上面的工控...

    企业环境中对机房温度要求很高,特别是现代企业中分布在全球各个地方的办公室及工厂,服务器24小时都要提供服务,所以远程能自动监控机房的温度是很有必要的,当监控到机房温度高于设定的警报值时,温度计上面的工控模块通过(TCP/IPGPRSWIFI)传输方式会自动发邮件到管理员的邮箱中,以便及时处理异常,保证服务器的稳定运行,另外现在好多网络温度计品牌都带有手机APP功能,可以在手机上查看实时,历史数据,异常报警功能都一一俱全,另外一些高级智能设备温度计云平台不仅可以监控机房温度,目前可接入的设备包含了 UPSEPS,精密空调,服务器,发电机,直流电源等所有具有物联网功能的设备,都可以采集到数据,并存储在云平台中,支持数据实时显示,事件及报警显示,历史数据及报表管理等功能。

     

    关于网络温度计的品牌,这里就不介绍了,建议使用国产的品牌,在手机发短信功能方面可能更强大和稳定点,大家可以在马云的店里找找,本章只介绍原理和功能,网络温度计流行的网络拓扑图如下图所示。


    wKiom1mP5SbTVw9PAABvTZYZWbw237.jpg


    本文转自成杭 51CTO博客,原文链接:http://blog.51cto.com/hangtc/1955895,如需转载请自行联系原作者


    展开全文
  • 服务器维护管理规范

    2015-02-09 23:08:00
    1. 环境要求 ... B每日检查服务器机房的温度和湿度,一般情况下必须保持恒温、恒湿 C 服务器机房不能放置食品和水,不得在服务器机房内就餐 D一般情况下,无关人员不得进入服务器机房 ...
    1. 环境要求
    A 服务器机房内必须保持整洁,不得放置无关的设备、物品
    B每日检查服务器机房的温度和湿度,一般情况下必须保持恒温、恒湿
    C 服务器机房不能放置食品和水,不得在服务器机房内就餐
    D一般情况下,无关人员不得进入服务器机房
    2. 软件环境
    去掉其它的网络文件与打印服务、QoS、终端服务、终端授权服务、Site Server ILS服务、消息队列服务(MSMQ)、远程存储、证书服务等其他目前暂时用不到的服务。为了保证该服务器的最大优化,除了安装解压缩、杀毒软件等必要的应用软件外,一般不安装其他非必要的软件,包括OFFICE等,平时最好不设置壁纸、屏幕保护等。严禁安装游戏、聊天工具。
    3. 日志检查
    A. 每天每隔2-3小时检查一次每台服务器的“事务日志”,发现有“严重错误”的,必须立即检查并排除故障;
    B. 所有日志在得到“事务已经满”提示的情况下,必须立即进行备份到C:\LOGS下,文件名格式为:01 DD(日) MM(月) YY(年)
    事务日志备份完毕应立即清空;
    4. 文件、磁盘检查
    A.每天检查每个服务器的磁盘情况,如果发现磁盘的使用容量超过70%以上时,应及时删除不必要的文件腾出磁盘空间,必要时提报申购新的磁盘
    B. 个人盘、部门盘、院级盘的内容,查看是否有反动、黄色、游戏、聊天等文档,一旦发现,立即通知当事人,并要求解释,如果情节严重时,应去除该用户的访问权限,保留现场,同时通知学院的权责部门进行下一步处理
    C. 每隔10天做一次磁盘碎片整理
    5. 开关机
    A.一般情况下,服务器不得随意关机,在以下情况下,可以关机,但尽量安排在晚上:
    a安装必要的服务
    b安装必要的软件
    c正常的维护需要
    服务器在出现严重故障非重起不能解决时,通��件或��方式通知用�。
    B. 服务器在得到UPS停电通知时,必须在1个小时内关闭。此项设置必须在APC的监控软件中设置
    D. 服务器出现严重的硬件故障时,应立即通知网络用户并立即关机,同时通知硬件供应商处理
    E. 服务器在开机时必须确认UPS供电是否正常
    6. 杀毒�件更新
    A. 每天在晚间22:00让服务器进行杀毒
    B. 设置杀毒软件为自动更新
    C.在得知有新病毒流行时应立即确认杀毒源库是否为最新,如果不是应立即上网下载,同时应立即上微软网站下载最新的补丁程序
    D.其他要求同《病毒防范》
    7. WSUS�丁分�
    A. 每隔7天上微软网站查看是否有最新的更新通知
    B. 在得知有最新的安全漏洞时,应立即上网查看微软最新安全补丁
    C. 微软一般在8-12个月内会发一次SP(目前为SP2),届时应全数下载,并立即分发各工作站
    D. 更新的网站为:windowsupdata.Microsoft.com或www.microsoft.com/china等网站
    E. WSUS�丁�自�更新,事先建立一��丁���。
    8. 防火�管理
    A.防火��所有策略在有任何改�的情�下,都需要做好提前�份。
    B.所有策略的更改,都必�有用�端的申�更改�告。
    C.每周一�布一周用�上���
    D.每次的策略更改都必��明更改原因。(ISA server 2006 SP1)
    9. �件管理
    A.新增人�一律�其建立�箱,但其�箱�示名的更改一律需要�交�告。
    B.��人�的�箱交接,由各部�完成!
    C.部�人�的�件自���各部�主管及公司高�。
    D.各部�主管出差期�,按需要可以�其�件代理�送�置�其助理。
    10. �份管理
    A. Exchange�件服�器,每晚上0:00�始�份
    B. 活�目�每周�份一次
    C. 文件服�器,每天�份一次。
    D. 文件�存�,每晚�份一次,�清除原文件。
    E. �份�查每天一次
    11. 活�目�管理
    A. AD的管理的主要工具为ACTIVTE DIRECTORY 用户和组管理工具,�於�管工作站,可以使用windows 2003系�管理工具���程管理。
    B. 一般原则按组织架构(部门)建立OU(组织单元),一个部门一个OU,同时将该部门的“用户”、“计算机”建立该OU下
    C. 所有的组建立在“XX组”内
    D. 对所建立的OU必须应用“组策略”,进行安全控制
    E. 所有新建立的策略必�����後,才能�用。
    12. 故障管理�收集
    A. 服务器的故障包括:软件故障,硬件故障,网站故障,黑客入侵与攻击,其他不可预料的未知故障等
    B. 故障记录:建立服务器故障日志数据库,对发现的各种故障现象进行详细记录,记录内容包括:故障发生的时间,故障现象,故障位置,故障分析,故障原因,故障记录人员
    C. 对于维护人员不能尽快处理的故障,应尽快以书面或者电话或者其他相关形式尽快通知上级主管领导并发布公告,自己保留相关记录存档。

    本文出自 “潜入技术的海洋” 博客,请务必保留此出处http://myhat.blog.51cto.com/391263/129505

    转载于:https://my.oschina.net/u/2316994/blog/376878

    展开全文
  • 服务器急救常识

    2010-04-20 18:04:48
    首先检查服务器的安装环境:一般服务器要安装在通风良好的场所,温度要求在10摄氏度至35摄氏度(运行时)或-30摄氏度至60摄氏度(非运行时),湿度要求在20%至80% (运行时)或5%至90% (非运行时)、要有稳定和持续的...
  • 首先,集成了大量的监测及管理电路,具有全面的服务器管理能力,可监测如温度、电压、风扇、机箱等状态参数。此外,结合服务器管理软件,可以使管理人员及时了解服务器的工作状况。同时,大多数部门级服务器具有优良...
  • 这种高精度和多温度/电压测量使该器件适用于笔记本电脑、台式电脑和服务器。  MAX6617的内部结构适合于带可编程温度和电压扫描功能的系统。故障-安全监视方案不要求系统控制器在供电状态下由系统进行任何编程,...
  • 树莓派上运行socket客户端程序,每隔30秒(可指定)以字符串“ID/时间/温度”形式上报采样温度,其中ID为树莓派的编号,便于服务器端区别是哪个树莓派客户端,如RPI0001/2019-01-05 11:40:30/30.0C 通过命令行参数指定...
  • 简单智能远程控制服务器课题

    千次阅读 2017-01-06 10:46:29
    一、项目概述:简单智能远程监控 功能:服务器端:1、服务器端利用随机数模拟向串口读取传感数据,需要模拟的传感数据要求有:温度、湿度、光 照、室内噪音度等等。 2、服务器要求在数据保中保存有采集传感数据的...
  • 众所周知,服务器与普通计算机主机最大的不同之处就在于服务器需要长时间不间断地工作,因此站长们在选择服务器时,对其稳定性的要求也一直比较高。因此,如何提高美国服务器的稳定性呢,这里以BlueHost美国服务器为...
  • Acer Altos S300服务器

    2020-03-04 21:31:18
    Acer Altos S300可以压缩的...而且也不需要花费时间去配置系统,它可以确保按照你的要求自动进行配置。它具有高效散热模块保证了流畅的空气流动,保护了机器内部的设备工作在安全的温度下,同时保证了系统的稳定运行。
  • 服务器要求和功能分析都类似,不再赘述,可参考下面链接:2. 代码模块分析create_database 创建数据库模块socket_server_init服务器端初始化server_poll主函数3. 服务器运行结果4. 客户端代码相同,方便查看直接贴...
  • 温度上报实时监控项目——客户端

    千次阅读 2019-03-22 23:40:50
    1、树莓派上运行socket客户端程序,每隔30秒以字符串“ID/时间/温度”形式上报 采样温度,其中ID为树莓派的编号,便于服务器端区别是哪个树莓派客户端,如“RPI0001/2019-01-05 11:40:30/30.0C”; 2、通过命令行...
  • 很不错的,适合大学生实...该实训以基于ARM7架构的Cortex-M0微控制器为核心,要求设计一个较为完整的“服务器主板温度监控系统”。设计的知识和能力包括:电子系统设计技术、传感器技术、嵌入式技术、 EDA软件使用等。
  • 俗话说的好,世界上没有懒女人只有丑女人,护肤好的女人的皮肤雪白雪白的,在...服务器对周边环境的温度和湿度也是有要求的。 温度方面, CPU的平均温度都在60º C以上,箱体内部温度也都在40º C以上,机房温度
  • 服务器稳定性测试方法

    千次阅读 2019-07-04 16:02:12
     正规的服务器厂商都会对产品惊醒不同温度和湿度下的运行稳定性测试。重点要考虑的是冗余功能,如:数据冗余、网卡荣誉、电源冗余、风扇冗余等。 一些测试方法主要分以下几种:  压力测试:已知系统高峰期使用...
  • HaLake API 服务器 安装 待定 执行方式 待定 海湖API Co-working 的基础 HaLake 提供了 API,因此可以从各种应用程序中使用 HaLake 的各种环境信息。目前提供的环境信息如下: 温度 湿度 拥塞度 用于获取每个环境...
  • 普通公司无法为服务器建立一间机房,用空调保证恒温恒湿防尘供电,而且适宜人生存的温度却不适用于服务器,相反适宜服务器温度又不是适应人的生存。 随着现在云服务器的广泛应用,很多公司的业务都上了云。但是在...
  • 普通公司无法为服务器建立一间机房,用空调保证恒温恒湿防尘供电,而且适宜人生存的温度却不适用于服务器,相反适宜服务器温度又不是适应人的生存。 2.保证网络连接,需要保证来自全国各地访问者的访问速度,要...
  • 正规的服务器厂商都会对产品进行不同温度和湿度下的运行稳定性测试。重点要考虑的是冗余功能,如:数据冗余、网卡冗余、电源冗余、风扇冗余等。 一些服务器稳定性测试方法主要为以下几种: 压力测试: 已知系统高峰...
  • 服务器稳定性测试

    2008-05-09 21:51:00
     正规的服务器厂商都会对产品进行不同温度和湿度下的运行稳定性测试。重点要考虑的是冗余功能,如:数据冗余、网卡荣誉、电源冗余、风扇冗余等。一些测试方法主要分以下几种: 压力测试:已知系统高峰期使用人数,...
  • 企业环境中对机房温度要求很严格,特别是现代企业中分布在全球各个地方的办公室及工厂,服务器24小时都要提供服务,所以远程能自动监控机房的温度是很有必要的,当监控到机房温度高于设定的警报值时,温度计上面的...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 152
精华内容 60
关键字:

服务器温度要求