mysql指令实现
ServA:192.168.1.1
ServB:192.168.1.2
1.查看3306端口是否互通
telnet 192.168.1.1 3306
telnet 192.168.1.2 3306
2.同步基础数据 保持两个库表数据一致性
将1.1数据库数据同步覆盖到 1.2 数据库中 – 在此之前两个库表的结构要一致
–ignore-table=database库名.table表名 – 表示不需要同步的数据表
mysqldump -h192.168.1.1 -uroot -proot -P3306
--default-character-set=utf8
--ignore-table=database库名.table表名
database库名 | mysql -h192.168.1.2 -uroot -proot -P3306 --default-character-set=utf8 database库名
3.修改配置文件my.cnf 两台服务其都要执行
[client]
port=3306
socket=/tmp/mysql.sock
[mysqld]
skip-name-resolve
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
lower_case_table_names=1
port=3306
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
pid-file=/usr/local/mysql/mysql.pid
socket=/tmp/mysql.sock
log_error=/usr/local/mysql/error.log
server-id=102
lower_case_table_names=1
max_connections=1000
secure-file-priv = ''
log-bin=MySQL-bin # 开启mysql binlog功能
binlog-do-db=database #需要同步的库
replicate-do-db=database #需要同步的库
replicate-wild-ignore-table=database.tables #不许需要同步的数据库表
slave-net-timeout=60
4.重启数据库
systemctl restart mysqld
5.创建同步用户 两台服务其都要执行
#mysql8.0创建同步用户 两台服务其都要执行
#删除同步用户 命令 mysql -uroot -p -e'DROP USER 'slave'@'%';flush privileges;'
# 创建用户 slave 密码123456 设置访问权限 %
mysql -uroot -p -e"CREATE USER 'slave'@'%' IDENTIFIED BY '123456';"
# 赋予权限
mysql -uroot -p -e"GRANT ALL PRIVILEGES ON *.* TO 'slave'@'%' WITH GRANT OPTION;"
# mysql8.0 需要修改下用户的连接方式
mysql -uroot -p -e"ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';flush privileges;"
#mysql8.4创建同步用户 两台服务其都要执行
#删除同步用户 命令 mysql -uroot -p -e'DROP USER 'slave'@'%';flush privileges;'
# 创建用户 slave 密码123456 设置访问权限 %
mysql -uroot -p -e"CREATE USER 'slave'@'%' IDENTIFIED BY '123456';"
# 赋予权限
mysql -uroot -p -e"GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' WITH GRANT OPTION;"
mysql -uroot -p -e"GRANT SUPER ON *.* TO 'slave'@'%' WITH GRANT OPTION;"
#数据库1.1执行 登录-h1.2 将密钥发送到1.2
mysql -uslave -h192.168.1.2 -p'123456' --get-server-public-key
#数据库1.2执行 登录-h1.1 将密钥发送到1.1
mysql -uslave -h192.168.1.1 -p'123456' --get-server-public-key
6.获取1.1服务器同步信息 配置1.2的同步信息
# mysql8.0获取1.1服务器同步信息 配置1.2的同步信息
# 1.2 执行 获取 master_log_file 和 master_log_pos 信息
mysql -uroot -proot -e"show master status;"
# 1.1 执行
mysql -uroot -proot -e"change master to master_host='192.168.1.2',master_user='slave',master_password='123456',master_log_file='MySQL-bin.000002',master_log_pos=301126;"
# mysql8.4获取1.1服务器同步信息 配置1.2的同步信息
# 1.2 执行 获取 master_log_file 和 master_log_pos 信息
mysql -uroot -proot -e"show binary log status;"
# 1.1 执行
mysql -uroot -proot -e"CHANGE REPLICATION SOURCE TO SOURCE_HOST='192.168.1.2',SOURCE_USER='slave',SOURCE_PASSWORD='123456',SOURCE_LOG_FILE='MySQL-bin.000002',SOURCE_LOG_POS=301126;"
7.获取1.2服务器同步信息 配置1.1的同步信息
# mysql8.0获取1.2服务器同步信息 配置1.1的同步信息
# 1.1 执行 获取 master_log_file 和 master_log_pos 信息
mysql -uroot -proot -e"show master status;"
# 1.2 执行
mysql -uroot -proot -e"change master to master_host='192.168.1.1',master_user='slave',master_password='123456',master_log_file='MySQL-bin.000002',master_log_pos=301126;"
# mysql8.4获取1.2服务器同步信息 配置1.1的同步信息
# 1.1 执行 获取 master_log_file 和 master_log_pos 信息
mysql -uroot -proot -e"show binary log status;"
# 1.2 执行
mysql -uroot -proot -e"change replication source to source_host='192.168.1.1',source_user='slave',source_password='123456',source_log_file='MySQL-bin.000002',source_log_pos=301126;"
8.启动同步 两台服务其都要执行
#mysql8.0启动同步
mysql -uroot -proot -e"start slave;"
#mysql8.4启动同步
mysql -uroot -proot -e"start replica;"
9.查看同步状态
#mysql8.0查看同步状态
mysql -uroot -proot -e"show slave status\G;"
#Slave Io Running:Yes
#Slave sol Running: Yes
#这两项为 yes 为成功
# Last Errno: 会展示异常信息 根据信息 自行查询问题
#mysql8.4查看同步状态
mysql -uroot -proot -e"show replica status\G;"
以下java实现的未写入8.4以后版本的改动,需要根据上面的修改部分代码
创建工具类MysqlSlaveUtil—java工具类版本
package ;
import ch.ethz.ssh2.Connection;
import cn.hutool.core.io.resource.ClassPathResource;
import com.mysql.cj.x.protobuf.MysqlxDatatypes;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* @author lpx
* 用于数据库数据同步和主主配置 适配8.0以上的数据库版本
* 在此之前请给root用户足够权限
* GRANT SYSTEM_USER ON *.* TO 'root'@'%' WITH GRANT OPTION;
* FLUSH PRIVILEGES;
* GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
* FLUSH PRIVILEGES;
*/
@Slf4j
@Component
public class MysqlSlaveUtil {
@Autowired
private DMruntimeUtil dMruntimeUtil ;
private final String CONF="[client]\n" +
"port=3306\n" +
"socket=/root/mysql/mysql.sock\n" +
"\n" +
"[mysqld]\n" +
"skip-name-resolve\n"+
"sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\n" +
"lower_case_table_names=1\n" +
"port=3306\n" +
"basedir=/root/mysql\n" +
"datadir=/root/mysql/data\n" +
"pid-file=/root/mysql/mysql.pid\n" +
"socket=/tmp/mysql.sock\n" +
"log_error=/root/mysql/error.log\n" +
"server-id={serverId}\n" +
"lower_case_table_names=1\n" +
"max_connections=1000\n" +
"secure-file-priv = ''\n" +
"log-bin=MySQL-bin # 开启mysql binlog功能\n" +
"binlog-do-db={DBbinlog} #需要同步的库\n" +
"replicate-do-db={DBreplicate} #需要同步的库\n" +
"replicate-wild-ignore-table={DBreplicate}.tables #不许需要同步的数据库表--写自己的配置表\n" +
"slave-net-timeout=60";
/**
* 同步数据库数据--方法
* hostIp 源服务器IP
* hostUser 源服务器数据库用户名
* hostPass 源服务器数据库用户密码
* targetIp 目标服务器IP
* targetUser 目标服务器数据库用户名
* targetPass 目标服务器数据库用户密码
* DBname 需要同步数据的数据库名称
* @return
*/
public List<String> mysqlDump(String hostIp, String hostUser, String hostPass
, String targetIp, String targetUser, String targetPass, String DBname){
List<String> cmds = new ArrayList<String>();
/** 同步两台服务器数据指令-----------------------------
* mysqldump -h192.168.1.1 -uroot -proot -P3306 --default-character-set=utf8
* --ignore-table=database库名.table表名
* | mysql -h192.168.1.2 -uroot -proot -P3306 --default-character-set=utf8 database库名
*/
String cmd = " mysqldump " +
"-h"+hostIp+" " +
"-u"+hostUser+" " +
"-p"+hostPass+" " +
"-P3306 --default-character-set=utf8 " +
"--ignore-table="+DBname+".t_route_info "+
"--ignore-table="+DBname+".t_virt_net_info "+
"--ignore-table="+DBname+".t_virt_server_info "+
DBname+" | mysql " +
"-h"+targetIp+" " +
"-u"+targetUser+" " +
"-p"+targetPass+" " +
"-P3306 --default-character-set=utf8 " +
DBname+";";
cmds.add(cmd);
return cmds;
}
/**
* 限制3306的端口访问权限
* 允许来自服务器B的TCP 3306流量:
* sudo iptables -A INPUT -p tcp -s 192.168.1.2 --dport 3306 -j ACCEPT
* (可选)拒绝所有其他到3306端口的流量:
* 这一步实际上是可选的,因为如果你的INPUT链默认是DROP,那么不需要显式拒绝。但如果你想要明确这一点,可以添加以下规则(但请注意,这应该在允许来自服务器B的流量之后添加,以确保不会意外阻止它):
* sudo iptables -A INPUT -p tcp --dport 3306 -j DROP
* 然而,通常推荐的做法是设置一个默认的DROP规则在链的末尾,而不是为特定端口添加DROP规则。
* 确保有默认的DROP规则(如果尚未设置):
* sudo iptables -P INPUT DROP
* 这条命令会将INPUT链的默认策略设置为DROP,意味着所有未明确允许的数据包都将被拒绝。注意,这条命令会影响所有进入服务器的数据包,而不仅仅是到3306端口的。
* 保存iptables规则(根据你的Linux发行版):
* sudo service iptables save
*/
public void iptablesPort(String masterIp,String backupIp,String masterPort,String backPort){
String cmd ="sudo iptables -A INPUT -p tcp -s "+backupIp+" --dport 3306 -j ACCEPT";
DMruntimeUtil(masterIp,masterPort,cmd);
cmd ="sudo iptables -A INPUT -p tcp -s "+masterIp+" --dport 3306 -j ACCEPT";
DMruntimeUtil(backupIp,backPort,cmd);
cmd ="sudo iptables -A INPUT -p tcp --dport 3306 -j DROP";
DMruntimeUtil(masterIp,masterPort,cmd);
DMruntimeUtil(backupIp,backPort,cmd);
cmd ="sudo service iptables save";
DMruntimeUtil(masterIp,masterPort,cmd);
DMruntimeUtil(backupIp,backPort,cmd);
}
/**
* 配置数据库主从配置,并开启主从配置的方法
* @param masterIp 主服务器IP
* @param masterUser 主服务器数据库用户
* @param masterPass 主服务器数据库密码
* @param userName 创建同步用户 用户名
* @param password 创建同步用户 密码
* @param backupIp 从服务器IP
* @param DBname 备份数据库名称
* @param proPath 数据库配置文件路径
* @param backupName 从服务器数据库用户
* @param backupPass 从服务器数据库密码
* @return
*/
public Boolean mysqlPropert(String masterIp,int masterServerId,int backupServerId,String masterUser,
String masterPass, String userName,
String password,String backupIp,
String backupName,String backupPass,
String DBname, String proPath){
String masterPort = "8080";
String backPort = "8080";
/**
* 采取http接口方式来同步数据指令----------------
* cmdA本机执行的mysql命令
* cmdB另一台要执行的mysql命令
*/
List<String> cmdA = new ArrayList<String>();
List<String> cmdB = new ArrayList<String>();
/**
1.修改 数据库配置文件 /root/mysql/my.cnf 主从都要改
*/
String conf = CONF.replace("{DBbinlog}",DBname).replace("{DBreplicate}",DBname).replace("{serverId}",masterServerId+"");
String cmd ="echo \""+conf+"\" > "+proPath;
if(null == dMruntimeUtil.login(masterIp,masterPort,cmd)){
log.error("主服务器 修改 数据库配置文件 Linux指令执行失败!");
}
conf= CONF.replace("{DBbinlog}",DBname).replace("{DBreplicate}",DBname).replace("{serverId}",backupServerId+"");
String cmd2 ="echo \""+conf+"\" > "+proPath;
if(null == dMruntimeUtil.login(backupIp,backPort,cmd2)){
log.error("备服务器 修改 数据库配置文件 Linux指令执行失败!");
}
/**
2.重启mysql数据库 主从都要进行重启
*/
ClassPathResource resource = new ClassPathResource("system.properties");
Properties properties = new Properties();
try {
properties.load(resource.getStream());
} catch (IOException e) {
e.printStackTrace();
}
try {
cmd = "bash " + properties.getProperty("linux.mysql.path") +" restart";
if(!DMruntimeUtil(masterIp,masterPort,cmd)){
return false;
}
if(!DMruntimeUtil(backupIp,backPort,cmd)){
return false;
}
/**
* 睡眠一下----防止数据库没有重启完毕,导致后续指令执行异常
*/
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
3.删除 同步用户DROP USER 'slave'@'%'信息,避免再次添加时的问题;
*/
cmd ="mysql -u"+masterUser+" -p"+masterPass+" " +
"-e'DROP USER \""+userName+"\"@\"%\";flush privileges;'";
DMruntimeUtil(masterIp,masterPort,cmd);
DMruntimeUtil(backupIp,backPort,cmd);
/**
4.创建用于复制的专门用户,并刷新用户权限
* mysql8.3
* 创建用户 slave 密码123456 设置访问权限 %
* mysql -uroot -p"password" -e"CREATE USER 'slave'@'%' IDENTIFIED BY '123456';"
* 赋予权限
* mysql -uroot -p"password" -e"GRANT ALL PRIVILEGES ON *.* TO 'slave'@'%' WITH GRANT OPTION;"
* */
cmd ="mysql -hlocalhost -p3306 -u"+masterUser+" -p"+masterPass+" " +
"-e'CREATE USER \""+userName+"\"@\"%\" IDENTIFIED BY \""
+password+"\"; flush privileges;'";
if(!DMruntimeUtil(masterIp,masterPort,cmd)){
return false;
}
cmd ="mysql -hlocalhost -p3306 -u"+masterUser+" -p"+masterPass+" " +
"-e'GRANT ALL PRIVILEGES ON *.* TO \""+userName+"\"@\"%\" WITH GRANT OPTION; flush privileges;'";
if(!DMruntimeUtil(masterIp,masterPort,cmd)){
return false;
}
cmd ="mysql -hlocalhost -p3306 -u"+backupName+" -p"+backupPass+" " +
"-e'CREATE USER \""+userName+"\"@\"%\" IDENTIFIED BY \""
+password+"\"; flush privileges;'";
if(!DMruntimeUtil(backupIp,backPort,cmd)){
return false;
}
cmd ="mysql -hlocalhost -p3306 -u"+backupName+" -p"+backupPass+" " +
"-e'GRANT ALL PRIVILEGES ON *.* TO \""+userName+"\"@\"%\" WITH GRANT OPTION; flush privileges;'";
if(!DMruntimeUtil(backupIp,backPort,cmd)){
return false;
}
/**
5.mysql8.0 需要修改用户的连接方式
* ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';flush privileges;
*/
cmd = "mysql -hlocalhost -p3306 -u"+masterUser+" -p"+masterPass+" " +
"-e'ALTER USER \""+userName+"\"@\"%\" IDENTIFIED WITH mysql_native_password BY \""+password+"\"; flush privileges;'";
if(!DMruntimeUtil(masterIp,masterPort,cmd)){
return false;
}
cmd = "mysql -hlocalhost -p3306 -u"+backupName+" -p"+backupPass+" " +
"-e'ALTER USER \""+userName+"\"@\"%\" IDENTIFIED WITH mysql_native_password BY \""+password+"\"; flush privileges;'";
if(!DMruntimeUtil(backupIp,backPort,cmd)){
return false;
}
/**
6.获取1.1主服务器同步信息
* mysql -uroot -proot -e"show master status;"
* */
cmd ="mysql -u"+masterUser+" -p"+masterPass+" " +
"-e'show master status;'";
Map<String, Object> result = dMruntimeUtil.login(masterIp,masterPort,cmd);
if(null == result){
log.error("获取主服务器同步信息--Linux指令执行失败:{}");
}
String value = (String) result.get("value");
String[] arrs = value.split("\n");
String[] arr = arrs[arrs.length-1].split("\t");
/**
6.1.配置从服务器 同步信息
* change master to master_host='192.168.1.1',master_user='slave',master_password='123456',master_log_file='MySQL-bin.000002',master_log_pos=301126;
* */
cmd ="mysql -u"+backupName+" -p"+backupPass+" " +
"-e'change master to master_host=\""+masterIp+"\",master_user=\""+userName+"\"," +
"master_password=\""+password+"\",master_log_file=\""+arr[0]+"\"," +
"master_log_pos="+arr[1]+";'";
cmdB.add(cmd);
/**
7.获取1.2备服务器同步信息
* mysql -uroot -proot -e"show master status;"
* */
cmd ="mysql -h"+backupIp+" -u"+backupName+" -p"+backupPass+" " + "--port=3306 "+
"-e'show master status;'";
result = dMruntimeUtil.login(backupIp,backPort,cmd);
if(null == result){
log.error("mysql数据同步http接口同步Linux指令为 null");
}
value = (String) result.get("value");
arrs = value.split("\n");
for (int i = 0; i <arrs.length ; i++) {
}
arr = arrs[arrs.length-1].split("\t");
/**
7.1.配置主服务器 同步信息
* change master to master_host='192.168.1.2',master_user='slave',master_password='123456',master_log_file='MySQL-bin.000002',master_log_pos=301126;
* */
cmd ="mysql -h"+masterIp+" -u"+masterUser+" -p"+masterPass+" " +
"-e'change master to master_host=\""+backupIp+"\",master_user=\""+userName+"\"," +
"master_password=\""+password+"\",master_log_file=\""+arr[0]+"\"," +
"master_log_pos="+arr[1]+";'";
cmdA.add(cmd);
/**
8.启动同步
* start slave;
* */
cmd ="mysql -h"+masterIp+" -u"+masterUser+" -p"+masterPass+" " +
"-e'start slave;'";
cmdA.add(cmd);
cmd ="mysql -h"+backupIp+" -u"+backupName+" -p"+backupPass+" " +
"-e'start slave;'";
cmdB.add(cmd);
for (String cmdt :cmdA) {
if(DMruntimeUtil(masterIp,masterPort,cmdt)){
}else{
return false;
}
}
for (String cmdt :cmdB) {
if(DMruntimeUtil(backupIp,backPort,cmdt)){
}else{
return false;
}
}
return true;
}
public Boolean DMruntimeUtil(String Ip,String ServerPort,String cmd) {
Map<String, Object> result = dMruntimeUtil.login(Ip,ServerPort,cmd);
if(null == result){
log.error("mysql数据同步http接口同步Linux指令为 null");
}
String value = (String) result.get("value").toString().replace("error.log","");
if(value.contains("Error") || value.contains("error") ||value.contains("ERROR")){
log.error("mysql数据同步http接口同步Linux指令执行失败:"+Ip);
log.error("mysql数据同步http接口同步Linux指令执行失败:"+cmd);
log.error("mysql数据同步http接口同步Linux指令执行失败:"+value);
return false;
}else{
return true;
}
}
/**
* 综合调用 同步以及配置主从开启的方法 统一入参
* @param masterIp 主服务器IP
* @param masterServerId 主服务器serverId
* @param backupServerId 备服务器serverId
* @param masterUser 主服务器数据库用户
* @param masterPass 主服务器数据库密码
* @param userName 创建同步用户 用户名
* @param password 创建同步用户 密码
* @param backupIp 从服务器IP
* @param DBname 备份数据库名称
* @param proPath 数据库配置文件路径
* @param backupName 从服务器数据库用户
* @param backupPass 从服务器数据库密码
* @return
*/
public String msyqlAll(String masterIp,int masterServerId,int backupServerId,String masterUser,
String masterPass, String userName,
String password,String backupIp,
String backupName,String backupPass,
String DBname, String proPath){
List<String> cmds = mysqlDump(masterIp,masterUser,masterPass
,backupIp,backupName,backupPass,DBname);
for (String cmd:cmds) {
Map<String, Object> result = dMruntimeUtil.login(masterIp,cmd);
if(null == result){
log.error("mysql数据同步http接口同步Linux指令为 null");
}
String value = (String) result.get("value");
if(value.contains("Error") || value.contains("error")){
log.error("mysql数据同步http接口同步Linux指令执行失败:"+value);
return value;
}
}
boolean type = mysqlPropert(masterIp,masterServerId,backupServerId,masterUser, masterPass,userName,password, backupIp,backupName,
backupPass, DBname,proPath);
if(type){
return "success";
}
return "error";
}
/**
* 停止并删除 主从关系以及配置数据信息
* @param masterIp 主服务器IP
* @param masterPort 主服务器IP
* @param backupIp 从服务器IP
* @param backupPort 从服务器IP
* @param backupName 从服务器数据库用户
* @param backupPass 从服务器数据库密码
* @param masterName 主服务器数据库用户
* @param masterPass 主服务器数据库密码
* @return
*/
public String stopMysqlSlave(String masterIp, String masterPort, String backupIp, String backupPort, String backupName,String backupPass,
String masterName,String masterPass){
/*
* stop slave 停止主从同步
* reset slave all 删除所有与主库之间的关联,如需再次启动需要重新配置连接信息
* */
String cmd ="mysql -h"+masterIp+" -u"+masterName+" -p"+masterPass+" " +
"-e'stop slave;reset slave all;'";
Map<String, Object> result = dMruntimeUtil.login(masterIp,masterPort,cmd);
if(null == result){
log.error("mysql数据同步http接口同步Linux指令执行失败:{}",cmd);
}
String value = (String) result.get("value");
if(value.contains("Error") || value.contains("error") ||value.contains("ERROR")){
log.error("命令::"+cmd+"执行失败::"+value);
return value;
}else{
log.info("命令::"+cmd+"执行成功::"+value);
}
cmd ="mysql -h"+backupIp+" -u"+backupName+" -p"+backupPass+" " +
"-e'stop slave;reset slave all;'";
result = dMruntimeUtil.login(backupIp,backupPort,cmd);
if(null == result){
log.error("mysql数据同步http接口同步Linux指令执行失败:{}",cmd);
}
value = (String) result.get("value");
if(value.contains("Error") || value.contains("error") ||value.contains("ERROR")){
log.error("命令::"+cmd+"执行失败::"+value);
return value;
}else{
log.info("命令::"+cmd+"执行成功::"+value);
}
return "success";
}
}
工具类 DMruntimeUtil
package utils;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.util.encoders.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*工具类
*/
@Slf4j
@Component
public class DMruntimeUtil {
private static final String DEFAULT_CHARSET = "utf-8";
private static final Logger LOGGER = LoggerFactory.getLogger(DMruntimeUtil.class);
private String PRE_SERVER_URL = "http://{ip}:{port}/linuxBash/linuxBash";
/**
* 改成发送http请求
*ip 要执行linux指令的服务器IP
*cmd 要执行的指令
*
*/
public Map<String, Object> login(String ip,String port ,String cmd) {
Map<String, Object> result = new HashMap<>();
try {
//如果是数据库同步 延迟2秒
if("restart".equals(cmd)){
Thread.sleep(2000);
}
String url = PRE_SERVER_URL.replace("{ip}",ip);
url = url.replace("{port}",port);
//自己做一下数据加密 把cmd给加密了 保证一下安全性
log.info("发送同步指令url="+url);
String resp = HttpSendUtils.sendPostWb(url,"application/json",Base64.toBase64String(cmd));
log.error("-==[linuxBashSyncHttpSyncUtil resp:{} ]==- ",resp);
if(StringUtils.isNotEmpty(resp)){
JSONObject jsonObjectResp = JSONObject.fromObject(resp);
if(StatusCode.SUCCESS.code.intValue() == jsonObjectResp.getInt("code")){
result.put("value",jsonObjectResp.getString("value"));
return result;
}else{
log.error("-==[linuxBashSyncHttpSyncUtil sendRequest ERROR ]==- ");
}
}else{
log.error("-==[linuxBashSyncHttpSyncUtil sendRequest ERROR ]==- Access server exception");
}
} catch (Exception e) {
log.error("-==[linuxBashSyncHttpSyncUtil sendRequest Exception ]==- ");
e.printStackTrace();
}
return null;
}
/**
* 改成发送http请求
*ip 要执行linux指令的服务器IP
*cmd 要执行的指令
*
*/
public Map<String, Object> login(String ip ,String cmd) {
Map<String, Object> result = new HashMap<>();
try {
//根据IP获取管理平台端口号
String port ="8080";
String url = PRE_SERVER_URL.replace("{ip}",ip);
url = url.replace("{port}",port);
//自己做一下数据加密 把cmd给加密了 保证一下安全性
String resp = HttpSendUtils.sendPostWb(url,"application/json",Base64.toBase64String(cmd));
log.error("-==[linuxBashSyncHttpSyncUtil resp:{} ]==- ",resp);
if(StringUtils.isNotEmpty(resp)){
JSONObject jsonObjectResp = JSONObject.fromObject(resp);
if(StatusCode.SUCCESS.code.intValue() == jsonObjectResp.getInt("code")){
result.put("value",jsonObjectResp.getString("value"));
return result;
}else{
log.error("-==[linuxBashSyncHttpSyncUtil sendRequest ERROR ]==- ");
}
}else{
log.error("-==[linuxBashSyncHttpSyncUtil sendRequest ERROR ]==- Access server exception");
}
} catch (Exception e) {
log.error("-==[linuxBashSyncHttpSyncUtil sendRequest Exception ]==- ");
e.printStackTrace();
}
return null;
}
/**
* 远程执行shll脚本或者命令
*
* @param cmd 即将执行的命令
* @return 命令执行完后返回的结果值
*/
public static Map<String, Object> execute(String cmd) {
Map<String, Object> result = new HashMap<String, Object>(16);
try {
Process p = Runtime.getRuntime().exec(new String[]{"sh", "-c", cmd});
result = processStdout(p.getInputStream(), DEFAULT_CHARSET);
// 如果为得到标准输出为空,说明脚本执行出错了
if (StringUtils.isBlank(result.get("value")+"")) {
LOGGER.info("得到标准输出为空,执行的命令:" + cmd);
result = processStdout(p.getErrorStream(), DEFAULT_CHARSET);
} else {
LOGGER.info("执行命令成功,执行的命令:" + cmd);
}
} catch (IOException e) {
LOGGER.error("执行命令失败,执行的命令:" + cmd + " " , e);
result= null;
}
System.out.println(result.toString());
return result;
}
}
接口 LinuxBashController
package ;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.util.encoders.Base64;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/linuxBash")
public class LinuxBashCmdController {
@PostMapping("")
public LinuxBashSycnRespVo linuxBashSync(@RequestBody String info) {
try {
/*
解密数据 获取cmd info
*/
Map<String, Object> result = DMruntimeUtil.execute(info);
if(null != result){
linuxBashSycnRespVo.setCode(StatusCode.SUCCESS.code.intValue());
linuxBashSycnRespVo.setValue((String) result.get("value"));
}else {
linuxBashSycnRespVo.setCode(StatusCode.ERROR.code.intValue());
}
log.info("-==[LinuxBashCmdController linuxBashSync end]==- ");
} catch (Exception e) {
linuxBashSycnRespVo.setCode(StatusCode.ERROR.code.intValue());
e.printStackTrace();
}
return linuxBashSycnRespVo;
}
}