This is an automated email from the ASF dual-hosted git repository. victory pushed a commit to branch samples-for-2.7.0-SNAPSHOT in repository https://gitbox.apache.org/repos/asf/incubator-dubbo-samples.git
commit 4cc70290677c1789fdf6222f2a0e967cc8197f2f Author: cvictory <shenglic...@gmail.com> AuthorDate: Wed Dec 26 14:18:04 2018 +0800 init resilience4j project --- dubbo-samples-resilience4j/README.md | 17 ++ .../dubbo-samples-resilience4j-filter/README.md | 17 ++ .../dubbo-samples-resilience4j-filter/pom.xml | 75 ++++++ .../samples/resilience4j/AnnotationConsumer.java | 63 +++++ .../samples/resilience4j/AnnotationProvider.java | 61 +++++ .../samples/resilience4j/EmbeddedZooKeeper.java | 255 +++++++++++++++++++++ .../resilience4j/action/AnnotationAction.java | 46 ++++ .../resilience4j/api/AnnotationService.java | 29 +++ .../filter/Resilience4jCircuitBreakerFilter.java | 42 ++++ .../resilience4j/impl/AnnotationServiceImpl.java | 40 ++++ .../src/main/resources/log4j.properties | 26 +++ .../resources/spring/dubbo-consumer.properties | 22 ++ .../resources/spring/dubbo-provider.properties | 23 ++ .../README.md | 17 ++ .../dubbo-samples-resilience4j-springboot2/pom.xml | 75 ++++++ .../samples/resilience4j/AnnotationConsumer.java | 63 +++++ .../samples/resilience4j/AnnotationProvider.java | 61 +++++ .../samples/resilience4j/EmbeddedZooKeeper.java | 255 +++++++++++++++++++++ .../resilience4j/action/AnnotationAction.java | 46 ++++ .../resilience4j/api/AnnotationService.java | 29 +++ .../filter/Resilience4jCircuitBreakerFilter.java | 42 ++++ .../resilience4j/impl/AnnotationServiceImpl.java | 40 ++++ .../src/main/resources/log4j.properties | 26 +++ .../resources/spring/dubbo-consumer.properties | 22 ++ .../resources/spring/dubbo-provider.properties | 23 ++ dubbo-samples-resilience4j/pom.xml | 43 ++++ .../samples/resilience4j/AnnotationConsumer.java | 63 +++++ .../samples/resilience4j/AnnotationProvider.java | 61 +++++ .../samples/resilience4j/EmbeddedZooKeeper.java | 255 +++++++++++++++++++++ .../resilience4j/action/AnnotationAction.java | 46 ++++ .../resilience4j/api/AnnotationService.java | 29 +++ .../filter/Resilience4jCircuitBreakerFilter.java | 42 ++++ .../resilience4j/impl/AnnotationServiceImpl.java | 40 ++++ .../src/main/resources/log4j.properties | 26 +++ .../resources/spring/dubbo-consumer.properties | 22 ++ .../resources/spring/dubbo-provider.properties | 23 ++ pom.xml | 1 + 37 files changed, 2066 insertions(+) diff --git a/dubbo-samples-resilience4j/README.md b/dubbo-samples-resilience4j/README.md new file mode 100644 index 0000000..12c735e --- /dev/null +++ b/dubbo-samples-resilience4j/README.md @@ -0,0 +1,17 @@ +## dubbo spring hystrix sample + +### Start Provider + +Run `org.apache.dubbo.samples.annotation.AnnotationProvider` + + +### Start Consumer + +Run `org.apache.dubbo.samples.annotation.AnnotationConsumer` + +### Result + +0. Start provider +0. Start consumer +0. The provider print `java.lang.RuntimeException: Exception to show hystrix enabled`. The exception stack conatins hystrix command info. +0. The consumer print `result :hystrix fallback value`, which means hystrix fallback configuration is effect. diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/README.md b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/README.md new file mode 100644 index 0000000..12c735e --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/README.md @@ -0,0 +1,17 @@ +## dubbo spring hystrix sample + +### Start Provider + +Run `org.apache.dubbo.samples.annotation.AnnotationProvider` + + +### Start Consumer + +Run `org.apache.dubbo.samples.annotation.AnnotationConsumer` + +### Result + +0. Start provider +0. Start consumer +0. The provider print `java.lang.RuntimeException: Exception to show hystrix enabled`. The exception stack conatins hystrix command info. +0. The consumer print `result :hystrix fallback value`, which means hystrix fallback configuration is effect. diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/pom.xml b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/pom.xml new file mode 100644 index 0000000..f7b6552 --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/pom.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>dubbo-samples-all</artifactId> + <groupId>org.apache.dubbo</groupId> + <version>1.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>dubbo-samples-resilience4j-filter</artifactId> + + <properties> + <resilience4j.version>0.13.1</resilience4j.version> + </properties> + + + <dependencies> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-circuitbreaker</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-ratelimiter</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-retry</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-bulkhead</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-cache</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-timelimiter</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + </dependency> + </dependencies> +</project> diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationConsumer.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationConsumer.java new file mode 100644 index 0000000..d74b20a --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationConsumer.java @@ -0,0 +1,63 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j; + +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import io.github.resilience4j.circuitbreaker.utils.CircuitBreakerUtils; +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; +import org.apache.dubbo.samples.resilience4j.action.AnnotationAction; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.context.annotation.PropertySource; + +/** + * CallbackConsumer + */ +public class AnnotationConsumer { + + public static void main(String[] args) throws Exception { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class); + context.start(); + final AnnotationAction annotationAction = (AnnotationAction) context.getBean("annotationAction"); + String hello = annotationAction.doSayHello("world"); + System.err.println("result :" + hello); + System.in.read(); + } + + @Configuration + @EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.resilience4j.action") + @PropertySource("classpath:/spring/dubbo-consumer.properties") + @ComponentScan(value = {"org.apache.dubbo.samples.resilience4j.action"}) + @EnableAspectJAutoProxy + static public class ConsumerConfiguration { + +// @Bean +// public HystrixCommandAspect hystrixCommandAspect() { +// return new HystrixCommandAspect(); +// } + + } + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationProvider.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationProvider.java new file mode 100644 index 0000000..be7715d --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationProvider.java @@ -0,0 +1,61 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j; + + +import org.apache.dubbo.config.ProviderConfig; +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.context.annotation.PropertySource; + +/** + * MergeProvider + */ +public class AnnotationProvider { + + public static void main(String[] args) throws Exception { + new EmbeddedZooKeeper(2181, false).start(); + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class); + context.start(); + System.in.read(); + } + + @Configuration + @EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.resilience4j.impl") + @PropertySource("classpath:/spring/dubbo-provider.properties") + @EnableAspectJAutoProxy + static public class ProviderConfiguration { + @Bean + public ProviderConfig providerConfig() { + ProviderConfig providerConfig = new ProviderConfig(); + providerConfig.setTimeout(1000); + return providerConfig; + } + +// @Bean +// public HystrixCommandAspect hystrixCommandAspect() { +// return new HystrixCommandAspect(); +// } + } + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/EmbeddedZooKeeper.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/EmbeddedZooKeeper.java new file mode 100644 index 0000000..9c8ae8a --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/EmbeddedZooKeeper.java @@ -0,0 +1,255 @@ +/* + * Copyright 2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.samples.resilience4j; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.Properties; +import java.util.UUID; + +import org.apache.zookeeper.server.ServerConfig; +import org.apache.zookeeper.server.ZooKeeperServerMain; +import org.apache.zookeeper.server.quorum.QuorumPeerConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.SmartLifecycle; +import org.springframework.util.ErrorHandler; +import org.springframework.util.SocketUtils; + +/** + * from: https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java + * + * Helper class to start an embedded instance of standalone (non clustered) ZooKeeper. + * + * NOTE: at least an external standalone server (if not an ensemble) are recommended, even for + * {@link org.springframework.xd.dirt.server.singlenode.SingleNodeApplication} + * + * @author Patrick Peralta + * @author Mark Fisher + * @author David Turanski + */ +public class EmbeddedZooKeeper implements SmartLifecycle { + + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(EmbeddedZooKeeper.class); + + /** + * ZooKeeper client port. This will be determined dynamically upon startup. + */ + private final int clientPort; + + /** + * Whether to auto-start. Default is true. + */ + private boolean autoStartup = true; + + /** + * Lifecycle phase. Default is 0. + */ + private int phase = 0; + + /** + * Thread for running the ZooKeeper server. + */ + private volatile Thread zkServerThread; + + /** + * ZooKeeper server. + */ + private volatile ZooKeeperServerMain zkServer; + + /** + * {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. + */ + private ErrorHandler errorHandler; + + private boolean daemon = true; + + /** + * Construct an EmbeddedZooKeeper with a random port. + */ + public EmbeddedZooKeeper() { + clientPort = SocketUtils.findAvailableTcpPort(); + } + + /** + * Construct an EmbeddedZooKeeper with the provided port. + * + * @param clientPort port for ZooKeeper server to bind to + */ + public EmbeddedZooKeeper(int clientPort, boolean daemon) { + this.clientPort = clientPort; + this.daemon = daemon; + } + + /** + * Returns the port that clients should use to connect to this embedded server. + * + * @return dynamically determined client port + */ + public int getClientPort() { + return this.clientPort; + } + + /** + * Specify whether to start automatically. Default is true. + * + * @param autoStartup whether to start automatically + */ + public void setAutoStartup(boolean autoStartup) { + this.autoStartup = autoStartup; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isAutoStartup() { + return this.autoStartup; + } + + /** + * Specify the lifecycle phase for the embedded server. + * + * @param phase the lifecycle phase + */ + public void setPhase(int phase) { + this.phase = phase; + } + + /** + * {@inheritDoc} + */ + @Override + public int getPhase() { + return this.phase; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isRunning() { + return (zkServerThread != null); + } + + /** + * Start the ZooKeeper server in a background thread. + * <p> + * Register an error handler via {@link #setErrorHandler} in order to handle + * any exceptions thrown during startup or execution. + */ + @Override + public synchronized void start() { + if (zkServerThread == null) { + zkServerThread = new Thread(new ServerRunnable(), "ZooKeeper Server Starter"); + zkServerThread.setDaemon(daemon); + zkServerThread.start(); + } + } + + /** + * Shutdown the ZooKeeper server. + */ + @Override + public synchronized void stop() { + if (zkServerThread != null) { + // The shutdown method is protected...thus this hack to invoke it. + // This will log an exception on shutdown; see + // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for details. + try { + Method shutdown = ZooKeeperServerMain.class.getDeclaredMethod("shutdown"); + shutdown.setAccessible(true); + shutdown.invoke(zkServer); + } + + catch (Exception e) { + throw new RuntimeException(e); + } + + // It is expected that the thread will exit after + // the server is shutdown; this will block until + // the shutdown is complete. + try { + zkServerThread.join(5000); + zkServerThread = null; + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("Interrupted while waiting for embedded ZooKeeper to exit"); + // abandoning zk thread + zkServerThread = null; + } + } + } + + /** + * Stop the server if running and invoke the callback when complete. + */ + @Override + public void stop(Runnable callback) { + stop(); + callback.run(); + } + + /** + * Provide an {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. If none + * is provided, only error-level logging will occur. + * + * @param errorHandler the {@link ErrorHandler} to be invoked + */ + public void setErrorHandler(ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + /** + * Runnable implementation that starts the ZooKeeper server. + */ + private class ServerRunnable implements Runnable { + + @Override + public void run() { + try { + Properties properties = new Properties(); + File file = new File(System.getProperty("java.io.tmpdir") + + File.separator + UUID.randomUUID()); + file.deleteOnExit(); + properties.setProperty("dataDir", file.getAbsolutePath()); + properties.setProperty("clientPort", String.valueOf(clientPort)); + + QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig(); + quorumPeerConfig.parseProperties(properties); + + zkServer = new ZooKeeperServerMain(); + ServerConfig configuration = new ServerConfig(); + configuration.readFrom(quorumPeerConfig); + + zkServer.runFromConfig(configuration); + } + catch (Exception e) { + if (errorHandler != null) { + errorHandler.handleError(e); + } + else { + logger.error("Exception running embedded ZooKeeper", e); + } + } + } + } + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/action/AnnotationAction.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/action/AnnotationAction.java new file mode 100644 index 0000000..785c9eb --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/action/AnnotationAction.java @@ -0,0 +1,46 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j.action; + +import org.apache.dubbo.config.annotation.Reference; + + +import org.apache.dubbo.samples.resilience4j.api.AnnotationService; +import org.springframework.stereotype.Component; + +/** + * AnnotationAction + */ +@Component("annotationAction") +public class AnnotationAction { + + @Reference + private AnnotationService annotationService; + +// @HystrixCommand(fallbackMethod = "reliable") + public String doSayHello(String name) { + return annotationService.sayHello(name); + } + + public String reliable(String name) { + return "hystrix fallback value"; + } + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/api/AnnotationService.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/api/AnnotationService.java new file mode 100644 index 0000000..74b849a --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/api/AnnotationService.java @@ -0,0 +1,29 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j.api; + +/** + * AsyncService + */ +public interface AnnotationService { + + String sayHello(String name); + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/filter/Resilience4jCircuitBreakerFilter.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/filter/Resilience4jCircuitBreakerFilter.java new file mode 100644 index 0000000..7b795cf --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/filter/Resilience4jCircuitBreakerFilter.java @@ -0,0 +1,42 @@ +package org.apache.dubbo.samples.resilience4j.filter; + +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import org.apache.dubbo.rpc.Filter; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.RpcException; + +/** + * @author cvictory ON 2018/12/25 + */ +public class Resilience4jCircuitBreakerFilter implements Filter { + + static CircuitBreaker circuitBreaker; + + static { + CircuitBreakerConfig config = CircuitBreakerConfig.custom() + .failureRateThreshold(20) + .ringBufferSizeInClosedState(5) + .build(); + CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config); + circuitBreaker = registry.circuitBreaker("my"); + } + + @Override + public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { + long start = System.nanoTime(); + try { + Result result = invoker.invoke(invocation); + long durationInNanos = System.nanoTime() - start; + circuitBreaker.onSuccess(durationInNanos); + return result; + } catch (Throwable throwable) { + long durationInNanos = System.nanoTime() - start; + circuitBreaker.onError(durationInNanos, throwable); + throw throwable; + } + } +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/impl/AnnotationServiceImpl.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/impl/AnnotationServiceImpl.java new file mode 100644 index 0000000..cc2e9f7 --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/java/org/apache/dubbo/samples/resilience4j/impl/AnnotationServiceImpl.java @@ -0,0 +1,40 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j.impl; + +import org.apache.dubbo.config.annotation.Service; +import org.apache.dubbo.samples.resilience4j.api.AnnotationService; + +/** + * AsyncServiceImpl + */ +@Service +public class AnnotationServiceImpl implements AnnotationService { + +// @HystrixCommand(commandProperties = { @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), +// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") }) + @Override + public String sayHello(String name) { +// System.out.println("async provider received: " + name); +// return "annotation: hello, " + name; + throw new RuntimeException("Exception to show hystrix enabled."); + } + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/resources/log4j.properties b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/resources/log4j.properties new file mode 100644 index 0000000..d6ecd5c --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/resources/log4j.properties @@ -0,0 +1,26 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +###set log levels### +log4j.rootLogger=info, stdout +###output to the console### +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n \ No newline at end of file diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/resources/spring/dubbo-consumer.properties b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/resources/spring/dubbo-consumer.properties new file mode 100644 index 0000000..96ab667 --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/resources/spring/dubbo-consumer.properties @@ -0,0 +1,22 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +dubbo.application.name=annotation-consumer +dubbo.registry.address=zookeeper://127.0.0.1:2181 +dubbo.consumer.timeout=3000 \ No newline at end of file diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/resources/spring/dubbo-provider.properties b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/resources/spring/dubbo-provider.properties new file mode 100644 index 0000000..51fccca --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-filter/src/main/resources/spring/dubbo-provider.properties @@ -0,0 +1,23 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +dubbo.application.name=annotation-provider +dubbo.registry.address=zookeeper://127.0.0.1:2181 +dubbo.protocol.name=dubbo +dubbo.protocol.port=20880 \ No newline at end of file diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/README.md b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/README.md new file mode 100644 index 0000000..12c735e --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/README.md @@ -0,0 +1,17 @@ +## dubbo spring hystrix sample + +### Start Provider + +Run `org.apache.dubbo.samples.annotation.AnnotationProvider` + + +### Start Consumer + +Run `org.apache.dubbo.samples.annotation.AnnotationConsumer` + +### Result + +0. Start provider +0. Start consumer +0. The provider print `java.lang.RuntimeException: Exception to show hystrix enabled`. The exception stack conatins hystrix command info. +0. The consumer print `result :hystrix fallback value`, which means hystrix fallback configuration is effect. diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/pom.xml b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/pom.xml new file mode 100644 index 0000000..862a475 --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/pom.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>dubbo-samples-all</artifactId> + <groupId>org.apache.dubbo</groupId> + <version>1.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>dubbo-samples-resilience4j-springboot2</artifactId> + + <properties> + <resilience4j.version>0.13.1</resilience4j.version> + </properties> + + + <dependencies> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-circuitbreaker</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-ratelimiter</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-retry</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-bulkhead</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-cache</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-timelimiter</artifactId> + <version>${resilience4j.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + </dependency> + </dependencies> +</project> diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationConsumer.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationConsumer.java new file mode 100644 index 0000000..d74b20a --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationConsumer.java @@ -0,0 +1,63 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j; + +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import io.github.resilience4j.circuitbreaker.utils.CircuitBreakerUtils; +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; +import org.apache.dubbo.samples.resilience4j.action.AnnotationAction; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.context.annotation.PropertySource; + +/** + * CallbackConsumer + */ +public class AnnotationConsumer { + + public static void main(String[] args) throws Exception { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class); + context.start(); + final AnnotationAction annotationAction = (AnnotationAction) context.getBean("annotationAction"); + String hello = annotationAction.doSayHello("world"); + System.err.println("result :" + hello); + System.in.read(); + } + + @Configuration + @EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.resilience4j.action") + @PropertySource("classpath:/spring/dubbo-consumer.properties") + @ComponentScan(value = {"org.apache.dubbo.samples.resilience4j.action"}) + @EnableAspectJAutoProxy + static public class ConsumerConfiguration { + +// @Bean +// public HystrixCommandAspect hystrixCommandAspect() { +// return new HystrixCommandAspect(); +// } + + } + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationProvider.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationProvider.java new file mode 100644 index 0000000..be7715d --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationProvider.java @@ -0,0 +1,61 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j; + + +import org.apache.dubbo.config.ProviderConfig; +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.context.annotation.PropertySource; + +/** + * MergeProvider + */ +public class AnnotationProvider { + + public static void main(String[] args) throws Exception { + new EmbeddedZooKeeper(2181, false).start(); + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class); + context.start(); + System.in.read(); + } + + @Configuration + @EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.resilience4j.impl") + @PropertySource("classpath:/spring/dubbo-provider.properties") + @EnableAspectJAutoProxy + static public class ProviderConfiguration { + @Bean + public ProviderConfig providerConfig() { + ProviderConfig providerConfig = new ProviderConfig(); + providerConfig.setTimeout(1000); + return providerConfig; + } + +// @Bean +// public HystrixCommandAspect hystrixCommandAspect() { +// return new HystrixCommandAspect(); +// } + } + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/EmbeddedZooKeeper.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/EmbeddedZooKeeper.java new file mode 100644 index 0000000..9c8ae8a --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/EmbeddedZooKeeper.java @@ -0,0 +1,255 @@ +/* + * Copyright 2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.samples.resilience4j; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.Properties; +import java.util.UUID; + +import org.apache.zookeeper.server.ServerConfig; +import org.apache.zookeeper.server.ZooKeeperServerMain; +import org.apache.zookeeper.server.quorum.QuorumPeerConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.SmartLifecycle; +import org.springframework.util.ErrorHandler; +import org.springframework.util.SocketUtils; + +/** + * from: https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java + * + * Helper class to start an embedded instance of standalone (non clustered) ZooKeeper. + * + * NOTE: at least an external standalone server (if not an ensemble) are recommended, even for + * {@link org.springframework.xd.dirt.server.singlenode.SingleNodeApplication} + * + * @author Patrick Peralta + * @author Mark Fisher + * @author David Turanski + */ +public class EmbeddedZooKeeper implements SmartLifecycle { + + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(EmbeddedZooKeeper.class); + + /** + * ZooKeeper client port. This will be determined dynamically upon startup. + */ + private final int clientPort; + + /** + * Whether to auto-start. Default is true. + */ + private boolean autoStartup = true; + + /** + * Lifecycle phase. Default is 0. + */ + private int phase = 0; + + /** + * Thread for running the ZooKeeper server. + */ + private volatile Thread zkServerThread; + + /** + * ZooKeeper server. + */ + private volatile ZooKeeperServerMain zkServer; + + /** + * {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. + */ + private ErrorHandler errorHandler; + + private boolean daemon = true; + + /** + * Construct an EmbeddedZooKeeper with a random port. + */ + public EmbeddedZooKeeper() { + clientPort = SocketUtils.findAvailableTcpPort(); + } + + /** + * Construct an EmbeddedZooKeeper with the provided port. + * + * @param clientPort port for ZooKeeper server to bind to + */ + public EmbeddedZooKeeper(int clientPort, boolean daemon) { + this.clientPort = clientPort; + this.daemon = daemon; + } + + /** + * Returns the port that clients should use to connect to this embedded server. + * + * @return dynamically determined client port + */ + public int getClientPort() { + return this.clientPort; + } + + /** + * Specify whether to start automatically. Default is true. + * + * @param autoStartup whether to start automatically + */ + public void setAutoStartup(boolean autoStartup) { + this.autoStartup = autoStartup; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isAutoStartup() { + return this.autoStartup; + } + + /** + * Specify the lifecycle phase for the embedded server. + * + * @param phase the lifecycle phase + */ + public void setPhase(int phase) { + this.phase = phase; + } + + /** + * {@inheritDoc} + */ + @Override + public int getPhase() { + return this.phase; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isRunning() { + return (zkServerThread != null); + } + + /** + * Start the ZooKeeper server in a background thread. + * <p> + * Register an error handler via {@link #setErrorHandler} in order to handle + * any exceptions thrown during startup or execution. + */ + @Override + public synchronized void start() { + if (zkServerThread == null) { + zkServerThread = new Thread(new ServerRunnable(), "ZooKeeper Server Starter"); + zkServerThread.setDaemon(daemon); + zkServerThread.start(); + } + } + + /** + * Shutdown the ZooKeeper server. + */ + @Override + public synchronized void stop() { + if (zkServerThread != null) { + // The shutdown method is protected...thus this hack to invoke it. + // This will log an exception on shutdown; see + // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for details. + try { + Method shutdown = ZooKeeperServerMain.class.getDeclaredMethod("shutdown"); + shutdown.setAccessible(true); + shutdown.invoke(zkServer); + } + + catch (Exception e) { + throw new RuntimeException(e); + } + + // It is expected that the thread will exit after + // the server is shutdown; this will block until + // the shutdown is complete. + try { + zkServerThread.join(5000); + zkServerThread = null; + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("Interrupted while waiting for embedded ZooKeeper to exit"); + // abandoning zk thread + zkServerThread = null; + } + } + } + + /** + * Stop the server if running and invoke the callback when complete. + */ + @Override + public void stop(Runnable callback) { + stop(); + callback.run(); + } + + /** + * Provide an {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. If none + * is provided, only error-level logging will occur. + * + * @param errorHandler the {@link ErrorHandler} to be invoked + */ + public void setErrorHandler(ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + /** + * Runnable implementation that starts the ZooKeeper server. + */ + private class ServerRunnable implements Runnable { + + @Override + public void run() { + try { + Properties properties = new Properties(); + File file = new File(System.getProperty("java.io.tmpdir") + + File.separator + UUID.randomUUID()); + file.deleteOnExit(); + properties.setProperty("dataDir", file.getAbsolutePath()); + properties.setProperty("clientPort", String.valueOf(clientPort)); + + QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig(); + quorumPeerConfig.parseProperties(properties); + + zkServer = new ZooKeeperServerMain(); + ServerConfig configuration = new ServerConfig(); + configuration.readFrom(quorumPeerConfig); + + zkServer.runFromConfig(configuration); + } + catch (Exception e) { + if (errorHandler != null) { + errorHandler.handleError(e); + } + else { + logger.error("Exception running embedded ZooKeeper", e); + } + } + } + } + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/action/AnnotationAction.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/action/AnnotationAction.java new file mode 100644 index 0000000..785c9eb --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/action/AnnotationAction.java @@ -0,0 +1,46 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j.action; + +import org.apache.dubbo.config.annotation.Reference; + + +import org.apache.dubbo.samples.resilience4j.api.AnnotationService; +import org.springframework.stereotype.Component; + +/** + * AnnotationAction + */ +@Component("annotationAction") +public class AnnotationAction { + + @Reference + private AnnotationService annotationService; + +// @HystrixCommand(fallbackMethod = "reliable") + public String doSayHello(String name) { + return annotationService.sayHello(name); + } + + public String reliable(String name) { + return "hystrix fallback value"; + } + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/api/AnnotationService.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/api/AnnotationService.java new file mode 100644 index 0000000..74b849a --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/api/AnnotationService.java @@ -0,0 +1,29 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j.api; + +/** + * AsyncService + */ +public interface AnnotationService { + + String sayHello(String name); + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/filter/Resilience4jCircuitBreakerFilter.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/filter/Resilience4jCircuitBreakerFilter.java new file mode 100644 index 0000000..7b795cf --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/filter/Resilience4jCircuitBreakerFilter.java @@ -0,0 +1,42 @@ +package org.apache.dubbo.samples.resilience4j.filter; + +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import org.apache.dubbo.rpc.Filter; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.RpcException; + +/** + * @author cvictory ON 2018/12/25 + */ +public class Resilience4jCircuitBreakerFilter implements Filter { + + static CircuitBreaker circuitBreaker; + + static { + CircuitBreakerConfig config = CircuitBreakerConfig.custom() + .failureRateThreshold(20) + .ringBufferSizeInClosedState(5) + .build(); + CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config); + circuitBreaker = registry.circuitBreaker("my"); + } + + @Override + public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { + long start = System.nanoTime(); + try { + Result result = invoker.invoke(invocation); + long durationInNanos = System.nanoTime() - start; + circuitBreaker.onSuccess(durationInNanos); + return result; + } catch (Throwable throwable) { + long durationInNanos = System.nanoTime() - start; + circuitBreaker.onError(durationInNanos, throwable); + throw throwable; + } + } +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/impl/AnnotationServiceImpl.java b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/impl/AnnotationServiceImpl.java new file mode 100644 index 0000000..cc2e9f7 --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/java/org/apache/dubbo/samples/resilience4j/impl/AnnotationServiceImpl.java @@ -0,0 +1,40 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j.impl; + +import org.apache.dubbo.config.annotation.Service; +import org.apache.dubbo.samples.resilience4j.api.AnnotationService; + +/** + * AsyncServiceImpl + */ +@Service +public class AnnotationServiceImpl implements AnnotationService { + +// @HystrixCommand(commandProperties = { @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), +// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") }) + @Override + public String sayHello(String name) { +// System.out.println("async provider received: " + name); +// return "annotation: hello, " + name; + throw new RuntimeException("Exception to show hystrix enabled."); + } + +} diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/resources/log4j.properties b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/resources/log4j.properties new file mode 100644 index 0000000..d6ecd5c --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/resources/log4j.properties @@ -0,0 +1,26 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +###set log levels### +log4j.rootLogger=info, stdout +###output to the console### +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n \ No newline at end of file diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/resources/spring/dubbo-consumer.properties b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/resources/spring/dubbo-consumer.properties new file mode 100644 index 0000000..96ab667 --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/resources/spring/dubbo-consumer.properties @@ -0,0 +1,22 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +dubbo.application.name=annotation-consumer +dubbo.registry.address=zookeeper://127.0.0.1:2181 +dubbo.consumer.timeout=3000 \ No newline at end of file diff --git a/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/resources/spring/dubbo-provider.properties b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/resources/spring/dubbo-provider.properties new file mode 100644 index 0000000..51fccca --- /dev/null +++ b/dubbo-samples-resilience4j/dubbo-samples-resilience4j-springboot2/src/main/resources/spring/dubbo-provider.properties @@ -0,0 +1,23 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +dubbo.application.name=annotation-provider +dubbo.registry.address=zookeeper://127.0.0.1:2181 +dubbo.protocol.name=dubbo +dubbo.protocol.port=20880 \ No newline at end of file diff --git a/dubbo-samples-resilience4j/pom.xml b/dubbo-samples-resilience4j/pom.xml new file mode 100644 index 0000000..404ea6f --- /dev/null +++ b/dubbo-samples-resilience4j/pom.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>dubbo-samples-all</artifactId> + <groupId>org.apache.dubbo</groupId> + <version>1.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>dubbo-samples-resilience4j</artifactId> + <packaging>pom</packaging> + <modules> + <module>dubbo-samples-resilience4j-filter</module> + <module>dubbo-samples-resilience4j-springboot2</module> + </modules> + + <properties> + <resilience4j.version>0.13.1</resilience4j.version> + </properties> + + +</project> diff --git a/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationConsumer.java b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationConsumer.java new file mode 100644 index 0000000..d74b20a --- /dev/null +++ b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationConsumer.java @@ -0,0 +1,63 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j; + +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import io.github.resilience4j.circuitbreaker.utils.CircuitBreakerUtils; +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; +import org.apache.dubbo.samples.resilience4j.action.AnnotationAction; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.context.annotation.PropertySource; + +/** + * CallbackConsumer + */ +public class AnnotationConsumer { + + public static void main(String[] args) throws Exception { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class); + context.start(); + final AnnotationAction annotationAction = (AnnotationAction) context.getBean("annotationAction"); + String hello = annotationAction.doSayHello("world"); + System.err.println("result :" + hello); + System.in.read(); + } + + @Configuration + @EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.resilience4j.action") + @PropertySource("classpath:/spring/dubbo-consumer.properties") + @ComponentScan(value = {"org.apache.dubbo.samples.resilience4j.action"}) + @EnableAspectJAutoProxy + static public class ConsumerConfiguration { + +// @Bean +// public HystrixCommandAspect hystrixCommandAspect() { +// return new HystrixCommandAspect(); +// } + + } + +} diff --git a/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationProvider.java b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationProvider.java new file mode 100644 index 0000000..be7715d --- /dev/null +++ b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/AnnotationProvider.java @@ -0,0 +1,61 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j; + + +import org.apache.dubbo.config.ProviderConfig; +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.context.annotation.PropertySource; + +/** + * MergeProvider + */ +public class AnnotationProvider { + + public static void main(String[] args) throws Exception { + new EmbeddedZooKeeper(2181, false).start(); + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class); + context.start(); + System.in.read(); + } + + @Configuration + @EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.resilience4j.impl") + @PropertySource("classpath:/spring/dubbo-provider.properties") + @EnableAspectJAutoProxy + static public class ProviderConfiguration { + @Bean + public ProviderConfig providerConfig() { + ProviderConfig providerConfig = new ProviderConfig(); + providerConfig.setTimeout(1000); + return providerConfig; + } + +// @Bean +// public HystrixCommandAspect hystrixCommandAspect() { +// return new HystrixCommandAspect(); +// } + } + +} diff --git a/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/EmbeddedZooKeeper.java b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/EmbeddedZooKeeper.java new file mode 100644 index 0000000..9c8ae8a --- /dev/null +++ b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/EmbeddedZooKeeper.java @@ -0,0 +1,255 @@ +/* + * Copyright 2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.samples.resilience4j; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.Properties; +import java.util.UUID; + +import org.apache.zookeeper.server.ServerConfig; +import org.apache.zookeeper.server.ZooKeeperServerMain; +import org.apache.zookeeper.server.quorum.QuorumPeerConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.SmartLifecycle; +import org.springframework.util.ErrorHandler; +import org.springframework.util.SocketUtils; + +/** + * from: https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java + * + * Helper class to start an embedded instance of standalone (non clustered) ZooKeeper. + * + * NOTE: at least an external standalone server (if not an ensemble) are recommended, even for + * {@link org.springframework.xd.dirt.server.singlenode.SingleNodeApplication} + * + * @author Patrick Peralta + * @author Mark Fisher + * @author David Turanski + */ +public class EmbeddedZooKeeper implements SmartLifecycle { + + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(EmbeddedZooKeeper.class); + + /** + * ZooKeeper client port. This will be determined dynamically upon startup. + */ + private final int clientPort; + + /** + * Whether to auto-start. Default is true. + */ + private boolean autoStartup = true; + + /** + * Lifecycle phase. Default is 0. + */ + private int phase = 0; + + /** + * Thread for running the ZooKeeper server. + */ + private volatile Thread zkServerThread; + + /** + * ZooKeeper server. + */ + private volatile ZooKeeperServerMain zkServer; + + /** + * {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. + */ + private ErrorHandler errorHandler; + + private boolean daemon = true; + + /** + * Construct an EmbeddedZooKeeper with a random port. + */ + public EmbeddedZooKeeper() { + clientPort = SocketUtils.findAvailableTcpPort(); + } + + /** + * Construct an EmbeddedZooKeeper with the provided port. + * + * @param clientPort port for ZooKeeper server to bind to + */ + public EmbeddedZooKeeper(int clientPort, boolean daemon) { + this.clientPort = clientPort; + this.daemon = daemon; + } + + /** + * Returns the port that clients should use to connect to this embedded server. + * + * @return dynamically determined client port + */ + public int getClientPort() { + return this.clientPort; + } + + /** + * Specify whether to start automatically. Default is true. + * + * @param autoStartup whether to start automatically + */ + public void setAutoStartup(boolean autoStartup) { + this.autoStartup = autoStartup; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isAutoStartup() { + return this.autoStartup; + } + + /** + * Specify the lifecycle phase for the embedded server. + * + * @param phase the lifecycle phase + */ + public void setPhase(int phase) { + this.phase = phase; + } + + /** + * {@inheritDoc} + */ + @Override + public int getPhase() { + return this.phase; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isRunning() { + return (zkServerThread != null); + } + + /** + * Start the ZooKeeper server in a background thread. + * <p> + * Register an error handler via {@link #setErrorHandler} in order to handle + * any exceptions thrown during startup or execution. + */ + @Override + public synchronized void start() { + if (zkServerThread == null) { + zkServerThread = new Thread(new ServerRunnable(), "ZooKeeper Server Starter"); + zkServerThread.setDaemon(daemon); + zkServerThread.start(); + } + } + + /** + * Shutdown the ZooKeeper server. + */ + @Override + public synchronized void stop() { + if (zkServerThread != null) { + // The shutdown method is protected...thus this hack to invoke it. + // This will log an exception on shutdown; see + // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for details. + try { + Method shutdown = ZooKeeperServerMain.class.getDeclaredMethod("shutdown"); + shutdown.setAccessible(true); + shutdown.invoke(zkServer); + } + + catch (Exception e) { + throw new RuntimeException(e); + } + + // It is expected that the thread will exit after + // the server is shutdown; this will block until + // the shutdown is complete. + try { + zkServerThread.join(5000); + zkServerThread = null; + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("Interrupted while waiting for embedded ZooKeeper to exit"); + // abandoning zk thread + zkServerThread = null; + } + } + } + + /** + * Stop the server if running and invoke the callback when complete. + */ + @Override + public void stop(Runnable callback) { + stop(); + callback.run(); + } + + /** + * Provide an {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. If none + * is provided, only error-level logging will occur. + * + * @param errorHandler the {@link ErrorHandler} to be invoked + */ + public void setErrorHandler(ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + /** + * Runnable implementation that starts the ZooKeeper server. + */ + private class ServerRunnable implements Runnable { + + @Override + public void run() { + try { + Properties properties = new Properties(); + File file = new File(System.getProperty("java.io.tmpdir") + + File.separator + UUID.randomUUID()); + file.deleteOnExit(); + properties.setProperty("dataDir", file.getAbsolutePath()); + properties.setProperty("clientPort", String.valueOf(clientPort)); + + QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig(); + quorumPeerConfig.parseProperties(properties); + + zkServer = new ZooKeeperServerMain(); + ServerConfig configuration = new ServerConfig(); + configuration.readFrom(quorumPeerConfig); + + zkServer.runFromConfig(configuration); + } + catch (Exception e) { + if (errorHandler != null) { + errorHandler.handleError(e); + } + else { + logger.error("Exception running embedded ZooKeeper", e); + } + } + } + } + +} diff --git a/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/action/AnnotationAction.java b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/action/AnnotationAction.java new file mode 100644 index 0000000..785c9eb --- /dev/null +++ b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/action/AnnotationAction.java @@ -0,0 +1,46 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j.action; + +import org.apache.dubbo.config.annotation.Reference; + + +import org.apache.dubbo.samples.resilience4j.api.AnnotationService; +import org.springframework.stereotype.Component; + +/** + * AnnotationAction + */ +@Component("annotationAction") +public class AnnotationAction { + + @Reference + private AnnotationService annotationService; + +// @HystrixCommand(fallbackMethod = "reliable") + public String doSayHello(String name) { + return annotationService.sayHello(name); + } + + public String reliable(String name) { + return "hystrix fallback value"; + } + +} diff --git a/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/api/AnnotationService.java b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/api/AnnotationService.java new file mode 100644 index 0000000..74b849a --- /dev/null +++ b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/api/AnnotationService.java @@ -0,0 +1,29 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j.api; + +/** + * AsyncService + */ +public interface AnnotationService { + + String sayHello(String name); + +} diff --git a/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/filter/Resilience4jCircuitBreakerFilter.java b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/filter/Resilience4jCircuitBreakerFilter.java new file mode 100644 index 0000000..7b795cf --- /dev/null +++ b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/filter/Resilience4jCircuitBreakerFilter.java @@ -0,0 +1,42 @@ +package org.apache.dubbo.samples.resilience4j.filter; + +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import org.apache.dubbo.rpc.Filter; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.RpcException; + +/** + * @author cvictory ON 2018/12/25 + */ +public class Resilience4jCircuitBreakerFilter implements Filter { + + static CircuitBreaker circuitBreaker; + + static { + CircuitBreakerConfig config = CircuitBreakerConfig.custom() + .failureRateThreshold(20) + .ringBufferSizeInClosedState(5) + .build(); + CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config); + circuitBreaker = registry.circuitBreaker("my"); + } + + @Override + public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { + long start = System.nanoTime(); + try { + Result result = invoker.invoke(invocation); + long durationInNanos = System.nanoTime() - start; + circuitBreaker.onSuccess(durationInNanos); + return result; + } catch (Throwable throwable) { + long durationInNanos = System.nanoTime() - start; + circuitBreaker.onError(durationInNanos, throwable); + throw throwable; + } + } +} diff --git a/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/impl/AnnotationServiceImpl.java b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/impl/AnnotationServiceImpl.java new file mode 100644 index 0000000..cc2e9f7 --- /dev/null +++ b/dubbo-samples-resilience4j/src/main/java/org/apache/dubbo/samples/resilience4j/impl/AnnotationServiceImpl.java @@ -0,0 +1,40 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dubbo.samples.resilience4j.impl; + +import org.apache.dubbo.config.annotation.Service; +import org.apache.dubbo.samples.resilience4j.api.AnnotationService; + +/** + * AsyncServiceImpl + */ +@Service +public class AnnotationServiceImpl implements AnnotationService { + +// @HystrixCommand(commandProperties = { @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), +// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") }) + @Override + public String sayHello(String name) { +// System.out.println("async provider received: " + name); +// return "annotation: hello, " + name; + throw new RuntimeException("Exception to show hystrix enabled."); + } + +} diff --git a/dubbo-samples-resilience4j/src/main/resources/log4j.properties b/dubbo-samples-resilience4j/src/main/resources/log4j.properties new file mode 100644 index 0000000..d6ecd5c --- /dev/null +++ b/dubbo-samples-resilience4j/src/main/resources/log4j.properties @@ -0,0 +1,26 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +###set log levels### +log4j.rootLogger=info, stdout +###output to the console### +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n \ No newline at end of file diff --git a/dubbo-samples-resilience4j/src/main/resources/spring/dubbo-consumer.properties b/dubbo-samples-resilience4j/src/main/resources/spring/dubbo-consumer.properties new file mode 100644 index 0000000..96ab667 --- /dev/null +++ b/dubbo-samples-resilience4j/src/main/resources/spring/dubbo-consumer.properties @@ -0,0 +1,22 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +dubbo.application.name=annotation-consumer +dubbo.registry.address=zookeeper://127.0.0.1:2181 +dubbo.consumer.timeout=3000 \ No newline at end of file diff --git a/dubbo-samples-resilience4j/src/main/resources/spring/dubbo-provider.properties b/dubbo-samples-resilience4j/src/main/resources/spring/dubbo-provider.properties new file mode 100644 index 0000000..51fccca --- /dev/null +++ b/dubbo-samples-resilience4j/src/main/resources/spring/dubbo-provider.properties @@ -0,0 +1,23 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +dubbo.application.name=annotation-provider +dubbo.registry.address=zookeeper://127.0.0.1:2181 +dubbo.protocol.name=dubbo +dubbo.protocol.port=20880 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7f5c36c..08eb7a2 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,7 @@ <module>dubbo-samples-simplified-registry</module> <module>dubbo-samples-chain</module> <module>dubbo-samples-generic-call</module> + <module>dubbo-samples-resilience4j</module> </modules> <properties>