Github 开源项目(一)websocketd (实战:实时监控服务器内存信息)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 官方地址:https://github.com/joewalnes/websocketd  websocketd是WebSocket守护进程,它负责处理WebSocket连接,启动您的程序来处理WebSockets,并在程序和Web浏览器之间传递消息。

官方地址:https://github.com/joewalnes/websocketd

  websocketd是WebSocket守护进程,它负责处理WebSocket连接,启动您的程序来处理WebSockets,并在程序和Web浏览器之间传递消息。

 一、安装:websocketd 

wget https://github.com/joewalnes/websocketd/releases/download/v0.2.12/websocketd-0.2.12-linux_amd64.zip

unzip  websocketd-0.2.12-linux_amd64.zip

解压后生成这个文件:websocketd

复制该文件到 /usr/bin目录下,修改环境变量

sudo cp websocketd /usr/bin/websocketd

sudo vim /etc/profile

export  PATH=$PATH:/usr/bin/websocketd

可能出现的错误:如果修改了/etc/profile,那么编辑结束后执行source profile 或 执行点命令 ./profile,PATH的值就会立即生效了,但是会提示以下错误:

#source /etc/profile   之后为什么会出现
command not found

解决办法,直接切换到root 用户模式既可,再次执行source profile 就可以了,输入help 看是否配置合适,如下所示:

tinywan@tinywan:~/shell$ websocketd --help
websocketd (0.2.12 (go1.6 linux-amd64) --)

websocketd is a command line tool that will allow any executable program
that accepts input on stdin and produces output on stdout to be turned into
a WebSocket server.

Usage:

  Export a single executable program a WebSocket server:
    websocketd [options] COMMAND [command args]

  Or, export an entire directory of executables as WebSocket endpoints:
    websocketd [options] --dir=SOMEDIR

Options:

  --port=PORT                    HTTP port to listen on.

  --address=ADDRESS              Address to bind to (multiple options allowed)
                                 Use square brackets to specify IPv6 address. 
                                 Default: "" (all)

二、开启WebSocketd 服务

tinywan@tinywan:~/shell$ websocketd --port=63800 ./count.sh 
Mon, 08 May 2017 17:26:50 +0800 | INFO   | server     |  | Serving using application   : ./count.sh 
Mon, 08 May 2017 17:26:50 +0800 | INFO   | server     |  | Starting WebSocket server   : ws://tinywan:8080/

测试代码:count.sh

#!/bin/bash
for ((COUNT = 1; COUNT <= 10; COUNT++)); do
  echo $COUNT
  sleep 1
done

运行脚本时你可能会遇到以下错误:

 

root@TinywanAliYun:/home/www/bin# websocketd --port=63800 ./count.sh 
Unable to locate specified COMMAND './count.sh' in OS path.

Usage:

  Export a single executable program a WebSocket server:
    websocketd [options] COMMAND [command args]

  Or, export an entire directory of executables as WebSocket endpoints:
    websocketd [options] --dir=SOMEDIR

  Or, show extended help message using:
    websocketd --help

 

请赋予权限,使其可执行:

$ chmod +x ./count.sh

随便打开一个浏览器,在console中输入一下代码测试:

var ws = new WebSocket('ws://192.168.18.12:63800/');
ws.onopen = function() {
    console.log('CONNECT');
};
ws.onclose = function() {
    console.log('DISCONNECT');
};
ws.onmessage = function(event) {
    console.log('MESSAGE: ' + event.data);
};

(1)测试结果如下所示:

  

(2)新建立一个客户端测试client.html

<!doctype html>
<html lang="">
<head>
    <meta charset="utf-8">
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title>websocketd</title>
</head>
<body>
<h2>websocketd 客户端的简单测试</h2>
<pre id="log"></pre>
<script>
    // helper function: log message to screen
    function log(msg) {
        document.getElementById('log').textContent += msg + '\n';
    }

    // setup websocket with callbacks
    var ws = new WebSocket('ws://192.168.18.12:8080/');
    ws.onopen = function() {
        console.log('CONNECT');
    };
    ws.onclose = function() {
        console.log('DISCONNECT');
    };
    ws.onmessage = function(event) {
        console.log('MESSAGE: ' + event.data);
    };
</script>
</body>
</html>

在查看结果信息,查看结果已经ok

 查看服务端信息

我本机IP地址为,也就是client.html客户端

 websocketd --port=9501 --devconsole luajit ./json_ws.lua

》》》实际案例,使用WebSocketd 实时监控内存信息

1、编写脚本,system_info_send_websocketd.sh

#!/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin

SHELL_DIR="/home/www/bin"
SHELL_NAME="system_info_websocketd"
SHELL_TIME=$(date '+%Y-%m-%d')
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}-${SHELL_TIME}.log"

REDIS_MEMORY_KEYS_NAME="REDIS_MEMORY_INFO:001"
REDIS_DISH_KEYS_NAME="REDIS_DISH_INFO:001"

while(true)
    do
        FIND_DATA=$(cat /proc/meminfo | grep "MemFree:" | awk '{print $2}')
        echo  "[$SHELL_TIME]: FIND_DATA = $FIND_DATA INSERT_RES = ${INSERT_RES} CUT_LIST_LEN = ${CUT_LIST_LEN}" >> $SHELL_LOG
        echo   '{"data":'"${FIND_DATA}"',"errcode":0,"errmsg":0}'
        sleep 2
done

2、客户端实时监控代码:

<div class="panel-footer" id="container" style="width: 100%; height: 400px; margin: 0 auto"></div>
<script language="JavaScript">
    //数据获取
    var moniServerIp = "{{moniServerIp}}";
    var moniServerSshUsername = "{$moniServerSshUsername}";
    var moniServerSshPassword = "{$moniServerSshPassword}";

    var wsServerIP = "127.0.0.1";
    var wsServerPort = "12380";
    var moniMehtod = "server02";
    var moniInterval = 1;
    var moniDataUnit = 'MB';

    var wsData = 0.0;
    wsSend = {
        "action": moniMehtod,
        "name": "tinywan",
    };
    $(document).ready(function () {
        //----------WebSocket部分--------------
        var ws = new WebSocket("ws://" + wsServerIP + ":" + wsServerPort);
        ws.onopen = function () {
            ws.send(JSON.stringify(wsSend));
        };
        ws.onclose = function () {
            console.log('链接已断开');
            ws.close();
        };
        ws.onmessage = function (e) {
            var response = JSON.parse(e.data);
            if (Number(response.errcode) !== 0) {
                console.log(String(response.errmsg));
                ws.close();
                alert('出错啦!' + String(response.errmsg));
                return;
            }
            var divisor = 1;
            switch (moniDataUnit.toLocaleLowerCase()) {
                case 'mb':
                    divisor = 1024;
                    break;
            }
            wsData = response.data / divisor;
            console.log("收到服务端的消息:" + wsData);
        };

        //----------highcharts的图标插件部分--------------
        Highcharts.setOptions({
            global: {
                useUTC: false
            }
        });

        $('#container').highcharts({
            chart: {
                type: 'spline',
                animation: Highcharts.svg, // don't animate in old IE
                marginRight: 10,
                events: {
                    load: function () {
                        // set up the updating of the chart each second
                        var series = this.series[0];
                        setInterval(function () {
                            // current time
                            var x = (new Date()).getTime(),
                                y = wsData * 1.00;
                            series.addPoint([x, y], true, true);
                        }, 2000);
                    }
                }
            },
            title: {
                text: '服务器【' + moniServerIp + '】内存指标(单位:' + moniDataUnit + ')'
            },
            xAxis: {
                type: 'datetime',
                tickPixelInterval: 150
            },
            yAxis: {
                title: {
                    text: 'MemFree'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                formatter: function () {
                    return '<b>' + this.series.name + '</b><br/>' +
                        Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
                        Highcharts.numberFormat(this.y, 2);
                }
            },
            legend: {
                enabled: false
            },
            exporting: {
                enabled: false
            },
            series: [{
                name: 'MemFree指标',
                data: (function () {
                    // generate an array
                    var data = [],
                        time = (new Date()).getTime(),
                        i;
                    for (i = -19; i <= 0; i += 1) {
                        data.push({
                            x: time + i * 1000,
                            y: wsData
                        });
                    }
                    return data;
                }())
            }]
        });
    });
</script>
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>

3、测试结果:

 

4、客户端可能会出现超时链接的,可以使用 ReconnectingWebSocket

 var ws = new ReconnectingWebSocket("ws://" + wsServerIP + ":" + wsServerPort);

 》》》》》》》》》》》》 参数详解                   

(1)参数一:--staticdir=.

--staticdir=.  Allow websocketd to serve count.html as a static file
//允许websocketd作为静态文件提供count.html

这个参数是什么意思来,就是在当前项目指定通知执行的语言脚本文件(count.sh)同名的count.html作为静态文件,直接使用http访问

当前目录

count.sh 文件 (tinywan@tinywan:~/Go/websocket$ cat count.sh)

#!/bin/bash
# Count from 1 to 10, pausing for a second between each iteration.
for COUNT in $(seq 1 10); do
  echo $COUNT
  sleep 1
done

count.html 文件

<!DOCTYPE html>
<html>
  <head>
    <title>websocketd count example</title>
    <style>
      #count {
        font: bold 150px arial;
        margin: auto;
        padding: 10px;
        text-align: center;
      }
    </style>
  </head>
  <body>

    <div id="count"></div>

    <script>
      var ws = new WebSocket('ws://192.168.18.180:8080/');
      ws.onopen = function() {
        document.body.style.backgroundColor = '#cfc';
      };
      ws.onclose = function() {
        document.body.style.backgroundColor = null;
      };
      ws.onmessage = function(event) {
        document.getElementById('count').textContent = event.data;
      };
    </script>

  </body>
</html>

 打开谷歌浏览器,在地址栏输入:http://192.168.18.180:8080/

  

点击count.html后的效果图

   

 (2)参数二: --devconsole

  该--devconsole标志使内置的控制台websocketd与WebSocket端点手动交互。

  指向浏览器http://localhost:8080/,您将看到控制台。按复选框连接。

      请注意,您不能同时使用--devconsole和--staticdir。开发控制台旨在提供临时用户界面,直到您构建了真实的用户界面。

开始测试:

  

打开浏览器测试,发送一个空数据是没办法发送的,由于我们没有指定开启那个一个语言脚本文件充当WebSocket 服务器,为我们提供客户端的服务

  

指定/home/tinywan/Go/websocket 目录下的 count.sh 作为服务文件,继续测试的结果如下所示

  

 Websocket 代理服务器

1、没代理之前访问

var ws = new WebSocket('ws://192.168.18.188:63800');
ws.onopen = function() {
    console.log('CONNECT');
};
ws.onclose = function() {
    console.log('DISCONNECT');
};
ws.onmessage = function(event) {
    console.log('MESSAGE: ' + event.data);
};

2、代理之后访问

var ws = new WebSocket('ws://192.168.18.188:8087/chat/');
ws.onopen = function() {
    console.log('CONNECT');
};
ws.onclose = function() {
    console.log('DISCONNECT');
};
ws.onmessage = function(event) {
    console.log('MESSAGE: ' + event.data);
};

守护进程运行

nohup websocketd --port=63800 /home/www/bin/system_info_send_all_websocketd.sh >/dev/null  2>&1 &

 加载证书

 sudo websocketd --port=6500 --ssl --sslcert="/etc/letsencrypt/live/www.tinywan.top/fullchain.pem" --

sslkey="/etc/letsencrypt/live/www.tinywan.top//privkey.pem" /home/www/bin/system_info_send_all_websocketd.s

 wss 协议测试

var ws = new WebSocket('wss://www.tinywan.top:6500');
ws.onopen = function() {
    console.log('CONNECT');
};
ws.onclose = function() {
    console.log('DISCONNECT');
};
ws.onmessage = function(event) {
    console.log('MESSAGE: ' + event.data);
};

 

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2天前
|
运维 安全 开发工具
GitHub 热门开源运维工具 Websoft9:如何实现服务器管理效率翻倍?
Websoft9 提供 200+ 开源应用一键部署,支持容器化隔离、GitOps 自动化和企业级安全防护,助力服务器管理效率提升 80%。
29 1
|
24天前
|
存储 弹性计算 安全
阿里云服务器实例选择:经济型、通用算力型、计算型、通用型、内存型实例选择参考
当我们通过阿里云的活动购买云服务器会发现,相同配置的云服务器往往有多个不同的实例可选,而且价格差别也比较大,例如同样是4核8G的配置的云服务器,经济型e实例活动价格1595.11元/1年起,通用算力型u1实例要955.58元/1年起,而计算型c8i实例则要2845.81元/1年起,价格差别还是比较大的,因此,阿里云经济型、通用算力型、计算型、通用型、内存型实例云服务器有何差别就是很多新手用户比较关心的问题了,下面小编来为大家简单介绍下它们之间的区别。
|
20天前
|
存储 缓存 安全
阿里云服务器计算型c7/c8y/c8i,通用型g7/g8y/g8i,内存型r7/r8y/r8i区别及选择参考
为了满足不同企业级用户的多样化需求,阿里云在当下的活动中推出了多款计算型、通用型和内存型的云服务器实例,包括计算型c7/c8y/c8i、通用型g7/g8y/g8i以及内存型r7/r8y/r8i等。这些实例各具特色,适用于不同的应用场景和业务需求。本文将为您详细解析这些实例的区别,以及选择参考,帮助您根据自己的需求选择合适的阿里云服务器实例。
|
27天前
|
人工智能 运维 监控
2025年阿里云服务器配置选择全攻略:CPU、内存、带宽与系统盘详解
在2025年,阿里云服务器以高性能、灵活扩展和稳定服务助力数字化转型,提供轻量应用服务器、通用型g8i实例等多样化配置,满足个人博客至企业级业务需求。针对不同场景(如计算密集型、内存密集型),推荐相应实例类型与带宽规划,强调成本优化策略,包括包年包月节省成本、ESSD云盘选择及地域部署建议。文中还提及安全设置、监控备份的重要性,并指出未来可关注第九代实例g9i支持的新技术。整体而言,阿里云致力于帮助用户实现性能与成本的最优平衡。 以上简介共计238个字符。
|
3月前
|
存储 缓存 资源调度
阿里云服务器经济型、通用算力型、计算型、通用型、内存型实例区别与选择指南
在我们通过阿里云的活动选购云服务器的时候会发现,相同配置的云服务器往往有多个不同的实例可选,而且价格差别也比较大,这会是因为不同实例规格的由于采用的处理器不同,底层架构也有所不同(例如X86 计算架构与Arm 计算架构),因此不同实例的云服务器其性能与适用场景是有所不同。本文将详细解析阿里云的经济型、通用算力型、计算型、通用型和内存型实例的性能特点及适用场景,帮助用户根据自己的业务需求做出明智的选择。
|
3月前
|
存储 监控 调度
云服务器成本优化深度解析与实战案例
本文深入探讨了云服务器成本优化的策略与实践,涵盖基本原则、具体策略及案例分析。基本原则包括以实际需求为导向、动态调整资源、成本控制为核心。具体策略涉及选择合适计费模式、优化资源配置、存储与网络配置、实施资源监控与审计、应用性能优化、利用优惠政策及考虑多云策略。文章还通过电商、制造企业和初创团队的实际案例,展示了云服务器成本优化的有效性,最后展望了未来的发展趋势,包括智能化优化、多云管理和绿色节能。
|
3月前
|
存储 分布式计算 安全
阿里云服务器经济型e、通用算力型u1、计算型c8i、通用型g8i、内存型r8i实例介绍与选择参考
在阿里云现在的活动中,可选的云服务器实例规格主要有经济型e、通用算力型u1、计算型c8i、通用型g8i、内存型r8i实例,虽然阿里云在活动中提供了多种不同规格的云服务器实例,以满足不同用户和应用场景的需求。但是有的用户并不清楚他们的性能如何,应该如何选择。本文将详细介绍阿里云服务器中的经济型e、通用算力型u1、计算型c8i、通用型g8i、内存型r8i实例的性能、适用场景及选择参考,帮助用户根据自身需求做出合适的选择。
|
3月前
|
开发框架 .NET PHP
网站应用项目如何选择阿里云服务器实例规格+内存+CPU+带宽+操作系统等配置
对于使用阿里云服务器的搭建网站的用户来说,面对众多可选的实例规格和配置选项,我们应该如何做出最佳选择,以最大化业务效益并控制成本,成为大家比较关注的问题,如果实例、内存、CPU、带宽等配置选择不合适,可能会影响到自己业务在云服务器上的计算性能及后期运营状况,本文将详细解析企业在搭建网站应用项目时选购阿里云服务器应考虑的一些因素,以供参考。
|
3天前
|
存储 缓存 算法
JVM简介—1.Java内存区域
本文详细介绍了Java虚拟机运行时数据区的各个方面,包括其定义、类型(如程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和直接内存)及其作用。文中还探讨了各版本内存区域的变化、直接内存的使用、从线程角度分析Java内存区域、堆与栈的区别、对象创建步骤、对象内存布局及访问定位,并通过实例说明了常见内存溢出问题的原因和表现形式。这些内容帮助开发者深入理解Java内存管理机制,优化应用程序性能并解决潜在的内存问题。
JVM简介—1.Java内存区域
|
2天前
|
缓存 监控 算法
JVM简介—2.垃圾回收器和内存分配策略
本文介绍了Java垃圾回收机制的多个方面,包括垃圾回收概述、对象存活判断、引用类型介绍、垃圾收集算法、垃圾收集器设计、具体垃圾回收器详情、Stop The World现象、内存分配与回收策略、新生代配置演示、内存泄漏和溢出问题以及JDK提供的相关工具。
JVM简介—2.垃圾回收器和内存分配策略