主要有eureka作服務發現、config作分佈式配置、zuul作api-gateway、feign作客戶端負載均衡、hystrix作斷路器、turbine作聚合的monitor、graphite作指標監控。html
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies>
server: port: 8761 eureka: instance: hostname: discovery client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://discovery:${server.port}/eureka/ spring.cloud.config.discovery.enabled: true
spring: application: name: discovery
@SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main( String[] args ) { SpringApplication.run(EurekaApplication.class, args); } }
http://192.168.99.100:8761/java
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> </dependencies>
spring: cloud: config: server: native: search-locations: classpath:/config server: port: 8888
spring: application: name: config profiles: active: native eureka: instance: preferIpAddress: true client: service-url: defaultZone: http://discovery:8761/eureka/
@SpringBootApplication @EnableConfigServer @EnableEurekaClient public class ConfigApplication { public static void main( String[] args ) { SpringApplication.run(ConfigApplication.class,args); } }
http://192.168.99.100:8888/review/default/mastergit
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>com.codecraft</groupId> <artifactId>common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--調用其餘微服務--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <!--使用hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency> </dependencies>
server: port: 9001 endpoints: restart: enabled: true shutdown: enabled: true health: sensitive: false ribbon: eureka: enabled: true
spring: application: name: product cloud: config: uri: http://config:8888 encrypt: failOnError: false eureka: instance: preferIpAddress: true client: registerWithEureka: true fetchRegistry: true serviceUrl: defaultZone: http://discovery:8761/eureka/
@FeignClient("recommend") public interface RemoteRecommendService { @RequestMapping(method = RequestMethod.GET,value = "/recommend") public List<Recommendation> getRecommendations( @RequestParam(value = "productId", required = true) int productId); }
@RestController public class ProductController { private static final Logger LOG = LoggerFactory.getLogger(ProductController.class); @Autowired private SetProcTimeBean setProcTimeBean; @Autowired RemoteRecommendService remoteRecommendService; @RequestMapping("/product/recommends") @HystrixCommand(fallbackMethod = "callRecommendFallback", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "100") }) public List<Recommendation> remoteRecommends(@RequestParam(value = "productId", required = true) int productId){ return remoteRecommendService.getRecommendations(productId); } public List<Recommendation> callRecommendFallback(int productId) { return Collections.emptyList(); } @RequestMapping("/product/{productId}") public Product getProduct(@PathVariable int productId) { int pt = setProcTimeBean.calculateProcessingTime(); LOG.info("/product called, processing time: {}", pt); sleep(pt); LOG.debug("/product return the found product"); return new Product(productId, "name", 123); } }
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients @EnableCircuitBreaker @EnableHystrix @EnableHystrixDashboard public class ProductApplication { private static final Logger LOG = LoggerFactory.getLogger(ProductApplication.class); public static void main(String[] args){ SpringApplication.run(ProductApplication.class,args); LOG.info("Register ShutdownHook"); Runtime.getRuntime().addShutdownHook(new Thread(){ @Override public void run() { LOG.info("Shutting down product service, unregister from Eureka!"); DiscoveryManager.getInstance().shutdownComponent(); } }); } }
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies>
server: port: 10000 #sidecar: #port: 8000 endpoints: restart: enabled: true shutdown: enabled: true health: sensitive: false zuul: ignored-services: "*" routes: product: path: /product/** url: http://product:9001/product recommend: path: /recommend/** url: http://recommend:9002/recommend review: path: /review/** url: http://review:9003/review
spring: application: name: gateway cloud: config: uri: http://config:8888 encrypt: failOnError: false eureka: instance: preferIpAddress: true client: registerWithEureka: true fetchRegistry: true serviceUrl: defaultZone: http://discovery:8761/eureka/
@SpringBootApplication @EnableCircuitBreaker @EnableDiscoveryClient @EnableZuulProxy public class ApiGatewayApplication { public static void main( String[] args ) { new SpringApplicationBuilder(ApiGatewayApplication.class).web(true).run(args); } }
http://192.168.99.100:10000/recommend?productId=1
轉向
http://192.168.99.100:9002/recommend?productId=1github
http://192.168.99.100:9001/product/recommends?productId=1
http://192.168.99.100:9001/hystrixweb
http://192.168.99.100:9003/hystrix/monitor?stream=http%3A%2F%2F192.168.99.100%3A9001%2Fhystrix.streamspring
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-turbine</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!--使用hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency> </dependencies>
server: port: 8889 eureka: instance: preferIpAddress: true client: registerWithEureka: true fetchRegistry: true serviceUrl: defaultZone: http://discovery:8761/eureka/ turbine: appConfig: product,review clusterNameExpression: new String("default")
spring: application: name: turbine cloud: config: uri: http://config:8888 encrypt: failOnError: false
@SpringCloudApplication @EnableTurbine @EnableHystrixDashboard public class TurbineApplication { public static void main(String[] args){ SpringApplication.run(TurbineApplication.class,args); } }
http://192.168.99.100:9001/hystrixbootstrap
http://192.168.99.100:9001/product/recommends?productId=1
http://192.168.99.100:9003/review/product/100api
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- metrics --> <dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-core</artifactId> <version>${dropwizard-metrics.version}</version> </dependency> <dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-graphite</artifactId> <version>${dropwizard-metrics.version}</version> </dependency> <dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-annotation</artifactId> <version>${dropwizard-metrics.version}</version> </dependency> <dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-jvm</artifactId> <version>${dropwizard-metrics.version}</version> </dependency> <dependency> <groupId>com.ryantenney.metrics</groupId> <artifactId>metrics-spring</artifactId> <version>3.1.0</version> <exclusions> <exclusion> <artifactId>spring-beans</artifactId> <groupId>org.springframework</groupId> </exclusion> <exclusion> <artifactId>spring-aop</artifactId> <groupId>org.springframework</groupId> </exclusion> </exclusions> </dependency> </dependencies>
@Configuration @AutoConfigureAfter(MetricRepositoryAutoConfiguration.class) @ConditionalOnProperty(prefix = "graphite", name = "enabled", matchIfMissing = true) @EnableConfigurationProperties(GraphiteProperties.class) @EnableScheduling @EnableMetrics public class GraphiteAutoConfiguration { private static final Logger logger = LoggerFactory.getLogger(GraphiteAutoConfiguration.class); @Bean public MetricsConfigurerAdapter metricsConfigurerAdapter(final GraphiteProperties graphiteProperties) { return new GraphiteReportingManager(graphiteProperties); } /** * https://qbgbook.gitbooks.io/spring-boot-reference-guide-zh/content/IV.%20Spring%20Boot%20features/36.3.3.%20Property%20conditions.html * @param graphiteProperties * @param metricRegistry * @return */ @Bean @ConditionalOnProperty(value = "graphite.host",matchIfMissing = true) public ConsoleReporter consoleReporter(GraphiteProperties graphiteProperties,MetricRegistry metricRegistry) { ConsoleReporter.Builder builder = ConsoleReporter.forRegistry(metricRegistry); ConsoleReporter reporter = builder.build(); reporter.start(graphiteProperties.getReportInterval(), TimeUnit.MILLISECONDS); return reporter; } }
public class GraphiteReportingManager extends MetricsConfigurerAdapter implements DisposableBean { private final Logger logger = LoggerFactory.getLogger(getClass()); private GraphiteProperties props; public GraphiteReportingManager(GraphiteProperties props) { this.props = props; } @Override public void configureReporters(MetricRegistry metricRegistry) { //gc的metrics,目前看來每秒發送一次貌似太頻繁,能夠另起一個reporter進行 metricRegistry.register("jvm.gc", new GarbageCollectorMetricSet()); metricRegistry.register("jvm.mem", new MemoryUsageGaugeSet()); metricRegistry.register("jvm.thread-states", new ThreadStatesGaugeSet()); logger.info("graphite host:{},port:{}", props.getHost(), props.getPort()); GraphiteReporter reporter = GraphiteReporter.forRegistry(metricRegistry) .prefixedWith(props.getPrefix()) // .convertRatesTo(TimeUnit.SECONDS) .convertDurationsTo(TimeUnit.MILLISECONDS) .filter(MetricFilter.ALL) .build(createSender(props)); registerReporter(reporter); reporter.start(1L, TimeUnit.SECONDS); } @Override public void destroy() throws Exception { super.destroy(); } private GraphiteSender createSender(GraphiteProperties props) { switch (props.getSenderType()) { case udp: return new GraphiteUDP(props.getHost(), props.getPort()); case tcp: return new Graphite(props.getHost(), props.getPort()); case pickled: return new PickledGraphite(props.getHost(), props.getPort()); default: return new GraphiteUDP(props.getHost(), props.getPort()); } } }
http://192.168.99.100:8070/app