大家好,我是冰河~~
❝一不小心《SpringCloud Alibaba实战》专栏都更新到第23章了,再不上车就跟不上了,小伙伴们快跟上啊!
注意:本项目完整源码加入 「冰河技术」 知识星球即可获取,文末有入场方式。
❞
前文回顾
在《SpringCloud Alibaba实战》专栏前面的文章中,我们实现了用户微服务、商品微服务和订单微服务之间的远程调用,并且实现了服务调用的负载均衡。
点击上方卡片关注我
基于阿里开源的Sentinel实现了服务的限流与容错,并详细介绍了Sentinel的核心技术与配置规则。简单介绍了服务网关,并对SpringCloud Gateway的核心架构进行了简要说明,也在项目中整合了SpringCloud Gateway网关实现了通过网关访问后端微服务.
同时,也基于SpringCloud Gateway整合Sentinel实现了网关的限流功能,详细介绍了SpringCloud Gateway网关的核心技术。在链路追踪章节,我们开始简单介绍了分布式链路追踪技术与解决方案,随后在项目中整合Sleuth实现了链路追踪,并使用Sleuth整合ZipKin实现了分布式链路追踪的可视化 。
在消息服务章节,我们介绍了MQ的使用场景,引入MQ后的注意事项以及MQ的选型对比,在项目中整合了RocketMQ,并给大家介绍了RocketMQ的核心技术。
在服务配置章节,我们首先介绍了服务配置与Nacos作为配置中心的相关概念,并在项目中整合了Nacos配置中心。接下来,就基于Nacos实现动态刷新与配置共享。
本章总览

「注意:本章中在测试每个案例时,都需要启动Nacos,Sentinel,ZipKin和RocketMQ。另外,本章对应的Nacos配置(冰河亲测的Nacos配置)放在了项目源码的doc/nacos/config/chapter23目录下,小伙伴们将Nacos的配置直接导入到Nacos的配置列表中,也可以按照文章自己手动实现。本项目完整源码加入 冰河技术 知识星球即可获取,文末有入场方式。」
实现动态刷新
细心的小伙伴可能已经发现了,之前我们将微服务的配置放入了Nacos,但是此时如果在Nacos中修改了配置,程序是无法读取到修改后的配置的。所以,我们需要实现动态刷新的功能。
「注意:为了描述上的简便,这里,我们就以用户微服务举例说明,其他微服务的实现方式都是一样的。」
修改Nacos配置
在Nacos中修改server-user-dev.yaml的配置,在server-user-dev.yaml配置中新增如下内容。
author:
name: binghe
如下所示。

点击发布后会弹出如下提示。

直接点击确认发布即可。
通过IOC容器获取Nacos配置
(1)在用户微服务shop-user的io.binghe.shop.user.controller
包下新建NacosController类,并在NacosController类中注入org.springframework.context.ConfigurableApplicationContext
类,通过ConfigurableApplicationContext获取到系统环境变量,并从环境变量中获取到author.name
属性的值,就是我们在Nacos中配置的作者姓名,如下所示。
/**
* @author binghe
* @version 1.0.0
* @description 从Nacos中获取配置项
*/
@Slf4j
@RestController
public class NacosController {
@Autowired
private ConfigurableApplicationContext context;
@GetMapping("/nacos/test")
public String nacosTest(){
String authorName = context.getEnvironment().getProperty("author.name");
log.info("获取到的作者姓名为:{}", authorName);
return authorName;
}
}
(2)启动用户微服务和网关服务,并在浏览器中输入http://localhost:10001/server-user/user/nacos/test
,如下所示。

可以看到,能够正确读取到Nacos中的配置信息。
(3)修改Nacos中server-user-dev.yaml的配置,将author.name
的值修改为binghe001,如下所示。

点击发布。
(4)发布后,不要重启用户微服务和网关服务,在浏览器上刷新http://localhost:10001/server-user/user/nacos/test
链接,发现读取到的信息已经变成了binghe001,如下所示。

可以看到,通过IOC容器能够读取到Nacos中修改后的配置。
通过注解获取Nacos配置
(1)在用户微服务shop-user的io.binghe.shop.user.controller.NacosController
类上添加@RefreshScope注解,并将Nacos中的author.name
的值注入到NacosController类中,并通过接口获取到注入的Nacos中的author.name
值,如下所示。
/**
* @author binghe
* @version 1.0.0
* @description 从Nacos中获取配置项
*/
@Slf4j
@RefreshScope
@RestController
public class NacosController {
@Autowired
private ConfigurableApplicationContext context;
@Value("${author.name}")
private String nacosAuthorName;
@GetMapping("/nacos/test")
public String nacosTest(){
String authorName = context.getEnvironment().getProperty("author.name");
log.info("获取到的作者姓名为:{}", authorName);
return authorName;
}
@GetMapping("/nacos/name")
public String nacosName(){
log.info("从Nacos中获取到的作者的姓名为:{}", nacosAuthorName);
return nacosAuthorName;
}
}
(2)启动用户微服务和网关服务,并在浏览器中输入http://localhost:10001/server-user/user/nacos/name
,如下所示。

(3)修改Nacos中server-user-dev.yaml的配置,将author.name
的值修改为binghe002,如下所示。

(4)发布后,不要重启用户微服务和网关服务,在浏览器上刷新http://localhost:10001/server-user/user/nacos/name
链接,发现读取到的信息已经变成了binghe002,如下所示。

说明使用注解的方式也能够读取到Nacos中更新后的配置信息。
注意:虽然通过IOC容器和注解都能够读取到Nacos中更新后的配置信息,但是在实际项目中,推荐使用注解的方式获取Nacos中更新后的配置信息。
实现配置共享
一般情况下,开发项目的过程中会包含:开发环境、测试环境、预发布环境和生成环境,每个环境中的配置大部分是相同的,有少部分配置不同,如果我们能够将大部分相同的配置抽取出来,让同一个微服务在不同的环境中共享,则能够大大降低我们的维护成本。
另外,如果使用的是相同的技术栈的话,对于每个微服务来说,可能大部分的配置也是相同的,如果我们将这些相同的配置抽取出来让各个微服务共享,则能够进一步降低维护成本。
所以,实现配置共享可以从 「单服务多环境配置和多服务配置」 两个角度来思考。
单服务多环境实现共享
实现单个微服务在多个不同环境中的配置共享比较简单,只要在Nacos中配置一个以spring.application.name
为Data ID的配置文件,并且将这个微服务在所有环境中公共的配置放进去即可。
「注意:这里我们以用户微服务为例进行实现。」
(1)在Nacos中新建一个以server-user.yaml为Data ID的配置,并且将用户微服务在各个环境中共有的配置复制进去,如下所示。

其中,我们假设用户微服务在多个环境下公共的配置如下所示。
server:
port: 8060
servlet:
context-path: /user
spring:
application:
name: server-user
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shop?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
username: root
password: root
platform: mysql
type: com.alibaba.druid.pool.DruidDataSource
# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
initialSize: 10
minIdle: 5
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 3600000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 3600000
validationQuery: select 1 from dual
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
maxOpenPreparedStatements: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
http:
encoding:
enabled: true
charset: UTF-8
force: true
mybatis-plus:
global-config:
db-config:
id-type: auto
field-strategy: not-empty
table-underline: true
db-type: oracle
logic-delete-value: 1
logic-not-delete-value: 0
mapper-locations: classpath:/mapper/*.xml
configuration:
jdbc-type-for-null: 'null'
rocketmq:
name-server: 127.0.0.1:9876
点击发布。
(2)将Nacos中用户微服务在开发环境下的配置server-user-dev.yaml修改成如下所示。
author:
name: binghe_dev
如下所示。

点击发布。
(3)在Nacos中添加用户微服务在测试环境下的配置server-user-test.yaml,配置中的主要内容如下所示。
author:
name: binghe_test
具体如下所示。

点击发布。
(4)此时Nacos中的配置如下所示。

(5)查看用户微服务中bootstrap.yml文件的配置,如下所示。
spring:
application:
name: server-user
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
group: user_group
profiles:
active: dev
可以看到,此时bootstrap.yml文件中配置的是环境是dev,表示开发环境。
(6)启动用户微服务和网关服务,在浏览器中输入http://localhost:10001/server-user/user/nacos/name
,如下所示。

可以看到,正确获取到了Nacos中server-user-dev.yaml配置中的author.name
的值。
(7)将用户微服务的bootstrap.yml文件中的环境变量修改成test,如下所示。
spring:
profiles:
active: test
(8)重启用户微服务,在浏览器中输入http://localhost:10001/server-user/user/nacos/name
,如下所示。

可以看到,正确获取到了Nacos中server-user-test.yaml配置中的author.name
的值。
综上:我们正确实现了单个微服务在多个不同环境下的公共配置的共享操作。
多服务配置实现共享
不同的微服务之间实现公共的配置共享也比较简单,在Nacos中定义一个公共配置,然后在当前的配置中引入即可。具体的实现步骤如下所示。
(1)在Nacos中新建一个以server-all.yaml为Data ID的配置,配置中的主要内容为用户微服务、商品微服务和订单微服务共有的配置,如下所示。
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shop?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
username: root
password: root
platform: mysql
type: com.alibaba.druid.pool.DruidDataSource
# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
initialSize: 10
minIdle: 5
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 3600000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 3600000
validationQuery: select 1 from dual
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
maxOpenPreparedStatements: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
http:
encoding:
enabled: true
charset: UTF-8
force: true
mybatis-plus:
global-config:
db-config:
id-type: auto
field-strategy: not-empty
table-underline: true
db-type: oracle
logic-delete-value: 1
logic-not-delete-value: 0
mapper-locations: classpath:/mapper/*.xml
configuration:
jdbc-type-for-null: 'null'
具体配置如下所示。

点击发布,接下来就是在Nacos中修改各个微服务的配置,将各个微服务的配置中公共的配置删除。
(2)在Nacos中修改server-user.yaml的配置,修改后的配置如下所示。
server:
port: 8060
servlet:
context-path: /user
spring:
application:
name: server-user
rocketmq:
name-server: 127.0.0.1:9876
具体如下所示。

点击发布。
(3)在Nacos中修改server-product-dev.yaml的配置,修改后的配置如下所示。
server:
port: 8070
servlet:
context-path: /product
spring:
application:
name: server-product
具体如下所示。

点击发布。
(4)在Nacos中修改server-order-dev.yaml的配置,修改后的配置如下所示。
server:
port: 8080
tomcat:
max-threads: 20
servlet:
context-path: /order
spring:
application:
name: server-order
cloud:
sentinel:
transport:
port: 9999
dashboard: 127.0.0.1:8888
web-context-unify: false
feign:
sentinel:
enabled: true
rocketmq:
name-server: 127.0.0.1:9876
producer:
group: order-group
具体如下所示。

点击发布。
(5)修改用户微服务shop-user中的bootstrap.yml文件,修改后的配置如下所示。
spring:
application:
name: server-user
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
group: user_group
shared-configs[0]:
data_id: server-all.yaml
group: all_group
refresh: true
profiles:
active: dev
(6)修改商品微服务shop-product中的bootstrap.yml文件,修改后的配置如下所示。
spring:
application:
name: server-product
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
group: product_group
shared-configs[0]:
data_id: server-all.yaml
group: all_group
refresh: true
profiles:
active: dev
(7)修改订单微服务shop-order中的bootstrap.yml文件,修改后的配置如下所示。
spring:
application:
name: server-order
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
group: order_group
shared-configs[0]:
data_id: server-all.yaml
group: all_group
refresh: true
profiles:
active: dev
(8)分别启动用户微服务,商品微服务,订单微服务和服务网关,在浏览器中输入localhost:10001/server-order/order/submit_order?userId=1001&productId=1001&count=1
,如下所示。

可以看到,浏览器中正确输出了结果信息。
查看各个微服务中也会打印出相关的日志,如下所示。
用户微服务会打印出如下信息
获取到的用户信息为:{"address":"北京","id":1001,"password":"c26be8aaf53b15054896983b43eb6a65","phone":"13212345678","username":"binghe"}
用户微服务收到了订单信息:{"address":"北京","id":15235872727371776,"phone":"13212345678","totalPrice":2399.00,"userId":1001,"username":"binghe"}
商品微服务会打印出如下信息
获取到的商品信息为:{"id":1001,"proName":"华为","proPrice":2399.00,"proStock":9999}
更新商品库存传递的参数为: 商品id:1001, 购买数量:1
订单微服务会打印出如下信息
提交订单时传递的参数:{"count":1,"empty":false,"productId":1001,"userId":1001}
库存扣减成功
网关服务会打印出如下信息
执行前置过滤器逻辑
执行后置过滤器逻辑
访问接口主机: localhost
访问接口端口: 10001
访问接口URL: /server-order/order/submit_order
访问接口URL参数: userId=1001&productId=1001&count=1
访问接口时长: 863ms
说明我们的项目中成功整合了Nacos的配置中心,并实现了配置的动态刷新和共享。
「好了,今天我们就到儿吧,限于篇幅,文中并未给出完整的案例源代码,想要完整源代码的小伙伴可加入【冰河技术】知识星球获取源码。也可以加我微信:hacker_binghe,一起交流技术。」
「另外,一不小心就写了23章了,小伙伴们你们再不上车就真的跟不上了!!!」
关于星球
最近,冰河创建了【冰河技术】知识星球,《SpringCloud Alibaba实战》专栏的源码获取方式会放到知识星球中,同时在微信上会创建专门的知识星球群,冰河会在知识星球上和星球群里解答球友的提问。
今天,【冰河技术】知识星球再开放200张优惠券,还没上车的小伙伴赶紧啦,再不上车就跟不上啦!!
星球提供的服务
冰河整理了星球提供的一些服务,如下所示。
加入星球,你将获得:
1.学习SpringCloud Alibaba实战项目—从零开发微服务项目
2.学习高并发、大流量业务场景的解决方案,体验大厂真正的高并发、大流量的业务场景
3.学习进大厂必备技能:性能调优、并发编程、分布式、微服务、框架源码、中间件开发、项目实战
4.提供站点 https://binghe001.github.io 所有学习内容的指导、帮助
5.GitHub:https://github.com/binghe001/BingheGuide - 非常有价值的技术资料仓库,包括冰河所有的博客开放案例代码
6.可以发送你的简历到我的邮箱,提供简历批阅服务
7.提供技术问题、系统架构、学习成长、晋升答辩等各项内容的回答
8.定期的整理和分享出各类专属星球的技术小册、电子书、编程视频、PDF文件
9.定期组织技术直播分享,传道、授业、解惑,指导阶段瓶颈突破技巧
星球门票价格
星球目前的门票价格50元,随着每次加入新实战项目和分享硬核技术上调入场价格。
「特别提醒:」 苹果用户进圈或续费,请「hacker_binghe」扫二维码,或者去公众号「冰河技术」回复「星球」扫二维码进圈。
最后,小伙伴们可以在 「冰河技术」 公众号回复 “ 「星球」 ” ,领取入场优惠券。
好了,今天就到这儿吧,我是冰河,我们下期见~~
往期推荐
推荐👍:《发现一个超硬核学习宝藏!爱了!爱了!》
推荐👍:《实践出真知:全网最强秒杀系统架构解密!!》
推荐👍:《高并发分布式锁架构解密,不是所有的锁都是分布式锁!》
推荐👍:《这部电子书凭什么短短几个月全网累计下载突破16万?(目前已破50W+)》
推荐👍:《,冰河又写了一本电子书!!》
---END---
扫一扫关注我

喜欢就点个 在看 呗 👇




