Skip to content
Permalink
Browse files
Support healthcheck and depends_on condition (#221)
  • Loading branch information
kylixs committed Jan 6, 2021
1 parent bec0c0e commit 55faef35061d8f31315af76d83e28071c1ac04aa
Show file tree
Hide file tree
Showing 19 changed files with 285 additions and 115 deletions.
@@ -21,13 +21,17 @@

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.concurrent.CountDownLatch;

public class AsyncProvider {

public static void main(String[] args) throws Exception {
new EmbeddedZooKeeper(2181, false).start();
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/async-provider.xml"});
context.start();
System.in.read();

System.out.println("dubbo service started");
new CountDownLatch(1).await();
}

}
@@ -26,7 +26,9 @@ services:
- apollo.port=8080
waitPortsBeforeRun:
- apollo-quick-start:8080
checkTimeout: 100
waitTimeout: 100
depends_on:
- apollo-db

dubbo-samples-configcenter-apollo-test:
type: test
@@ -41,17 +43,17 @@ services:
waitPortsBeforeRun:
- dubbo-samples-configcenter-apollo:2181
- dubbo-samples-configcenter-apollo:20880
checkTimeout: 100
waitTimeout: 100
depends_on:
- dubbo-samples-configcenter-apollo

apollo-quick-start:
image: nobodyiam/apollo-quick-start
depends_on:
- apollo-db
# ports:
# - "8080:8080"
# - "8070:8070"
expose:
- 8080
- 8070
links:
- apollo-db

@@ -60,8 +62,14 @@ services:
environment:
- TZ=Asia/Shanghai
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
# ports:
# - "13306:3306"
expose:
- 3306
healthcheck:
# mysql host MUST be ip address, if the host is localhost, may connect via socket file, the port will be ignored
test: ["CMD", "mysqladmin" ,"ping", "-h", "127.0.0.1"]
interval: 5s
timeout: 5s
retries: 20
volumes:
- ${_basedir}/src/main/resources/docker/sql:/docker-entrypoint-initdb.d
# - ./sql_data:/var/lib/mysql
@@ -31,6 +31,7 @@ public static void main(String[] args) throws InterruptedException {
new EmbeddedZooKeeper(2181, true).start();
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-demo.xml");
context.start();
System.out.println("dubbo service started");

DemoService demoService = context.getBean("demoService", DemoService.class);
String hello = demoService.sayHello("world");
@@ -21,10 +21,15 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

import java.util.concurrent.CountDownLatch;

@SpringBootApplication
public class ProviderApp {

public static void main(String[] args) {
public static void main(String[] args) throws Exception {
new SpringApplicationBuilder(ProviderApp.class).web(WebApplicationType.NONE).run(args);

System.out.println("dubbo service started");
new CountDownLatch(1).await();
}
}
@@ -22,13 +22,17 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.concurrent.CountDownLatch;

public class RestProvider {

public static void main(String[] args) throws Exception {
new EmbeddedZooKeeper(2181, false).start();
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/rest-provider.xml"});
context.start();
System.in.read();

System.out.println("dubbo service started");
new CountDownLatch(1).await();
}

@Configuration
@@ -19,29 +19,29 @@ props:
zookeeper_port: 2181

services:
${project_name}:
dubbo-samples-spi-compatible:
type: app
basedir: .
mainClass: org.apache.dubbo.samples.basic.SpiCompatibleProvider
systemProps:
- zookeeper.address=127.0.0.1
- zookeeper.port=${zookeeper_port}
checkPortsAfterRun:
- ${zookeeper_port}
- zookeeper.port=2181
checkPorts:
- 2181
checkLog: "dubbo service started"

${project_name}-test:
dubbo-samples-spi-compatible-test:
type: test
basedir: .
tests:
- "**/*IT.class"
systemProps:
- zookeeper.address=${project_name}
- zookeeper.port=${zookeeper_port}
- dubbo.address=${project_name}
- zookeeper.address=dubbo-samples-spi-compatible
- zookeeper.port=2181
- dubbo.address=dubbo-samples-spi-compatible
waitPortsBeforeRun:
- ${project_name}:${zookeeper_port}
- dubbo-samples-spi-compatible:2181
# Disable Dubbo port check due to Dubbo-Samples-SPI-Compatible implements a new protocol ---- CompatibleProtocol
# CompatibleProtocol will not expose a port and port check is invalid for it
depends_on:
- ${project_name}
- dubbo-samples-spi-compatible
@@ -34,6 +34,12 @@ services:
- 3306
volumes:
- ${_basedir}/src/main/resources/docker/mysql/sql:/docker-entrypoint-initdb.d
healthcheck:
# mysql host MUST be ip address, if the host is localhost, may connect via socket file, the port will be ignored
test: ["CMD", "mysqladmin" ,"ping", "-h", "127.0.0.1"]
interval: 5s
timeout: 5s
retries: 20

seata-server:
#build: ${_basedir}/src/main/resources/docker/seata
@@ -101,4 +107,8 @@ services:
- storage-service:20882
- account-service:20881
- order-service:20883
depends_on:
- order-service
- account-service
- storage-service

@@ -33,6 +33,7 @@
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -53,9 +54,9 @@ public class ConfigurationImpl implements IConfiguration {
public static final String ENV_SERVICE_TYPE = "SERVICE_TYPE";
public static final String ENV_APP_MAIN_CLASS = "APP_MAIN_CLASS";
public static final String ENV_WAIT_PORTS_BEFORE_RUN = "WAIT_PORTS_BEFORE_RUN";
public static final String ENV_CHECK_PORTS_AFTER_RUN = "CHECK_PORTS_AFTER_RUN";
public static final String ENV_CHECK_PORTS = "CHECK_PORTS";
public static final String ENV_CHECK_LOG = "CHECK_LOG";
public static final String ENV_CHECK_TIMEOUT = "CHECK_TIMEOUT";
public static final String ENV_WAIT_TIMEOUT = "WAIT_TIMEOUT";
public static final String ENV_TEST_PATTERNS = "TEST_PATTERNS";
public static final String ENV_JAVA_OPTS = "JAVA_OPTS";
public static final String ENV_DEBUG_OPTS = "DEBUG_OPTS";
@@ -76,6 +77,7 @@ public class ConfigurationImpl implements IConfiguration {
private int javaDebugPort = 20660;
private int debugTimeout = 36000;
private Set<String> debugServices = new HashSet<>();
private Set<String> healthcheckServices = new HashSet<>();

public ConfigurationImpl() throws IOException, ConfigureFileNotFoundException {
String configureFile = System.getProperty("configure.file");
@@ -252,7 +254,7 @@ private void fillupServices(CaseConfiguration caseConfiguration) throws IOExcept

//set check timeout
if (isDebug()) {
service.setCheckTimeout(debugTimeout);
service.setWaitTimeout(debugTimeout);

if (debugServices.contains(serviceName)) {
//set java remote debug opts
@@ -268,8 +270,8 @@ private void fillupServices(CaseConfiguration caseConfiguration) throws IOExcept
service.getPorts().add(debugPort + ":" + debugPort);
}
}
if (service.getCheckTimeout() > 0) {
setEnv(service, ENV_CHECK_TIMEOUT, service.getCheckTimeout() + "");
if (service.getWaitTimeout() > 0) {
setEnv(service, ENV_WAIT_TIMEOUT, service.getWaitTimeout() + "");
}

if ("app".equals(type)) {
@@ -284,15 +286,32 @@ private void fillupServices(CaseConfiguration caseConfiguration) throws IOExcept
//set SCENARIO_HOME
setEnv(service, ENV_SCENARIO_HOME, scenarioHome);

boolean addHealthcheck = false;
//set check_log env
if (StringUtils.isNotBlank(service.getCheckLog())) {
addHealthcheck = true;
setEnv(service, ENV_CHECK_LOG, service.getCheckLog());
}

//set check ports
if (isNotEmpty(service.getCheckPortsAfterRun())) {
String str = convertAddrPortsToString(service.getCheckPortsAfterRun());
setEnv(service, ENV_CHECK_PORTS_AFTER_RUN, str);
if (isNotEmpty(service.getCheckPorts())) {
addHealthcheck = true;
String str = convertAddrPortsToString(service.getCheckPorts());
setEnv(service, ENV_CHECK_PORTS, str);
}

//add healthcheck
if (addHealthcheck) {
if (service.getHealthcheck() == null) {
Map<String, Object> healthcheckMap = new LinkedHashMap<>();
service.setHealthcheck(healthcheckMap);
}
Map<String, Object> healthcheck = service.getHealthcheck();
healthcheck.putIfAbsent("test", Arrays.asList("CMD", "/usr/local/dubbo/healthcheck.sh"));
healthcheck.putIfAbsent("interval", "5s");
healthcheck.putIfAbsent("timeout", "5s");
healthcheck.putIfAbsent("retries", 20);
healthcheck.putIfAbsent("start_period", "60s");
}
} else if ("test".equals(type)) {
String mainClass = service.getMainClass();
@@ -330,6 +349,9 @@ private void fillupServices(CaseConfiguration caseConfiguration) throws IOExcept
appendEnv(service, ENV_JAVA_OPTS, str);
}

if (service.getHealthcheck() != null) {
healthcheckServices.add(serviceName);
}
}
}

@@ -579,12 +601,36 @@ protected List<DockerService> convertDockerServices(final String version,
service.setHostname(dependency.getHostname());
service.setExpose(dependency.getExpose());
service.setPorts(dependency.getPorts());
service.setDepends_on(dependency.getDepends_on());
service.setLinks(dependency.getDepends_on());
service.setEntrypoint(dependency.getEntrypoint());
service.setHealthcheck(dependency.getHealthcheck());
service.setLinks(dependency.getDepends_on());

//convert depends_on to map
if (dependency.getDepends_on() != null) {
Map<String, String> dependsOnMap = new LinkedHashMap<>();
service.setDepends_on(dependsOnMap);
for (String serviceName : dependency.getDepends_on()) {
if (healthcheckServices.contains(serviceName)) {
dependsOnMap.put(serviceName, "{condition: service_healthy}");
} else {
dependsOnMap.put(serviceName, "{condition: service_started}");
}
}
}

//convert healthcheck to string map
if (dependency.getHealthcheck() != null) {
Yaml yaml = new Yaml();
Map<String, Object> healthcheckMap = dependency.getHealthcheck();
Map<String, String> newMap = new LinkedHashMap<>();
for (Map.Entry<String, Object> entry : healthcheckMap.entrySet()) {
String value = yaml.dump(entry.getValue());
newMap.put(entry.getKey(), value.trim());
}
service.setHealthcheck(newMap);
}
service.setEnvironment(dependency.getEnvironment());
service.setVolumes(dependency.getVolumes());
service.setVolumes_from(dependency.getVolumes_from());
service.setRemoveOnExit(dependency.isRemoveOnExit());
services.add(service);
});
@@ -18,6 +18,7 @@
package org.apache.dubbo.scenario.builder.vo;

import java.util.List;
import java.util.Map;

public class DockerService {
private String name;
@@ -30,10 +31,11 @@ public class DockerService {
private List<String> expose;
private List<String> ports;
private List<String> entrypoint;
private List<String> healthcheck;
private List<String> depends_on;
private Map<String, String> healthcheck;
private Map<String, String> depends_on;
private List<String> environment;
private List<String> volumes;
private List<String> volumes_from;

public String getName() {
return name;
@@ -99,19 +101,19 @@ public void setEntrypoint(List<String> entrypoint) {
this.entrypoint = entrypoint;
}

public List<String> getHealthcheck() {
public Map<String, String> getHealthcheck() {
return healthcheck;
}

public void setHealthcheck(List<String> healthcheck) {
public void setHealthcheck(Map<String, String> healthcheck) {
this.healthcheck = healthcheck;
}

public List<String> getDepends_on() {
public Map<String, String> getDepends_on() {
return depends_on;
}

public void setDepends_on(List<String> depends_on) {
public void setDepends_on(Map<String, String> depends_on) {
this.depends_on = depends_on;
}

@@ -131,6 +133,14 @@ public void setVolumes(List<String> volumes) {
this.volumes = volumes;
}

public List<String> getVolumes_from() {
return volumes_from;
}

public void setVolumes_from(List<String> volumes_from) {
this.volumes_from = volumes_from;
}

public List<String> getPorts() {
return ports;
}
@@ -155,6 +165,7 @@ public String toString() {
", depends_on=" + depends_on +
", environment=" + environment +
", volumes=" + volumes +
", volumes_from=" + volumes_from +
'}';
}
}

0 comments on commit 55faef3

Please sign in to comment.