/** * Tencent is pleased to support the open source community by making MSEC available. * * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. * * Licensed under the GNU General Public License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may * obtain a copy of the License at * * https://opensource.org/licenses/GPL-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions * and limitations under the License. */ package beans.service; import beans.dbaccess.ServerInfo; import beans.request.AddSecondLevelServiceIPInfoRequest; import beans.response.AddSecondLevelServiceIPInfoResponse; import msec.org.DBUtil; import msec.org.JsonRPCHandler; import msec.org.RemoteShell; import msec.org.Tools; import org.apache.log4j.Logger; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.*; /** * Created by Administrator on 2016/1/27. * 扩容流程第一步 - 生成分配方案 */ public class AddSecondLevelServiceIPInfo extends JsonRPCHandler { private String ipinfo_cmd = "cores=`cat /proc/cpuinfo | grep processor | wc -l`\n"+ "mhz=$(printf \"%.0f\" `cat /proc/cpuinfo | grep MHz | head -n1 | awk '{print $4}'`)\n"+ "memavail=`grep -i Memtotal /proc/meminfo | awk '{printf(\"%d\", $2*0.8)}'`\n"+ "id1=`grep 'cpu ' /proc/stat | awk '{print $5}'`\n"+ "all1=`grep 'cpu ' /proc/stat | awk '{print $2+$3+$4+$5+$6+$7}'`\n"+ "sleep 1\n"+ "id2=`grep 'cpu ' /proc/stat | awk '{print $5}'`\n"+ "all2=`grep 'cpu ' /proc/stat | awk '{print $2+$3+$4+$5+$6+$7}'`\n"+ "usage=$(printf \"%.0f\" `echo \"scale=1;100-($id2-$id1)*100/($all2-$all1)\"|bc`)\n"+ "echo -n $cores $mhz $memavail $usage"; public final static int INSTANCE_MEMORY_STEP = 900; //实例最小内存 public void CalcAddedIPForServers(AddSecondLevelServiceIPInfoResponse response, int copy, ArrayList<String> set_ids, int group_id_index, int instance_memory) { boolean check_ok = true; int total_memory = 0; Map<String, Integer> set_instance_map = new HashMap<>(); int i = 0; for(AddSecondLevelServiceIPInfoResponse.IPInfo ip : response.getAdded_ips()){ if(!ip.getStatus_message().equals("shell")) { if (ip.getCpu_load() >= 10) { ip.setStatus_message("cpu"); check_ok = false; } else { if (ip.getInstance_num() < 1) { ip.setStatus_message("memory"); check_ok = false; } else { ip.setStatus_message("ok"); String set_id = set_ids.get(i/copy); if(set_instance_map.containsKey(set_id)) set_instance_map.put(set_id, Math.min(set_instance_map.get(set_id), ip.getInstance_num())); else set_instance_map.put(set_id, ip.getInstance_num()); i++; } } } else check_ok = false; } if(!check_ok){ response.setMessage("machine"); } else { response.setMessage("success"); i = 0; int allocated_group_id = group_id_index+1; int allocated_instance_num = 0; for(AddSecondLevelServiceIPInfoResponse.IPInfo ip : response.getAdded_ips()) { ArrayList<ServerInfo> servers = new ArrayList<>(); String set_id = set_ids.get(i/copy); int set_innerid = i % copy; ip.setSet_id(set_id); int instance_num = set_instance_map.get(set_id); for(int j = 0; j < instance_num; j++) { ServerInfo server = new ServerInfo(); server.setGroup_id(j + allocated_group_id); if(j >= allocated_instance_num && j < allocated_instance_num+(instance_num-allocated_instance_num)/(copy-set_innerid)) { server.setMaster(true); } else server.setMaster(false); server.setSet_id(set_id); server.setIp(ip.getIp()); server.setPort(10000 + j + allocated_group_id); server.setMemory(instance_memory); servers.add(server); } ip.setServers(servers); allocated_instance_num+=(instance_num-allocated_instance_num)/(copy-set_innerid); i++; if(set_innerid == copy-1) { allocated_group_id += instance_num; allocated_instance_num = 0; } } } response.setStatus(0); } public static String newPlanID() { double r = Math.random(); SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss_");//设置日期格式 String ret = df.format(new Date()); ret = ret + (int)(Integer.MAX_VALUE * r); return ret; } public AddSecondLevelServiceIPInfoResponse exec(AddSecondLevelServiceIPInfoRequest request) { Logger logger = Logger.getLogger("AddSecondLevelServiceIPInfo"); AddSecondLevelServiceIPInfoResponse response = new AddSecondLevelServiceIPInfoResponse(); int instance_memory = request.getInstance_type() * INSTANCE_MEMORY_STEP; response.setMessage("unkown error."); response.setStatus(100); String result = checkIdentity(); if (!result.equals("success")) { response.setStatus(99); response.setMessage(result); return response; } if (request.getIp() == null || request.getIp().equals("")) { response.setMessage("Some request field is empty."); response.setStatus(100); return response; } ArrayList<String> ips = Tools.splitBySemicolon(request.getIp()); Set<String> set_ips = new HashSet<>(ips); if (ips.size() < 2 || set_ips.size() != ips.size()) { response.setMessage("IP input error!"); response.setStatus(100); return response; } if(ips.size() % request.getCopy() != 0) { response.setMessage("the number of IPs is not divisible by the number of copies!"); response.setStatus(100); return response; } DBUtil util = new DBUtil(); if (util.getConnection() == null) { response.setMessage("DB connect failed."); response.setStatus(100); return response; } try{ //check if the IP has been installed in set... String sql = "select ip, port, group_id, memory, master, status from t_service_info where first_level_service_name=? and second_level_service_name=? and ip in ("; List<Object> params = new ArrayList<>(); params.add(request.getFirst_level_service_name()); params.add(request.getSecond_level_service_name()); for(int i = 0; i < ips.size(); i++) { if(i == 0) { params.add(ips.get(i)); sql += "?"; } else { params.add(ips.get(i)); sql += ",?"; } } sql += ")"; try { List<ServerInfo> serverList = util.findMoreRefResult(sql, params, ServerInfo.class); if(serverList.size() > 0) { response.setStatus(101); response.setMessage("Input IP(s) is already installed."); return response; } } catch (Exception e) { response.setStatus(100); response.setMessage("db query exception!"); e.printStackTrace(); return response; } int group_id_index = 0; sql = "select COALESCE(max(group_id),0) as group_id from t_service_info where first_level_service_name=? and second_level_service_name=?"; params.clear(); params.add(request.getFirst_level_service_name()); params.add(request.getSecond_level_service_name()); try { Map<String, Object> result_map = util.findSimpleResult(sql, params); if(result_map.size() != 1) { response.setStatus(101); response.setMessage("db set error!"); return response; } group_id_index = ((Long)result_map.get("group_id")).intValue(); } catch (Exception e) { response.setStatus(100); response.setMessage("db query exception!"); e.printStackTrace(); return response; } ArrayList<AddSecondLevelServiceIPInfoResponse.IPInfo> addedIPs = new ArrayList<>(); for(String ip: ips) { AddSecondLevelServiceIPInfoResponse.IPInfo info = response.new IPInfo(); info.setIp(ip); RemoteShell remoteShell = new RemoteShell(); StringBuffer output = new StringBuffer(); result = remoteShell.SendCmdsToRunAndGetResultBack(ipinfo_cmd, ip, output); if (result == null || !result.equals("success")) { logger.info(String.format("remote error:%s|%s", ip, result)); info.setStatus_message("shell"); } else { logger.info(output); String[] ipinfo_results = output.toString().split(" "); if(ipinfo_results.length != 4) { info.setStatus_message("shell"); } else { //core mhz mem cpu info.setCpu_cores(Integer.parseInt(ipinfo_results[0])); info.setCpu_mhz(Integer.parseInt(ipinfo_results[1])); info.setMemory_avail(Integer.parseInt(ipinfo_results[2])/1024); info.setCpu_load(Integer.parseInt(ipinfo_results[3])); } } addedIPs.add(info); } response.setAdded_ips(addedIPs, instance_memory); ArrayList<String> set_ids = new ArrayList<>(); //get set ids int set_num = ips.size() / request.getCopy(); sql = "select name from t_set_id_name where name not in (select distinct set_id from t_service_info where first_level_service_name=? and second_level_service_name=?) order by name asc limit ?"; params.clear(); params.add(request.getFirst_level_service_name()); params.add(request.getSecond_level_service_name()); params.add(set_num); try { ArrayList<Map<String, Object>> result_list = util.findModeResult(sql, params); if(result_list.size() != set_num) { response.setStatus(101); response.setMessage("db set error!"); return response; } for(int i = 0; i < result_list.size(); i++) set_ids.add(result_list.get(i).get("name").toString()); } catch (SQLException e) { response.setStatus(100); response.setMessage("db query exception!"); e.printStackTrace(); return response; } CalcAddedIPForServers(response, request.getCopy(), set_ids, group_id_index, instance_memory); if(response.getMessage().equals("success") && group_id_index == 0) { //update t_second_level_service logger.info(String.format("Create|Update copy_num & mem_per_instance|%d|%d", group_id_index, instance_memory)); sql = "update t_second_level_service set copy_num=?, memory_per_instance=? where first_level_service_name=? and second_level_service_name=?"; params.clear(); params.add(request.getCopy()); params.add(instance_memory); params.add(request.getFirst_level_service_name()); params.add(request.getSecond_level_service_name()); try { int addNum = util.updateByPreparedStatement(sql, params); if (addNum < 0) { response.setMessage("failed to update table"); response.setStatus(100); return response; } } catch (SQLException e) { response.setMessage("update status failed:" + e.toString()); response.setStatus(100); e.printStackTrace(); return response; } } else logger.info(group_id_index); return response; } finally { util.releaseConn(); } } }