windows环境jar包部署到linux服务器,一键操作
背景:
windows系统下生成的jar包通过FTP上传到linux服务器,然后通过XShell进行jar包的发布,这样反复了几个月后,开发阶段需要频繁更新包的部署。个人觉得很繁琐,想一键式把这个工作做了,不想经常花时间发布。前几天去了解了下Docker+Jenkins的方式,但是过于麻烦,对我个人学习时间和成本比较高。从而衍生出想用自己比较拿手的C#编写一个小工具解决我这个问题
需求:
windows环境jar包部署到linux服务器,一键操作
下载:
https://files.cnblogs.com/files/shexunyu/Linux%E9%83%A8%E7%BD%B2%E5%B0%8F%E5%B7%A5%E5%85%B7V2.zip
https://pan.baidu.com/s/15HpNjKDBiuLf7mNgSlbDFw 提取码:pk5n
小工具:
界面

程序构建方式
1.通过Neget安装SSH.NET


2.后端代码
1.设计器代码
namespace Deploy
{
partial class DeployFrm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region Windows Form Designer generated code /// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.txtLocalFilePath = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.txtServerFilePath = new System.Windows.Forms.TextBox();
this.txtPort = new System.Windows.Forms.TextBox();
this.label8 = new System.Windows.Forms.Label();
this.IP = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.txtPassword = new System.Windows.Forms.TextBox();
this.label5 = new System.Windows.Forms.Label();
this.txtUserName = new System.Windows.Forms.TextBox();
this.txtIP = new System.Windows.Forms.TextBox();
this.txtServerDirectory = new System.Windows.Forms.TextBox();
this.btnConnection = new System.Windows.Forms.Button();
this.btnUpload = new System.Windows.Forms.Button();
this.btnRun = new System.Windows.Forms.Button();
this.label7 = new System.Windows.Forms.Label();
this.txtLog = new System.Windows.Forms.TextBox();
this.btnSaveInfo = new System.Windows.Forms.Button();
this.btnStop = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(, );
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(, );
this.label1.TabIndex = ;
this.label1.Text = "LocalFilePath:";
//
// txtLocalFilePath
//
this.txtLocalFilePath.Location = new System.Drawing.Point(, );
this.txtLocalFilePath.Name = "txtLocalFilePath";
this.txtLocalFilePath.Size = new System.Drawing.Size(, );
this.txtLocalFilePath.TabIndex = ;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(, );
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(, );
this.label2.TabIndex = ;
this.label2.Text = "ServerFilePath:";
//
// txtServerFilePath
//
this.txtServerFilePath.Location = new System.Drawing.Point(, );
this.txtServerFilePath.Name = "txtServerFilePath";
this.txtServerFilePath.Size = new System.Drawing.Size(, );
this.txtServerFilePath.TabIndex = ;
//
// txtPort
//
this.txtPort.Location = new System.Drawing.Point(, );
this.txtPort.Name = "txtPort";
this.txtPort.Size = new System.Drawing.Size(, );
this.txtPort.TabIndex = ;
//
// label8
//
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(, );
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(, );
this.label8.TabIndex = ;
this.label8.Text = "Port:";
//
// IP
//
this.IP.AutoSize = true;
this.IP.Location = new System.Drawing.Point(, );
this.IP.Name = "IP";
this.IP.Size = new System.Drawing.Size(, );
this.IP.TabIndex = ;
this.IP.Text = "IP:";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(, );
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(, );
this.label3.TabIndex = ;
this.label3.Text = "ServerDirectory:";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(, );
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(, );
this.label4.TabIndex = ;
this.label4.Text = "UserName:";
//
// txtPassword
//
this.txtPassword.Location = new System.Drawing.Point(, );
this.txtPassword.Name = "txtPassword";
this.txtPassword.Size = new System.Drawing.Size(, );
this.txtPassword.TabIndex = ;
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(, );
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(, );
this.label5.TabIndex = ;
this.label5.Text = "Password:";
//
// txtUserName
//
this.txtUserName.Location = new System.Drawing.Point(, );
this.txtUserName.Name = "txtUserName";
this.txtUserName.Size = new System.Drawing.Size(, );
this.txtUserName.TabIndex = ;
//
// txtIP
//
this.txtIP.Location = new System.Drawing.Point(, );
this.txtIP.Name = "txtIP";
this.txtIP.Size = new System.Drawing.Size(, );
this.txtIP.TabIndex = ;
//
// txtServerDirectory
//
this.txtServerDirectory.Location = new System.Drawing.Point(, );
this.txtServerDirectory.Name = "txtServerDirectory";
this.txtServerDirectory.Size = new System.Drawing.Size(, );
this.txtServerDirectory.TabIndex = ;
//
// btnConnection
//
this.btnConnection.Location = new System.Drawing.Point(, );
this.btnConnection.Name = "btnConnection";
this.btnConnection.Size = new System.Drawing.Size(, );
this.btnConnection.TabIndex = ;
this.btnConnection.Text = "Connection";
this.btnConnection.UseVisualStyleBackColor = true;
this.btnConnection.Click += new System.EventHandler(this.btnConnection_Click);
//
// btnUpload
//
this.btnUpload.Location = new System.Drawing.Point(, );
this.btnUpload.Name = "btnUpload";
this.btnUpload.Size = new System.Drawing.Size(, );
this.btnUpload.TabIndex = ;
this.btnUpload.Text = "Upload";
this.btnUpload.UseVisualStyleBackColor = true;
this.btnUpload.Click += new System.EventHandler(this.btnUpload_Click);
//
// btnRun
//
this.btnRun.Location = new System.Drawing.Point(, );
this.btnRun.Name = "btnRun";
this.btnRun.Size = new System.Drawing.Size(, );
this.btnRun.TabIndex = ;
this.btnRun.Text = "Run";
this.btnRun.UseVisualStyleBackColor = true;
this.btnRun.Click += new System.EventHandler(this.btnRun_Click);
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(, );
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(, );
this.label7.TabIndex = ;
this.label7.Text = "Log:";
//
// txtLog
//
this.txtLog.Location = new System.Drawing.Point(, );
this.txtLog.Multiline = true;
this.txtLog.Name = "txtLog";
this.txtLog.Size = new System.Drawing.Size(, );
this.txtLog.TabIndex = ;
//
// btnSaveInfo
//
this.btnSaveInfo.Location = new System.Drawing.Point(, );
this.btnSaveInfo.Name = "btnSaveInfo";
this.btnSaveInfo.Size = new System.Drawing.Size(, );
this.btnSaveInfo.TabIndex = ;
this.btnSaveInfo.Text = "SaveInfo";
this.btnSaveInfo.UseVisualStyleBackColor = true;
this.btnSaveInfo.Click += new System.EventHandler(this.btnSaveInfo_Click);
//
// btnStop
//
this.btnStop.Location = new System.Drawing.Point(, );
this.btnStop.Name = "btnStop";
this.btnStop.Size = new System.Drawing.Size(, );
this.btnStop.TabIndex = ;
this.btnStop.Text = "Stop";
this.btnStop.UseVisualStyleBackColor = true;
this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
//
// DeployFrm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(, );
this.Controls.Add(this.btnStop);
this.Controls.Add(this.btnSaveInfo);
this.Controls.Add(this.txtLog);
this.Controls.Add(this.label7);
this.Controls.Add(this.btnRun);
this.Controls.Add(this.btnUpload);
this.Controls.Add(this.btnConnection);
this.Controls.Add(this.txtPort);
this.Controls.Add(this.label8);
this.Controls.Add(this.IP);
this.Controls.Add(this.label3);
this.Controls.Add(this.label4);
this.Controls.Add(this.txtPassword);
this.Controls.Add(this.label5);
this.Controls.Add(this.txtUserName);
this.Controls.Add(this.txtIP);
this.Controls.Add(this.txtServerDirectory);
this.Controls.Add(this.txtServerFilePath);
this.Controls.Add(this.label2);
this.Controls.Add(this.txtLocalFilePath);
this.Controls.Add(this.label1);
this.Name = "DeployFrm";
this.Text = "DeployFrm";
this.Load += new System.EventHandler(this.DeployFrm_Load);
this.ResumeLayout(false);
this.PerformLayout(); } #endregion private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox txtLocalFilePath;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox txtServerFilePath;
private System.Windows.Forms.TextBox txtPort;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.Label IP;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TextBox txtPassword;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.TextBox txtUserName;
private System.Windows.Forms.TextBox txtIP;
private System.Windows.Forms.TextBox txtServerDirectory;
private System.Windows.Forms.Button btnConnection;
private System.Windows.Forms.Button btnUpload;
private System.Windows.Forms.Button btnRun;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.TextBox txtLog;
private System.Windows.Forms.Button btnSaveInfo;
private System.Windows.Forms.Button btnStop;
}
}
2.业务代码
using Renci.SshNet;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Windows.Forms; namespace Deploy
{
public partial class DeployFrm : Form
{
public DeployFrm()
{
InitializeComponent();
deployBus.TxtLog = this.txtLog;
} public static DeployBusness deployBus = new DeployBusness(); public Deploy GetDeploy()
{
DateTime dt = DateTime.Parse("2019-09-30");
if (DateTime.Now > dt)
{
throw new Exception("请联系shexun进行版本更新");
}
var deploy = new Deploy(this.txtIP.Text, this.txtPort.Text, this.txtServerDirectory.Text, this.txtUserName.Text, this.txtPassword.Text, this.txtLocalFilePath.Text, this.txtServerFilePath.Text, "");
return deploy;
} public void LoadInfo()
{
var deploy = deployBus.ReadInfo();
if (deploy != null)
{
this.txtIP.Text = deploy.Host;
this.txtPort.Text = deploy.Port;
this.txtServerDirectory.Text = deploy.ServerDirectory;
this.txtUserName.Text = deploy.UserName;
this.txtPassword.Text = deploy.Password;
this.txtLocalFilePath.Text = deploy.LocalFilePath;
this.txtServerFilePath.Text = deploy.ServerFilePath; }
} private void btnUpload_Click(object sender, EventArgs e)
{
try
{
deployBus.Upload(GetDeploy());
}
catch (Exception ex)
{
deployBus.ShowLog(ex.Message);
}
} private void btnRun_Click(object sender, EventArgs e)
{
try
{
deployBus.Run(GetDeploy());
}
catch (Exception ex)
{
deployBus.ShowLog(ex.Message);
}
} private void btnSaveInfo_Click(object sender, EventArgs e)
{
try
{
deployBus.SaveInfo(GetDeploy());
}
catch (Exception ex)
{
deployBus.ShowLog(ex.Message);
}
} private void DeployFrm_Load(object sender, EventArgs e)
{
try
{
LoadInfo();
}
catch (Exception ex)
{
deployBus.ShowLog(ex.Message);
}
} private void btnStop_Click(object sender, EventArgs e)
{
try
{
deployBus.Stop(GetDeploy());
}
catch (Exception ex)
{
deployBus.ShowLog(ex.Message);
}
} private void btnBackUp_Click(object sender, EventArgs e)
{
} private void btnConnection_Click(object sender, EventArgs e)
{
try
{
deployBus.Connection(GetDeploy());
}
catch (Exception ex)
{
deployBus.ShowLog(ex.Message);
}
}
/// <summary>
/// 部署类
/// </summary>
[DataContract]
public class Deploy
{ public Deploy(string Host, string Port, string ServerDirectory, string UserName, string Password, string LocalFilePath, string ServerFilePath, string Log)
{
this.Host = Host != null ? Host.Trim() : null;
this.Port = Port != null ? Port.Trim() : null;
this.ServerDirectory = ServerDirectory != null ? ServerDirectory.Trim() : null;
this.UserName = UserName != null ? UserName.Trim() : null;
this.Password = Password != null ? Password.Trim() : null;
this.LocalFilePath = LocalFilePath != null ? LocalFilePath.Trim() : null;
this.ServerFilePath = ServerFilePath != null ? ServerFilePath.Trim() : null;
this.Log = Log != null ? Log.Trim() : null;
} [DataMember]
public string Host { get; set; }
[DataMember]
public string Port { get; set; }
[DataMember]
public string ServerDirectory { get; set; }
[DataMember]
public string UserName { get; set; }
[DataMember]
public string Password { get; set; }
[DataMember]
public string LocalFilePath { get; set; }
[DataMember]
public string ServerFilePath { get; set; }
[DataMember]
public string Log { get; set; }
} public class DeployBusness
{ public TextBox TxtLog { get; set; } public emAction EmAction { get; set; } public enum emAction { ___, Connection, Upload, BackUp, Run, Stop, SaveInfo, ReadInfo, Download }
public void ShowLog(string log)
{
string logStr = "";
logStr = EmAction.ToString();
var defaultNull = - logStr.Length;
if (defaultNull > )
{
string temp = "";
for (int i = ; i < defaultNull; i++)
{
temp += " ";
}
logStr += temp;
}
logStr += " => [ " + DateTime.Now.ToString() + " ] ";
logStr += log + "。\r\n";
if (this.TxtLog != null)
{
TxtLog.Text += logStr;
}
EmAction = emAction.___;
} public bool Connection(Deploy deploy)
{
this.EmAction = emAction.Connection;
using (var client = new SftpClient(deploy.Host, int.Parse(deploy.Port), deploy.UserName, deploy.Password)) //创建连接对象
{
client.Connect(); //连接
this.ShowLog("连接服务器成功");
}
return true;
} public bool BackUp(Deploy deploy)
{
//对应的服务未停止不能进行上传 this.EmAction = emAction.BackUp;
using (var client = new SftpClient(deploy.Host, int.Parse(deploy.Port), deploy.UserName, deploy.Password)) //创建连接对象
{
client.Connect(); //连接
var fileName = Path.GetFileName(deploy.ServerFilePath);
var changeDir = deploy.ServerFilePath.Replace(fileName, "");
client.ChangeDirectory(changeDir); //切换目录
//复制文件到新的文件目录 using (var fileStream = new FileStream(deploy.LocalFilePath, FileMode.Open))
{
this.ShowLog("正在上传文件,请稍等......");
client.BufferSize = * ; // bypass Payload error large
client.UploadFile(fileStream, fileName); //上传文件
this.ShowLog("上传文件成功");
}
}
return true;
} public bool Upload(Deploy deploy)
{
//对应的服务未停止不能进行上传 this.EmAction = emAction.Upload;
using (var client = new SftpClient(deploy.Host, int.Parse(deploy.Port), deploy.UserName, deploy.Password)) //创建连接对象
{
client.Connect(); //连接
var fileName = Path.GetFileName(deploy.ServerFilePath);
var changeDir = deploy.ServerFilePath.Replace(fileName, "");
client.ChangeDirectory(changeDir); //切换目录
using (var fileStream = new FileStream(deploy.LocalFilePath, FileMode.Open))
{
this.ShowLog("正在上传文件,请稍等......");
client.BufferSize = * ; // bypass Payload error large
client.UploadFile(fileStream, fileName); //上传文件
this.ShowLog("上传文件成功");
}
}
return true;
} public void Run(Deploy deploy)
{
this.EmAction = emAction.Run;
var con = new ConnectionInfo(deploy.Host, int.Parse(deploy.Port), deploy.UserName,
new AuthenticationMethod[]{
// Pasword based Authentication
new PasswordAuthenticationMethod(deploy.UserName,deploy.Password)
});
// Execute (SHELL) Commands
using (var sshclient = new SshClient(con))
{
sshclient.Connect();
this.ShowLog("连接服务器成功");
var psResevice = sshclient.CreateCommand("ps -ef").Execute();
var runList = new List<string>();
string[] lines = psResevice.Split('\n'); //用\n表示换行符 注意是char类型 分割行
var fileName = Path.GetFileName(deploy.ServerFilePath);
foreach (var item in lines)
{
if (item.Contains(fileName))
{
runList.Add(item);
this.ShowLog("找到服务:" + item);
}
} foreach (var item in runList)
{
var temp = item.Substring(, );
var pid = temp.Substring(, - ).Trim();
//获取到PID
var msg = sshclient.CreateCommand("kill -9 " + pid).Execute();
this.ShowLog("关闭服务PID:" + pid);
}
//更新文件 成功后执行命令
var changeDir = deploy.ServerFilePath.Replace(fileName, "").TrimEnd('/');
var command = "nohup java -jar " + fileName + ">>m.out.log 2>&1 &";
var msg2 = sshclient.CreateCommand("cd " + changeDir + ";" + command).Execute();
this.ShowLog("启动服务成功");
}
} public void Stop(Deploy deploy)
{
this.EmAction = emAction.Stop;
var con = new ConnectionInfo(deploy.Host, int.Parse(deploy.Port), deploy.UserName,
new AuthenticationMethod[]{
// Pasword based Authentication
new PasswordAuthenticationMethod(deploy.UserName,deploy.Password)
});
// Execute (SHELL) Commands
using (var sshclient = new SshClient(con))
{
sshclient.Connect();
var psResevice = sshclient.CreateCommand("ps -ef").Execute();
string[] lines = psResevice.Split('\n'); //用\n表示换行符 注意是char类型 分割行
var fileName = Path.GetFileName(deploy.ServerFilePath);
if (lines != null && lines.Length > )
{
this.ShowLog("存在" + lines.Length.ToString() + "个服务");
}
foreach (var item in lines)
{
if (item.Contains(fileName))
{
this.ShowLog("找到服务:" + item);
var temp = item.Substring(, );
var pid = temp.Substring(, - ).Trim();
//获取到PID
var msg = sshclient.CreateCommand("kill -9 " + pid).Execute(); }
}
psResevice = sshclient.CreateCommand("ps -ef").Execute();
lines = psResevice.Split('\n'); //用\n表示换行符 注意是char类型 分割行
var stopStatus = false;
foreach (var item in lines)
{
if (item.Contains(fileName))
{
stopStatus = true;
}
}
if (!stopStatus)
{
this.ShowLog("停止服务成功");
} }
} /// <summary>
/// 读取信息
/// </summary>
public Deploy ReadInfo()
{
this.EmAction = emAction.ReadInfo;
string path = AppDomain.CurrentDomain.BaseDirectory + @"Temp\Record\";
var defaultFileName = "Info.txt";
string fileFullPath = path + defaultFileName;
//加载对应的文件目录的所有文件
if (File.Exists(fileFullPath))
{
string info = File.ReadAllText(fileFullPath);
this.ShowLog("读取配置成功");
//反序列化
var deploy = MySerializer.JsonToObject<Deploy>(info);
return deploy;
} return null;
} /// <summary>
/// 保存信息
/// </summary>
public void SaveInfo(Deploy deploy)
{
this.EmAction = emAction.SaveInfo;
string path = AppDomain.CurrentDomain.BaseDirectory + @"Temp\Record\";
var fileFullPath = path + "Info.txt";
StreamWriter sw;
if (File.Exists(fileFullPath))
{
File.Delete(fileFullPath);
}
var info = MySerializer.ObjectToJson(deploy);
sw = File.CreateText(fileFullPath);
sw.WriteLine(info);
sw.Close();
this.ShowLog("保存配置成功");
} } public class MySerializer
{
/// <summary>
/// 将对象序列化为json字符串
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">实例</param>
/// <returns>json字符串</returns>
public static string ObjectToJson<T>(T t) where T : class
{
DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream())
{
formatter.WriteObject(stream, t);
string result = System.Text.Encoding.UTF8.GetString(stream.ToArray());
return result;
}
} /// <summary>
/// json字符串转成对象
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="json">json格式字符串</param>
/// <returns>对象</returns>
public static T JsonToObject<T>(string json) where T : class
{
DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(json)))
{
T result = formatter.ReadObject(stream) as T;
return result;
}
}
}
}
}
总结:此工具我已分享给小组的开发同事一起使用,目前也有考虑在此基础上增加新的小功能,有兴趣的朋友请评论留言。
windows环境jar包部署到linux服务器,一键操作的更多相关文章
- windows环境jar包部署到linux服务器,一键操作(帮助说明)
背景:在上次https://www.cnblogs.com/shexunyu/p/11165282.html发布了第一个版本后,后面增加了相关功能 需求:做下简单的说明文档 下载:https://fi ...
- 解决springboot项目打成jar包部署到linux服务器后上传图片无法访问的问题
前言:目前大三,自己也在学习和摸索的阶段.在和学校的同学一起做前后端分离项目的时候,我们发现将后端打包成jar,然后部署到服务器中通过java -jar xxx.jar运行项目以后,项目中存在文件上传 ...
- springboot Jar包 部署到Linux服务器运行脚本
1.jar包同级目录 , 如下: #!/bin/sh RESOURCE_NAME=demo.jar tpid=`ps -ef|grep $RESOURCE_NAME|grep -v grep|grep ...
- Windows下war包部署到Linux下Tomcat出现的问题
最近,将Windows下开发的war包部署到Linux下的Tomcat时报了一个错误:tomcat error in opening zip file.按理说,如果正常,当把war包复制到webapp ...
- jar包部署在linux上后浏览器访问不到的问题
1.首先保证程序是正常运行的 2.linux的防火墙是否关闭 3.可能是iptables里面需要设置白名单 可编辑/etc/sysconfig/iptables文件加入应用端口的白名单 修改后执行sy ...
- 把jar包部署为linux服务
一直未配置成功,直到放弃后reboot了下,才直到错的不是自己的配置,而是自己不懂 1.在touch /etc/rc.d/init.d/tl_c_cons_service(创建新文件) 2.vi /e ...
- 自己挖的坑自己填-- maven打jar包部署服务器报错
1.今天 mvn install 后把 jar 包部署到服务器上,执行 java -jar xx.jar 报 "no main manifest attribute,in xx.jar&qu ...
- 把 web 项目部署到 Linux 服务器上
1.打开 eclipse,在已经完成的 web 项目上面点击右键,选择 export,然后选择导出成 war 包. 以部署 SMBMS 项目为例 2.项目打包成 war ,选择项目导出到的位置. ...
- 将Web项目War包部署到Tomcat服务器
1. 配置Java运行环境 1.1 下载并安装JDK 从官网上下载最新的JDK:http://java.sun.com/javase/downloads/index.jsp ,下载后安装,选择想把JD ...
随机推荐
- Hdu 1247 Hat's Words(Trie树)
Hat's Words Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- kubernetes 的数据的存储 存储卷
根据应用本身是否 需要持久存储数据,以及某一此请求和此前的请求是否有关联性,可以分为四类应用: 1.有状态要存储 2.有状态无持久存储 3.无状态无持久存储4.无状态有持久存储 在k8s上的数据持久性 ...
- Python中的函数递归思想,以及对比迭代和递归解决Fibonacci数列
什么是递归?简单的说就是:函数自身调用自身. “普通程序员用迭代,天才程序员用递归” 虽然递归 在运行时会不断出栈压栈,调用底层的寄存器,造成空间上的占用以及时间上的缓慢, 但在一些算法上面仍然是递归 ...
- Python实用黑科技——解包元素(2)
需求: 前面的文章讲的是使用变量的个数需要和迭代器数据变量的元素个数相同的方法,但更多的时候确实不想根据元素个数n来定义相应多的变量,而是希望用较少的变量( def drop_first_last(g ...
- win 内网frp反弹到内网liunx
前提:frp不同系统 但是版本必须完全相同 这是我的两个版本 我这个就是验证frp可以在不同系统之间使用 准备工作 靶机 win2003 ip 192.168.1.132 公网 vps windows ...
- JVM----双亲委派模型
加载类的开放性 我们在了解双亲委派模型之前,不得不先了解一下什么是类加载器.虚拟机设计团队之初是希望类加载过程“通过一个类的全限定名来获取描述该类的二进制字节流”这个动作能放到虚拟机外部实现,以便于让 ...
- LeetCode 279. 完全平方数(Perfect Squares)
题目描述 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n.你需要让组成和的完全平方数的个数最少. 示例 1: 输入: n = 12 输出: 3 解释 ...
- macos npm + node 环境启动问题排查
MacOS安装npm全局包的权限问题 解决办法:修改npm包所安装目录的权限:sudo chown -R $USER /usr/local 然后输入密码就可以了 deMBP:~ $ sudo ch ...
- Qt DLL总结【一】-链接库预备知识
1.链接库概念 静态链接库和动态链接库介绍 我们可以创建一种文件里面包含了很多函数和变量的目标代码,链接的时候只要把这个文件指示给链接程序就自动地从文件中查找符合要求的函数和变量进行链接,整个查找过程 ...
- js回调函数(callback)(转载)
学习jquery时,对回调函数感觉很困惑,在晚上找了半天,忽然发现这篇文章很浅显,基本说明了问题.故转载 原文: 自学jquery的时候,看到一英文词(Callback),顿时背部隐隐冒冷汗.迅速go ...