(六)Alian 的 Spring Cloud Config 配置中心(服务端)
目录
- 一、简介
- 二、数据库
- 2.1、应用表
- 2.2、属性表
- 2.3、视图
- 2.4、初始化数据
- 三、配置
- 3.1、pom.xml
- 3.2、application.properties
- 3.3、主类
- 3.4、应用的默认日志配置
- 3.5、应用属性切面
一、简介
Spring Cloud Config 包含以下两个部分:
- Config Server :一般称为分布式配置中心,是一个独立运行的微服务应用,它通过连接数据服务(git,db等)为客户端提供获取配置信息、加密信息和解密信息的访问接口
- Config Client :一般是微服务架构中的各个微服务,它们通过 Config Server 的接口获取和加载配置信息
本文中的配置中心的 数据是保存在mysql数据库中 ,并且可以 给客户端提供统一的日志管理 。
二、数据库
在实际中,我们的服务有很多,每个服务都有很多的配置,并且有很多配置是一样的,有很多又不是一样的,基于这种情况,我们创建一个数据库config_center,然后新建两个表和一个视图(根据自己需要,你也可以连表查询)。分别是应用表,对应客户端应用,属性表对应每个应用的配置项。
2.1、应用表
CREATE TABLE `tb_app` (`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`app_name` varchar(30) NOT NULL DEFAULT '' COMMENT '应用名',`priority` int unsigned NOT NULL DEFAULT '1' COMMENT '优先级',`remark` varchar(45) NOT NULL DEFAULT '' COMMENT '备注',PRIMARY KEY (`id`),UNIQUE KEY `app_name_UNIQUE` (`app_name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='应用表';
实际工作中会有很多的工程,我们把它叫应用,可以通过后台去添加这些应用。
2.2、属性表
CREATE TABLE `tb_property` (`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',`app_id` int NOT NULL COMMENT '应用id',`config_key` varchar(200) NOT NULL DEFAULT '' COMMENT '键',`config_value` varchar(500) NOT NULL DEFAULT '' COMMENT '值',`enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否启用',`refreshable` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否可动态刷新',`remark` varchar(200) NOT NULL DEFAULT '' COMMENT '备注',`profile` varchar(10) CHARACTER SET utf8 NOT NULL DEFAULT 'default' COMMENT 'profile',`label` varchar(10) CHARACTER SET utf8 NOT NULL DEFAULT 'master' COMMENT 'label',PRIMARY KEY (`id`),UNIQUE KEY `property_un` (`app_id`,`config_key`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='配置表';
一个应用会有很多的属性,我们也可以去把每个应用的属性管理起来。
2.3、视图
CREATE VIEW `v_app_properties` (`id` , `appName` , `configKey` , `configValue` , `PROFILE` , `label`, `priority`) ASSELECT `tp`.`id` AS `id`,`ta`.`app_name` AS `appName`,`tp`.`config_key` AS `configKey`,`tp`.`config_value` AS `configValue`,`tp`.`profile` AS `profile`,`tp`.`label` AS `label`,`ta`.`priority` AS `priority`FROM`tb_property` `tp`LEFT JOIN `tb_app` `ta` ON `tp`.`app_id` = `ta`.`id`WHERE`tp`.`enabled` = 1
为什么要创建一个视图呢?实际是可以通过应用表和属性表连查得到结果,但是我们这些应用及属性是一个数量有限的,并且数据增长不会很快,为了便于观察和查询,我觉得此处使用视图,可能效果会更好。当然你也可以不用,就使用我上面的连接查询也行。
2.4、初始化数据
两个截图!!!(这样看起来结构清晰)
三、配置
3.1、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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>cn.alian.microservice</groupId><artifactId>parent</artifactId><version>1.0.0-SNAPSHOT</version></parent><artifactId>config-service</artifactId><version>1.0.0-SNAPSHOT</version><packaging>jar</packaging><name>config-service</name><description>配置中心</description><dependencies><!--自定义的db starter--><dependency><groupId>cn.alian.microservice</groupId><artifactId>common-db</artifactId><version>1.0.0-SNAPSHOT</version></dependency><!--配置中心服务--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId></dependency><!--注册中心--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--打印sql执行--><dependency><groupId>com.googlecode.log4jdbc</groupId><artifactId>log4jdbc</artifactId></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--日志--><dependency><groupId>org.zalando</groupId><artifactId>logbook-spring-boot-starter</artifactId><version>2.0.0</version></dependency></dependencies></project>
需要注意的是
<!--自定义的db starter-->
<dependency><groupId>cn.alian.microservice</groupId><artifactId>common-db</artifactId><version>1.0.0-SNAPSHOT</version>
</dependency>
是我上一篇文章自定义的starter,不知道的,可以查看上一篇文章,所以我这里就不用再手动引入ebean相关的依赖了,是不是很简洁方便?当然我这里的配置中心也注册到了Eureka了。
3.2、application.properties
#应用名
spring.application.name=config-service
#后定义的bean会覆盖之前定义的相同名称的bean
spring.main.allow-bean-definition-overriding=true
#端口
server.port=6666#数据库配置(生产可以换其他的)
spring.datasource.driver-class-name=net.sf.log4jdbc.DriverSpy
spring.datasource.url=jdbc:log4jdbc:mysql://10.130.3.99:3306/config_center?autoReconnect=true&useSSL=false
spring.datasource.username=alian
spring.datasource.password=Alian1223
spring.datasource.hikari.connection-timeout=5000
spring.datasource.hikari.maximum-pool-size=10#配置采用数据库存储
spring.profiles.active=jdbc
#配置中心默认profile
spring.cloud.config.server.default-profile=default
#配置中心默认label
spring.cloud.config.server.default-label=master
#查询配置中心配置的语句
spring.cloud.config.server.jdbc.sql=SELECT configKey,configValue FROM v_app_properties WHERE appName=? AND profile=? AND label=? ORDER BY priority;
#优先级配置(jdbc大于native)
spring.cloud.config.server.jdbc.order=0#日志配置文件
#app.logback.dir=/microservice/config-service/logback
app.logback.dir=C:/workspace/study/spring-cloud-microservices/config-service/logback#部署时
#logging.config=file:config/logback.xml
我们着重关注下这个
#查询配置中心配置的语句
spring.cloud.config.server.jdbc.sql=SELECT configKey,configValue FROM v_app_properties
WHERE appName=? AND profile=? AND label=? ORDER BY priority;
我这里就是查询我们之前创建的那个视图,因为如果你没有设置这个语句,那么默认查询就是
private static final String DEFAULT_SQL = "SELECT KEY, VALUE from PROPERTIES"+ " where APPLICATION=? and PROFILE=? and LABEL=?";
不过你就得按照它的要求去减表和字段了。从这里你就知道我们自定义sql的灵活的优势了,尤其是对于微服务来说。不管怎么样,默认的和自定义的都会有这三个参数:
- APPLICATION
- PROFILE
- LABEL
对这个地方每个人的看法都不一样,也没有谁对谁错。我就讲下我的理解,第一个APPLICATION是应用的名称(spring.application.name),基本也就固定了,后面两个可以自由发挥;第二个当做环境变量,比如开发(dev)还是测试(test),反正别扯蛋说生产了,谁会生产和测试在一个环境乱搞啊;第三个就当做代码版本配置,比如主干和分支,在没有特别大团队的情况下,一般改动第二个就可以了。含义没有绝对的要求,只要能满足你的查询需求即可。
3.3、主类
ConfigServiceApplication.java
package cn.alian.microservice.configService;import cn.alian.microservice.configService.config.AppProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.config.server.EnableConfigServer;@EnableConfigServer
@EnableConfigurationProperties({AppProperties.class})
@SpringBootApplication
public class ConfigServiceApplication {public static void main(String[] args) {SpringApplication.run(ConfigServiceApplication.class, args);}}
注意这里使用注解 @EnableConfigServer
3.4、应用的默认日志配置
LogbackController
package cn.alian.microservice.configService.controller;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;import java.io.File;
import java.io.FileReader;@Controller
public class LogbackController {private static final Logger log = LoggerFactory.getLogger(LogbackController.class);@Value("${app.logback.dir}")private String logbackDir;@GetMapping({"/logback/{appName}.xml"})@ResponseBodypublic String logback(@PathVariable("appName") String appName) throws Exception {log.info("logback appName = [" + appName + "]");try {if (!(new File(this.logbackDir + "/" + appName + ".xml")).exists()) {log.info("指定日志配置【{}】不存在,使用默认配置", appName);appName = "default";}return FileCopyUtils.copyToString(new FileReader(this.logbackDir + "/" + appName + ".xml"));} catch (Exception e) {log.error(null, e);throw e;}}
}
日志配置文件: C:/workspace/study/spring-cloud-microservices/config-service/logback/default.xml
default.xml
<!--scan:为true时,配置文件如果发生改变,将会被重新加载,默认为true-->
<!--scanPeriod:当scan为true时,监测配置文件是否有修改的时间间隔。如果没有给出时间单位,默认单位是毫秒。默认时间间隔1分钟。英文不要写错了second minute hour-->
<!--debug:为true时,可打印出logback内部日志信息。默认为false-->
<configuration scan="true" scanPeriod="30 seconds" debug="false"><property name="appName" value="app"/><!--定义日志路径--><property name="log.path" value="logs"/><!--定义控制台日志输出格式--><property name="console.pattern" value="%d{yyyy-MM-dd HH:mm:ss SSS} [%thread] %level %method %line:%m%n"/><!--定义控制台日志输出格式--><property name="file.pattern" value="%d{yyyy-MM-dd HH:mm:ss SSS} [%thread] %level %method %line:%m%n"/><!--控制台日志输出--><appender name="Console" class="ch.qos.logback.core.ConsoleAppender"><!--字符串值System.out或System.err之一。默认目标是System.out--><Target>System.out</Target><!--只配置最底级别,控制台输出的日志级别大于或等于此级别的日志信息--><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>debug</level></filter><!--编码器--><encoder><!-- 输出日志信息格式 --><pattern>${console.pattern}</pattern><!-- 设置字符集 --><charset>UTF-8</charset></encoder></appender><!--文件滚动追加器(基于时间滚动策略按日滚动,最多保存90天历史记录,总文档大小不超过20GB)--><appender name="File" class="ch.qos.logback.core.rolling.RollingFileAppender"><!--日志文件命名--><File>logs/${appName}.log</File><!--基于时间滚动策略--><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--按日滚动--><fileNamePattern>logs/${appName}.%d{yyyy-MM-dd}.log</fileNamePattern><!--按小时滚动--><!--<fileNamePattern>logs/app.%d{yyyy-MM-dd_HH}.log</fileNamePattern>--><!--按分钟滚动--><!--<fileNamePattern>logs/app.%d{yyyy-MM-dd_HH-mm-ss}.log</fileNamePattern>--><!--日志保留份数--><MaxHistory>10</MaxHistory><!--日志文件最大的大小--><totalSizeCap>20GB</totalSizeCap></rollingPolicy><!--文件追加到末尾--><Append>true</Append><!--编码器--><encoder><!-- 输出日志信息格式 --><pattern>${file.pattern}</pattern><!-- 设置字符集 --><charset>UTF-8</charset></encoder><!--只配置最底级别,控制台输出的日志级别大于或等于此级别的日志信息--><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>info</level></filter></appender><logger name="cn.alian" level="debug"/><logger name="io.swagger" level="error"/><logger name="jdbc.sqlonly" level="ERROR" additivity="false"><appender-ref ref="File"/></logger><logger name="jdbc.audit" level="ERROR" additivity="false"><appender-ref ref="File"/></logger><logger name="jdbc.resultset" level="ERROR" additivity="false"><appender-ref ref="File"/></logger><logger name="jdbc.connection" level="ERROR" additivity="false"><appender-ref ref="File"/></logger><logger name="jdbc.sqltiming" level="info" additivity="false"><appender-ref ref="File"/></logger><root level="info"><appender-ref ref="Console"/><appender-ref ref="File"/></root>
</configuration>
我们这个日志有什么用呢,实际就是当应用通过配置方式请求到配置中心的日志接口时,如
#日志配置,通过配置中心获取
logging.config=${spring.cloud.config.uri}/logback/${spring.application.name}.xml
我们就可以把这个默认的日志提供给应用,这样可以通过配置中心达到统一日志格式。
3.5、应用属性切面
AppPropertiesAspect
package cn.alian.microservice.configService.config;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.PropertySource;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Map;
import java.util.Set;@Component
@Aspect
public class AppPropertiesAspect {private static final Logger log = LoggerFactory.getLogger(AppPropertiesAspect.class);@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")public void requestMapping() {}@Around("requestMapping()")public Object printAppProperties(ProceedingJoinPoint point) throws Throwable {Object object = point.proceed();if (object instanceof Environment) {List<PropertySource> propertySources = ((Environment) object).getPropertySources();for (PropertySource propertySource : propertySources) {String sourceName = propertySource.getName();Map<String, Object> source = (Map<String, Object>) propertySource.getSource();Set<Map.Entry<String, Object>> entrySet = source.entrySet();for (Map.Entry<String, Object> entry : entrySet) {log.info("sourceName={}, key={}, value={}", sourceName, entry.getKey(), entry.getValue());}}}return object;}}
通过切面我们可以可以打印出每个应用获取的属性配置,便于开发调试时查找问题。其实到这里我们的配置中心服务端就弄好了。主要有两个功能,一个是提供配置,一个是提供日志,接下里我们准备通过订单服务去搭建配置中心客户端吧。
(六)Alian 的 Spring Cloud Config 配置中心(服务端)相关推荐
- (七)Alian 的 Spring Cloud Config 配置中心(客户端)
目录 一.背景 二.maven依赖 三.配置文件 四.验证 一.背景 通过上一篇文章,我们已经搭建了配置中心了,接下里我们继续改造我们的订单服务了,之前我们的订单服务的数据库配置还是写在配置文件中 ...
- Spring Cloud Config 配置中心实践过程中,你需要了解这些细节!
本文导读: Spring Cloud Config 基本概念 Spring Cloud Config 客户端加载流程 Spring Cloud Config 基于消息总线配置 Spring Cloud ...
- Spring Cloud Config 配置中心
1.构建config-server 创建一个pom.xml <?xml version="1.0" encoding="UTF-8"?> <p ...
- Spring Cloud Config配置中心的使用
一.概述 1. 为什么使用? 1> 配置文件太多,不方便维护 2> 配置文件一般都保存这各种明文显示的密码,无法保证配置内容的安全性,也无法做到按权限分配给个人 3> 更新配置项目需 ...
- git在clone时需要输入密码Enter passphrase for key 导致spring cloud config 配置中心无法拉取配置文件的解决方法
前几天把系统从win7换到了win10 重装了开发环境 一直没什么问题 今天在调试spring cloud 时 发现无论如何都拉取不到配置文件, 通过微服务日志提示 Could not locate ...
- 【SpringCloud】Spring Cloud Config 配置中心
文章目录 1.概述 1.1 是什么 1.2 怎么玩 1.3 怎么用 3.案例 3.1 案例1 3.1.1 配置 3.1.2 主类 3.1.3 Git信息 3.1.4 访问 4. 例子 5.客户端 5. ...
- Spring Cloud Config配置中心使用(草稿版)
服务端搭建: cli:
- (十九)Alian 的 Spring Cloud Config 集群配置
目录 一.简介 1.1.第一步 二.maven依赖 三.配置 3.1.application.properties 3.2.主类 四.客户端修改(支付系统) 4.1 maven依赖 4.2 支付系统主 ...
- 玩转Spring Cloud之配置中心(config server config client)
玩转Spring Cloud之配置中心(config server &config client) 本文内容导航: 一.搭建配置服务中心(config server) 1.1.git方式 1 ...
最新文章
- 跟我学Spring Cloud(Finchley版)-16-Zuul
- empty怎么发音_empty,怎么读,解答要读出来,empty怎么读慢一点,清楚一点!
- 过去一个月发生了什么,C++再次真香了吗?
- python类型-python基础之五大标准数据类型
- 模态框在IE下的问题,即position:fixed在IE下不兼容的处理方式
- docker中部署Tomcat
- boost::graph模块实现分布式压缩稀疏行图类型的测试
- poj1673 EXOCENTER OF A TRIANGLE
- audiorecord怎么释放_Android 开发 AudioRecord音频录制
- 使用tcpdump,adb进行手机抓包
- linux保存编辑信息,linux系统编辑神器 -vim用法大全
- 《菜菜的机器学习sklearn课堂》学习笔记 + 课件
- Zabbix 3.0入门到企业实战阅读目录
- C语言谭浩强第三版例题及课后题汇总
- 工作中ibatis中的连表查询及in()的使用案例
- idea中自动生成Java类图和时序图
- 11.7 项目:下载所有 XKCD 漫画
- 【Docker】MySQL 主从配置(一主一从)
- 冯雪 手术机器人的应用_智能手术机器人及其应用_谢俊祥.
- BERT模型的结构,特点和实践
热门文章
- 快来一起拼团,惠购EasyRecovery
- 基于springboot开发的国际物流管理系统
- 微信小程序多文件上传(docx,ppt,pdf,zip,jpg···)
- 初二因式分解奥数竞赛题_[2018初二奥数因式分解练习题] 因式分解练习题
- mysql毫秒转分钟_[MYSQL]时间毫秒数转换
- SWD下载调试接口原理深度剖析
- Extjs grid 合并行
- 为什么我们要使用std::alloctor
- 达梦数据库查询与操作
- 如何在CSDN获取更多的铁粉?