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

版权声明:欢迎转载,转载请指明出处 https://blog.csdn.net/yjw123456/article/details/83513465

管理配置

管理配置的四个原则

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

建立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: license
  profiles:
    active: dev
  cloud:
    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 {

    @Autowired
    private 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 {

    @Autowired
    private LicenseRepository licenseRepository;

    @Autowired
    ServiceConfig 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

猜你喜欢

转载自blog.csdn.net/yjw123456/article/details/83513465