文章目录
一、需求概况
现有某云主机服务器,用来做项目演示用,上面运行了docker应用,现希望有一总览页面,用来展示部署的应用。
二、业务流程
获取docker信息 模板生成页面 挂载到nginx
任务调度采用crontab
三、运行效果
四、实现过程
1. 基础前提
服务器已经安装jdk、docker环境、nginx。
bash
#安装Jdk
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.rpm
rpm -ivh jdk-8u131-linux-x64.rpm
java -version
#安装nginx
vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
#查看yum的nginx信息
yum info nginx
#执行命令安装
yum -y install nginx
#查看安装目录
whereis nginx
#设为开机启动
sudo systemctl enable nginx.service
启动/停止/重启/查看状态 nginx
sudo systemctl start nginx.service
sudo systemctl stop nginx.service
sudo systemctl restart nginx.service
sudo systemctl status nginx.service
2. 源码放送
https://gitcode.com/00fly/demo
bash
git clone https://gitcode.com/00fly/demo.git
3.核心代码
FreeMarkerUtil
java
package com.fly.simple.utils;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
*
* FreeMarkers
*
* @author 00fly
* @version [版本号, 2017-4-4]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
public class FreeMarkerUtil
{
private static Configuration config;
static
{
config = new Configuration(Configuration.VERSION_2_3_32);
config.setDefaultEncoding(StandardCharsets.UTF_8.name());
}
/**
* 获取模板填充model解析后的内容
*
* @param template
* @param model
* @return
* @throws IOException
* @throws TemplateException
* @see [类、类#方法、类#成员]
*/
private static String renderTemplate(Template template, Map<String, Object> model)
throws TemplateException, IOException
{
StringWriter result = new StringWriter();
template.process(model, result);
return result.toString();
}
/**
* 获取模板填充model后的内容
*
* @param templatePath
* @param model
* @return
* @throws IOException
* @throws TemplateException
* @see [类、类#方法、类#成员]
*/
public static String renderTemplate(String templatePath, Map<String, Object> model)
throws TemplateException, IOException
{
config.setClassForTemplateLoading(FreeMarkerUtil.class, "/");
Template template = config.getTemplate(templatePath);
return renderTemplate(template, model);
}
}
Executor
java
package com.fly.simple;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
public class Executor
{
/**
* execute命令
*
* @param command
* @throws IOException
* @see [类、类#方法、类#成员]
*/
public static List<String> execute(String command)
throws IOException
{
List<String> resultList = new ArrayList<>();
String[] cmd = SystemUtils.IS_OS_WINDOWS ? new String[] {"cmd", "/c", command} : new String[] {"/bin/sh", "-c", command};
Process ps = Runtime.getRuntime().exec(cmd);
try (InputStream in = ps.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)))
{
String line;
while ((line = br.readLine()) != null)
{
resultList.add(line);
}
}
return resultList;
}
public static Map<String, Set<String>> getDockerInfo()
throws IOException
{
String dockerCmd = "docker ps --format \"{{.Names}} {{.Ports}}\"";
Map<String, Set<String>> map = new TreeMap<>();
execute(dockerCmd).stream()
.map(line -> Collections.singletonMap(StringUtils.substringBefore(line, " "),
Stream.of(StringUtils.substringAfter(line, " ").split(",")).map(p -> StringUtils.substringBetween(p, ":", "->")).filter(StringUtils::isNotBlank).map(p -> p.replace(":", "")).sorted().collect(Collectors.toSet())))
.forEach(it -> map.putAll(it));
return map;
}
}
TemplateRun
java
package com.fly.simple;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import com.fly.simple.utils.FreeMarkerUtil;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TemplateRun
{
public static void main(String[] args)
throws IOException, TemplateException, InterruptedException
{
// Jar运行,必须提供参数server.net.ip
URL url = TemplateRun.class.getProtectionDomain().getCodeSource().getLocation();
log.info("path: {}", url.getPath());
String ip = null;
if (url.getPath().endsWith(".jar"))
{
if (args.length > 0)
{
ip = Stream.of(args).filter(arg -> arg.contains("--server.net.ip")).map(arg -> StringUtils.substringAfter(arg, "=")).collect(Collectors.joining());
log.info("server.net.ip={}", ip);
}
if (StringUtils.isBlank(ip))
{
log.error("please start jar like:\n java -jar docker-show-jar-with-dependencies.jar --server.net.ip=124.71.129.204");
return;
}
}
// 写入文件
if (SystemUtils.IS_OS_WINDOWS)
{
File file = new File("index.html");
creatPage(ip, file);
// 打开页面10秒后删除文件
Runtime.getRuntime().exec("cmd /c start /min " + file.getCanonicalPath());
TimeUnit.SECONDS.sleep(10);
file.deleteOnExit();
return;
}
if (SystemUtils.IS_OS_LINUX)
{
// crontab -e
// */30 * * * * java -jar /work/gitcode/docker-run/docker-show-jar-with-dependencies.jar --server.net.ip=124.71.129.204
creatPage(ip, new File("/usr/share/nginx/html/index.html"));
}
}
private static void creatPage(String ip, File file)
throws IOException, TemplateException
{
// 收集docker信息
Map<String, Object> model = new HashMap<>(3);
model.put("date", new Date());
model.put("map", Executor.getDockerInfo());
model.put("ip", StringUtils.defaultIfBlank(ip, "127.0.0.1"));
// {mysql5=[3306, 13306], mysql8=[23306], redis-server=[6379]}
String content = FreeMarkerUtil.renderTemplate("/templates/index.html.ftl", model);
try (FileWriter writer = new FileWriter(file))
{
writer.write(content);
writer.flush();
}
}
}
4. 项目打包
执行mvn clean package
会在项目target 生成可执行包
5.部署步骤
将docker-show-jar-with-dependencies.jar
拷贝到服务器位置 /work/gitcode/docker-run
输入crontab -e
添加如下内容,实现每30分钟执行一次生成页面,并复制到nginx首页位置/usr/share/nginx/html/index.html
bash
*/30 * * * * java -jar /work/gitcode/docker-run/docker-show-jar-with-dependencies.jar --server.net.ip=124.71.129.204
这边的124.71.129.204为服务器ip。
有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!
-over-