循序渐进企业级搜索引擎之Master模块设计及实现-系统加载

来源:互联网 发布:马季打侯宝林真相知乎 编辑:程序博客网 时间:2024/06/07 05:22

第二章              Master模块设计及实现

Master具体细分为系统配置及监控加载模块、请求及相应封装处理模块、统计模块、监控及负载均衡等模块。具体的关系图如下:

 

2.1 Master系统逻辑框架图

下面逐个对这些模块及主要代码进行分析讲解。

2.1 系统配置及监控加载模块

由于系统需要在启动的时候加载一些配置和监控模块,同时还需要在最后做一些系统的资源释放和销毁动作,加上spring提供了类似的重写接口,所以系统的入口类需要实现如下三个接口:ApplicationContextAware,InitializingBean,DisposableBean实现如下:

/* * (non-Javadoc) *  * @see org.springframework.beans.factory.DisposableBean#destroy() */public void destroy() throws Exception {MasterCfgManager.destory();}/* * (non-Javadoc) *  * @see * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */public void afterPropertiesSet() throws Exception {MasterCfgManager.init();}/* * (non-Javadoc) *  * @see * org.springframework.context.ApplicationContextAware#setApplicationContext * (org.springframework.context.ApplicationContext) */public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {WebAppContextUtil.setAppContext(applicationContext);}

 

afterPropertiesSet在这个方法中主要是在spring对系统上下文加载完成之后会直接触发调用,系统的初始化就此开始。setApplicationContext这个方法主要是加载在spring中定义的类,用于系统master中加载对index和query分开处理的provider。接下来看下系统init中都加载了什么内容。

具体的初始化函数如下:

/** * 初始化函数 */public static void init() {loadCfg();initSlaveClientPool();initIndexPool();initSearchPool();initStatisticPool();initParam();ChameleonKeeperThreadPoolManager.init();startChameleonKeeper();registerZKRoot();}


 

初始化主要是负责配置文件的加载,slave客户端restful调用的实例化类,初始化索引线程池和搜索线程池,以及master中需要用到的统计线程池,接下来就是启动一个zookeeperserver的守护线程,最后将master注册在zookeeper的一个root节点上,监听其下面的所有slaves端的节点信息变化。其中添加zookeeper server端的守护线程实现如下:

public static void startChameleonKeeper() {ServerConfig config = loadServerConfig();ChameleonKeeperThreadPoolManager.addJobToZKServerStartExecutor(new ZKServerStartUpJob(config));}public static void addJobToZKServerStartExecutor(Runnable command) {init();DaemonThreadFactory daemon = new DaemonThreadFactory();zkServerStartExecutor = daemon.newThread(command);makeThreadName(zkServerStartExecutor,"-zkServerStartExecutor");setUncaughtExceptionHandler(zkServerStartExecutor);zkServerStartExecutor.start();}


 

具体启动的线程run方法如下:

public void run() {ZooKeeperServerMain main = new ZooKeeperServerMain();try {System.out.println("zookeeper server 启动");main.runFromConfig(config);System.out.println("zookeeper server 启动完成");} catch (IOException e) {LOG.error( "zookeeper server启动出错: " + e.getMessage() );e.printStackTrace();}}

而监控zookeeper节点的创建如下:

public static void initZK(String server, String root) {try {if (zk == null || !zk.getState().isAlive()) {synchronized (mutex) {if (zk == null || !zk.getState().isAlive()) {closeZK();init(root);createZK(server, root);}}}} catch (Exception e) {e.printStackTrace();LOG.error("init zk ConnectionLossException!", e);}}private static void createZK(String server, String root) throws Exception {zk = new ZooKeeper(server, sessionTimeOut, new ClientWatcher());try {Stat stat = zk.exists(root, false);if (stat == null) {zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);registerWatcher();System.out.println("connect zk server success!");}} catch (KeeperException.ConnectionLossException e) {System.out.println("ConnectionLoss exception sleep for 3s...");Thread.sleep(3 * 1000);System.out.println("connect zk server again");createZK(server, root);}}

至此系统配置加载已经完成,同时对系统监控系统也已经启动完成,可以对slaves端的节点信息变化做出相应的处理。



0 0
原创粉丝点击