手动备份项目流程
1 web项目:
backup/manual
BackupController
web 项目controller
/**
* @Title: create
* @Description: 手动创建备份
* @author zhangjiankang
* @param req
* @param request
* @param response
* @return
* @return Object
* @throws
* @date 2017年4月7日 下午1:19:43
*/
@RequestMapping(value = "manual", method = RequestMethod.POST)
public @ResponseBody Object create(@RequestBody BackupCreateReq req, HttpServletRequest request, HttpServletResponse response) {
CustomerInfoVo customer = getLogonUserInfo();
GenericDataResponse<List<BackupBean>> resultData = new GenericDataResponse<List<BackupBean>>();
resultData.success();
List<BackupBean> backupList = new ArrayList<BackupBean>();
if (null == customer)
return IWebResponses.NO_AUTH;
if (UString.isEmpty(req.getSysName()) && UString.isEmpty(req.getDataName()))
return IWebResponses.BACKUP_NAME_NOT_NULL;
if (UString.isEmpty(req.getArrow_id()))
return IWebResponses.PARAMETER_ERROR;
if (UString.isEmpty(req.getOnline()))
return IWebResponses.REQ_IS_NULL;
if (req.getSysDiskId() == null && req.getDataDiskId() == null)
return IWebResponses.REQ_IS_NULL;
try {
req.setCustomerId(customer.getId());
req.setSubAccountId(getSubAccountId());
//为备份设置时间戳
req.setBackupStamp(System.currentTimeMillis());
ArrowBean arrowBean = arrowCustomDao.selectOne(new ArrowBean(req.getCustomerId(), Integer.valueOf(req.getArrow_id())));
if (arrowBean == null) {
return IWebResponses.ARROW_NOT_EXISTS;
}
String backupContent = "手动为:" + req.getArrow_id() + "云主机创建备份";
logService.saveWebArrowLogNew(customer, LogTypeEnum.WEB_BACKUP_IMAGE.getDes(), IPAddress.getIpAddr(request), backupContent, LogType.write.getId(),
(req.getArrow_id() != null ? req.getArrow_id() : ""));
//远程调用controller查询备份文件大小
// String BACKUP_QUERYBACKUP_SIZE = "backup/querySize";
String visitUrl = ZoneCache.getZoneByUuid(arrowBean.getZoneUuid()).getUrl() + ControllerApiDeclarations.BACKUP_QUERYBACKUP_SIZE;
Map<String, Object> map = new HashMap<String, Object>();
map.put("instanceId", arrowBean.getUuid());
Double sysSize = 0.00;//系统盘大小
Double dataSize = 0.00;//数据盘大小
if (req.getSysDiskId() != null) {
//查询系统盘备份文件大小
map.put("diskId", req.getSysDiskId());
map.put("diskType", 0);
//查询备份文件大小
HttpProxyResponse respose = HttpConnectProxy.post(visitUrl, map);
if (respose.notSuccess()) {
return IWebResponses.QUERY_IMAGE_SIZE_FAIL;//@IResponse(message = "查询备份文件大小失败")
}
GenericDataResponse<Double> rest = UJson.toObject(respose.getResult(), GenericDataResponse.class);
if (rest.notSuccess()) {
return rest.getData();
}
sysSize = rest.getData();
//1.验证资源和状态
GenericResponse validResult = createBackupService.validateResource(arrowBean, req, sysSize, 0);
if (validResult.notSuccess()) {
return validResult;
}
//2.web处理,系统盘备份创建
GenericDataResponse<BackupBean> result = createBackupService.create(arrowBean, req, sysSize, 0);
if (result.notSuccess()) {
return result;
}
BackupBean backupBean = result.getData();
//准备backupDto参数
BackupCreateT2C_DTO backupDto = new BackupCreateT2C_DTO(backupBean.getUuid(), backupBean.getName(), backupBean.getArrowUuid(), backupBean.getSize(), backupBean.getManualType(),
backupBean.getOnline(), backupBean.getContentType(), req.getSysDiskId());
//BackupCreateDTO backupDto = new BackupCreateDTO(backupBean.getUuid(), backupBean.getName(), backupBean.getArrowUuid(), backupBean.getSize(), backupBean.getManualType(), backupBean.getOnline(),backupBean.getContentType());
String url = ZoneCache.getZoneByUuid(arrowBean.getZoneUuid()).getUrl() + ControllerApiDeclarations.BACKUP_MANUAL_CREATE;
//远程调用controller创建备份
HttpProxyResponse hr = HttpConnectProxy.post(url, UMethod.getMap(backupDto));
cacheService.updateActionState(ArrowActionEnum.BACKUP, backupBean.getArrowUuid());
/* if (hr.isSuccess()) {// 访问成功
GenericResponse res = UJson.toObject(hr.getResult(), GenericResponse.class);
if (res.isSuccess()) {
cacheService.updateActionState(ArrowActionEnum.BACKUP, backupBean.getArrowUuid());
} else {
createBackupService.saveSYSException("创建备份失败controller环节错误" + hr.getResult());
createBackupService.createFailed(backupBean);
}
} else {
createBackupService.saveSYSException("创建备份连接controller失败");
createBackupService.createFailed(backupBean);
return hr;
}*/
backupList.add(backupBean);
resultData.setData(backupList);
}
if (req.getDataDiskId() != null) {
//查询数据盘备份文件大小
map.put("diskId", req.getDataDiskId());
map.put("diskType", 1);
HttpProxyResponse respose = HttpConnectProxy.post(visitUrl, map);
if (respose.notSuccess()) {
createBackupService.saveOperateLog(req.getCustomerId(),3,"数据盘备份异常",IWebResponses.QUERY_IMAGE_SIZE_FAIL.toString());
resultData.setMsgInfo("数据盘备份失败,"+IWebResponses.QUERY_IMAGE_SIZE_FAIL);
resultData.setSuccess(false);
return resultData;
}
GenericDataResponse<Double> rest = UJson.toObject(respose.getResult(), GenericDataResponse.class);
if (rest.notSuccess()) {
Map<String,String> restMap = JSONObject.fromObject(UJson.toObject(respose.getResult(), GenericDataResponse.class).getData());
createBackupService.saveOperateLog(req.getCustomerId(),3,"数据盘备份异常",restMap.get("message"));
resultData.setMsgInfo("数据盘备份失败,"+restMap.get("message"));
resultData.setSuccess(false);
return resultData;
}
dataSize = rest.getData();
//1.验证资源和状态
GenericResponse validResult = createBackupService.validateResource(arrowBean, req, dataSize, 1);
if (validResult.notSuccess()) {
createBackupService.saveOperateLog(req.getCustomerId(),3,"数据盘备份异常",validResult.toString());
resultData.setMsgInfo("数据盘备份失败,"+validResult.getMsgInfo());
resultData.setSuccess(false);
return resultData;
}
//2.web处理,数据盘备份创建
GenericDataResponse<BackupBean> result = createBackupService.create(arrowBean, req, dataSize, 1);
if (result.notSuccess()) {
createBackupService.saveOperateLog(req.getCustomerId(),3,"数据盘备份异常",result.toString());
resultData.setMsgInfo("数据盘备份失败,"+result.getMsgInfo());
resultData.setSuccess(false);
return resultData;
}
BackupBean backupBean = result.getData();
//准备backupDto参数
BackupCreateT2C_DTO backupDto = new BackupCreateT2C_DTO(backupBean.getUuid(), backupBean.getName(), backupBean.getArrowUuid(), backupBean.getSize(), backupBean.getManualType(),
backupBean.getOnline(), backupBean.getContentType(), req.getDataDiskId());
String url = ZoneCache.getZoneByUuid(arrowBean.getZoneUuid()).getUrl() + ControllerApiDeclarations.BACKUP_MANUAL_CREATE;
//远程调用controller创建备份
HttpProxyResponse hr = HttpConnectProxy.post(url, UMethod.getMap(backupDto));
if (hr.isSuccess()) {// 访问成功
GenericResponse res = UJson.toObject(hr.getResult(), GenericResponse.class);
if (res.isSuccess()) {
cacheService.updateActionState(ArrowActionEnum.BACKUP, backupBean.getArrowUuid());
} else {
if (!res.getMsgCode().equals("backup_queue_full")) {
logger.info("创建数据盘手动备份失败,backup.uuid=" + backupBean.getUuid() + hr.getResult());
createBackupService.saveSYSException(ExceptionSystemTypeEnum.CONTROLLER,
"创建数据盘手动备份失败,backup.uuid=" + backupBean.getUuid() + hr.getResult());
createBackupService.createFailed(backupBean);
} else {
logger.info("创建备份时,备份服务器连接数已满,请耐心等待!备份uuid:" + backupBean.getUuid());
resultData.setMsgInfo("数据盘备份繁忙,请耐心等待," + hr.getMsgInfo());
resultData.setSuccess(false);
return resultData;
}
}
} else {
createBackupService.saveSYSException(ExceptionSystemTypeEnum.CONTROLLER,
"创建数据盘手动备份连接controller失败,backup.uuid=" + backupBean.getUuid() + hr.getResult());
createBackupService.createFailed(backupBean);
createBackupService.saveOperateLog(req.getCustomerId(),3,"数据盘备份异常",hr.toString());
resultData.setMsgInfo("数据盘备份失败,"+hr.getMsgInfo());
resultData.setSuccess(false);
return resultData;
}
backupList.add(backupBean);
}
resultData.setData(backupList);
return resultData;
} catch (Exception e) {
logger.error(UTrace.trace(e));
return IWebResponses.UNKNOWN_ERROR;
}
}
======================================================
contraller 项目
contraller 项目
@Controller
@RequestMapping("/api/backup")
public class CreateBackupController {
/**
* 查询备份文件实际大小
*/
/**
* @Title: querySize
* @Description: 查询备份文件实际大小
* @author zhangjiankang
* @param instanceId
* @param diskId
* @param diskType:系统盘:0,数据盘:1
* @return Object
* @date 2017年4月10日 下午1:20:57
*/
@RequestMapping(value = "/querySize")
@ResponseBody
public Object querySize(Long instanceId,Long diskId,Integer diskType, HttpServletRequest request, HttpServletResponse response) {
GenericDataResponse<Object> returnResult = new GenericDataResponse<Object>();
//检查arrow和diskId是否一致,判断数据一致性
GenericResponse resMsg = createBackupService.checkArrowAndDisk(instanceId,diskId);
if(resMsg.notSuccess()){
returnResult.init(ISmartResponses.FAIL);
returnResult.setData(resMsg);
return returnResult;
}
HttpProxyResponse queryResult = createBackupService.querySize(instanceId,diskId,diskType);
if (queryResult.isSuccess()) {
GenericDataResponse<String> result = UJson.tryParametricTypeObject(queryResult.getResult(), GenericDataResponse.class, String.class);
if (result.isSuccess()) {
String message = result.getData();
Map<String, Long> map = UJson.tryParametricTypeObject(message, Map.class, String.class, Long.class);
Long size = Long.valueOf(map.get("size"));
Double sizeG = DoubleTools.div(size, 1024 * 1024, 5);
returnResult.init(ISmartResponses.SUCCESS);
returnResult.setData(sizeG);
}
} else {
returnResult.init(ISmartResponses.FAIL);
returnResult.setData(ISmartResponses.CONNECT_ERROR);
}
return returnResult;
}
----------------------------------------------------------------------------------
/**
* @Title: querySize
* @Description: 查询备份主机文件大小
* @author zhangjiankang
* @param instanceId
* @param dataDiskId
* @param sysDiskId
* @return HttpProxyResponse
* @date 2017年4月10日 下午1:22:01
*/
public HttpProxyResponse querySize(Long instanceId, Long diskId, Integer diskType) {
HttpProxyResponse response = new HttpProxyResponse();
String storagePath = diskType.intValue() == 0 ? configService.get("volume", "volumePoolMountPath") : configService.get("volume", "dataDiskMountPath"); // 镜像本地缓存目录
TInstanceDisk diskw = new TInstanceDisk();
diskw.setInstanceId(instanceId);
diskw.setId(diskId);
TInstanceDisk disk = diskDao.selectOne(diskw);
//查询备份将要做增量还是
TBackup backupWhere = new TBackup();
backupWhere.setInstanceId(instanceId);
backupWhere.setState(1);
backupWhere.setCurrentNode(1);
backupWhere.setDelete(false);
backupWhere.setManualType(1);
//diskType:系统盘:0,数据盘:1
backupWhere.setContentType(diskType);
TBackup backup = backupDao.selectOne(backupWhere);
StringBuffer imagePath = new StringBuffer();
imagePath.append(storagePath);
imagePath.append("/");
if (backup == null) {//要做全量大小:bs3pycnb4cn5_bs3pycrwk4jl.img*
String[] split = disk.getName().split("-");
imagePath.append(split[0]);
imagePath.append("*");
} else {
//要做增量大小查询:bs3pycnb4cn5_bs3pycrwk4jl.img-1478832661
imagePath.append(disk.getName());
}
Map<String, Object> hmap = new HashMap<String, Object>();
hmap.put("vmName", imagePath.toString());
THost host = hostService.selectByInstanceId(instanceId);
//10.12.30.101 String BACKUP_QUERYBACKUP_SIZE = "backup/querySize";
response = HttpConnectProxy.post(PropertiesZone.getServicePath(host.getIpAdmin()) + "/" + AgentApiDeclarations.BACKUP_QUERYBACKUP_SIZE, hmap);
if (response.notSuccess()) {
onHostResult(host);
}
return response;
}
======================================================
host 项目:
package com.xinnet.agent.backup.app;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.xinnet.agent.PropertiesUtils;
import com.xinnet.agent.backup.service.BackupService;
import com.xinnet.smart.base.PropertiesBase;
import com.xinnet.smart.base.enums.ContentTypeEnum;
import com.xinnet.smart.base.util.HttpConnectProxy;
import com.xinnet.smart.base.util.UJson;
import com.xinnet.smart.base.util.UTrace;
import com.xinnet.smart.dto.backup.BackupCreateB2C_DTO;
import com.xinnet.smart.dto.backup.BackupCreateC2B_DTO;
import com.xinnet.smart.vo.GenericDataResponse;
import com.xinnet.smart.vo.ISmartResponses;
import com.xinnet.smart.vo.URequest;
import com.xinnet.smart.vo.UResponse;
@RequestMapping("backup")
@Controller
public class BackUpController {
static final Logger logger = LoggerFactory.getLogger(BackUpController.class);
@Autowired
private BackupService backupServiceImpl;
/**
* 创建备份,controller调用Agent
* @param json
*/
@RequestMapping("/create")
public void create(HttpServletRequest request, HttpServletResponse response) {
BackupCreateC2B_DTO dto = URequest.getObject(request, BackupCreateC2B_DTO.class);
new Thread(new Runnable() {
public void run() {
GenericDataResponse<BackupCreateB2C_DTO> gd = backupServiceImpl.createBackup(dto);
HttpConnectProxy.post(ContentTypeEnum.JSON, PropertiesUtils.controllerUrl + "api/backup/createAgentResult", UJson.toString(gd));
}
}).start();
UResponse.json(PropertiesBase.SUCCESS, response);
}
@RequestMapping(value = "/querySize")
public void querySize(String vmName, HttpServletResponse response) {
GenericDataResponse gr = new GenericDataResponse();
try {
String size = backupServiceImpl.querySystemVolume(vmName);
if (size != null) {
Map<String, Long> map = new HashMap<String, Long>();
map.put("size", Long.valueOf(size));
gr.init(ISmartResponses.SUCCESS);
gr.setData(UJson.toString(map));
UResponse.json(gr, response);
} else {
gr.init(ISmartResponses.FAIL);
gr.setData("查询镜像大小失败");
UResponse.json(gr, response);
}
} catch (Throwable e) {
logger.error(UTrace.trace(e));
gr.setData(e.getMessage());
UResponse.json(gr, response);
}
}
}
------------------------------------
/**
* 查询大小
* @author duanxia
* @date 2017年3月10日 下午5:03:53
*/
public String querySystemVolume(String imagePath) {
String size = null;
List<String> cmds = new ArrayList<String>();
cmds.add("sh");
cmds.add("-c");
String str = "du -sk " + imagePath + " |awk '{sum+=$1}END{print sum}'";
cmds.add(str);
GenericShellResponse gsr = PropertiesAgent.AGENT_SHELL.runs(cmds);
String result = gsr.getResult();
size = result.substring(0, result.indexOf("\n")).trim();
return size;
}
------------------------------------------------
// 创建ProcessBuilder 开启进程 查看计算机底层数据
public final GenericShellResponse runs(final List<String> commands) {
GenericShellResponse ret = new GenericShellResponse();
Process process = null;
try {
ProcessBuilder pb = new ProcessBuilder(commands);
if (direcotry != null) {
pb.directory(direcotry);
if (logger.isDebugEnabled() || logger.isInfoEnabled()) {
logger.info("shell direcotry---------->{}", direcotry);
}
}
process = pb.start();
ret.setCode(process.waitFor());
ret.setResult(UStream.read(process.getInputStream(), Charsets.UTF_8));
return ret;
} catch (Throwable e) {
ret.setErrorMessage(UTrace.trace(e));
return ret;
} finally {
if (process != null) {
try {
if (process.getInputStream() != null) {
process.getInputStream().close();
}
if (process.getOutputStream() != null) {
process.getOutputStream().close();
}
if (process.getErrorStream() != null) {
process.getErrorStream().close();
}
} catch (IOException e) {
logger.error(UTrace.trace(e));
}
//process.destroy();
process.destroyForcibly();
}
info(ret, commands);
}
}