Nacos Config--服务配置基于网关,网关详情请见下方链接
http://t.csdn.cn/A8R4Yhttp://t.csdn.cn/A8R4Y
首先我们来看一下,微服务架构下关于配置文件的一些问题:
1. 配置文件相对分散。在一个微服务架构下,配置文件会随着微服务的增多变的越来越多,而且分散在各个微服务中,不好统一配置和管理。
2. 配置文件无法区分环境--开发环境 测试环境 线上环境。微服务项目可能会有多个环境,例如:测试环境、预发布环境、生产环
境。每一个环境所使用的配置理论上都是不同的,一旦需要修改,就需要我们去各个微服务下手动
维护,这比较困难。
3. 配置文件无法实时更新。我们修改了配置文件之后,必须重新启动微服务才能使配置生效,这对一个正在运行的项目来说是非常不友好的。
基于上面这些问题,我们就需要配置中心的加入来解决这些问题。
配置中心的思路是:
当加入了服务配置中心之后,我们的系统架构图会变成下面这样:
在业界常见的服务配置中心,有下面这些:
Apollo是由携程开源的分布式配置中心。特点有很多,比如:配置更新之后可以实时生效,支持灰度发布功能,并且能对所有的配置进行版本管理、操作审计等功能,提供开放平台API。并且资料 也写的很详细。
Disconf是由百度开源的分布式配置中心。它是基于Zookeeper来实现配置变更后实时通知和生效的。
这是Spring Cloud中带的配置中心组件。它和Spring是无缝集成,使用起来非常方便,并且它的配置存储支持Git
这是SpingCloud alibaba技术栈中的一个组件,前面我们已经使用它做过服务注册中心。其实它也集成了服务配置的功能,我们可以直接使用它作为服务配置中心。
使用nacos作为配置中心,其实就是将nacos当做一个服务端,将各个微服务看成是客户端,我们将各个微服务的配置文件统一存放在nacos上,然后各个微服务从nacos上拉取配置即可。
接下来我们以商品微服务为例,学习nacos config的使用。
以下链接详细描述了nacos环境的搭建http://t.csdn.cn/A8R4Yhttp://t.csdn.cn/A8R4Y
点击配置列表,点击右边+号,新建配置。在新建配置过程中,要注意下面的细节:
1)Data ID不能随便写,尽量与配置文件中的微服务名对应,对应关系如图所示
2)配置文件格式要跟配置文件的格式对应,且目前仅仅支持YAML和Properties
3)配置内容按照上面选定的格式书写
点击创建
设置创建的前置内容
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
注意:不能使用原来的application.yml作为配置文件,而是新建一个bootstrap.yml作为配置文件
bootstrap和application都是SpringBoot项目中的配置文件,他们的区别主要有以下的几个方面:
(1)加载顺序区别
bootstrap配置文件是比application配置文件优先加载的,因为bootstrap是由spring父上下文加载,而application是由子上下文加载
(2)优先级区别
bootstrap加载的配置信息是不能被application的相同配置覆盖的,如果两个配置文件同时存在,也是以bootstrap为主
(3)应用场景区别
bootstrap常见应用场景:
1.配置一些固定的,不能被覆盖的属性.用于一些系统级别的参数配置
本地的配置文件是默认不能覆盖远程的配置的
2.一些需要加密/解密的场景
3.当你使用了Spring Cloud Config配置中心时,这时需要在boostrap配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息,专业翻译如下
application常见应用场景:
1.常用于SpringBoot项目的自动化配置
2.用于一些应用级别的参数配置
在大部分情况下不用区分这两种情况,只需要使用application即可,效果基本是一致的
配置文件优先级(由高到低):
bootstrap.properties -> bootstrap.yml -> application.properties -> application.yml
# 该文件优先级高于application.properties --引用配置中心的配置内容
# 若application与bootstrap中有相同的内容,以bootstrap为主
#微服务名
spring.application.name=springcloud03-sleuth-order
# 指定nacos配置中心的地址
spring.cloud.nacos.config.server-addr=localhost:81
#指定nacos中心文件的后缀--默认为properties
spring.cloud.nacos.config.file-extension=properties
#必须指定引用哪个配置内容
spring.cloud.nacos.config.name=springcloud03-order
在order微服务的controller层创建接口sss,通过Value获取配置中心的自定义内容,测试是否连接成功
ps:若运行报获取不到student.name,检查配置文件;
若测试报503,将网关的微服务也重启一下,再进行测试
@Value("${student.name}")
private String name;
@GetMapping("/sss")
public String sss(){
return "配置中心的值"+name;
}
记得点击发布
移动完成后删除application.properties配置文件,重新运行测试是否成功
其它微服务的配置相同:
1.先在注册中心创建配置文件
2. 在微服务创建bootstrap文件
3.将注册中心的配置注册到bootstrap文件中
4.复制application.properties中的文件
5.粘贴到注册中心的相关配置文件中并发布
6.删除application.properties文件并进行测试
在入门案例中,我们实现了配置的远程存放,但是此时如果修改了配置,我们的程序是无法读取到的,因此,我们需要开启配置的实时动态刷新功能。
添加实时刷新注解
package com.wt.controller;
import com.wt.service.OrderService;
import com.wt.utils.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/order")
@RefreshScope //实时刷新读取配置文件===读取的为自定义配置内容
public class OrderController {
@Value("${student.name}")
private String name;
@GetMapping("/sss")
public String sss(){
return "配置中心的值"+name;
}
}
在实际开发中,我们需要创建不同的配置文件,开发环境,测试环境,线上环境等,在nacos中默认为公共环境(public)
创建命名空间(环境)
我们在公共环境下的配置文件可通过克隆直接克隆到其它环境
选择克隆的环境
查看相关环境下克隆的内容
# 该文件优先级高于application.properties --引用配置中心的配置内容
# 若application与bootstrap中有相同的内容,以bootstrap为主
#微服务名
spring.application.name=springcloud03-sleuth-order
# 指定nacos配置中心的地址
spring.cloud.nacos.config.server-addr=localhost:81
#指定nacos中心文件的后缀--默认为properties
spring.cloud.nacos.config.file-extension=properties
#必须指定引用哪个配置内容
spring.cloud.nacos.config.name=springcloud03-order
#指定配置文件所在的命名空间----默认为public
spring.cloud.nacos.config.namespace=2a328813-1fc4-4ebb-acd1-642139dcf6c1
可将原公共的配置文件删除,在bootstrap配置命名空间,测试是否能够成功连接
当配置越来越多的时候,我们就发现有很多配置是重复的,这时候就考虑可不可以将公共配置文件提取出来,然后实现共享呢?当然是可以的。接下来我们就来探讨如何实现这一功能。
同一个微服务的不同环境之间共享配置
如果想在同一个微服务的不同环境之间实现配置共享,其实很简单。
只需要提取一个以 spring.application.name 命名的配置文件,然后将其所有环境的公共配置放在里面即可。
创建数据源公共配置文件并配置数据源
#引用扩展的配置文件
#扩展文件的id---dataId
spring.cloud.nacos.config.extension-configs[0].data-id=datasource.properties
#扩展文件所在的组---group 默认为DEFAULT_GROUP
spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP
#是否实时刷新
spring.cloud.nacos.config.extension-configs[0].refresh=true
修改各个相应的微服务,重新加载微服务并进行相关测试
配置详细步骤:
1.创建公共配置文件
2.将各个配置文件都有的配置放入公共配置文件中
3.删除各个配置文件中的公共内容并发布
4.在bootstrap文件中注册公共配置文件
命名空间(Namespace) (dev开发环境 test测试环境 online线上环境)
命名空间可用于进行不同环境的配置隔离。一般一个环境划分到一个命名空间
配置分组(Group) (区分的项目)
配置分组用于将不同的服务可以归类到同一分组。一般将一个项目的配置分到一组
配置集(Data ID)
在系统中,一个配置文件通常就是一个配置集。一般微服务的配置就是一个配置集
在大型系统的微服务化构建中,一个系统被拆分成了许多微服务。这些模块负责不同的功能,组合成系统,最终可以提供丰富的功能。在这种架构中,一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心【】,也就意味着这种架构形式也会存在一些问题:
分布式链路追踪(Distributed Tracing),就是将一次分布式请求还原成调用链路,进行日志记录,性能监控并将一次分布式请求的调用情况集中展示。比如各个服务节点上的耗时、请求具体到达哪台机器上IP、每个服务节点的请求状态200 500等等。
常见的链路追踪技术有下面这些:
cat 由大众点评开源,基于Java开发的实时应用监控平台,包括实时应用监控,业务监控 。 集成
方案是通过代码埋点的方式来实现监控,比如: 拦截器,过滤器等。 对代码的侵入性很大,集成成本较高。风险较大。
zipkin 由Twitter公司开源,开放源代码分布式的跟踪系统,用于收集服务的定时数据,以解决微
服务架构中的延迟问题,包括:数据的收集、存储、查找和展现《图形化》。该产品结合spring-cloud-sleuth 使用较为简单, 集成很方便, 但是功能较简单。
pinpoint Pinpoint是韩国人开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点
是支持多种插件,UI功能强大,接入端无代码侵入。
skywalking 【未来企业会使用的多】
SkyWalking是本土开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多
种插件,UI功能较强,接入端无代码侵入。目前已加入Apache孵化器。
Sleuth (日志记录每一条链路上的所有节点,以及这些节点所在的机器,和耗时。)log4j
SpringCloud 提供的分布式系统中链路追踪解决方案。
注意:SpringCloud alibaba技术栈中并没有提供自己的链路追踪技术的,我们可以采用Sleuth +
Zipkin来做链路追踪解决方案
Springcloud 并不是自己技术---而是把所有框架整合在一起 来解决微服务上的问题。
SpringCloud Sleuth主要功能就是在分布式系统中提供追踪解决方案。它大量借用了Google Dapper的设计, 先来了解一下Sleuth中的术语和相关概念。
Trace (一条完整链路--包含很多span(微服务接口))
由一组Trace Id(贯穿整个链路)相同的Span串联形成一个树状结构。为了实现请求跟踪,当请求到达分布式系统的入口端点时,只需要服务跟踪框架为该请求创建一个唯一的标识(即TraceId),同时在分布式系统内部流转的时候,框架始终保持传递该唯一值,直到整个请求的返回。那么我们就可以使用该唯一标识将所有的请求串联起来,形成一条完整的请求链路。
Span
代表了一组基本的工作单元。为了统计各处理单元的延迟,当请求到达各个服务组件的时候,也通过一个唯一标识(SpanId)来标记它的开始、具体过程和结束。通过SpanId的开始和结束时间戳,就能统计该span的调用时间,除此之外,我们还可以获取如事件的名称。请求信息等元数据。
Annotation
用它记录一段时间内的事件,内部使用的重要注释:
生成链路的日志。
接下来通过之前的项目案例整合Sleuth,完成入门案例的编写。
在父工程引入Sleuth依赖
启动微服务,调用之后,我们可以在控制台观察到sleuth的日志输出
上面并没有Traceld的id,也没有SpanId ,这是因为我们并没有运行相关功能,调用相关接口进行运行测试,查看日志输出
其中 0ba37a01dae44ae1 是TraceId, 0ba37a01dae44ae1 是SpanId,依次调用有一个全局的TraceId,将调用链路串起来。仔细分析每个微服务的日志,不难看出请求的具体过程。
查看日志文件并不是一个很好的方法,当微服务越来越多日志文件也会越来越多,通过Zipkin可以将日志聚合,并进行可视化展示和全文检索。
Zipkin 是 Twitter 的一个开源项目,它基于Google Dapper实现,它致力于收集服务的定时数据,以解决微服务架构中的延迟问题,包括数据的收集、存储展现、查找和我们可以使用它来收集各个服务器上请求链路的跟踪数据,并通过它提供的REST API接口来辅助我们查询跟踪数据以实现对分布式系统的监控程序,从而及时地发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源
除了面向开发的 API 接口之外,它也提供了方便的UI组件来帮助我们直观的搜索跟踪信息和分析请求链路明细,比如:可以查询某段时间内各用户请求的处理时间等。
Zipkin 提供了可插拔数据存储方式:In-Memory、MySql、Cassandra 以及 Elasticsearch。
上图展示了 Zipkin 的基础架构,它主要由 4 个核心组件构成:
Zipkin 分为两端,一个是 Zipkin 服务端,一个是 Zipkin 客户端,客户端也就是微服务的应用。客户端会配置服务端的 URL 地址,一旦发生服务间的调用的时候,会被配置在微服务里面的 Sleuth 的监听器监听,并生成相应的 Trace 和 Span 信息发送给服务端。
第1步: 下载ZipKin的jar包
https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/ |
访问上面的网址,即可得到一个jar包,这就是ZipKin服务端的jar包
第2步: 通过命令行,输入下面的命令启动ZipKin Server
java -jar zipkin-server-2.12.9-exec.jar
第3步:通过浏览器访问 http://localhost:9411访问
ZipKin客户端和Sleuth的集成非常简单,只需要在微服务中添加其依赖和配置即可。
第1步:在父工程添加zipkin依赖
org.springframework.cloud
spring-cloud-starter-zipkin
第2步:添加配置
在每个微服务的bootstrap.properties文件添加以下内容---包括网关微服务
#指定zipkin服务端所在的地址
spring.zipkin.base-url=http://localhost:9411
#不要让nacos 把zipkin注册到注册中心
spring.zipkin.discovery-client-enabled=false
#设置zipkin对 seluth链路日志的采样比例 0.03企业默认0.03%---1.0~=100%
spring.sleuth.sampler.probability=1.0
http://localhost:7000/order/buy/1/100---访问相关接口测试
第4步: 访问zipkin的UI界面,观察效果
每调用一次接口,UI界面就会出现一条新的链路记录
点击记录查看链路详细信息
Zipkin Server默认会将追踪数据信息保存到内存,但这种方式不适合生产环境。Zipkin支持将追踪数据持久化到mysql数据库或elasticsearch中。
第1步: 创建mysql数据环境
在本地数据库创建数据库名为zipkin的数据库,执行下列命令,创建持久化所需的表
CREATE TABLE IF NOT EXISTS zipkin_spans (
`trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
`trace_id` BIGINT NOT NULL,
`id` BIGINT NOT NULL,
`name` VARCHAR(255) NOT NULL,
`parent_id` BIGINT,
`debug` BIT(1),
`start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
`duration` BIGINT COMMENT 'Span.duration(): micros used for minDuration and maxDuration query' )
ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT 'ignore insert on duplicate';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`, `id`) COMMENT 'for joining with zipkin_annotations';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTracesByIds';
ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames';
ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range';
CREATE TABLE IF NOT EXISTS zipkin_annotations (
`trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
`trace_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',
`span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id',
`a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1',
`a_value` BLOB COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB',
`a_type` INT NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
`a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
`endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is null',
`endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
`endpoint_port` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null',
`endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation.endpoint is null' )
ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`) COMMENT 'for joining with zipkin_spans';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTraces/ByIds';
ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames';
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'for dependencies job';
CREATE TABLE IF NOT EXISTS zipkin_dependencies (
`day` DATE NOT NULL,
`parent` VARCHAR(255) NOT NULL,
`child` VARCHAR(255) NOT NULL,
`call_count` BIGINT )
ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);
第2步: 在启动ZipKin Server的时候,指定数据保存的mysql的信息
jar包版本号和localhost随着ip的变化可随时更改
java -jar zipkin-server-2.21.0-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=localhost --MYSQL_TCP_PORT=3306 --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=root
链路追踪插件使用一个即可,若使用skywalking可以把前面使用的Sleuth+Zipkin的jar包和配置文件注释
分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。
提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案
skywalking链路追踪的好处:
无侵入,而且搜集和展示链路信息
支持多种插件,UI功能较强
目前已加入Apache孵化器。
skywalking默认不支持gateway服务。但在skywalking的文件中又存在gateway的jar包,我们将agent\optional-plugins下的gateway的jar复制到/agent/plugins目录下,让skywalking支持gateway
1. 进入apache-skywalking-apm-bin的bin目录
2.双击startup.bat启动skywalking
第一步,选择微服务,右击Edit Configuration..
第二步:选择VM options 并点开其扩展页
第三步: 配置skywalking
每个微服务都进行相关配置,更改配置名
-javaagent:D:/qy151/qy151/software/apache-skywalking-apm-bin/agent/skywalking-agent.jar
-Dskywalking.agent.service_name=springcloud-product
-Dskywalking.collector.backend_service=localhost:11800
第四步:重新运行各个微服务
当微服务启动时出现以下日志且成功运行表示配置成功
第一步:端口配置
第二步:图形化界面
在浏览器输入ip+配置好的端口号,打开skywalking图形化界面
可通过运行程序接口查看功能
skywalking的日志信息默认保存在h2内存中,若服务重新启动,链路日志就会消失。
我们可以将链路持久化存储到mysql/es存储引擎中
第一步: 修改application.yml文件 config/application
第二步: 把mysql的驱动放入skywalking中
复制remaven本地仓库中的mysql的jar包到aop-libs中
第三步: 创建数据库
skywalking会为我们创建表,但数据库需要我们自己创建,在数据库中创建名为swtest的数据库