管理配置

管理配置的四个原则

  • 隔离
    将服务配置信息与服务的实例物理部署完全分离
  • 抽象
    抽象服务接口背后的配置数据访问
  • 集中
    将应用程序配置集中到尽可能少的存储库中
  • 稳定
    实现高可用和冗余

建立Spring Cloud 配置服务器

Spring Cloud配置服务器是构建在Spring Boot之上基于REST的应用程序。

添加一个新的项目,称为confsvr。

添加如下依赖:

    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency>

我们会使用license服务作为使用Spring Cloud 配置服务的客户端。为了简单,我们将使用三个环境来设置应用的配置数据:default,用于本地运行;dev以及prod。

在每个环境中,将会设置两个配置属性

  • 由license服务直接使用的示例属性
  • 存储license服务数据的Postgres数据的配置属性

  1. 增加@EnableConfigServer注解
@SpringBootApplication
@EnableConfigServer
public class ConfsvrApplication {public static void main(String[] args) {SpringApplication.run(ConfsvrApplication.class, args);}
}
  1. 添加bootstrap.yml文件
server:port: 8888
spring:cloud:config:server:git:uri: https://gitee.com/safika/eagle-eye-config.git# 查询配置文件的位置,可通过,分隔search-paths: licensea

启动,访问http://localhost:8888/license/dev,可以看到输出如下:

{name: "license",profiles: ["dev"],label: null,version: "13fc97719dca692cc0fe793eb62bedfca42766da",state: null,propertySources: [{name: "https://gitee.com/safika/eagle-eye-config.git/license/license-dev.yml",source: {tracer.property: "I AM THE DEFAULT",spring.jpa.show - sql: true,management.security.enabled: false,endpoints.health.sensitive: false}}]
}

新建配置服务客户端

  1. 添加依赖
     <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-client</artifactId></dependency><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency>

我们使用h2嵌入式数据库用于开发测试,因为Spring boot能帮我自动配置默认属性,因此不需要我们自己写默认数据库名称,驱动,用户名,密码等。

  1. 指定配置文件
spring:application:# 和配置服务器指定的目录相同name: licenseprofiles:active: devcloud:config:uri: http://localhost:8888 # 指定配置服务器的地址

关键步骤已经完成了,接下来是一些其他类的编写

package com.learn.license.config;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component
public class ServiceConfig{// 通过@Value注解注入配置文件中的属性@Value("${tracer.property}")private String exampleProperty;public String getExampleProperty(){return exampleProperty;}
}package com.learn.license.controllers;import com.learn.license.model.License;
import com.learn.license.services.LicenseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** @RequestMapping 暴露Controller的根URL* {organizationId}是一个占位符,表示URL在每次调用会传递一个organizationId参数*/
@RestController
@RequestMapping(value = "/v1/organizations/{organizationId}/licenses")
public class LicenseServiceController {@Autowiredprivate LicenseService licenseService;@RequestMapping(value="/",method = RequestMethod.GET)public List<License> getLicenses(@PathVariable("organizationId") String organizationId) {return licenseService.getLicensesByOrg(organizationId);}@RequestMapping(value="/{licenseId}",method = RequestMethod.GET)public License getLicenses( @PathVariable("organizationId") String organizationId,@PathVariable("licenseId") String licenseId) {return licenseService.getLicense(organizationId,licenseId);}@RequestMapping(value="{licenseId}",method = RequestMethod.PUT)public String updateLicenses( @PathVariable("licenseId") String licenseId) {return String.format("This is the put");}@RequestMapping(value="/",method = RequestMethod.POST)public void saveLicenses(@RequestBody License license) {licenseService.saveLicense(license);}@RequestMapping(value="{licenseId}",method = RequestMethod.DELETE)@ResponseStatus(HttpStatus.NO_CONTENT)public String deleteLicenses( @PathVariable("licenseId") String licenseId) {return String.format("This is the Delete");}
}package com.learn.license.model;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "licenses")
public class License{@Id@Column(name = "license_id", nullable = false)private String licenseId;@Column(name = "organization_id", nullable = false)private String organizationId;@Column(name = "product_name", nullable = false)private String productName;@Column(name = "license_type", nullable = false)private String licenseType;@Column(name = "license_max", nullable = false)private Integer licenseMax;@Column(name = "license_allocated", nullable = false)private Integer licenseAllocated;@Column(name="comment")private String comment;public License withComment(String comment){this.setComment(comment);return this;}}package com.learn.license.repository;import com.learn.license.model.License;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;import java.util.List;@Repository
public interface LicenseRepository  extends CrudRepository<License,String> {List<License> findByOrganizationId(String organizationId);License findByOrganizationIdAndLicenseId(String organizationId,String licenseId);
}package com.learn.license.services;import com.learn.license.config.ServiceConfig;
import com.learn.license.model.License;
import com.learn.license.repository.LicenseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.UUID;@Service
public class LicenseService {@Autowiredprivate LicenseRepository licenseRepository;@AutowiredServiceConfig config;public License getLicense(String organizationId, String licenseId) {License license = licenseRepository.findByOrganizationIdAndLicenseId(organizationId, licenseId);return license.withComment(config.getExampleProperty());}public List<License> getLicensesByOrg(String organizationId){return licenseRepository.findByOrganizationId( organizationId );}public void saveLicense(License license){license.setLicenseId( UUID.randomUUID().toString());licenseRepository.save(license);}public void updateLicense(License license){licenseRepository.save(license);}public void deleteLicense(License license){licenseRepository.delete( license.getLicenseId());}}

以及data.sql(放到src/resource目录下,一般用于初始化数据)

DELETE FROM licenses;INSERT INTO licenses (license_id,  organization_id, license_type, product_name, license_max, license_allocated)
VALUES ('f3831f8c-c338-4ebe-a82a-e2fc1d1ff78a', '1', 'user','customer-crm-co', 100,5);
INSERT INTO licenses (license_id,  organization_id, license_type, product_name, license_max, license_allocated)
VALUES ('t9876f8c-c338-4abc-zf6a-ttt1', '1', 'user','suitability-plus', 200,189);
INSERT INTO licenses (license_id,  organization_id, license_type, product_name, license_max, license_allocated)
VALUES ('38777179-7094-4200-9d61-edb101c6ea84', '2', 'user','HR-PowerSuite', 100,4);
INSERT INTO licenses (license_id,  organization_id, license_type, product_name, license_max, license_allocated)
VALUES ('08dbe05-606e-4dad-9d33-90ef10e334f9', '2', 'core-prod','WildCat Application Gateway', 16,16);

启动,访问http://localhost:8080/v1/organizations/1/licenses/f3831f8c-c338-4ebe-a82a-e2fc1d1ff78a

得到输出如下

{"licenseId": "f3831f8c-c338-4ebe-a82a-e2fc1d1ff78a","organizationId": "1","productName": "customer-crm-co","licenseType": "user","licenseMax": 100,"licenseAllocated": 5,"comment": "I AM THE DEFAULT"
}

完成项目地址: https://gitee.com/safika/eagle-eye

《Spring微服务实战》读书笔记——通过配置服务器来管理配置相关推荐

  1. springcloud微服务实战 学习笔记五 Hystrix服务降级 Hystrix依赖隔离 断路器

    ###服务降级 在之前eureka-consumer的基础上 添加依赖 <dependency><groupId>org.springframework.cloud</g ...

  2. java微服务实战.pdf_Spring微服务实战 ([美]约翰·卡内尔) 中文完整pdf扫描版[172MB]...

    <Spring微服务实战>以一个名为EagleEye的项目为主线,介绍云.微服务等概念以及Spring Boot和Spring Cloud等诸多Spring项目,并介绍如何将EagleEy ...

  3. Spring Cloud 微服务实战笔记

    Spring Cloud 微服务实战笔记 微服务知识 传统开发所有业务逻辑都在一个应用中, 开发,测试,部署随着需求增加会不断为单个项目增加不同业务模块:前端展现也不局限于html视图模板的形式,后端 ...

  4. 《ASP.NET Core 微服务实战》-- 读书笔记(第9章)

    第 9 章 微服务系统的配置 微服务系统中的配置需要关注更多其他方面的因素,包括: 配置值的安全读写 值变更的审计能力 配置信息源本身的韧性和可靠性 少量的环境变量难以承载大型.复杂的配置信息 应用要 ...

  5. SpringCloud Alibaba微服务实战(四) - Nacos Config 配置中心

    说在前面 Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平台.Nacos Config就是一个类似于SpringCloud Config的配置中心. 一.启动N ...

  6. Spring Cloud 微服务实战系列-Spring Boot再次入门(一)

    导语   看到标题大家都疑惑,为什么叫做再入门呢?在之前的博客中也分享过相关的内容,但为了让Spring Cloud 微服务实战系列更加完整就再次编写一个入门的内容,也是为了这个系列的内容更加的完整, ...

  7. 手把手,嘴对嘴教你Spring Cloud 微服务实战 -- 前言

    Spring Cloud 总结 博主接触到Spring Cloud 大概已经一年多了,当时Spring Cloud微服务框架已经是潮流了,不会一点都不好意思出去面试.并且主流技术基本上都在谈论微服务, ...

  8. SpringCloud Alibaba微服务实战(五) - Sentinel实现限流熔断

    什么是Sentinel? 请查看文章:SpringCloud Alibaba微服务实战(一) - 基础环境搭建 构建服务消费者cloud-sentinel进行服务调用 服务创建请查看文章:Spring ...

  9. SpringCloud Alibaba微服务实战(三) - Nacos服务创建消费者(Feign)

    什么是Feign Feign 是一个声明式的伪 Http 客户端,它使得写 Http 客户端变得更简单.使用 Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用 Feign 注解和 ...

  10. 微服务实战(六):选择微服务部署策略

    http://dockone.io/article/1066 微服务实战(六):选择微服务部署策略 [编者的话]这篇博客是用微服务建应用的第六篇,第一篇介绍了微服务架构模板,并且讨论了使用微服务的优缺 ...

最新文章

  1. PUTTY登录树莓派Network error:Software caused connection abort
  2. portainer容器可视化管理部署简要笔记
  3. 11月16日 个人战立会议内容报告
  4. PL/SQL程序设计以及安全管理实验遇到的问题及解决
  5. python报错defined_python问卷星报错NameError: name 'filename' is not defined
  6. 好文推荐 | 从数据的属性看数据资产
  7. 利用ptrace和memfd_create混淆程序名和参数
  8. JSP 文件上传下载系列之二[Commons fileUpload]
  9. XSS的基本概念和原理
  10. 《机器人自动化:建模、仿真与控制》——第2章 仿真
  11. ecshop添加404页面
  12. 针对利用tzselect修改时间及ln -sf 修改系统时间不好使的情况 linux 6.5
  13. 7.2.3 十字链表
  14. html中好看的英文字体,一组漂亮的英文字体在线演示
  15. 扫普通二维码打开小程序,可进入体验版
  16. 负反馈放大电路实验报告
  17. 设计递归函数模拟汉诺塔游戏
  18. 18 | 需求管理:太多人给你安排任务,怎么办?
  19. 与大佬沟通,聊到四层代理和七层代理分别指的是什么这个问题时?会擦出什么火花呢
  20. 06_USB设备驱动

热门文章

  1. 测试管理中的一个问题—功能点覆盖还是功能测试点覆盖
  2. 【排序算法】快速排序-迭代方法
  3. 技术人生:立志、勤学、改过、责善
  4. 如何开启深度学习之旅?这三大类125篇论文为你导航(附资源下载)
  5. 170819-关于JSTL的知识点
  6. Visual studio 代码管理工具Git
  7. 看了看几个数据库厂商的发展历史
  8. 一天一个小技巧(1)——CSDN编辑器中文字颜色、尺寸、类型修改
  9. 【Selenium2】【Shell】
  10. 更多和最小生成树相关的问题