diff --git a/client/pom.xml b/client/pom.xml index 498cb40..bef7233 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -3,8 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.test - feign-eureka-hello-client + client 0.0.1-SNAPSHOT jar @@ -12,7 +11,7 @@ Demo project for Spring Cloud - org.test + org.fegin.demo feign-eureka 0.0.1-SNAPSHOT .. @@ -34,11 +33,11 @@ org.springframework.cloud - spring-cloud-starter-feign + spring-cloud-starter-openfeign org.springframework.cloud - spring-cloud-starter-eureka + spring-cloud-starter-netflix-eureka-client org.springframework.boot diff --git a/client/src/main/java/demo/HelloClientApplication.java b/client/src/main/java/demo/HelloClientApplication.java deleted file mode 100644 index 1131de6..0000000 --- a/client/src/main/java/demo/HelloClientApplication.java +++ /dev/null @@ -1,39 +0,0 @@ -package demo; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.springframework.web.bind.annotation.RequestMethod.GET; - -/** - * @author Spencer Gibb - */ -@SpringBootApplication -@EnableDiscoveryClient -@RestController -@EnableFeignClients -public class HelloClientApplication { - @Autowired - HelloClient client; - - @RequestMapping("/") - public String hello() { - return client.hello(); - } - - public static void main(String[] args) { - SpringApplication.run(HelloClientApplication.class, args); - } - - @FeignClient("HelloServer") - interface HelloClient { - @RequestMapping(value = "/", method = GET) - String hello(); - } -} diff --git a/client/src/main/java/org/fegin/demo/client/HelloClient.java b/client/src/main/java/org/fegin/demo/client/HelloClient.java new file mode 100644 index 0000000..72f5f0c --- /dev/null +++ b/client/src/main/java/org/fegin/demo/client/HelloClient.java @@ -0,0 +1,16 @@ +package org.fegin.demo.client; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.RequestMapping; + +import static org.springframework.web.bind.annotation.RequestMethod.GET; + +/** + * @author steel + * @datetime 2019/4/26 15:55 + */ +@FeignClient(name = "HelloServer", fallbackFactory = HelloClientFallbackFactory.class) +public interface HelloClient { + @RequestMapping(value = "/", method = GET) + String hello(); +} diff --git a/client/src/main/java/org/fegin/demo/client/HelloClientApplication.java b/client/src/main/java/org/fegin/demo/client/HelloClientApplication.java new file mode 100644 index 0000000..cbf41da --- /dev/null +++ b/client/src/main/java/org/fegin/demo/client/HelloClientApplication.java @@ -0,0 +1,21 @@ +package org.fegin.demo.client; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * @author Spencer Gibb + */ +@SpringBootApplication +@EnableDiscoveryClient +@EnableHystrixDashboard +@EnableFeignClients +public class HelloClientApplication { + public static void main(String[] args) { + SpringApplication.run(HelloClientApplication.class, args); + } + +} diff --git a/client/src/main/java/org/fegin/demo/client/HelloClientFallback.java b/client/src/main/java/org/fegin/demo/client/HelloClientFallback.java new file mode 100644 index 0000000..e02a903 --- /dev/null +++ b/client/src/main/java/org/fegin/demo/client/HelloClientFallback.java @@ -0,0 +1,15 @@ +package org.fegin.demo.client; + +import org.springframework.stereotype.Service; + +/** + * @author steel + * @datetime 2019/4/26 15:55 + */ +@Service("helloClientFallback") +public class HelloClientFallback implements HelloClient { + @Override + public String hello() { + return "fallback"; + } +} diff --git a/client/src/main/java/org/fegin/demo/client/HelloClientFallbackFactory.java b/client/src/main/java/org/fegin/demo/client/HelloClientFallbackFactory.java new file mode 100644 index 0000000..89604c7 --- /dev/null +++ b/client/src/main/java/org/fegin/demo/client/HelloClientFallbackFactory.java @@ -0,0 +1,27 @@ +package org.fegin.demo.client; + +import feign.hystrix.FallbackFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +/** + * @author steel + * @datetime 2019/4/26 17:39 + */ +@Service +public class HelloClientFallbackFactory implements FallbackFactory { + private static final Logger LOGGER = LoggerFactory.getLogger(HelloClientFallbackFactory.class); + private HelloClient helloClient; + + public HelloClientFallbackFactory(@Qualifier("helloClientFallback") HelloClient helloClient) { + this.helloClient = helloClient; + } + + @Override + public HelloClient create(Throwable throwable) { + LOGGER.error("fallback error ", throwable); + return helloClient; + } +} diff --git a/client/src/main/java/org/fegin/demo/client/HelloController.java b/client/src/main/java/org/fegin/demo/client/HelloController.java new file mode 100644 index 0000000..7088452 --- /dev/null +++ b/client/src/main/java/org/fegin/demo/client/HelloController.java @@ -0,0 +1,25 @@ +package org.fegin.demo.client; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author steel + * @datetime 2019/4/26 15:56 + */ +@RestController +public class HelloController { + private final HelloClient helloClient; + + @Autowired + public HelloController(HelloClient helloClient) { + this.helloClient = helloClient; + } + + @RequestMapping(method = RequestMethod.GET, value = "/") + public String hello() { + return helloClient.hello(); + } +} diff --git a/client/src/main/java/org/fegin/demo/client/HystrixServletRegistrationBean.java b/client/src/main/java/org/fegin/demo/client/HystrixServletRegistrationBean.java new file mode 100644 index 0000000..d46d06d --- /dev/null +++ b/client/src/main/java/org/fegin/demo/client/HystrixServletRegistrationBean.java @@ -0,0 +1,16 @@ +package org.fegin.demo.client; + +import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; +import org.springframework.boot.web.servlet.ServletRegistrationBean; + +/** + * @author steel + * @datetime 2019/4/28 11:46 + */ +public class HystrixServletRegistrationBean extends ServletRegistrationBean { + + public HystrixServletRegistrationBean(HystrixMetricsStreamServlet servlet, String... urlMappings) { + super(servlet, urlMappings); + } + +} diff --git a/client/src/main/java/org/fegin/demo/client/configuration/HystrixConfiguration.java b/client/src/main/java/org/fegin/demo/client/configuration/HystrixConfiguration.java new file mode 100644 index 0000000..a3ae3d5 --- /dev/null +++ b/client/src/main/java/org/fegin/demo/client/configuration/HystrixConfiguration.java @@ -0,0 +1,24 @@ +package org.fegin.demo.client.configuration; + +import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; +import org.fegin.demo.client.HystrixServletRegistrationBean; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author steel + * @datetime 2019/4/28 11:40 + */ +@Configuration +public class HystrixConfiguration { + @Bean(name = "hystrixRegistrationBean") + public ServletRegistrationBean servletRegistrationBean() { + ServletRegistrationBean registration = new HystrixServletRegistrationBean( + new HystrixMetricsStreamServlet(), "/hystrix.stream"); + registration.setName("hystrixServlet"); + registration.setLoadOnStartup(1); + return registration; + } + +} diff --git a/client/src/main/resources/application.yml b/client/src/main/resources/application.yml index b2cfa78..b1d85a1 100644 --- a/client/src/main/resources/application.yml +++ b/client/src/main/resources/application.yml @@ -1,12 +1,17 @@ +info: + version: 1.0.0 + spring: application: name: HelloClient + cloud: + inetutils: + default-hostname: hello.client server: port: 7211 eureka: - password: password client: serviceUrl: defaultZone: https://user:${eureka.password}@localhost:8761/eureka/ @@ -14,12 +19,64 @@ eureka: leaseRenewalIntervalInSeconds: 10 metadataMap: instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}} + prefer-ip-address: true +# ip-address: 192.168.6.132 + hostname: hello.client + instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port} +management: + endpoint: + restart: + enabled: true + shutdown: + enabled: true + health: + enabled: true + hystrix: + config: + default: + execution: + isolation: + thread: + timeoutInMilliseconds: 2000 -endpoints: - restart: - enabled: true - shutdown: +feign: + httpclient: + max-connections: 200 + max-connections-per-route: 50 + connection-timeout: 2000 + compression: + request: + enabled: true + response: + enabled: true + client: + config: + default: + connectTimeout: 5000 + readTimeout: 5000 + loggerLevel: basic + hystrix: enabled: true - health: - sensitive: false \ No newline at end of file + +# 以配置hystrix超时时间为例 +hystrix: + command: + #默认的超时时间设置 + default: + execution: + isolation: + thread: + timeoutInMilliseconds: 1000 + # commandKey,默认为方法名 + HelloClient#hello(): + execution: + isolation: + thread: + timeoutInMilliseconds: 1500 + +# logging +logging: + level: + com: + netflix: debug \ No newline at end of file diff --git a/client/src/test/java/org/fegin/demo/client/CommonMainTests.java b/client/src/test/java/org/fegin/demo/client/CommonMainTests.java new file mode 100644 index 0000000..3543c08 --- /dev/null +++ b/client/src/test/java/org/fegin/demo/client/CommonMainTests.java @@ -0,0 +1,42 @@ +package org.fegin.demo.client; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.HttpClientBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * @author steel + * @datetime 2019/4/26 16:33 + */ +public class CommonMainTests { + private static final Logger LOGGER = LoggerFactory.getLogger(CommonMainTests.class); + private static HttpClient httpClient = HttpClientBuilder.create().build(); + + public static void main(String[] args) { + ExecutorService executorService = Executors.newFixedThreadPool(100); + CountDownLatch countDownLatch = new CountDownLatch(1); + for (int i = 0; i < 1000; i++) { + executorService.submit(() -> { + try { + countDownLatch.await(); + HttpResponse httpResponse = httpClient.execute(new HttpGet("http://192.168.115.1:7211/")); + LOGGER.info(IOUtils.toString(httpResponse.getEntity().getContent(), "UTF-8")); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + + }); + } + countDownLatch.countDown(); + + } +} diff --git a/client/src/test/java/org/fegin/demo/client/CommonTests.java b/client/src/test/java/org/fegin/demo/client/CommonTests.java new file mode 100644 index 0000000..6022eb4 --- /dev/null +++ b/client/src/test/java/org/fegin/demo/client/CommonTests.java @@ -0,0 +1,9 @@ +package org.fegin.demo.client; + +/** + * @author steel + * @datetime 2019/4/26 16:31 + */ +public class CommonTests { + +} diff --git a/pom.xml b/pom.xml index 1d2574e..27e949b 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.test + org.fegin.demo feign-eureka 0.0.1-SNAPSHOT pom @@ -14,7 +14,7 @@ org.springframework.boot spring-boot-starter-parent - 1.4.2.RELEASE + 2.1.4.RELEASE @@ -26,14 +26,23 @@ UTF-8 1.8 + 1.4.6.RELEASE + + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix-dashboard + 2.1.0.RELEASE + + + org.springframework.cloud spring-cloud-dependencies - Camden.BUILD-SNAPSHOT + Greenwich.RELEASE pom import diff --git a/server/pom.xml b/server/pom.xml index 4a5689d..6455dd8 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -3,8 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.test - feign-eureka-hello-server + server 0.0.1-SNAPSHOT jar @@ -12,7 +11,7 @@ Demo project for Spring Cloud - org.test + org.fegin.demo feign-eureka 0.0.1-SNAPSHOT .. @@ -34,11 +33,11 @@ org.springframework.cloud - spring-cloud-starter-feign + spring-cloud-starter-openfeign org.springframework.cloud - spring-cloud-starter-eureka + spring-cloud-starter-netflix-eureka-client org.springframework.boot diff --git a/server/src/main/java/demo/HelloServerApplication.java b/server/src/main/java/demo/HelloServerApplication.java deleted file mode 100644 index 08d09fa..0000000 --- a/server/src/main/java/demo/HelloServerApplication.java +++ /dev/null @@ -1,31 +0,0 @@ -package demo; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Spencer Gibb - */ -@SpringBootApplication -@EnableDiscoveryClient -@RestController -public class HelloServerApplication { - @Autowired - DiscoveryClient client; - - @RequestMapping("/") - public String hello() { - ServiceInstance localInstance = client.getLocalServiceInstance(); - return "Hello World: "+ localInstance.getServiceId()+":"+localInstance.getHost()+":"+localInstance.getPort(); - } - - public static void main(String[] args) { - SpringApplication.run(HelloServerApplication.class, args); - } -} diff --git a/server/src/main/java/org/fegin/demo/server/HelloController.java b/server/src/main/java/org/fegin/demo/server/HelloController.java new file mode 100644 index 0000000..a3546ca --- /dev/null +++ b/server/src/main/java/org/fegin/demo/server/HelloController.java @@ -0,0 +1,32 @@ +package org.fegin.demo.server; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang.math.RandomUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * @author steel + * @datetime 2019/4/26 16:13 + */ +@RestController +public class HelloController { + private final DiscoveryClient discoveryClient; + + @Autowired + public HelloController(DiscoveryClient client) { + this.discoveryClient = client; + } + + @RequestMapping("/") + public String hello() throws JsonProcessingException, InterruptedException { + Thread.sleep(RandomUtils.nextInt(2000)); + List localInstance = discoveryClient.getServices(); + return "Hello World: "+ new ObjectMapper().writeValueAsString(localInstance); + } +} diff --git a/server/src/main/java/org/fegin/demo/server/HelloServerApplication.java b/server/src/main/java/org/fegin/demo/server/HelloServerApplication.java new file mode 100644 index 0000000..0f761d8 --- /dev/null +++ b/server/src/main/java/org/fegin/demo/server/HelloServerApplication.java @@ -0,0 +1,18 @@ +package org.fegin.demo.server; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; + +/** + * @author Spencer Gibb + */ +@SpringBootApplication +@EnableDiscoveryClient +@EnableHystrixDashboard +public class HelloServerApplication { + public static void main(String[] args) { + SpringApplication.run(HelloServerApplication.class, args); + } +} diff --git a/server/src/main/java/org/fegin/demo/server/HystrixServletRegistrationBean.java b/server/src/main/java/org/fegin/demo/server/HystrixServletRegistrationBean.java new file mode 100644 index 0000000..b242181 --- /dev/null +++ b/server/src/main/java/org/fegin/demo/server/HystrixServletRegistrationBean.java @@ -0,0 +1,16 @@ +package org.fegin.demo.server; + +import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; +import org.springframework.boot.web.servlet.ServletRegistrationBean; + +/** + * @author steel + * @datetime 2019/4/28 11:46 + */ +public class HystrixServletRegistrationBean extends ServletRegistrationBean { + + public HystrixServletRegistrationBean(HystrixMetricsStreamServlet servlet, String... urlMappings) { + super(servlet, urlMappings); + } + +} diff --git a/server/src/main/java/org/fegin/demo/server/configuration/HystrixConfiguration.java b/server/src/main/java/org/fegin/demo/server/configuration/HystrixConfiguration.java new file mode 100644 index 0000000..34b6fc6 --- /dev/null +++ b/server/src/main/java/org/fegin/demo/server/configuration/HystrixConfiguration.java @@ -0,0 +1,24 @@ +package org.fegin.demo.server.configuration; + +import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; +import org.fegin.demo.server.HystrixServletRegistrationBean; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author steel + * @datetime 2019/4/28 11:40 + */ +@Configuration +public class HystrixConfiguration { + @Bean(name = "hystrixRegistrationBean") + public ServletRegistrationBean servletRegistrationBean() { + ServletRegistrationBean registration = new HystrixServletRegistrationBean( + new HystrixMetricsStreamServlet(), "/hystrix.stream"); + registration.setName("hystrixServlet"); + registration.setLoadOnStartup(1); + return registration; + } + +} diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index d2068da..a0cefb0 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -1,16 +1,63 @@ +info: + version: 1.0.0 + spring: application: name: HelloServer + cloud: + inetutils: + default-hostname: hello.server server: port: 7111 eureka: - password: password client: serviceUrl: defaultZone: https://user:${eureka.password}@localhost:8761/eureka/ instance: leaseRenewalIntervalInSeconds: 10 - metadataMap: - instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}} \ No newline at end of file + prefer-ip-address: true +# ip-address: 192.168.6.132 + hostname: hello.server + # 本地有虚拟机网卡会导致windows一直获取的是localhost + instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port} + +feign: + hystrix: + enabled: true + httpclient: + max-connections: 200 + max-connections-per-route: 50 + connection-timeout: 2000 + compression: + request: + enabled: true + response: + enabled: true + client: + config: + default: + connectTimeout: 5000 + readTimeout: 5000 + loggerLevel: basic + +management: + endpoint: + restart: + enabled: true + shutdown: + enabled: true + health: + enabled: true + hystrix: + config: + default: + execution: + isolation: + thread: + timeoutInMilliseconds: 2000 +logging: + level: + com: + netflix: debug \ No newline at end of file