SpringCloud微服务 Apollo分布式配置中心客户端获取配置(三)

前言

本小节我们将系统学习一下Apollo Client 从配置中心获取配置的几种实现方法。、
首先声明一点,Apollo github wiki中有说明JAVA客户端如何获取Apollo配置中心的配置。获取配置的方法与场景大概如下:

  • 获取配置方式
    • API
    • 整合Spring,然后通过Spring的IOC特性获取。
  • 获取配置属性
    • 获取单个属性值
    • 获取聚合对象属性值(一个对象的多个属性)
  • 获取配置命名空间
    • 获取默认的namespace(默认命名空间)
    • 自定义优先级来获取多个namespcace中的属性

本小节就不在重复说明了,这里只是提出一种想法和场景假设来更方便高效地获取配置信息。

案例

  • 第一步,模拟场景
    在实际的应用场景中一个服务节点或者一个Client的配置信息可能会有很多种形式,比如需要定义三个application.properties/dustyone.yml/customized.properties namespace才能支持节点正常运行,其中dustyone.yml中的配置信息是具有聚合对象属性特性的,而customized.properties中的只是一些零散的配置,作为一个Apollo Client要制定出比较又要的解决方案来实现配置信息的读取,同时还要实时地监听配置信息的更新状态,一旦任何一个配置项发生更新/删除/新建,客户端都应做出相应的反应机制。

  • 第二步,准备案例

    • 配置中心配置信息准备
      SpringCloud微服务 Apollo分布式配置中心客户端获取配置(三)

      • application.properties

        timeout = 1500
        server.port = 8087
        spring.application.name = microservice-deal-cloud
        eureka.client.serviceUrl.defaultZone = http://localhost:8080/eureka/
        eureka.instance.hostname = Swift
        eureka.instance.prefer-ip-address = true
        eureka.instance.metadata-map.zone = Asia
        eureka.instance.metadata-map.customizedMetadata = eurekaCustomizedMetadata
        eureka.instance.metadata-map.instanceId = ${spring.application.name}:${server.port}
        feign.hystrix.enabled = true
        
        
      • dustyone.yml

        #crm property setting
        crm:
          role: #角色
            treasurer: treasurer  #财务
            departmentManager: departmentManager #部门经理
            hr: humanResource  #HR
            customerService: customerService #客服
            dispatcherManager: dispatcherManager #派单主管
            dispatcher: dispatcher #派单员
            salesman: salesman #业务员
            admin: admin #管理员
          dictionary: #数据字典代码引用
            product: #产品类
              type: 
                orign: sys_product_type #产品类型  crm.dictionary.product.type=sys_product_type  #crm.dictionary.product.type
                tourismr: tourismr #乐享旅游
                recure: recure #康复项目
                department: department #二期床位
            customer:  #客户类
              type: sys_customer_type #客户类型
              background: sys_customer_background #客户背景
              job:  sys_customer_job #客户职业
              education: sys_customer_education #学历类型
            visit: #拜访类
              type: sys_visit_type #拜访类型
            question: #问题类
              type: sys_question_type #常见问题类型
            clue: #线索类
              channel: sys_clue_channel #线索渠道
          workflow:  #工作流配置
              deal: dealProcess #成单审批
              refund: refundProcess #退单审批
              register: registerProcess #注册审批
        
        
      • customized.properties

        customized.broker = ASIA
        
        
    • Client端准备

      • 项目结构
        SpringCloud微服务 Apollo分布式配置中心客户端获取配置(三)
      • Core Code
        • ApolloConfig.java

          /**
           * Client端需要通过Bean封装的配置信息都可以在此类中声名
           * @author Dustyone
           * @DateTime 2019年3月22日 下午3:47:14
           *
           */
          @Configuration
          @EnableApolloConfig
          public class ApolloConfig {
          
          	@Bean
          	public CrmRole findDefaultCrmRole() {
          		return new CrmRole();
          	}
          }
          
          
        • CrmRoleController.java

          /**
           * 
           * @author Dustyone
           * @DateTime 2019年3月22日 下午4:04:39
           *
           */
          @RestController
          public class CrmRoleController {
          
          	@Autowired
          	private CrmRole crmRole;
          
          	@Value("${customized.broker:Eurp}")
          	private String broker; // 注入普通字符串
          	
          	/**
          	 * 获取dustyone.yml中的配置信息
          	 * @return
          	 */
          	@GetMapping("/defaultRole")
          	public CrmRole findDefaultRole() {
          		return this.crmRole;
          	}
          	
          	
          	/**
          	 * 获取customized.properties中的信息
          	 * @return
          	 */
          	@GetMapping("/defaulCustomized")
          	public String findDefaulCustomizedConfig() {
          		return this.broker;
          	}
          }
          
        • CrmRole.java.

          /**
           * 
           * @author Dustyone
           * @DateTime 2019年3月22日 下午3:37:31
           *
           */
          @ConfigurationProperties(prefix = "crm.role")
          public class CrmRole {
          
          	/**
          	 * 财务
          	 */
          	private String treasurer;
          
          	/**
          	 * 部门经理
          	 */
          	private String departmentManager;
          
          	/**
          	 * 人事经理
          	 */
          	private String hr;
          
          	/**
          	 * 客服
          	 */
          	private String customerService;
          
          	/**
          	 * 派单经理
          	 */
          	private String dispatcherManager;
          
          	/**
          	 * 派单员
          	 */
          	private String dispatcher;
          
          	/**
          	 * 业务员
          	 */
          	private String salesman;
          
          	/**
          	 * 管理员
          	 */
          	private String admin;
          }
          
        • MicroserviceDealApolloClientPropertiesApplication.java

          @SpringBootApplication
          @EnableDiscoveryClient
          @EnableApolloConfig
          public class MicroserviceDealApolloClientPropertiesApplication {
          
          	public static void main(String[] args) throws Exception {
          		
          		SpringApplication.run(MicroserviceDealApolloClientPropertiesApplication.class, args);
          	}
          }
          
        • application.properties

          #与Apollo配置中心的APPID一致
          app.id=Dustyone163
          #设置Client的meta即配置中心地址
          apollo.meta=http://127.0.0.1:8080
          
          #开启namespace注入功能,默认注入的是application.properties/application.yml
          apollo.bootstrap.enabled = true
          #申明注入的namespace
          apollo.bootstrap.namespaces = application,dustyone.yml,customized.properties
          
        • pom.xml

          <?xml version="1.0" encoding="UTF-8"?>
          <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">
          	<modelVersion>4.0.0</modelVersion>
          
          	<artifactId>microservice-deal-apollo-client-properties</artifactId>
          	<packaging>jar</packaging>
          
          	<name>microservice-deal-apollo-client-properties</name>
          	<description>Demo project for Spring Boot</description>
          
          	<parent>
          		<groupId>com.example</groupId>
          		<artifactId>microservice-deal-parent</artifactId>
          		<version>0.0.1-SNAPSHOT</version>
          	</parent>
          
          	<dependencies>
          		<dependency>
          			<groupId>com.ctrip.framework.apollo</groupId>
          			<artifactId>apollo-client</artifactId>
          			<version>1.3.0</version>
          		</dependency>
          		<dependency>
          			<groupId>com.ctrip.framework.apollo</groupId>
          			<artifactId>apollo-core</artifactId>
          			<version>1.3.0</version>
          		</dependency>
          	</dependencies>
          </project>
          
  • 第三步,确定获取配置信息的命名空间
    官方推荐获取namespace的方式有很多种,这里不赘述。本案例实现的是通过配置namespace的方式获取。
    在application.properties中配置:

    #开启namespace注入功能,默认注入的是application.properties/application.yml
    apollo.bootstrap.enabled = true
    #申明注入的namespace
    apollo.bootstrap.namespaces = application,dustyone.yml,customized.properties
    
  • 获取配置信息

    • 通过Bean封装直接获取
      SpringCloud微服务 Apollo分布式配置中心客户端获取配置(三)
    • 通过使用@Value直接获取
      SpringCloud微服务 Apollo分布式配置中心客户端获取配置(三)
      SpringCloud微服务 Apollo分布式配置中心客户端获取配置(三)

小结

  • 不得不承认Apollo Client从配置中心获取配置的方法有很多种,但如何高效率地获取配置信息是我们需要考虑的
  • 通过Bean封装的方式获取配置信息时需要注意:
    • 需要专门编写一个config类,并使用@Configuration/@EnableApolloConfig注解修饰,并且还要将该Bean注入到Spring IOC中以方便调用。
    • Bean实体类可以考虑使用@ConfigurationProperties(prefix = “crm.role”)来做prefix修饰申明。
  • 在使用任何方式获取配置信息时都应该要考虑代码的健壮性,比如我要获取某个属性,但这个属性不在配置项中我们最好各一个default值来代替否则将出现异常。