Skip to content

Commit

Permalink
support toml
Browse files Browse the repository at this point in the history
  • Loading branch information
YeautyYE committed Nov 12, 2019
1 parent 2b916a3 commit 60a4fcd
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 68 deletions.
24 changes: 14 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,20 @@

点击此处下载:[最新稳定版](https://github.com/YeautyYE/nacos-nginx-template/releases/)

2. #### 配置config.properties

| 参数 | 描述 | 例子 |
| ------------------------ | ---------------------------------------------- | ----------------------------------------------------- |
| nginx.cmd | nginx命令的全路径 | /usr/sbin/nginx |
| nacos.addr | nacos的地址 | 172.16.0.100:8848,172.16.0.101:8848,172.16.0.102:8848 |
| reload-interval | nginx reload命令执行间隔时间(ms 默认值1000) | 1000 |
| nacos.service-name.{num} | nacos服务名; {num}从0开始递增 | com.nacos.service.impl.NacosService |
| nginx.config.{num} | 需要修改nginx配置的路径;{num}从0开始递增 | /etc/nginx/nginx.conf |
| nginx.proxy-pass.{num} | nginx中proxy_pass的名字;{num}从0开始递增 | nacos-service |
2. #### 配置config.toml

配置文件使用[TOML](<https://github.com/toml-lang/toml>)进行配置

demo : {nacos-nginx-template.home}/conf/config.toml.example

| 参数 | 描述 | 例子 |
| ------------------ | ---------------------------------------------- | ------------------------------------------------------- |
| nginx_cmd | nginx命令的全路径 | "/usr/sbin/nginx" |
| nacos_addr | nacos的地址 | "172.16.0.100:8848,172.16.0.101:8848,172.16.0.102:8848" |
| reload_interval | nginx reload命令执行间隔时间(ms 默认值1000) | 1000 |
| nacos_service_name | nacos服务名 | "com.nacos.service.impl.NacosService" |
| nginx_config | 需要修改nginx配置的路径 | "/etc/nginx/nginx.conf" |
| nginx_upstream | nginx中upstream的名字 | "nacos-service" |

3. #### 启动

Expand Down
7 changes: 6 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.yeauty</groupId>
<artifactId>nacos-nginx-template</artifactId>
<version>0.5.0</version>
<version>0.6.0</version>

<properties>
<java.version>1.8</java.version>
Expand All @@ -30,6 +30,11 @@
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.tomlj</groupId>
<artifactId>tomlj</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>

<build>
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/org/yeauty/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.alibaba.nacos.api.exception.NacosException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tomlj.Toml;
import org.tomlj.TomlParseResult;
import org.yeauty.service.MonitorService;
import org.yeauty.service.StartupService;
import org.yeauty.service.impl.MonitorServiceImpl;
Expand All @@ -11,6 +13,8 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

Expand All @@ -26,6 +30,7 @@ public static void main(String[] args) throws IOException, InterruptedException,
if (configPath == null || "".equals(configPath.trim())) {
throw new IllegalArgumentException("config is empty");
}

//判断config是否存在
File file = new File(configPath);
if (!file.exists()) {
Expand All @@ -36,9 +41,16 @@ public static void main(String[] args) throws IOException, InterruptedException,
throw new FileNotFoundException("config is not a file");
}

Path source = Paths.get(configPath);
TomlParseResult result = Toml.parse(source);
if (result.hasErrors()) {
result.errors().forEach(error -> System.err.println(error.toString()));
throw new InterruptedException();
}

//开始进行监听
MonitorService monitorService = new MonitorServiceImpl();
monitorService.updateNginxFromNacos(file);
monitorService.updateNginxFromNacos(result);

logger.info("nacos-nginx-template start up!");

Expand Down
16 changes: 8 additions & 8 deletions src/main/java/org/yeauty/pojo/DiscoverConfigBO.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
public class DiscoverConfigBO {

private String configPath;
private String proxyPass;
private String upstream;
private String serviceName;

public DiscoverConfigBO(String configPath, String proxyPass, String serviceName) {
public DiscoverConfigBO(String configPath, String upstream, String serviceName) {
this.configPath = configPath;
this.proxyPass = proxyPass;
this.upstream = upstream;
this.serviceName = serviceName;
}

@Override
public String toString() {
return "DiscoverConfigBO{" +
"configPath='" + configPath + '\'' +
", proxyPass='" + proxyPass + '\'' +
", upstream='" + upstream + '\'' +
", serviceName='" + serviceName + '\'' +
'}';
}
Expand All @@ -29,12 +29,12 @@ public void setConfigPath(String configPath) {
this.configPath = configPath;
}

public String getProxyPass() {
return proxyPass;
public String getUpstream() {
return upstream;
}

public void setProxyPass(String proxyPass) {
this.proxyPass = proxyPass;
public void setUpstream(String upstream) {
this.upstream = upstream;
}

public String getServiceName() {
Expand Down
17 changes: 9 additions & 8 deletions src/main/java/org/yeauty/service/MonitorService.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.yeauty.service;

import com.alibaba.nacos.api.exception.NacosException;
import org.tomlj.TomlParseResult;

import java.io.File;
import java.io.IOException;

public interface MonitorService {
Expand All @@ -12,12 +12,13 @@ public interface MonitorService {
String UPSTREAM_REG = "upstream\\s*" + PLACEHOLDER + "\\s*\\{[^}]+\\}";
String UPSTREAM_FOMAT = "upstream " + PLACEHOLDER + " {\n" + PLACEHOLDER_SERVER + "}";

String NGINX_CMD = "nginx.cmd";
String NGINX_CONFIG = "nginx.config";
String NGINX_PROXY_PASS = "nginx.proxy-pass";
String NACOS_ADDR = "nacos.addr";
String NACOS_SERVICE_NAME = "nacos.service-name";
String RELOAD_INTERVAL = "reload-interval";
String NGINX_CMD = "nginx_cmd";
String NACOS_ADDR = "nacos_addr";

void updateNginxFromNacos(File configFile) throws IOException, InterruptedException, NacosException;
String NGINX_CONFIG = "nginx_config";
String NGINX_UPSTREAM = "nginx_upstream";
String NACOS_SERVICE_NAME = "nacos_service_name";
String RELOAD_INTERVAL = "reload_interval";

void updateNginxFromNacos(TomlParseResult result) throws IOException, InterruptedException, NacosException;
}
95 changes: 55 additions & 40 deletions src/main/java/org/yeauty/service/impl/MonitorServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tomlj.TomlInvalidTypeException;
import org.tomlj.TomlParseResult;
import org.yeauty.pojo.DiscoverConfigBO;
import org.yeauty.service.MonitorService;

Expand All @@ -16,7 +18,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Matcher;
Expand All @@ -31,14 +33,19 @@ public class MonitorServiceImpl implements MonitorService {
private AtomicLong lastReloadTime = new AtomicLong(0);

@Override
public void updateNginxFromNacos(File configFile) throws IOException, InterruptedException, NacosException {
Properties pro = new Properties();
FileInputStream in = new FileInputStream(configFile);
pro.load(in);
in.close();
public void updateNginxFromNacos(TomlParseResult tomlParseResult) throws IOException, InterruptedException, NacosException {

boolean containNginxCmd = tomlParseResult.contains(NGINX_CMD);
boolean containNacosAddr = tomlParseResult.contains(NACOS_ADDR);
if (!containNginxCmd) {
throw new IllegalArgumentException(NGINX_CMD + " is no such");
}
if (!containNacosAddr) {
throw new IllegalArgumentException(NACOS_ADDR + " is no such");
}

//判断nginx的指令是否可用
String cmd = pro.getProperty(NGINX_CMD);
String cmd = tomlParseResult.getString(NGINX_CMD);
if (StringUtils.isEmpty(cmd)) {
throw new IllegalArgumentException(NGINX_CMD + " is empty");
}
Expand All @@ -54,7 +61,7 @@ public void updateNginxFromNacos(File configFile) throws IOException, Interrupte
}

//判断nacos地址
String nacosAddr = pro.getProperty(NACOS_ADDR);
String nacosAddr = tomlParseResult.getString(NACOS_ADDR);
if (StringUtils.isEmpty(nacosAddr)) {
throw new IllegalArgumentException(NACOS_ADDR + " is empty");
}
Expand All @@ -63,19 +70,24 @@ public void updateNginxFromNacos(File configFile) throws IOException, Interrupte
//获取配置项
List<DiscoverConfigBO> list = new ArrayList<>();
int num = 0;
while (true) {
String configPath = pro.getProperty(NGINX_CONFIG + "." + num);
String proxyPass = pro.getProperty(NGINX_PROXY_PASS + "." + num);
String serviceName = pro.getProperty(NACOS_SERVICE_NAME + "." + num);
if (StringUtils.isEmpty(configPath) || StringUtils.isEmpty(proxyPass) || StringUtils.isEmpty(serviceName)) {
break;
}
DiscoverConfigBO discoverConfigBO = new DiscoverConfigBO(configPath, proxyPass, serviceName);
list.add(discoverConfigBO);
num++;
}
Set<String> groupNames = tomlParseResult.keySet();
groupNames.stream()
.filter(groupName -> !groupName.equals(NGINX_CMD) && !groupName.equals(NACOS_ADDR) && !groupName.equals(RELOAD_INTERVAL))
.forEach(groupName -> {
String configPath = tomlParseResult.getString(groupName + "." + NGINX_CONFIG);
String upstream = tomlParseResult.getString(groupName + "." + NGINX_UPSTREAM);
String serviceName = tomlParseResult.getString(groupName + "." + NACOS_SERVICE_NAME);
if (StringUtils.isEmpty(configPath) || StringUtils.isEmpty(upstream) || StringUtils.isEmpty(serviceName)) {
logger.warn("group_name:{} . {} or {} or {} is empty", groupName, NGINX_CONFIG, NGINX_UPSTREAM, NACOS_SERVICE_NAME);
return;
}
DiscoverConfigBO discoverConfigBO = new DiscoverConfigBO(configPath, upstream, serviceName);
list.add(discoverConfigBO);
logger.info("add config success , group_name:{} ", groupName);
});

if (list.size() == 0) {
throw new IllegalArgumentException(NGINX_CONFIG + "," + NGINX_PROXY_PASS + "," + NACOS_SERVICE_NAME + " are at least one group exists ");
throw new IllegalArgumentException(NGINX_CONFIG + "," + NGINX_UPSTREAM + "," + NACOS_SERVICE_NAME + " are at least one group exists ");
}

//开始监听nacos
Expand All @@ -84,10 +96,12 @@ public void updateNginxFromNacos(File configFile) throws IOException, Interrupte
event -> {
try {
List<Instance> instances = namingService.getAllInstances(configBO.getServiceName());
//更新nginx中的proxy_pass
refreshProxyPass(instances, configBO.getProxyPass(), configBO.getConfigPath());
lastReloadTime.set(System.currentTimeMillis());
logger.info("proxy_pass:{} update success!", configBO.getServiceName());
//更新nginx中的upstream
boolean updated = refreshUpstream(instances, configBO.getUpstream(), configBO.getConfigPath());
if (updated) {
lastReloadTime.set(System.currentTimeMillis());
logger.info("upstream:{} update success!", configBO.getServiceName());
}
} catch (Exception e) {
e.printStackTrace();
}
Expand All @@ -97,12 +111,13 @@ public void updateNginxFromNacos(File configFile) throws IOException, Interrupte

//开启线程定时reload
new Thread(() -> {
String intervalStr = pro.getProperty(RELOAD_INTERVAL);
long interval = 1000;
try {
interval = Long.parseLong(intervalStr);
} catch (NumberFormatException e) {
logger.warn("incorrect parameter :{} ", RELOAD_INTERVAL);
if (tomlParseResult.contains(RELOAD_INTERVAL)) {
try {
interval = tomlParseResult.getLong(RELOAD_INTERVAL);
} catch (TomlInvalidTypeException e) {
logger.warn("incorrect parameter :{} ", RELOAD_INTERVAL);
}
}
while (true) {
if (lastReloadTime.get() == 0L || (System.currentTimeMillis() - lastReloadTime.get()) < interval) {
Expand Down Expand Up @@ -138,18 +153,17 @@ public void updateNginxFromNacos(File configFile) throws IOException, Interrupte

}

private void refreshProxyPass(List<Instance> instances, String nginxProxyPass, String nginxConfigPath) {
//获取到proxy_pass对应的upstream
Pattern pattern = Pattern.compile(UPSTREAM_REG.replace(PLACEHOLDER, nginxProxyPass));
private boolean refreshUpstream(List<Instance> instances, String nginxUpstream, String nginxConfigPath) {
//获取到upstream
Pattern pattern = Pattern.compile(UPSTREAM_REG.replace(PLACEHOLDER, nginxUpstream));
//判断文件是否存在
File file = new File(nginxConfigPath);
if (!file.exists() || !file.isFile()) {
throw new IllegalArgumentException("file : " + nginxConfigPath + " is not exists or not a file");
}
Long length = file.length();
byte[] bytes = new byte[length.intValue()];
try {
FileInputStream fileInputStream = new FileInputStream(file);
try (FileInputStream fileInputStream = new FileInputStream(file)) {
fileInputStream.read(bytes);
} catch (IOException e) {
e.printStackTrace();
Expand All @@ -170,7 +184,7 @@ private void refreshProxyPass(List<Instance> instances, String nginxProxyPass, S
}

//拼接新的upstream
String newUpstream = UPSTREAM_FOMAT.replace(PLACEHOLDER, nginxProxyPass);
String newUpstream = UPSTREAM_FOMAT.replace(PLACEHOLDER, nginxUpstream);
StringBuffer servers = new StringBuffer();
if (instances.size() > 0) {
for (Instance instance : instances) {
Expand All @@ -189,19 +203,20 @@ private void refreshProxyPass(List<Instance> instances, String nginxProxyPass, S
}
servers.append(formatSymbol);
newUpstream = newUpstream.replace(PLACEHOLDER_SERVER, servers.toString());

if (oldUpstream.equals(newUpstream)) {
return false;
}
//替换原有的upstream
conf = matcher.replaceAll(newUpstream);
} else {
throw new IllegalArgumentException("can not found proxy_pass:" + nginxProxyPass);
throw new IllegalArgumentException("can not found upstream:" + nginxUpstream);
}
try {
FileWriter fileWriter = new FileWriter(file, false);
try (FileWriter fileWriter = new FileWriter(file, false)) {
fileWriter.write(conf);
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}

0 comments on commit 60a4fcd

Please sign in to comment.