Package com.taobao.zeus.jobs

Source Code of com.taobao.zeus.jobs.ProcessJob

package com.taobao.zeus.jobs;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.hadoop.conf.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.io.Files;
import com.taobao.zeus.jobs.sub.conf.ConfUtil;
import com.taobao.zeus.jobs.sub.tool.CancelHadoopJob;
import com.taobao.zeus.store.HierarchyProperties;
/**
* 通过操作系统创建进程Process的Job任务
* @author zhoufang
*
*/
public abstract class ProcessJob extends AbstractJob implements Job {
 
  private static Logger log=LoggerFactory.getLogger(ProcessJob.class);
 
  protected volatile Process process;
 
  protected final Map<String, String> envMap;
 
  public static final int CLEAN_UP_TIME_MS = 1000;
 
  public ProcessJob(JobContext jobContext){
    super(jobContext);
    envMap=new HashMap<String, String>(System.getenv());
  }

 
  public abstract List<String> getCommandList();
 
 
  private void buildHadoopConf(){
    File dir=new File(jobContext.getWorkDir()+File.separator+"hadoop_conf");
    if(!dir.exists()){
      dir.mkdirs();
    }
    Map<String, String> core=new HashMap<String, String>();
    Map<String, String> hdfs=new HashMap<String, String>();
    Map<String, String> mapred=new HashMap<String, String>();
    for(String key:jobContext.getProperties().getAllProperties().keySet()){
      if(key.startsWith("core-site.")){
        core.put(key.substring("core-site.".length()), jobContext.getProperties().getProperty(key));
      }else if(key.startsWith("hdfs-site.")){
        hdfs.put(key.substring("hdfs-site.".length()), jobContext.getProperties().getProperty(key));
      }else if(key.startsWith("mapred-site.")){
        mapred.put(key.substring("mapred-site.".length()), jobContext.getProperties().getProperty(key));
      }
    }
    if(!core.isEmpty()){
      Configuration coreC=ConfUtil.getDefaultCoreSite();
      for(String key:core.keySet()){
        coreC.set(key, core.get(key));
      }
      try {
        File xml=new File(dir.getAbsolutePath()+File.separator+"core-site.xml");
        if(xml.exists()){
          xml.delete();
        }
        xml.createNewFile();
        coreC.writeXml(new FileOutputStream(xml));
      } catch (Exception e) {
        log.error("create file core-site.xml error",e);
      }
    }
    if(!hdfs.isEmpty()){
      Configuration hdfsC=ConfUtil.getDefaultHdfsSite();
      for(String key:hdfs.keySet()){
        hdfsC.set(key, hdfs.get(key));
      }
      try {
        File xml=new File(dir.getAbsolutePath()+File.separator+"hdfs-site.xml");
        if(xml.exists()){
          xml.delete();
        }
        xml.createNewFile();
        hdfsC.writeXml(new FileOutputStream(xml));
      } catch (Exception e) {
        log.error("create file hdfs-site.xml error",e);
      }
    }
    if(!mapred.isEmpty()){
      Configuration mapredC=ConfUtil.getDefaultMapredSite();
      for(String key:mapred.keySet()){
        mapredC.set(key, mapred.get(key));
      }
      try {
        File xml=new File(dir.getAbsolutePath()+File.separator+"mapred-site.xml");
        if(xml.exists()){
          xml.delete();
        }
        xml.createNewFile();
        mapredC.writeXml(new FileOutputStream(xml));
      } catch (Exception e) {
        log.error("create file mapred-site.xml error",e);
      }
    }
   
    //HADOOP_CONF_DIR添加2个路径,分别为 WorkDir/hadoop_conf 和 HADOOP_HOME/conf
    String HADOOP_CONF_DIR=jobContext.getWorkDir()+File.separator+"hadoop_conf"+File.pathSeparator
        +ConfUtil.getHadoopConfDir();
    envMap.put("HADOOP_CONF_DIR", HADOOP_CONF_DIR);
  }
  private void buildHiveConf(){
    File dir=new File(jobContext.getWorkDir()+File.separator+"hive_conf");
    if(!dir.exists()){
      dir.mkdirs();
    }
    Map<String, String> hive=new HashMap<String, String>();
    for(String key:jobContext.getProperties().getAllProperties().keySet()){
      if(key.startsWith("hive-site.")){
        hive.put(key.substring("hive-site.".length()), jobContext.getProperties().getProperty(key));
      }
    }
    if(!hive.isEmpty()){
      Configuration hiveC=ConfUtil.getDefaultCoreSite();
      for(String key:hive.keySet()){
        hiveC.set(key, hive.get(key));
      }
      try {
        File xml=new File(dir.getAbsolutePath()+File.separator+"hive-site.xml");
        if(xml.exists()){
          xml.delete();
        }
        xml.createNewFile();
        hiveC.writeXml(new FileOutputStream(xml));
      } catch (Exception e) {
        log.error("create file hive-site.xml error",e);
      }
    }
   
   
    String HIVE_CONF_DIR=jobContext.getWorkDir()+File.separator+"hive_conf"+File.pathSeparator+
        ConfUtil.getHiveConfDir();
    envMap.put("HIVE_CONF_DIR", HIVE_CONF_DIR);
  }
 
  public Integer run() throws Exception{
   
    int exitCode=-999;
   
    buildHadoopConf();
    buildHiveConf();
   
    //设置环境变量
    for(String key:jobContext.getProperties().getAllProperties().keySet()){
      if(jobContext.getProperties().getProperty(key)!=null && (key.startsWith("instance.") || key.startsWith("secret."))){
        envMap.put(key, jobContext.getProperties().getProperty(key));
      }
    }
    envMap.put("instance.workDir", jobContext.getWorkDir());
   
    List<String> commands=getCommandList();
    for(String s:commands){
      log("DEBUG Command:"+s);
     
      ProcessBuilder builder = new ProcessBuilder(partitionCommandLine(s));
      builder.directory(new File(jobContext.getWorkDir()));
      builder.environment().putAll(envMap);
      process=builder.start();
      final InputStream inputStream = process.getInputStream();
            final InputStream errorStream = process.getErrorStream();
     
      String threadName=null;
      if(jobContext.getJobHistory()!=null && jobContext.getJobHistory().getJobId()!=null){
        threadName="jobId="+jobContext.getJobHistory().getJobId();
      }else if(jobContext.getDebugHistory()!=null && jobContext.getDebugHistory().getId()!=null){
        threadName="debugId="+jobContext.getDebugHistory().getId();
      }else{
        threadName="not-normal-job";
      }
      new Thread(new Runnable() {
        @Override
        public void run() {
          try{
            BufferedReader reader=new BufferedReader(new InputStreamReader(inputStream));
            String line;
            while((line=reader.readLine())!=null){
              logConsole(line);
            }
          }catch(Exception e){
            log(e);
            log("接收日志出错,推出日志接收");
          }
        }
      },threadName).start();
      new Thread(new Runnable() {
        @Override
        public void run() {
          try {
            BufferedReader reader=new BufferedReader(new InputStreamReader(errorStream));
            String line;
            while((line=reader.readLine())!=null){
                logConsole(line);
             
            }
          } catch (Exception e) {
              log(e);
              log("接收日志出错,推出日志接收");
            }
        }
      },threadName).start();
     
      exitCode = -999;
      try {
        exitCode = process.waitFor();
      } catch (InterruptedException e) {
        log(e);
      } finally{
        process=null;
      }
      if(exitCode!=0){
        return exitCode;
      }
    }
    return exitCode;
  }
 
  public void cancel(){
    try {
      new CancelHadoopJob(jobContext).run();
    } catch (Exception e1) {
      log(e1);
    }
    //强制kill 进程
    if (process != null) {
      log("WARN Attempting to kill the process ");
      try {
        process.destroy();
        int pid=getProcessId();
        Runtime.getRuntime().exec("kill "+pid);
      } catch (Exception e) {
        log(e);
      } finally{
        process=null;
      }
    }
  }
  private int getProcessId() {
    int processId = 0;

    try {
      Field f = process.getClass().getDeclaredField("pid");
      f.setAccessible(true);

      processId = f.getInt(process);
    } catch (Throwable e) {
    }

    return processId;
  }

 
  protected String getProperty(String key,String defaultValue){
    String value=jobContext.getProperties().getProperty(key);
    if(value==null){
      value=defaultValue;
    }
    return value;
  }
  /**
   * Splits the command into a unix like command line structure. Quotes and
   * single quotes are treated as nested strings.
   *
   * @param command
   * @return
   */
  public static String[] partitionCommandLine(String command) {
   
    ArrayList<String> commands = new ArrayList<String>();
   
    String os=System.getProperties().getProperty("os.name");
    if(os!=null && (os.startsWith("win") || os.startsWith("Win"))){
      commands.add("CMD.EXE");
      commands.add("/C");
      commands.add(command);
    }else{
      int index = 0;

          StringBuffer buffer = new StringBuffer(command.length());

          boolean isApos = false;
          boolean isQuote = false;
          while(index < command.length()) {
              char c = command.charAt(index);

              switch(c) {
                  case ' ':
                      if(!isQuote && !isApos) {
                          String arg = buffer.toString();
                          buffer = new StringBuffer(command.length() - index);
                          if(arg.length() > 0) {
                              commands.add(arg);
                          }
                      } else {
                          buffer.append(c);
                      }
                      break;
                  case '\'':
                      if(!isQuote) {
                          isApos = !isApos;
                      } else {
                          buffer.append(c);
                      }
                      break;
                  case '"':
                      if(!isApos) {
                          isQuote = !isQuote;
                      } else {
                          buffer.append(c);
                      }
                      break;
                  default:
                      buffer.append(c);
              }

              index++;
          }

          if(buffer.length() > 0) {
              String arg = buffer.toString();
              commands.add(arg);
          }
    }
        return commands.toArray(new String[commands.size()]);
  }

  public HierarchyProperties getProperties(){
    return jobContext.getProperties();
  }
  public JobContext getJobContext() {
    return jobContext;
  }
 
}
TOP

Related Classes of com.taobao.zeus.jobs.ProcessJob

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.