Eureka是一个Netflix开元的服务发现组件,本身是一个基于REST的服务。它包含Server和Client两部分。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
#应用名称
spring.application.name=octopus-eureka-server
#端口号
server.port=8761
#配置启用所有的监控端点
management.endpoints.web.exposure.include=*
#注册中心地址(可配置为集群)
eureka.client.service-url.default-zone=http://localhos:${server.port}/eureka/
#false 表示不向注册中心注册自己
eureka.client.register-with-eureka=false
#false 表示不从注册中心获取注册信息
eureka.client.fetch-registry=false
/**
* code is far away from bug with the animal protecting
* @date 2018/12/4 14:17
* @description : 注册中心启动引导类 {@link SpringBootApplication}
**/
@EnableEurekaServer
@SpringBootApplication
public class OctopusEurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(OctopusEurekaServerApplication.class, args);
}
}
Config用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持, 它分为服务端与客户端两个部分。。
服务端也称为分布式配置中心, 它是一个独立的微服务应用, 用来连接配置仓库并为客户端提供获取配置信息、加密/解密信息等访问接口;
客户端则是微服务架构中的各个微服务应用或基础设施, 它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-config-serverartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
#端口号
server.port=8060
#应用名
spring.application.name=octopus-config-server
#配置启用所有的监控端点
management.endpoints.web.exposure.include=*
#git仓库配置
spring.cloud.config.server.git.uri=http://192.168.0.113/sunxiaojun/octopus.cloud.config.profile.git
spring.cloud.config.server.git.username=sunxiaojun
spring.cloud.config.server.git.password=XIAOjun901008
#注册中心地址(可配置多个)
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
/**
* code is far away from bug with the animal protecting
* @date 2018/12/4 14:17
* @description : 配置中心启动引导类 {@link SpringBootApplication}
**/
@EnableConfigServer
@SpringBootApplication
public class OctopusConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(OctopusConfigServerApplication.class, args);
}
}
config配置中心会在应用启动的时候,将远程服务器(Git,Svn等)上的配置文件缓存到本地,生成一个List
/**
* code is far away from bug with the animal protecting
* @date 2018/12/4 14:17
* @description : {@link PropertySourceLoader}
* 自定义JSON格式配置文件加载
* 启动时,通过自动加载(AutoConfiguration)对Bean进行注册
* 在读取配置时,根据配置文件的后缀选用不同的配置文件读取方案
**/
public class JsonPropertiesSourceLoader implements PropertySourceLoader {
@Override
public String[] getFileExtensions() {
return new String[]{"json"};
}
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
Map<String, ?> properties = loadJsonProperties(resource);
if (properties.isEmpty()) {
return Collections.emptyList();
}
return Collections
.singletonList(new OriginTrackedMapPropertySource(name, properties));
}
/**
* 读取JSON格式配置文件
* @param resource
* @return
*/
private Map<String, ?> loadJsonProperties(Resource resource) {
FileInputStream is = null;
try {
File file = resource.getFile();
is = new FileInputStream(file);
JsonNode jsonNode = objectMapper.readTree(is);
Map<String, Object> result = objectMapper.convertValue(jsonNode, Map.class);
is.close();
return result;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
在resources目录下建一个META-INF/spring.factories配置文件,这个配置文件是Spring实现自动加载定义的文件
# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
com.octopus.cloud.configserver.env.JsonPropertiesSourceLoader
启动后,即可解析.json格式的配置文件。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-config-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-busartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-stream-binder-rabbitartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-zipkinartifactId>
dependency>
#修改日志权限
logging.level.root=INFO
logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG
#端口号
server.port=1000
#应用名称
spring.application.name=octopus-provider
#配置启用所有的监控端点
management.endpoints.web.exposure.include=*
#注册中心地址
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
#微服务配置
spring.cloud.config.profile=dev
spring.cloud.config.label=master
#开启通过微服务发现组件访问Config Server功能
spring.cloud.config.discovery.enabled=true
#跟踪总线事件
spring.cloud.bus.trace.enabled=true
#指定Config Server在服务发现组件中的ServiceId
spring.cloud.config.discovery.service-id=octopus-config-server
#RabbitMQ配置
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
本地的application.proerties可以配置为空,下面的配置为远程配置中心文件
#端口号
server.port=1000
eureka.instance.prefer-ip-address=true
eureka.instance.metadata-map.my-metadata:我自定义的元数据
#配置日志
#logging.level.root=INFO
#logging.level.org.hibernate=INFO
#logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
#logging.level.org.hibernate.type.descriptor.sql.BasicExtractor=TRACE
#修改日志权限
logging.level.root=INFO
logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG
#配置采样比例
spring.sleuth.sampler.probability=1.0
/**
* code is far away from bug with the animal protecting
* @date 2018/12/4 14:17
* @description : 服务提供者启动引导类 {@link SpringBootApplication}
**/
@EnableDiscoveryClient
@SpringBootApplication
public class OctopusProviderApplication {
public static void main(String[] args) {
SpringApplication.run(OctopusProviderApplication.class, args);
}
}
@RestController
public class ProviderController {
@GetMapping("/{id}")
public Optional<String> findById(@PathVariable Long id) {
return Optional.ofNullable(UUID.randomUUID().toString().toUpperCase());
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-config-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-busartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-stream-binder-rabbitartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-zipkinartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-netflix-hystrix-streamartifactId>
dependency>
#修改日志权限
logging.level.root=INFO
logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG
#应用名称
spring.application.name=octopus-consumer
#配置启用所有的监控端点
management.endpoints.web.exposure.include=*
#注册中心地址
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
eureka.instance.prefer-ip-address=true
#微服务配置
spring.cloud.config.profile=dev
spring.cloud.config.label=master
#开启通过微服务发现组件访问Config Server功能
spring.cloud.config.discovery.enabled=true
#跟踪总线事件
spring.cloud.bus.trace.enabled=true
#指定Config Server在服务发现组件中的ServiceId
spring.cloud.config.discovery.service-id=octopus-config-server
#RabbitMQ配置
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
本地的application.proerties可以配置为空,下面的配置为远程配置中心文件
#端口号
server.port=2000
eureka.instance.prefer-ip-address=true
eureka.instance.metadata-map.my-metadata:我自定义的元数据
#配置日志
#logging.level.root=INFO
#logging.level.org.hibernate=INFO
#logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
#logging.level.org.hibernate.type.descriptor.sql.BasicExtractor=TRACE
#配置采样比例
spring.sleuth.sampler.probability=1.0
/**
* code is far away from bug with the animal protecting
* @date 2018/12/4 14:17
* @description : 服务消费者启动引导类 {@link SpringBootApplication}
**/
@EnableDiscoveryClient
@SpringBootApplication
@EnableCircuitBreaker
public class OctopusComsumerApplication {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
/**
* 因2.X后的版本不在开放hystrix.stream端点,需要自定义配置
* @return
*/
@Bean
public ServletRegistrationBean getServlet(){
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
public static void main(String[] args) {
SpringApplication.run(OctopusComsumerApplication.class, args);
}
}
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/user/{id}")
@HystrixCommand(fallbackMethod = "findByIdFallback")
public String findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://OCTOPUS-PROVIDER/" + id, String.class);
}
public String findByIdFallback(Long id){
return "默认用户";
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboardartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
#端口号
server.port=8090
#应用名称
spring.application.name=octopus-hystrix-dashboard
#配置启用所有的监控端点
management.endpoints.web.exposure.include=*
#注册中心地址
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
/**
* code is far away from bug with the animal protecting
* @date 2018/12/4 14:17
* @description : Hystrix监控平台启动引导类 {@link SpringBootApplication}
**/
@EnableDiscoveryClient
@SpringBootApplication
@EnableHystrixDashboard
public class OctopusHystrixDashboardApplication {
public static void main(String[] args) {
SpringApplication.run(OctopusHystrixDashboardApplication.class, args);
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-netflix-hystrix-streamartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-stream-binder-rabbitartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-turbine-streamartifactId>
dependency>
#端口号
server.port=8031
#项目名称
spring.application.name=octopus-hystrix-turbine
#配置启用所有的监控端点
management.endpoints.web.exposure.include=*
#注册中心地址
eureka.client.service-url.default-zone=http://com.octopus.cloud:8761/eureka/
eureka.instance.prefer-ip-address=true
#turbine聚合
# 指定聚合哪些集群,多个使用","分割,默认为default。可使用http://.../turbine.stream?cluster={clusterConfig之一}访问
#turbine.aggregator.cluster-config=default
#turbine.cluster-name-expression="default"
#turbine.app-config=octopus-consumer
#turbine.combine-host-port=true
#这里和被监控启动类里的 registrationBean.addUrlMappings("/hystrix.stream")一致
#turbine.instanceUrlSuffix=/hystrix.stream
#RabbitMQ配置
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
/**
* code is far away from bug with the animal protecting
* @date 2018/12/4 14:17
* @description : Hystrix监控平台启动引导类 {@link SpringBootApplication}
**/
@EnableDiscoveryClient
@SpringBootApplication
@EnableTurbineStream
public class OctopusHystrixTurbineApplication {
public static void main(String[] args) {
SpringApplication.run(OctopusHystrixTurbineApplication.class, args);
}
}
使用RabbitMQ使用数据时,目前发现服务消费者发送到的熔断信息的数据为能进入聚合监控,跟踪源码得知,在消费者应用和聚合监控的医用启动时,RabbitMQ中的Exchange:hystrixStreamOutput与turbineStreamInput未进行绑定,导致写入hystrixStreamOutput的数据未能传入turbineStreamInput中,这边需要手动建立一个绑定关系:
2.X之后,SpringCloud不在集成Zipkin,可以使用开源的Zipkin进行二次开发或使用打包好的zipkin.jar,因zipkin.jar是SpringBoot项目,可以直接使用java -jar zipkin.jar 启动,默认端口为 9411,使用rabbitmq作为进行数据收集。
curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar --zipkin.collector.rabbitmq.addresses=localhost
依次启动
至此,基于SpringBoot2.X的微服务架构,整合Eureka注册中心、Config配置中心、Bus消息总线、Hystrix熔断、Turbine聚合监控、Zipkin服务跟踪搭建完成。
1、聚合监控 Turbine 需要手动对RabbitMQ中的Exchange 进行绑定;
2、Zipkin在SpringBoot2.X之后已不在集成,可通过源码进行编译或使用打包好的jar包;
源码地址