jmx包
从ComonNames文件中知道,org.apache.ZooKeeperService很重要
//CommonNames.java
public class CommonNames {
public static final String DOMAIN="org.apache.ZooKeeperService";
public static final String DATA_TREE_KEY="DataTree";
public static final String STANDALONE_SERVER_KEY="StandaloneServer";
}
//ManagedUtil.java
//配置log4j
//MBeanRegistry.java
//不懂JMX,看不懂
//ZKMBeabInfo.java
//ZooKeeper要监控的bean的接口
public interface ZKMBeanInfo {
public String getName();
public boolean isHidden();
}
cli包
这个包是解析zk-cli的命令的,所有命令的就是继承自CliCommand类。看到这么命名的,就基本知道是命令模式了。
abstract public class CliCommand {
protected ZooKeeper zk; //要自己设置
protected PrintStream out; //默认System.out
protected PrintStream err; //默认System.err
private String cmdStr; //这个是子类传入的,如"create"
private String optionStr; //这个也是子类传入的,如"[-s] [-e] [-c] [-t ttl] path [data] [acl]"
public void addToMap(Map<String, CliCommand> cmdMap) {
//记录下命令
.3
cmdMap.put(cmdStr, this);
}
abstract public CliCommand parse(String cmdArgs[]) throws CliParseException;
abstract public boolean exec() throws CliException;
看一下CreateCommand的实现,结果发现比3.4.10还多了一些选项
public class CreateCommand extends CliCommand {
private static Options options = new Options();
private String[] args;
private CommandLine cl;
static {
options.addOption(new Option("e", false, "ephemeral"));
options.addOption(new Option("s", false, "sequential"));
options.addOption(new Option("c", false, "container"));
options.addOption(new Option("t", true, "ttl"));
}
public CreateCommand() {
super("create", "[-s] [-e] [-c] [-t ttl] path [data] [acl]");
}
}
//用于解析输入的命令
public CliCommand parse(String[] cmdArgs){ ... }
//用于执行解析的命令
//委派给父类的ZooKeeper来执行
public boolean exec() throws CliException {
//...
String newPath = hasT ?
zk.create(path, data, acl, flags, new Stat(), ttl) :
zk.create(path, data, acl, flags);
//...
}
来,那就看看全部的命令吧
//e->ephemeral, s->sequential
//c->container, t->ttl
public class CreateCommand extends CliCommand {
public CreateCommand() {
super("create", "[-s] [-e] [-c] [-t ttl] path [data] [acl]");
}
}
//v->version
public class DeleteCommand extends CliCommand {
public DeleteCommand() {
super("delete", "[-v version] path");
}
}
public class DeleteAllCommand extends CliCommand {
public DeleteAllCommand() {
this("deleteall");
}
}
//s->stats, w->watch
public class GetCommand extends CliCommand {
private static Options options = new Options();
public GetCommand() {
super("get", "[-s] [-w] path");
}
}
//s->stats, v->version
public class SetCommand extends CliCommand {
public SetCommand() {
super("set", "[-s] [-v version] path data");
}
}
public class Ls2Command extends CliCommand {
public Ls2Command() {
super("ls2", "path [watch]");
}
}
//ls ? ->help
//s->stat, w->watch, r->recurse
public class LsCommand extends CliCommand {
public LsCommand() {
super("ls", "[-s] [-w] [-R] path");
}
}
//b->bytes quota, n->num quota
public class SetQuotaCommand extends CliCommand {
public SetQuotaCommand() {
super("setquota", "-n|-b val path");
}
}
public class ListQuotaCommand extends CliCommand {
public ListQuotaCommand() {
super("listquota", "path");
}
}
//b->bytes quota, n->num quota
public class DelQuotaCommand extends CliCommand {
public DelQuotaCommand() {
super("delquota", "[-n|-b] path");
}
}
//s->stats
public class GetAclCommand extends CliCommand {
public GetAclCommand() {
super("getAcl", "[-s] path");
}
}
//s->stats, v->version
public class SetAclCommand extends CliCommand {
public SetAclCommand() {
super("setAcl", "[-s] [-v version] path acl");
}
}
public class AddAuthCommand extends CliCommand {
public AddAuthCommand() {
super("addauth", "scheme auth");
}
}
public class CloseCommand extends CliCommand {
public CloseCommand() {
super("close", "");
}
}
//s->stats, w->watch
//c->client connection string
public class GetConfigCommand extends CliCommand {
private static Options options = new Options();
public GetConfigCommand() {
super("config", "[-c] [-w] [-s]");
}
}
//s->stats
//v->required current config version
//file->path of config file to parse for membership
//members->comma-separated list of config strings for non-incremental reconfig
//add->comma-separated list of config strings for new servers
//remove->comma-separated list of server IDs to remove
public class ReconfigCommand extends CliCommand {
public ReconfigCommand() {
super("reconfig", "[-s] " +
"[-v version] " +
"[[-file path] | " +
"[-members serverID=host:port1:port2;port3[,...]*]] | " +
"[-add serverId=host:port1:port2;port3[,...]]* " +
"[-remove serverId[,...]*]");
}
}
//c->child watcher type
//d->data watcher type
//a->any watcher type
//l->remove locally when there is no server connection
public class RemoveWatchesCommand extends CliCommand {
public RemoveWatchesCommand() {
super("removewatches", "path [-c|-d|-a] [-l]");
}
}
//w->watch
public class StatCommand extends CliCommand {
public StatCommand() {
super("stat", "[-w] path");
}
}
public class SyncCommand extends CliCommand {
public SyncCommand() {
super("sync", "path");
}
}
client包
//ConnectStringParser
//解析localhost:2181,localhost:2182这种
//全部加入一个List
public final class ConnectStringParser {
private static final int DEFAULT_PORT = 2181;
private final String chrootPath;
private final ArrayList<InetSocketAddress> serverAddresses = new ArrayList<InetSocketAddress>();
}
//FourLetterWordMain
//四字命令的客户端吧
//只是为了便于测试,使用了SSLSocket
//HostProvider
//StaticHostProvider
//cli连接时,是可以传入多个地址的,这里的作用就是随机分配一个地址,也算负载均衡吧
//没错,还有篇论文,这里用的将服务器打乱随机选一个。https://issues.apache.org/jira/browse/ZOOKEEPER-1355
//ZKClientConfig
//配置文件
//ZooKeeperSaslClient
//SASL全称Simple Authentication and Security Layer,是一种用来扩充C/S模式验证能力的机制。在Postfix可以利用SASL来判断用户是否有权使用转发服务,或是辨认谁在使用你的服务器。
common包
AtomicFileOutputStream: 但是没有看出哪里原子了…这个类是从HDFS直接弄过来的
public class AtomicFileOutputStream extends FilterOutputStream {
private static final String TMP_EXTENSION = ".tmp";
private final File origFile;
private final File tmpFile;
public AtomicFileOutputStream(File f) throws FileNotFoundException {
// Code unfortunately must be duplicated below since we can't assign
// anything
// before calling super
super(new FileOutputStream(new File(f.getParentFile(), f.getName()
+ TMP_EXTENSION)));
origFile = f.getAbsoluteFile();
tmpFile = new File(f.getParentFile(), f.getName() + TMP_EXTENSION)
.getAbsoluteFile();
}
AtomicFileWritingIdiom:为了提供文件的原子写入,Based on the org.apache.zookeeper.server.quorum.QuorumPeer.writeLongToFile(…) idiom ,using the HDFS AtomicFileOutputStream class.
public class AtomicFileWritingIdiom {
public static interface OutputStreamStatement {
public void write(OutputStream os) throws IOException;
}
public static interface WriterStatement {
public void write(Writer os) throws IOException;
}
public AtomicFileWritingIdiom(File targetFile, OutputStreamStatement osStmt) throws IOException {
this(targetFile, osStmt, null);
}
public AtomicFileWritingIdiom(File targetFile, WriterStatement wStmt) throws IOException {
this(targetFile, null, wStmt);
}
private AtomicFileWritingIdiom(File targetFile, OutputStreamStatement osStmt, WriterStatement wStmt) throws IOException {
AtomicFileOutputStream out = null;
boolean error = true;
try {
out = new AtomicFileOutputStream(targetFile);
if (wStmt == null) {
// execute output stream operation
osStmt.write(out);
} else {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
// execute writer operation and flush
wStmt.write(bw);
bw.flush();
}
out.flush();
// everything went ok
error = false;
} finally {
// nothing interesting to do if out == null
if (out != null) {
if (error) {
// worst case here the tmp file/resources(fd) are not cleaned up
// and the caller will be notified (IOException)
out.abort();
} else {
// if the close operation (rename) fails we'll get notified.
// worst case the tmp file may still exist
IOUtils.closeStream(out);
}
}
}
}
}
IOUtil
closeStream(Closeable stream)
cleanup(Logger log, Closeable... closeables)
copyBytes(InputStream in, OutputStream out,int buffSize, boolean close)
copyBytes(InputStream in, OutputStream out, int buffSize)
PathTrie:有空好好研究,这东西是一个单词树
PathUtil: 验证路径没有错, 和Window里面的//进行转换
public static void validatePath(String path, boolean isSequential)
public static void validatePath(String path)
public static String normalizeFileSystemPath(String path)
StringUtil: 分割和拼接字符串,默认是分割成String[],这里改进为列表
public static List<String> split(String value, String separator)
public static String joinStrings(List<String> list, String delim)