1. 程式人生 > >網際網路技術23——心跳檢查及sigar的使用示例

網際網路技術23——心跳檢查及sigar的使用示例

心跳檢測示例中需要結合sigar,所以這裡先演示一下sigar的使用。

1.首先要下載sigar包,匯入包或使用maven依賴匯入

2.這點一定要注意,Sigar工具類下載地址需要將相應系統的DLL庫放入jdk或jre的bin目錄下才可以正常使用

  • Windows下配置:根據自己的作業系統版本選擇sigar-amd64-winnt.dll或sigar-x86-winnt.dll拷貝到C:\Windows\System32中

  • Linux下配置:將libsigar-amd64-linux.so或libsigar-x86-linux.so拷貝到/usr/lib64或/lib64或/lib或/usr/lib目錄下,如果不起作用,還需要sudochmod 744修改libsigar-amd64-linux.so檔案許可權

演示程式碼:

package com.sigarTest;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Properties;

import org.hyperic.sigar.Cpu;
import org.hyperic.sigar.CpuInfo;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.FileSystem;
import org.hyperic.sigar.FileSystemUsage;
import org.hyperic.sigar.Mem;
import org.hyperic.sigar.NetFlags;
import org.hyperic.sigar.NetInterfaceConfig;
import org.hyperic.sigar.NetInterfaceStat;
import org.hyperic.sigar.OperatingSystem;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.Swap;
import org.hyperic.sigar.Who;

public class TestSigar {
    public static void main(String[] args) {
        try {
            // System資訊,從jvm獲取
            property();
            System.out.println("----------------------------------");
            // cpu資訊
            cpu();
            System.out.println("----------------------------------");
            // 記憶體資訊
            memory();
            System.out.println("----------------------------------");
            // 作業系統資訊
            os();
            System.out.println("----------------------------------");
            // 使用者資訊
            who();
            System.out.println("----------------------------------");
            // 檔案系統資訊
            file();
            System.out.println("----------------------------------");
            // 網路資訊
            net();
            System.out.println("----------------------------------");
            // 乙太網資訊
            ethernet();
            System.out.println("----------------------------------");
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

    private static void property() throws UnknownHostException {
        Runtime r = Runtime.getRuntime();
        Properties props = System.getProperties();
        InetAddress addr;
        addr = InetAddress.getLocalHost();
        String ip = addr.getHostAddress();
        Map<String, String> map = System.getenv();
        String userName = map.get("USERNAME");// 獲取使用者名稱
        String computerName = map.get("COMPUTERNAME");// 獲取計算機名
        String userDomain = map.get("USERDOMAIN");// 獲取計算機域名
        System.out.println("使用者名稱:    " + userName);
        System.out.println("計算機名:    " + computerName);
        System.out.println("計算機域名:    " + userDomain);
        System.out.println("本地ip地址:    " + ip);
        System.out.println("本地主機名:    " + addr.getHostName());
        System.out.println("JVM可以使用的總記憶體:    " + r.totalMemory());
        System.out.println("JVM可以使用的剩餘記憶體:    " + r.freeMemory());
        System.out.println("JVM可以使用的處理器個數:    " + r.availableProcessors());
        System.out.println("Java的執行環境版本:    " + props.getProperty("java.version"));
        System.out.println("Java的執行環境供應商:    " + props.getProperty("java.vendor"));
        System.out.println("Java供應商的URL:    " + props.getProperty("java.vendor.url"));
        System.out.println("Java的安裝路徑:    " + props.getProperty("java.home"));
        System.out.println("Java的虛擬機器規範版本:    " + props.getProperty("java.vm.specification.version"));
        System.out.println("Java的虛擬機器規範供應商:    " + props.getProperty("java.vm.specification.vendor"));
        System.out.println("Java的虛擬機器規範名稱:    " + props.getProperty("java.vm.specification.name"));
        System.out.println("Java的虛擬機器實現版本:    " + props.getProperty("java.vm.version"));
        System.out.println("Java的虛擬機器實現供應商:    " + props.getProperty("java.vm.vendor"));
        System.out.println("Java的虛擬機器實現名稱:    " + props.getProperty("java.vm.name"));
        System.out.println("Java執行時環境規範版本:    " + props.getProperty("java.specification.version"));
        System.out.println("Java執行時環境規範供應商:    " + props.getProperty("java.specification.vender"));
        System.out.println("Java執行時環境規範名稱:    " + props.getProperty("java.specification.name"));
        System.out.println("Java的類格式版本號:    " + props.getProperty("java.class.version"));
        System.out.println("Java的類路徑:    " + props.getProperty("java.class.path"));
        System.out.println("載入庫時搜尋的路徑列表:    " + props.getProperty("java.library.path"));
        System.out.println("預設的臨時檔案路徑:    " + props.getProperty("java.io.tmpdir"));
        System.out.println("一個或多個擴充套件目錄的路徑:    " + props.getProperty("java.ext.dirs"));
        System.out.println("作業系統的名稱:    " + props.getProperty("os.name"));
        System.out.println("作業系統的構架:    " + props.getProperty("os.arch"));
        System.out.println("作業系統的版本:    " + props.getProperty("os.version"));
        System.out.println("檔案分隔符:    " + props.getProperty("file.separator"));
        System.out.println("路徑分隔符:    " + props.getProperty("path.separator"));
        System.out.println("行分隔符:    " + props.getProperty("line.separator"));
        System.out.println("使用者的賬戶名稱:    " + props.getProperty("user.name"));
        System.out.println("使用者的主目錄:    " + props.getProperty("user.home"));
        System.out.println("使用者的當前工作目錄:    " + props.getProperty("user.dir"));
    }

    private static void memory() throws SigarException {
        Sigar sigar = new Sigar();
        Mem mem = sigar.getMem();
        // 記憶體總量
        System.out.println("記憶體總量:    " + mem.getTotal() / 1024L + "K av");
        // 當前記憶體使用量
        System.out.println("當前記憶體使用量:    " + mem.getUsed() / 1024L + "K used");
        // 當前記憶體剩餘量
        System.out.println("當前記憶體剩餘量:    " + mem.getFree() / 1024L + "K free");
        Swap swap = sigar.getSwap();
        // 交換區總量
        System.out.println("交換區總量:    " + swap.getTotal() / 1024L + "K av");
        // 當前交換區使用量
        System.out.println("當前交換區使用量:    " + swap.getUsed() / 1024L + "K used");
        // 當前交換區剩餘量
        System.out.println("當前交換區剩餘量:    " + swap.getFree() / 1024L + "K free");
    }

    private static void cpu() throws SigarException {
        Sigar sigar = new Sigar();
        CpuInfo infos[] = sigar.getCpuInfoList();
        CpuPerc cpuList[] = null;

        System.out.println("cpu 總量引數情況:" + sigar.getCpu());
        System.out.println("cpu 總百分比情況:" + sigar.getCpuPerc());
        
        cpuList = sigar.getCpuPercList();
        for (int i = 0; i < infos.length; i++) {// 不管是單塊CPU還是多CPU都適用
            CpuInfo info = infos[i];
            System.out.println("第" + (i + 1) + "塊CPU資訊");
            System.out.println("CPU的總量MHz:    " + info.getMhz());// CPU的總量MHz
            System.out.println("CPU生產商:    " + info.getVendor());// 獲得CPU的賣主,如:Intel
            System.out.println("CPU類別:    " + info.getModel());// 獲得CPU的類別,如:Celeron
            System.out.println("CPU快取數量:    " + info.getCacheSize());// 緩衝儲存器數量
            printCpuPerc(cpuList[i]);
        }
    }

    private static void printCpuPerc(CpuPerc cpu) {
        System.out.println("CPU使用者使用率:    " + CpuPerc.format(cpu.getUser()));// 使用者使用率
        System.out.println("CPU系統使用率:    " + CpuPerc.format(cpu.getSys()));// 系統使用率
        System.out.println("CPU當前等待率:    " + CpuPerc.format(cpu.getWait()));// 當前等待率
        System.out.println("CPU當前錯誤率:    " + CpuPerc.format(cpu.getNice()));//
        System.out.println("CPU當前空閒率:    " + CpuPerc.format(cpu.getIdle()));// 當前空閒率
        System.out.println("CPU總的使用率:    " + CpuPerc.format(cpu.getCombined()));// 總的使用率
    }

    private static void os() {
        OperatingSystem OS = OperatingSystem.getInstance();
        // 作業系統核心型別如: 386、486、586等x86
        System.out.println("作業系統:    " + OS.getArch());
        System.out.println("作業系統CpuEndian():    " + OS.getCpuEndian());//
        System.out.println("作業系統DataModel():    " + OS.getDataModel());//
        // 系統描述
        System.out.println("作業系統的描述:    " + OS.getDescription());
        // 作業系統型別
        // System.out.println("OS.getName():    " + OS.getName());
        // System.out.println("OS.getPatchLevel():    " + OS.getPatchLevel());//
        // 作業系統的賣主
        System.out.println("作業系統的賣主:    " + OS.getVendor());
        // 賣主名稱
        System.out.println("作業系統的賣主名:    " + OS.getVendorCodeName());
        // 作業系統名稱
        System.out.println("作業系統名稱:    " + OS.getVendorName());
        // 作業系統賣主型別
        System.out.println("作業系統賣主型別:    " + OS.getVendorVersion());
        // 作業系統的版本號
        System.out.println("作業系統的版本號:    " + OS.getVersion());
    }

    private static void who() throws SigarException {
        Sigar sigar = new Sigar();
        Who who[] = sigar.getWhoList();
        if (who != null && who.length > 0) {
            for (int i = 0; i < who.length; i++) {
                // System.out.println("當前系統程序表中的使用者名稱" + String.valueOf(i));
                Who _who = who[i];
                System.out.println("使用者控制檯:    " + _who.getDevice());
                System.out.println("使用者host:    " + _who.getHost());
                // System.out.println("getTime():    " + _who.getTime());
                // 當前系統程序表中的使用者名稱
                System.out.println("當前系統程序表中的使用者名稱:    " + _who.getUser());
            }
        }
    }

    private static void file() throws Exception {
        Sigar sigar = new Sigar();
        FileSystem fslist[] = sigar.getFileSystemList();
        for (int i = 0; i < fslist.length; i++) {
            System.out.println("分割槽的碟符名稱" + i);
            FileSystem fs = fslist[i];
            // 分割槽的碟符名稱
            System.out.println("碟符名稱:    " + fs.getDevName());
            // 分割槽的碟符名稱
            System.out.println("碟符路徑:    " + fs.getDirName());
            System.out.println("碟符標誌:    " + fs.getFlags());//
            // 檔案系統型別,比如 FAT32、NTFS
            System.out.println("碟符型別:    " + fs.getSysTypeName());
            // 檔案系統型別名,比如本地硬碟、光碟機、網路檔案系統等
            System.out.println("碟符型別名:    " + fs.getTypeName());
            // 檔案系統型別
            System.out.println("碟符檔案系統型別:    " + fs.getType());
            FileSystemUsage usage = null;
            usage = sigar.getFileSystemUsage(fs.getDirName());
            switch (fs.getType()) {
            case 0: // TYPE_UNKNOWN :未知
                break;
            case 1: // TYPE_NONE
                break;
            case 2: // TYPE_LOCAL_DISK : 本地硬碟
                // 檔案系統總大小
                System.out.println(fs.getDevName() + "總大小:    " + usage.getTotal() + "KB");
                // 檔案系統剩餘大小
                System.out.println(fs.getDevName() + "剩餘大小:    " + usage.getFree() + "KB");
                // 檔案系統可用大小
                System.out.println(fs.getDevName() + "可用大小:    " + usage.getAvail() + "KB");
                // 檔案系統已經使用量
                System.out.println(fs.getDevName() + "已經使用量:    " + usage.getUsed() + "KB");
                double usePercent = usage.getUsePercent() * 100D;
                // 檔案系統資源的利用率
                System.out.println(fs.getDevName() + "資源的利用率:    " + usePercent + "%");
                break;
            case 3:// TYPE_NETWORK :網路
                break;
            case 4:// TYPE_RAM_DISK :快閃記憶體
                break;
            case 5:// TYPE_CDROM :光碟機
                break;
            case 6:// TYPE_SWAP :頁面交換
                break;
            }
            System.out.println(fs.getDevName() + "讀出:    " + usage.getDiskReads());
            System.out.println(fs.getDevName() + "寫入:    " + usage.getDiskWrites());
        }
        return;
    }

    private static void net() throws Exception {
        Sigar sigar = new Sigar();
        String ifNames[] = sigar.getNetInterfaceList();
        for (int i = 0; i < ifNames.length; i++) {
            String name = ifNames[i];
            NetInterfaceConfig ifconfig = sigar.getNetInterfaceConfig(name);
            System.out.println("網路裝置名:    " + name);// 網路裝置名
            System.out.println("IP地址:    " + ifconfig.getAddress());// IP地址
            System.out.println("子網掩碼:    " + ifconfig.getNetmask());// 子網掩碼
            if ((ifconfig.getFlags() & 1L) <= 0L) {
                System.out.println("!IFF_UP...skipping getNetInterfaceStat");
                continue;
            }
            NetInterfaceStat ifstat = sigar.getNetInterfaceStat(name);
            System.out.println(name + "接收的總包裹數:" + ifstat.getRxPackets());// 接收的總包裹數
            System.out.println(name + "傳送的總包裹數:" + ifstat.getTxPackets());// 傳送的總包裹數
            System.out.println(name + "接收到的總位元組數:" + ifstat.getRxBytes());// 接收到的總位元組數
            System.out.println(name + "傳送的總位元組數:" + ifstat.getTxBytes());// 傳送的總位元組數
            System.out.println(name + "接收到的錯誤包數:" + ifstat.getRxErrors());// 接收到的錯誤包數
            System.out.println(name + "傳送資料包時的錯誤數:" + ifstat.getTxErrors());// 傳送資料包時的錯誤數
            System.out.println(name + "接收時丟棄的包數:" + ifstat.getRxDropped());// 接收時丟棄的包數
            System.out.println(name + "傳送時丟棄的包數:" + ifstat.getTxDropped());// 傳送時丟棄的包數
        }
    }

    private static void ethernet() throws SigarException {
        Sigar sigar = null;
        sigar = new Sigar();
        String[] ifaces = sigar.getNetInterfaceList();
        for (int i = 0; i < ifaces.length; i++) {
            NetInterfaceConfig cfg = sigar.getNetInterfaceConfig(ifaces[i]);
            if (NetFlags.LOOPBACK_ADDRESS.equals(cfg.getAddress()) || (cfg.getFlags() & NetFlags.IFF_LOOPBACK) != 0
                    || NetFlags.NULL_HWADDR.equals(cfg.getHwaddr())) {
                continue;
            }
            System.out.println(cfg.getName() + "IP地址:" + cfg.getAddress());// IP地址
            System.out.println(cfg.getName() + "閘道器廣播地址:" + cfg.getBroadcast());// 閘道器廣播地址
            System.out.println(cfg.getName() + "網絡卡MAC地址:" + cfg.getHwaddr());// 網絡卡MAC地址
            System.out.println(cfg.getName() + "子網掩碼:" + cfg.getNetmask());// 子網掩碼
            System.out.println(cfg.getName() + "網絡卡描述資訊:" + cfg.getDescription());// 網絡卡描述資訊
            System.out.println(cfg.getName() + "網絡卡型別" + cfg.getType());//
        }
    }
}

 

心跳檢測

在使用socket時一般會處理多個伺服器之間的心跳檢測,一般來講,我們去維護服務叢集,肯定又一個或幾臺伺服器主機(Maser),然後還應該有n臺伺服器從機(Slave),那麼我們的主機肯定要時時刻刻知道自己下面的從伺服器的各個方面情況,然後進行實時監控的功能,這個在分散式架構裡叫做心跳檢測或者說心跳監控,最佳處理方案我們實施決定是使用一些通訊架構來實現,Netty就可以去做這樣一件事。

AuthReques

package com.nettyHeart;

import java.io.Serializable;

/**
 * Created by BaiTianShi on 2018/9/13.
 */
public class AuthRequest implements Serializable{

    private static final long serialVersionUID = 1862080046425754797L;
    private String auth;

    public AuthRequest(String auth) {
        this.auth = auth;
    }

    public String getAuth() {
        return auth;
    }

    public void setAuth(String auth) {
        this.auth = auth;
    }
}

 

AuthResponse

package com.nettyHeart;

import java.io.Serializable;

/**
 * Created by BaiTianShi on 2018/9/13.
 */
public class AuthRequest implements Serializable{

    private static final long serialVersionUID = 1862080046425754797L;
    private String auth;

    public AuthRequest(String auth) {
        this.auth = auth;
    }

    public String getAuth() {
        return auth;
    }

    public void setAuth(String auth) {
        this.auth = auth;
    }
}

Error

package com.nettyHeart;

/**
 * Created by BaiTianShi on 2018/9/13.
 */
public class Error {
    private String error;
    public Error(String error) {
        this.error = error;
    }
    public String getError() {
        return error;
    }



    public void setError(String error) {
        this.error = error;
    }
}

HeartRequest

package com.nettyHeart;

import java.io.Serializable;
import java.util.Map;

/**
 * Created by BaiTianShi on 2018/9/13.
 */
public class HeartRequest implements Serializable{

    private static final long serialVersionUID = -6839771181547020216L;
    private String ip;
    private Map<String,Object> cupMap;
    private Map<String,Object> memoryMap;

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public Map<String, Object> getCupMap() {
        return cupMap;
    }

    public void setCupMap(Map<String, Object> cupMap) {
        this.cupMap = cupMap;
    }

    public Map<String, Object> getMemoryMap() {
        return memoryMap;
    }

    public void setMemoryMap(Map<String, Object> memoryMap) {
        this.memoryMap = memoryMap;
    }
}

HeartResponse

package com.nettyHeart;

import java.io.Serializable;

/**
 * Created by BaiTianShi on 2018/9/13.
 */
public class HeartResponse implements Serializable{

    private static final long serialVersionUID = -702866278650479762L;
    private String msg;

    public HeartResponse(String msg) {
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

MarshallingCodeCFactory

package com.nettyHeart;

import io.netty.handler.codec.marshalling.*;
import org.jboss.marshalling.MarshallerFactory;
import org.jboss.marshalling.Marshalling;
import org.jboss.marshalling.MarshallingConfiguration;

public final class MarshallingCodeCFactory {

    /**
     * 建立Jboss Marshalling解碼器MarshallingDecoder
     */
    public static MarshallingDecoder buildMarshallingDecoder() {
        //首先通過Marshalling工具類的getProvidedMarshallerFactory靜態方法獲取MarshallerFactory例項
        //引數“serial”表示建立的是Java序列化工廠物件,它由jboss-marshalling-serial-1.3.0.CR9.jar提供。
        final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
        //建立了MarshallingConfiguration物件
        final MarshallingConfiguration configuration = new MarshallingConfiguration();
        //將它的版本號設定為5
        configuration.setVersion(5);
        //然後根據MarshallerFactory和MarshallingConfiguration建立UnmarshallerProvider例項
        UnmarshallerProvider provider = new DefaultUnmarshallerProvider(marshallerFactory, configuration);
        //最後通過建構函式建立Netty的MarshallingDecoder物件
        //它有兩個引數,分別是UnmarshallerProvider和單個訊息序列化後的最大長度。
        MarshallingDecoder decoder = new MarshallingDecoder(provider, 1024);
        return decoder;
    }

    /**
     * 建立Jboss Marshalling編碼器MarshallingEncoder
     */
    public static MarshallingEncoder buildMarshallingEncoder() {
        final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
        final MarshallingConfiguration configuration = new MarshallingConfiguration();
        configuration.setVersion(5);
        //建立MarshallerProvider物件,它用於建立Netty提供的MarshallingEncoder例項
        MarshallerProvider provider = new DefaultMarshallerProvider(marshallerFactory, configuration);
        //MarshallingEncoder用於將實現序列化介面的POJO物件序列化為二進位制陣列。
        MarshallingEncoder encoder = new MarshallingEncoder(provider);
        return encoder;
    }
}

MasterServer

package com.nettyHeart;

import com.nettyMarshalling.MarshallingCodeFactory;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

/**
 * Created by BaiTianShi on 2018/9/13.
 */
public class MasterServer {
    public void init (int port){
        //用於接收網路連線
        EventLoopGroup bootGroup = new NioEventLoopGroup();
        EventLoopGroup workGroup = new NioEventLoopGroup();

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bootGroup,workGroup);
        bootstrap.channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG,1024)
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(MarshallingCodeFactory.buildMarshallingEncoder());
                        socketChannel.pipeline().addLast(MarshallingCodeFactory.buildMarshallingDecode());
                        socketChannel.pipeline().addLast(new ServerHandler());
                    }
                });
        try {
            ChannelFuture cf = bootstrap.bind(8765).sync();
            cf.channel().closeFuture().sync();
            bootGroup.shutdownGracefully();
            workGroup.shutdownGracefully();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        MasterServer ms = new MasterServer();
        ms.init(8765);
    }
}

ServerHandler

package com.nettyHeart;

import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by BaiTianShi on 2018/9/13.
 */
public class ServerHandler extends ChannelHandlerAdapter{
    private static final String SUCCESS_KEY = "auth_success_key";
    private static final String FAILURE_KEY = "auth_failure_key";

    //存放從機資訊的列表map
    private static Map<String,String> AUTH_IP_MAP = new HashMap<>();
    static {
        AUTH_IP_MAP.put("192.168.156.1","1234");
    }

    private boolean auth(ChannelHandlerContext chx, Object msg){
        String[] ret = ((AuthRequest)msg).getAuth().split(":");
        String auth =AUTH_IP_MAP.get(ret[0]);
        if(auth != null && auth.equals(ret[1])){
            chx.writeAndFlush(new AuthResponse(SUCCESS_KEY));
            return true;
        }else {
            chx.writeAndFlush(new AuthResponse(FAILURE_KEY));
            return false;
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("master read....");
        System.out.println(msg instanceof AuthRequest);
        if(msg instanceof AuthRequest){
            this.auth(ctx,msg);
        }else if(msg instanceof HeartRequest){
            HeartRequest req = (HeartRequest) msg;
            System.out.println("--------------------------------------");
            System.out.println("當前主機ip為:"+req.getIp());
            System.out.println("當前主機cpu情況:");
            Map cpu = req.getCupMap();
            System.out.println("總使用率:"+cpu.get("combind"));
            System.out.println("使用者使用率:"+cpu.get("user"));
            System.out.println("系統使用率:"+cpu.get("sys"));
            System.out.println("等待率:"+cpu.get("wait"));
            System.out.println("空閒率:"+cpu.get("idle"));

            Map memory = req.getMemoryMap();
            System.out.println("記憶體總量:"+memory.get("total"));
            System.out.println("使用者使用率:"+memory.get("used"));
            System.out.println("系統使用率:"+memory.get("free"));
            System.out.println("-----------------------------------");

            ctx.writeAndFlush(new HeartResponse("info received"));

        }else {
            ctx.writeAndFlush(new Error("connect failure")).addListener(ChannelFutureListener.CLOSE);
        }
    }
}

SlaveClient

package com.nettyHeart;

import com.nettyMarshalling.MarshallingCodeFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

/**
 * Created by BaiTianShi on 2018/9/13.
 */
public class SlaveClient {
    private void init (String ip, int port){
        EventLoopGroup workGroup = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(workGroup);
        bootstrap.channel(NioSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.INFO))
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(MarshallingCodeFactory.buildMarshallingEncoder());
                        socketChannel.pipeline().addLast(MarshallingCodeFactory.buildMarshallingDecode());
                        socketChannel.pipeline().addLast(new SlaveClientHeartBeat());
                    }
                });
        try {
            ChannelFuture cf = bootstrap.connect(ip,port).sync();
            System.out.println("Slave Client started. IP : " + ip + ":" + port);
            cf.channel().closeFuture().sync();
            workGroup.shutdownGracefully();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SlaveClient sc =new SlaveClient();
        sc.init("127.0.0.1",8765);
    }
}

SlaveClientHeartBeat

package com.nettyHeart;

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.Mem;
import org.hyperic.sigar.Sigar;

import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * Created by BaiTianShi on 2018/9/13.
 */
public class SlaveClientHeartBeat extends ChannelHandlerAdapter {
    private ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1);

    private ScheduledFuture<?> heartBeat;

    private InetAddress address;

    private static final String SUCCESS_KEY = "auth_success_key";
    private static final String FAILURE_KEY = "auth_failure_key";

    /**
     * 當連線建立啟用時呼叫
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("auth start...");
        address = InetAddress.getLocalHost();
        String ip = address.getHostAddress();
        System.out.println(ip);
        String key = "1234";
        //模擬證書與主機進行認證, 真實環境中此處應該進行加密處理
        ctx.writeAndFlush(new AuthRequest(ip + ":" + key));
    }



    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        try{
            if((msg instanceof AuthResponse)){
                AuthResponse ret = (AuthResponse)msg;
                if( SUCCESS_KEY.equals(ret.getResult()) ){
                    //定時任務,每隔5秒鐘執行一次HeartBeatTask, 延遲0秒開始
                    this.heartBeat = this.scheduled.scheduleWithFixedDelay(new HeartBeatTask(ctx), 0, 5, TimeUnit.SECONDS);
                    System.out.println(ret.getResult());
                }else if(FAILURE_KEY.equals(ret.getResult())){
                    System.out.println("許可權認證失敗。");
                }
            }else if((msg instanceof HeartResponse)){
                HeartResponse ret = (HeartResponse)msg;
                System.out.println(ret.getMsg());
            }else if((msg instanceof Error)){
                Error ret = (Error) msg;
                System.out.println(ret.getError());
            }else{
                System.out.println(msg);
            }
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally{
            ReferenceCountUtil.release(msg);
        }

    }


    public class HeartBeatTask implements Runnable{

        private final ChannelHandlerContext ctx;

        public HeartBeatTask(ChannelHandlerContext ctx) {
            // TODO Auto-generated constructor stub
            this.ctx = ctx;
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
                HeartRequest requestInfo = new HeartRequest();
                requestInfo.setIp(address.getHostAddress());
                //Sigar工具類,用來獲取當前系統的CPU記憶體等等資訊,下面有詳細使用介紹
                Sigar sigar = new Sigar();

                CpuPerc cpuPerc = sigar.getCpuPerc();
                Map<String, Object> cpuMap = new HashMap<>();
                cpuMap.put("combined", cpuPerc.getCombined());
                cpuMap.put("user", cpuPerc.getUser());
                cpuMap.put("sys", cpuPerc.getSys());
                cpuMap.put("wait", cpuPerc.getWait());
                cpuMap.put("idle", cpuPerc.getIdle());
                requestInfo.setCupMap(cpuMap);

                Mem memPerc = sigar.getMem();
                Map<String, Object> memMap = new HashMap<String, Object>();
                memMap.put("total", memPerc.getTotal() / 1024L);
                memMap.put("used", memPerc.getUsed() / 1024L);
                memMap.put("free", memPerc.getFree() / 1024L);
                requestInfo.setMemoryMap(memMap);

                ctx.writeAndFlush(requestInfo);

            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
    }
}