Java は SSH 接続を介してサーバー モデルの操作を呼び出します

      最近のプロジェクト開発中に、モデルの呼び出しに Java を使用する必要があるインターフェイスのカプセル化に遭遇しました。Linux サーバー モデルの計算と呼び出しで困難に遭遇しました。インターネットで情報を検索した後、cross の実装に関する記事をまとめました。 -プラットフォーム呼び出し操作。

1. 依存関係の追加

pom.xml ファイルに ssh 依存関係を追加します。

  <!-- 远程连接linux服务器工具 -->
  <dependency>
     <groupId>ch.ethz.ganymed</groupId>
     <artifactId>ganymed-ssh2</artifactId>
     <version>262</version>
  </dependency>

2. コードを整理する

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import org.springframework.util.ObjectUtils;

import java.io.*;
import java.util.Calendar;

public class SshUtil {

	private static String DEFAULT_CHAR_SET = "UTF-8";
	private static String tipStr = "=======================%s=======================";
	private static String splitStr = "=====================================================";

	/**
	 * 登录主机
	 * @return
	 *      登录成功返回true,否则返回false
	 */
	public static Connection login(String ip, String userName, String password){
		boolean isAuthenticated = false;
		Connection conn = null;
		long startTime = Calendar.getInstance().getTimeInMillis();
		try {
			conn = new Connection(ip);
			conn.connect(); // 连接主机

			isAuthenticated = conn.authenticateWithPassword(userName, password); // 认证
			if(isAuthenticated){
				System.out.println(String.format(tipStr, "认证成功"));
			} else {
				System.out.println(String.format(tipStr, "认证失败"));
			}
		} catch (IOException e) {
			System.err.println(String.format(tipStr, "登录失败"));
			e.printStackTrace();
		}
		long endTime = Calendar.getInstance().getTimeInMillis();
		System.out.println("登录用时: " + (endTime - startTime)/1000.0 + "s\n" + splitStr);
		return conn;
	}

	/**
	 * 远程执行shell脚本或者命令
	 * @param cmd
	 *      即将执行的命令
	 * @return
	 *      命令执行完后返回的结果值
	 */
	public static String execute(Connection conn, String cmd){
		String result = "";
		Session session = null;
		try {
			if(conn != null){
				session = conn.openSession();  // 打开一个会话
				session.execCommand(cmd);      // 执行命令
				result = processStdout(session.getStdout(), DEFAULT_CHAR_SET);

				//如果为得到标准输出为空,说明脚本执行出错了
				if(ObjectUtils.isEmpty(result)){
					System.err.println("【得到标准输出为空】\n执行的命令如下:\n" + cmd);
					result = processStdout(session.getStderr(), DEFAULT_CHAR_SET);
				}else{
					System.out.println("【执行命令成功】\n执行的命令如下:\n" + cmd);
				}
			}
		} catch (IOException e) {
			System.err.println("【执行命令失败】\n执行的命令如下:\n" + cmd + "\n" + e.getMessage());
			e.printStackTrace();
		} finally {
			if (conn != null) {
				conn.close();
			}
			if (session != null) {
				session.close();
			}
		}
		return result;
	}

	/**
	 * 解析脚本执行返回的结果集
	 * @param in 输入流对象
	 * @param charset 编码
	 * @return
	 *       以纯文本的格式返回
	 */
	private static String processStdout(InputStream in, String charset){
		InputStream stdout = new StreamGobbler(in);
		StringBuffer buffer = new StringBuffer();
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(stdout, charset));
			String line = null;
			while((line = br.readLine()) != null){
				buffer.append(line + "\n");
			}
		} catch (UnsupportedEncodingException e) {
			System.err.println("解析脚本出错:" + e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			System.err.println("解析脚本出错:" + e.getMessage());
			e.printStackTrace();
		}
		return buffer.toString();
	}
	public static void main(String[] args){
		String ip = "服务器IP地址";   // 此处根据实际情况,换成自己需要访问的主机IP
		String userName = "root";
		String password = "Admin@123!";
		Connection conn =  SshUtil.login(ip, userName, password);

		String cmd = "cd /home/w/modelTest/test2/src && export LD_LIBRARY_PATH=/usr/local/cuda/lib64/:$LD_LIBRARY_PATH && ./main";
		String result = SshUtil.execute(conn, cmd);
		System.out.println(splitStr + "\n执行的结果如下: \n" + result + splitStr);
	}
}

3. 問題の分類

  • 1 つ目は、リモート ログイン接続でエラーが報告され続け、ssh ログインが実行できないという問題です。

sshd キー交換が完了していないため、接続が切断されました。

参照のクエリを実行した後、サーバーの SSH 構成ファイルで構成操作を実行する必要があります。

コマンド sudo vim /etc/ssh/sshd_config を使用して構成ファイルを開き、最後の行に次の行を追加します。

KexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group1-sha1,[email protected]

ファイルを保存した後、コマンドを使用して ssh:service sshd restart を再起動し、有効にします。         

  • モデル計算を呼び出すときに、jar パッケージが見つからないという問題が発生しました。

ただし、モデルがサーバー上で実行されている場合、jar パッケージは通常どおり見つかります。

テストを繰り返した結果、サーバーによって設定された LD_LIBRARY_PATH 環境変数がリモート Java 呼び出し中に機能しなかったためであることが判明しました。リモート Java 呼び出しを行うときに、export コマンドが追加されました。

エクスポート LD_LIBRARY_PATH=/usr/local/cuda/lib64/:$LD_LIBRARY_PATH

現在の動作環境を構成して、後で通常のモデル計算を実行できるようにします。

感謝: この記事は CSDN マスターの記事を参照しています。リンクが見つからないため、再度参照リンクを追加することはできません。マスターの記事に改めて感謝します。

おすすめ

転載: blog.csdn.net/weixin_38863607/article/details/132202884