今天搭建Hbase集群过程中,在页面http://hadoop01:16010/zk.jsp发现zk 通讯统计节(Quorum Server Statistics)存在提示stat is not executed because it is not in the whitelist.

解决思路:

[root@hadoop01 bigdata]# echo conf|nc hadoop01 2181
conf is not executed because it is not in the whitelist.
zk的这些指令未在白名单里。这些指令有
    // specify all of the commands that are available
    static {
        cmd2String.put(confCmd, "conf");
        cmd2String.put(consCmd, "cons");
        cmd2String.put(crstCmd, "crst");
        cmd2String.put(dirsCmd, "dirs");
        cmd2String.put(dumpCmd, "dump");
        cmd2String.put(enviCmd, "envi");
        cmd2String.put(getTraceMaskCmd, "gtmk");
        cmd2String.put(ruokCmd, "ruok");
        cmd2String.put(setTraceMaskCmd, "stmk");
        cmd2String.put(srstCmd, "srst");
        cmd2String.put(srvrCmd, "srvr");
        cmd2String.put(statCmd, "stat");
        cmd2String.put(wchcCmd, "wchc");
        cmd2String.put(wchpCmd, "wchp");
        cmd2String.put(wchsCmd, "wchs");
        cmd2String.put(mntrCmd, "mntr");
        cmd2String.put(isroCmd, "isro");
        cmd2String.put(telnetCloseCmd, "telnet close");
    }

搜索源码is not executed because it is not in the whitelist.

/** Return if four letter word found and responded to, otw false **/
    private boolean checkFourLetterWord(final Channel channel,
            ChannelBuffer message, final int len) throws IOException
    {
        // We take advantage of the limited size of the length to look
        // for cmds. They are all 4-bytes which fits inside of an int
        if (!FourLetterCommands.isKnown(len)) {
            return false;
        }
 
        String cmd = FourLetterCommands.getCommandString(len);
 
        channel.setInterestOps(0).awaitUninterruptibly();
        packetReceived();
 
        final PrintWriter pwriter = new PrintWriter(
                new BufferedWriter(new SendBufferWriter()));
 
        // ZOOKEEPER-2693: don't execute 4lw if it's not enabled.
        // 注意此处命令是否允许执行,isEnabled方法用于判断
        if (!FourLetterCommands.isEnabled(cmd)) {
            LOG.debug("Command {} is not executed because it is not in the whitelist.", cmd);
            NopCommand nopCmd = new NopCommand(pwriter, this, cmd +
                    " is not executed because it is not in the whitelist.");
            nopCmd.start();
            return true;
        }
 
        LOG.info("Processing " + cmd + " command from "
                + channel.getRemoteAddress());
 
       if (len == FourLetterCommands.setTraceMaskCmd) {
            ByteBuffer mask = ByteBuffer.allocate(8);
            message.readBytes(mask);
            mask.flip();
            long traceMask = mask.getLong();
            ZooTrace.setTextTraceLevel(traceMask);
            SetTraceMaskCommand setMask = new SetTraceMaskCommand(pwriter, this, traceMask);
            setMask.start();
            return true;
        } else {
            CommandExecutor commandExecutor = new CommandExecutor();
            return commandExecutor.execute(this, pwriter, len, zkServer,factory);
        }
    }
 /**
     * Check if the specified command is enabled.
     *
     * In ZOOKEEPER-2693 we introduce a configuration option to only
     * allow a specific set of white listed commands to execute.
     * A command will only be executed if it is also configured
     * in the white list.
     *
     * @param command The command string.
     * @return true if the specified command is enabled
     */
    public synchronized static boolean isEnabled(String command) {
        // whiteListInitialized是否初始化过的标记,默认是false,whiteListedCommands相关命令加载完成后,就为true了
        if (whiteListInitialized) {
            return whiteListedCommands.contains(command);
        }
 
        // 参数key名称zookeeper.4lw.commands.whitelist的值直接用*,则会把cmd2String里已经缓存的所有指令放到这个白名单里
        String commands = System.getProperty(ZOOKEEPER_4LW_COMMANDS_WHITELIST);
        if (commands != null) {
            String[] list = commands.split(",");
            for (String cmd : list) {
                if (cmd.trim().equals("*")) {
                    for (Map.Entry<Integer, String> entry : cmd2String.entrySet()) {
                        whiteListedCommands.add(entry.getValue());
                    }
                    break;
                }
                if (!cmd.trim().isEmpty()) {
                    whiteListedCommands.add(cmd.trim());
                }
            }
        }
 
        // It is sad that isro and srvr are used by ZooKeeper itself. Need fix this
        // before deprecating 4lw.
        if (System.getProperty("readonlymode.enabled", "false").equals("true")) {
            whiteListedCommands.add("isro");
        }
        // zkServer.sh depends on "srvr".
        whiteListedCommands.add("srvr");
        whiteListInitialized = true;
        LOG.info("The list of known four letter word commands is : {}", Arrays.asList(cmd2String));
        LOG.info("The list of enabled four letter word commands is : {}", Arrays.asList(whiteListedCommands));
        return whiteListedCommands.contains(command);
    }

解决方法:

方法1和2均可解决,采用其一即可。

1、在zoo.cfg 文件里加入配置项让这些指令放行

#开启四字命令
4lw.commands.whitelist=*

2、在zk的启动脚本zkServer.sh中新增放行指令

    ZOOMAIN="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=$JMXPORT -Dcom.sun.management.jmxremote.authenticate=$JMXAUTH -Dcom.sun.management.jmxremote.ssl=$JMXSSL -Dzookeeper.jmx.log4j.disable=$JMXLOG4J org.apache.zookeeper.server.quorum.QuorumPeerMain"
  fi
else
    echo "JMX disabled by user request" >&2
    ZOOMAIN="org.apache.zookeeper.server.quorum.QuorumPeerMain"
fi

#添加VM环境变量-Dzookeeper.4lw.commands.whitelist=*
ZOOMAIN="-Dzookeeper.4lw.commands.whitelist=* ${ZOOMAIN}"

if [ "x$SERVER_JVMFLAGS" != "x" ]
then
    JVMFLAGS="$SERVER_JVMFLAGS $JVMFLAGS"
fi

注:配置完毕后,记得重启集群。./zkServer.sh restart

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐