Spring Cloud系列之Commons - 2. 服务发现 - 如何通过配置文件配置服务实例?(下)

简介: Spring Cloud系列之Commons - 2. 服务发现 - 如何通过配置文件配置服务实例?(下)

我们可以直接通过 uri 配置,也可以具体配置其中的 host,port 和 isSecure,两者是等价的。例如:


spring:
  cloud:
    discovery:
      client:
        # SimpleDiscoveryClient与SimpleReactiveDiscoveryClient的配置
        simple:
          instances:
            #微服务1
            service1:
              #实例1
              - host: instance1 #地址
                port: 8080 #端口


等价于

spring:
  cloud:
    discovery:
      client:
        # SimpleDiscoveryClient与SimpleReactiveDiscoveryClient的配置
        simple:
          instances:
            #微服务1
            service1:
              #实例1
              - uri: http://instance1:8080


instanceId 不一定需要指定,serviceId 会根据实例配置的上一级取,就算自己配置了,例如:

spring:
  cloud:
    discovery:
      client:
        # SimpleDiscoveryClient与SimpleReactiveDiscoveryClient的配置
        simple:
          instances:
            #微服务1
            service1:
              #实例1
              - host: instance1 #地址
                port: 8080 #端口
                serviceId: service2 #无效,实际还是service1


serviceId 还是实际合理的那个,也就是 service1。

这些机制在后面的源码分析就会理解了。 我们的测试代码会用到 Spring Boot 的事件机制,也就是在 ApplicationContext 到某一生命周期的时候,这些事件会被发布出来,由实现了对应事件的ApplicationListener接口的 Bean 消费,Spring boot 中,事件主要包括:


  • ApplicationStartingEvent:这个是spring boot应用一开始启动时,发出的事件,只是用来标识,应用开始启动了,一般没什么用
  • ApplicationEnvironmentPreparedEvent:这个是在创建好Environment(通过上下文配置,判断到底创建StandardServletEnvironment(针对Servlet环境),StandardReactiveWebEnvironment(针对Reactive环境)还是StandardEnvironment(针对无servlet环境))之后发出的事件。
  • ApplicationContextInitializedEvent: 这个是在创建好Context并调用ApplicationContextInitializer初始化context之后发布这个事件,在加载bean信息之前
  • ApplicationPreparedEvent:加载bean信息之后,但是还没有创建bean的时候,发步这个事件。这个事件是和调用ApplicationContextAware设置ApplicationContext一起进行的,可以看出,setApplicationContext方法里面不能去获取bean,因为bean可能还没有初始化完成
  • ApplicationStartedEvent: 加载初始化各种需要的bean并依赖注入之后,在运行ApplicationRunner做一些用户自定义的初始化操作之前,会发布这个事件。
  • ApplicationReadyEvent:运行ApplicationRunner做一些用户自定义的初始化操作之后,会发布这个事件。


我们使用ApplicationReadyEventApplicationListener确保所有的DiscoveryClient都初始化完成并可以使用作为测试类。


编写测试类: TestSimpleDiscoveryClient


/**
 * 通过消费 ApplicationReadyEvent 来确保 DiscoveryClient 初始化完成并可用
 */
@Slf4j
@Component
public class TestSimpleDiscoveryClient implements ApplicationListener<ApplicationReadyEvent> {
    /**
     * 初始化的方法返回类型是 DiscoveryClient 并且不是 Primary,这里只能通过 @Resource 自动装载不能通过 @Autowired
     * 这里不排除以后返回类型修改为 SimpleDiscoveryClient 的可能性
     * @see org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration
     */
    @Resource
    private SimpleDiscoveryClient simpleDiscoveryClient;
    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        List<String> services = simpleDiscoveryClient.getServices();
        services.forEach(serviceId -> {
            log.info("{}: {}", serviceId, simpleDiscoveryClient.getInstances(serviceId));
        });
    }
}


TestSimpleReactiveDiscoveryClient


/**
 * 通过消费 ApplicationReadyEvent 来确保 DiscoveryClient 初始化完成并可用
 */
@Slf4j
@Component
public class TestSimpleReactiveDiscoveryClient implements ApplicationListener<ApplicationReadyEvent> {
    @Autowired
    private SimpleReactiveDiscoveryClient simpleReactiveDiscoveryClient;
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        simpleReactiveDiscoveryClient.getServices().subscribe(serviceId -> {
            simpleReactiveDiscoveryClient.getInstances(serviceId).collect(Collectors.toList()).subscribe(serviceInstances -> {
                log.info("{}: {}", serviceId, serviceInstances);
            });
        });
    }
}


启动类:DiscoveryClientMain


@SpringBootApplication
public class DiscoveryClientMain {
    public static void main(String[] args) {
        SpringApplication.run(DiscoveryClientMain.class, args);
    }
}


启动后,可以看到日志:


2021-01-19 09:38:05.646  INFO 6168 --- [           main] .h.s.c.i.s.d.s.TestSimpleDiscoveryClient : service2: [DefaultServiceInstance{instanceId='instance3:80', serviceId='service2', host='instance3', port=80, secure=false, metadata={}}, DefaultServiceInstance{instanceId='null', serviceId='service2', host='instance4', port=8080, secure=true, metadata={}}]
2021-01-19 09:38:05.647  INFO 6168 --- [           main] .h.s.c.i.s.d.s.TestSimpleDiscoveryClient : service1: [DefaultServiceInstance{instanceId='instance:8080', serviceId='service1', host='instance1', port=8080, secure=false, metadata={}}, DefaultServiceInstance{instanceId='null', serviceId='service1', host='instance2', port=443, secure=true, metadata={}}]
2021-01-19 09:38:05.913  INFO 6168 --- [           main] .s.d.s.TestSimpleReactiveDiscoveryClient : service2: [DefaultServiceInstance{instanceId='instance3:80', serviceId='service2', host='instance3', port=80, secure=false, metadata={}}, DefaultServiceInstance{instanceId='null', serviceId='service2', host='instance4', port=8080, secure=true, metadata={}}]
2021-01-19 09:38:05.913  INFO 6168 --- [           main] .s.d.s.TestSimpleReactiveDiscoveryClient : service1: [DefaultServiceInstance{instanceId='instance:8080', serviceId='service1', host='instance1', port=8080, secure=false, metadata={}}, DefaultServiceInstance{instanceId='null', serviceId='service1', host='instance2', port=443, secure=true, metadata={}}]


相关文章
|
3天前
|
SQL Java 数据库连接
(自用)Spring常用配置
(自用)Spring常用配置
12 0
|
26天前
|
负载均衡 Java API
Spring Cloud 面试题及答案整理,最新面试题
Spring Cloud 面试题及答案整理,最新面试题
127 1
|
25天前
|
SQL Java 数据库连接
挺详细的spring+springmvc+mybatis配置整合|含源代码
挺详细的spring+springmvc+mybatis配置整合|含源代码
33 1
|
26天前
|
Java Nacos Sentinel
Spring Cloud Alibaba 面试题及答案整理,最新面试题
Spring Cloud Alibaba 面试题及答案整理,最新面试题
128 0
|
27天前
|
SpringCloudAlibaba Java 持续交付
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
120 0
|
3天前
|
JSON Java 数据库连接
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
11 1
|
3天前
|
Java 数据库连接 Spring
简化配置,提高灵活性:Spring中的参数化配置技巧
简化配置,提高灵活性:Spring中的参数化配置技巧
14 0
|
3天前
|
Java Shell 测试技术
一次配置,多场景适用:Spring Boot多套配置文件的深度剖析
一次配置,多场景适用:Spring Boot多套配置文件的深度剖析
15 0
一次配置,多场景适用:Spring Boot多套配置文件的深度剖析
|
7天前
|
Java 容器
SpringBoot使用配置注解开启自动配置功能&整合spring-boot-configuration-processor
SpringBoot使用配置注解开启自动配置功能&整合spring-boot-configuration-processor
11 0
|
14天前
|
负载均衡 网络协议 Java
构建高效可扩展的微服务架构:利用Spring Cloud实现服务发现与负载均衡
本文将探讨如何利用Spring Cloud技术实现微服务架构中的服务发现与负载均衡,通过注册中心来管理服务的注册与发现,并通过负载均衡策略实现请求的分发,从而构建高效可扩展的微服务系统。