首先,说一下大概的思路
- 在服务器上部署服务的时候,是不是用的本地打包好的jar包呢?答案是的,所以这种就是手动部署的方式,特别的繁琐。那么如何能在服务器上完成这一步呢?
- 得先拿到代码吧?怎么拿?本地传上去吗?当然不是,那多low啊。我们直接从git上拉下来不就好了。
- 有了代码,我们是不是就可以像在本地一样使用mvn命令打包成jar包?想一想打包过程中还需要什么?会不会报错?答案是肯定的,在本地打包的时候,我们有本地maven仓库,里面放着我们的thrift服务的jar包,所以本地打包的时候是不会报错的。所以我们的思路就来了,能不能把依赖的jar包放到一个自己搭建的私服中,然后配置好一切,打包就没问题了吧?答案是YES!
- 打成jar包后,还需要自己手动运行?那这个自动化部署,也只是自动化打包了而已啊。。。所以接下来的思路,如何让它自动运行。办法还是有很多的,比如我在项目里面写一个运行脚本,到时候代码拉下来,打完包之后,直接运行就完事了。没错就是这么简单,但是我们回到第一步,我们怎么不上服务器,让它自己就能完成这一切?
- OK,来到了我们的第四步,需要一个第三方服务,姑且叫它自动化发布服务,这个服务的功能暂且就只有一个,那就是和服务器上的代理进程通信,告诉它,运行xxx脚本,这样就能完成一个自动化发布的过程了。
好了,思路有了,接下来,开干!
一、配置git环境
为了方便,直接使用yum安装吧
yum install git.x86_64
测试一下
将代码拉下来
可以拉取指定分支
git clone -b 你想要拉的分支 git地址
二、配置maven环境
在web服务器和thrift服务器上,配置maven环境
直接使用yum安装,图方便
如果没有指定maven后面的名字,它会安装有关maven的依赖、插件,我比较懒,就不选了
yum install maven
测试一下
接下来,让你们看看打包的时候的报错信息
记住,不要在父project那里打包
mvn clean install -Dmaven.test.skip=true
报错
和预测的一样,找不到core包
三、搭建nexus私服
接下来,搭建一个私服,将我们的jar包deploy上去
可以参考这篇文章搭建私服 第8章 私服nexus
我这里主要说一下坑和一些配置信息
首先,需要去下载nexus,但是坑爹的是官网下不下来。。。所以我从其它渠道下载下来了。可以百度云上下,可以CSDN上下,都有资源。
然后按照步骤操作,都挺顺畅的
接着就是配置settings.xml文件
这个需要在服务器、本地都配置
<?xml version="1.0"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<!--http://maven.apache.org/ref/3.5.0/maven-settings/settings.html-->
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>nexus</id>
<name>crop-nexus</name>
<url>http://192.168.0.103:8081/nexus/content/groups/public/</url>
<releases>
<!-- true表示开启仓库发布版本下载,false表示禁止 -->
<enabled>true</enabled>
</releases>
<snapshots>
<!-- true表示开启仓库快照版本下载,false表示禁止 -->
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<url> http://192.168.0.103:8081/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<!-- 禁止快照版本,防止不稳定的插件影响项目构建 -->
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<!-- 激活nexus私服 -->
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<name>crop-nexus</name>
<url>http://192.168.0.103:8081/nexus/content/groups/public/</url>
</mirror>
</mirrors>
<servers>
<!-- 发布Releases版的账号,ID要与distributionManagement中的Releases ID一致 -->
<server>
<id>nexus-releases</id>
<username>admin</username>
<password>你的密码</password>
</server>
<!-- 发布snapshot版的账号,ID要与distributionManagement中的snapshot ID一致 -->
<server>
<id>nexus-snapshot</id>
<username>admin</username>
<password>你的密码</password>
</server>
</servers>
</settings>
接着代码里面,配置一下
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>corp nexus-releases</name>
<url>http://192.168.0.103:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshot</id>
<name>corp nexus-snapshot</name>
<url>http://192.168.0.103:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
然后点击deploy,即可把jar包发布到私服仓库中
PS:第一次deploy的时候和第一次在服务上打包的时候,会非常的慢,耐心等待即可好了,私服仓库搭建起来了,我们再回过头来打包一遍项目看看
哈哈,看,是不是打包成功了,接下来,运行看看,是不是能运行成功
OK,运行成功,现在就差搭建一个自动化发布服务,让它帮我们把这整个流程自己走一遍,就达到自动化发布的效果了。
四、搭建自动化发布服务
首先,我们先模拟自动化发布服务的操作,写一个自动化脚本,然后手动执行它,看看效果如何?
完美,没报错,哈哈,run.sh脚本如下
#!/bin/bash
echo '【INFO】正在拉取代码……'
git clone https://github.com/coderxj/min-system-web-service.git
echo '【INFO】拉取代码完成,目录:' `pwd`
echo '\n\n\n'
cd ./min-system-web-service/min-system-service/
echo '【INFO】正在打包……'
mvn clean install -Dmaven.test.skip=true
cd ./target
echo '【INFO】打包完成,目录:' `pwd`
echo '\n\n\n'
echo '【INFO】开始启动服务……'
java -jar min-system-service-*.jar
到了这一步,思路已经非常清晰了吧?无非就是,在服务器上运行一个代理进程,然后自动化发布服务通过socket跟这个代理进程通信,告诉它,你要运行这个脚本了。但是这还不够,我们应该还能够指定它发布哪个分支。
因为时间不够,先暂时写个超级简单的demo
(PS:完整的自动化发布服务代码,等有时间写了,会传到github上)
服务端:
@RestController
@RequestMapping("/publish")
public class AutoPublishController {
private ServerSocket serverSocket;
private Socket socket;
{
new Thread(new Runnable() {
@Override
public void run() {
try {
serverSocket = new ServerSocket(9999);
socket = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
@PostMapping
public Object publish(@RequestBody PublishParamVo publishParamVo){
try {
socket.getOutputStream().write("run".getBytes());
} catch (IOException e) {
return new HashMap<Object, Object>(){{put("error", e.getMessage());}};
}
return new HashMap<Object, Object>(){{put("success", "发布成功");}};
}
}
客户端(代理进程)
public class Main {
public static void main(String[] args) {
try {
Socket socket = new Socket("192.168.0.101", 9999);
if(socket.isConnected()){
byte[] buf = new byte[32];
socket.getInputStream().read(buf);
if((new String(buf).trim()).equalsIgnoreCase("run")){
exec("sh /root/run.sh");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void exec(String cmd) {
Process process = null;
try {
process = Runtime.getRuntime().exec(cmd);
InputStream in = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
for(String line = br.readLine(); line != null; line = br.readLine()) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println(e);
} finally {
if (process != null){
process.destroy();
}
}
}
}
大概就是,部署自动化发布服务,接着在各个服务器上运行客户端,最后使用postman模拟发布请求操作。
结果如图
五、总结
自动化发布的必要条件
- 每个服务器上都需要配置好git、maven等环境,用于拉取代码,打包项目。
- 需要自己搭建一个私服仓库,用于将自己的jar包deploy上去,之后供其它服务器拉取。
- 需要有一个自动化发布服务,只需要选择想发布的项目和分支,即可远程自动发布。
- 项目里面必须配置好发布脚本,或者可以配置参数,让自动化发布服务来组装都行。
改进的地方(可以说非常多了,这个例子,非常的简单和粗糙。。。)
- 环境的搭建,可以写脚本自动化搭建。
- 私服仓库的配置,可以更定制化一些。
- 自动化发布服务,应该支持和每个服务器的长连接,以及掉线重连,那么就要保证服务器上的代理进程不能被kill,准确的说,就算kill了,或者机器重启了,也要自动重启这个进程,并且无限重连自动化发布服务。这里面涉及到的点很多(PS:我对java的socket不熟悉,所以这次才没将这个服务的代码写好,待我研究一番,再上代码)。
- 发布脚本如何更通用,如何约定更好?
……