【SpringCloud Alibaba】Nacos Config配置管理与Gateway 网关

目录

一、Config 远程配置

1.1 config 介绍

1.2 bootstrap.yml 配置文件

二、Gateway 网关

2.1 gateway 介绍

2.2 gateway 使用

2.2.1 方式一

2.2.2 方式二(动态路由)


一、Config 远程配置

1.1 config 介绍

        微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大 量的服务。 由于每个服务都需要必要的配置信息才能运行,所以一套集中式的,动态的配置管理设施是必不可少的。

        Spring Cloud 提供了 ConfigServer来解决这个问题,Spring Cloud Config 为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服 务应用的所有环境提供了一个中心化的外部配置。

一个使用微服务架构的应用系统可能会包括成百上千个微服务,配置各部相同,需求各不相同:

  • 不同环境不同配置:例如数据源在不同的环境(开发,测试,生产)是不同的
  • 运行期间可以动态调整。例如根据各个微服务的负载状况,动态调整数据源连接池大小或者熔断阀 值,并且调整时不停止微服务(配置修改后可以自动更新)

        使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外 部属性配置。 

1.2 bootstrap.yml 配置文件

SpringBoot 默认支持propertiesYAML两种格式的配置文件。

  1. bootstrap.yml(bootstrap.properties)用来程序引导时执行,应用于更加早期配置信息读取,如可以使用来配置application.yml中使用到参数等
  2. application.yml(application.properties) 应用程序特有配置信息,可以用来配置后续各个模块中需使用 的公共参数等。

bootstrap.yml 先于 application.yml 加载 !!!

1、添加依赖

        <!--config配置管理--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency>

2、添加bootsrap.yml配置

server:port: 8080
spring:application:name: basketballcloud:nacos:server-addr: localhost:8848config:server-addr: ${spring.cloud.nacos.server-addr}#指定nacos配置中心地址prefix: ${spring.application.name}file-extension: yaml # 使用的 nacos 配置集的 dataId 的文件拓展名,同时也是Nacos 配置集的配置格式,默认为 propertiesgroup: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP# 共享配置集数组shared-configs:- data-id: redis.ymlgroup: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUPrefresh: true # 是否自动刷新配置,默认为 fals- data-id: basketball.ymlgroup: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUPrefresh: true # 是否自动刷新配置,默认为 false# 使用的 nacos 的命名空间(指定项目环境),namespace: 363830b6-d72e-4868-a028-6be9c2cfd267

3、对应Nacos也添加配置信息

redis.yml:

basketball.yml:

4、编写两个配置类读取Nacos配置文件属性值

5、编写测试接口类

package com.example.basketball.controller;import com.example.basketball.config.EmailProperies;
import com.example.basketball.config.RedisProperies;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import pojo.dto.IkunDto;import java.util.Map;@Slf4j
@RestController
@RequestMapping("/user")
public class ConfigController {@Autowiredprivate EmailProperies emailProperies;@Autowiredprivate RedisProperies redisProperies;/*编写测试接口读取远程配置信息*/@RequestMapping("/test1")public Object test01() {return emailProperies;}@RequestMapping("/test2")public Object test02() {return redisProperies;}}

6、启动类添加刷新配置注解

7、测试

        这样我们就能将一些基本配置信息添加到Nacot进行远程配置管理,其实这里还有一个缺点:如果我们要个更换环境需要修改指定的nacos命名空间在这我们其实可以不写,把项目导成jar包,直接设置指定命名空间运行项目:

cmd指令示例:

java -jar xxx.jar --spring.cloud.nacos.config.namespace=xxx

二、Gateway 网关

2.1 gateway 介绍

        Spring Cloud Gateway是Spring官方基于Spring5.0、SpringBoot2.0和Project Reactor等技术开发的网关,旨在为微服务框架提供一种简单而有效的统一的API路由管理方式,统一访问接口。

        Spring Cloud Gateway作为Spring Cloud生态体系中的网关,目标是替代Netflix的Zuul,其不仅提供统 一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全、监控/埋点和限流等等。 它是基于Netty的响应式开发模式。

1️⃣路由(route):路由是网关最基础的部分,路由信息由一个ID,一个目的URL、一组断言predicates)工厂和一 组Filter组成。如果断言为真,则说明请求URL和配置的路由匹配。

2️⃣断言(Predicate):Java8中的断言函数,Spring Cloud Gateway中的断言函数输入类型是 Spring5.0框架中的ServerWebExchange。Spring Cloud Gateway中的断言函数允许开发者去定义匹配 来自http Request中的任何信息,比如请求头和参数等。

3️⃣过滤器(Filter):一个标准的Spring WebFilter,Spring Cloud Gateway中的Filter分为两种类型: Gateway Filter和Global Filter。过滤器Filter可以对请求和响应进行处理

2.2 gateway 使用

创建网关服务:

添加依赖 :

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--阿里json解析--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.35</version></dependency></dependencies>

2.2.1 方式一

本地yml配置

server:port: 8082
spring:application:name: gatewaycloud:nacos:server-addr: localhost:8848gateway:routes:#路由标识(id:标识,具有唯一性)配合读取类使用- id: user-basketball-api#目标服务地址(uri:地址,请求转发后的地址),会自动从注册中心获得服务的IP,不需要手动写死uri: lb://ikun#优先级,越小越优先order: 999#路由条件(predicates:断言)predicates:# 路径匹配,- Path=/kun/**filters:#路径前缀删除示例- StripPrefix=1

        这样同时启动gateway和ikun(消费者)服务,通过网关端口8082路径kun就能访问ikun服务的接口方法。但是这样还是不太方便,建议使用方法二动态路由远程配置👇

2.2.2 方式二(动态路由)

如果是跳到该目录的小帅和小美请看上面的服务创建与依赖配置哦! 

1、修改yml配置 :

server:port: 8082
spring:application:name: gatewaycloud:nacos:server-addr: localhost:8848
#自定义读取配置
gateway:nacos:server-addr: ${spring.cloud.nacos.server-addr}#namespace: xxx-xx-xx-xx (指定环境命名空降如[dev,test,pro...])data-id: dynamic-routing.jsongroup: DEFAULT_GROUP

2、添加Nacos远程配置信息

{"refreshGatewayRoute": true,"routeList": [{"id": "basketball-api","predicates": [{"name": "Path","args": {"_genkey_0": "/ball/**"}}],"filters": [{"name": "StripPrefix","args": {"_genkey_0": "1"}}],"uri": "lb://basketball","order": 0},{"id": "ikun-api","predicates": [{"name": "Path","args": {"_genkey_0": "/kun/**"}}],"filters": [{"name": "StripPrefix","args": {"_genkey_0": "1"}}],"uri": "lb://ikun","order": 0}]
}

 

3、添加相关远程配置解析类

GatewayNacosProperties:
package com.example.gateway.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@SuppressWarnings("all")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ConfigurationProperties(prefix = "gateway.nacos")
@Component
public class GatewayNacosProperties {private String serverAddr; //nacos服务地址private String dataId; //配置文件名称private String namespace; //指定命名空间private String group; //分组}
RouteEntity:
package com.example.gateway.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import java.util.ArrayList;
import java.util.List;/*** @author 云村小威*/
@SuppressWarnings("all")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class RouteEntity {//路由idprivate String id;//路由断言集合private List<PredicateEntity> predicates = new ArrayList<>();//路由过滤器集合private List<FilterEntity> filters = new ArrayList<>();//路由转发的目标uriprivate String uri;//路由执行的顺序private int order = 0;}
PredicateEntity:
package com.example.gateway.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import java.util.LinkedHashMap;
import java.util.Map;/*** @author 云村小威*/
@SuppressWarnings("all")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class PredicateEntity {//断言对应的Nameprivate String name;//断言规则private Map<String, String> args = new LinkedHashMap<>();}
FilterEntity:
package com.example.gateway.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import java.util.LinkedHashMap;
import java.util.Map;/*** @author 云村小威*/
@SuppressWarnings("all")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class FilterEntity {//过滤器对应的Nameprivate String name;//路由规则private Map<String, String> args = new LinkedHashMap<>();}

 

DynamicRoutingConfig : 🌟

package com.example.gateway;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.example.gateway.pojo.FilterEntity;
import com.example.gateway.pojo.GatewayNacosProperties;
import com.example.gateway.pojo.PredicateEntity;
import com.example.gateway.pojo.RouteEntity;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;/*** 此类实现了Spring Cloud Gateway + nacos 的动态路由,* 它实现一个Spring提供的事件推送接口ApplicationEventPublisherAware*/
@SuppressWarnings("all")
@Slf4j
@Component
public class DynamicRoutingConfig implements ApplicationEventPublisherAware {@Autowiredprivate RouteDefinitionWriter routeDefinitionWriter;@Autowiredprivate GatewayNacosProperties gatewayProperties;@Autowiredprivate ObjectMapper mapper;private ApplicationEventPublisher applicationEventPublisher;@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}/*** 这个方法主要负责监听Nacos的配置变化,这里先使用参数构建一个ConfigService,* 再使用ConfigService开启一个监听,* 并且在监听的方法中刷新路由信息。*/@Beanpublic void refreshRouting() throws NacosException {//创建Properties配置类Properties properties = new Properties();System.out.println(gatewayProperties);//设置nacos的服务器地址,从配置类GatewayProperties中获取properties.put(PropertyKeyConst.SERVER_ADDR, gatewayProperties.getServerAddr());//设置nacos的命名空间,表示从具体的命名空间中获取配置信息,不填代表默认从public获得if (gatewayProperties.getNamespace() != null) {properties.put(PropertyKeyConst.NAMESPACE, gatewayProperties.getNamespace());}//根据Properties配置创建ConfigService类ConfigService configService = NacosFactory.createConfigService(properties);//获得nacos中已有的路由配置String json = configService.getConfig(gatewayProperties.getDataId(), gatewayProperties.getGroup(), 5000);this.parseJson(json);//添加监听器,监听nacos中的数据修改事件configService.addListener(gatewayProperties.getDataId(), gatewayProperties.getGroup(), new Listener() {@Overridepublic Executor getExecutor() {return null;}/*** 用于接收远端nacos中数据修改后的回调方法*/@Overridepublic void receiveConfigInfo(String configInfo) {log.warn(configInfo);//获取nacos中修改的数据并进行转换parseJson(configInfo);}});}/*** 解析从nacos读取的路由配置信息(json格式)*/public void parseJson(String json) {log.warn("从Nacos返回的路由配置(JSON格式):" + json);boolean refreshGatewayRoute = JSONObject.parseObject(json).getBoolean("refreshGatewayRoute");if (refreshGatewayRoute) {List<RouteEntity> list = JSON.parseArray(JSONObject.parseObject(json).getString("routeList")).toJavaList(RouteEntity.class);for (RouteEntity route : list) {update(assembleRouteDefinition(route));}} else {log.warn("路由未发生变更");}}/*** 路由更新*/public void update(RouteDefinition routeDefinition) {try {this.routeDefinitionWriter.delete(Mono.just(routeDefinition.getId()));log.warn("路由删除成功:" + routeDefinition.getId());} catch (Exception e) {log.error(e.getMessage(), e);}try {routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));log.warn("路由更新成功:" + routeDefinition.getId());} catch (Exception e) {log.error(e.getMessage(), e);}}/*** 路由定义*/public RouteDefinition assembleRouteDefinition(RouteEntity routeEntity) {RouteDefinition definition = new RouteDefinition();// IDdefinition.setId(routeEntity.getId());// PredicatesList<PredicateDefinition> pdList = new ArrayList<>();for (PredicateEntity predicateEntity : routeEntity.getPredicates()) {PredicateDefinition predicateDefinition = new PredicateDefinition();predicateDefinition.setArgs(predicateEntity.getArgs());predicateDefinition.setName(predicateEntity.getName());pdList.add(predicateDefinition);}definition.setPredicates(pdList);// FiltersList<FilterDefinition> fdList = new ArrayList<>();for (FilterEntity filterEntity : routeEntity.getFilters()) {FilterDefinition filterDefinition = new FilterDefinition();filterDefinition.setArgs(filterEntity.getArgs());filterDefinition.setName(filterEntity.getName());fdList.add(filterDefinition);}definition.setFilters(fdList);// URIURI uri = UriComponentsBuilder.fromUriString(routeEntity.getUri()).build().toUri();definition.setUri(uri);return definition;}}

 

4、接口调用测试

        这样就可以通过配置统一管理服务接口, 如下图所示;通过网关端口8082可访问不同服务的接口实现路由转发、处理请求和响应。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/339049.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python异步网络编程库之twisted 详解

概要 Python twisted 是一个强大的异步网络编程框架&#xff0c;它允许开发者轻松构建高性能的网络应用和协议。无论是构建网络服务器、客户端、聊天应用还是实时通信工具&#xff0c;twisted 都提供了丰富的工具和组件。本文将深入探讨 twisted 的基本概念、安装方法以及详细…

yolov5无人机视频检测与计数系统(创新点和代码)

标题&#xff1a;基于YOLOv5的无人机视频检测与计数系统 摘要&#xff1a; 无人机技术的快速发展和广泛应用给社会带来了巨大的便利&#xff0c;但也带来了一系列的安全隐患。为了实现对无人机的有效管理和监控&#xff0c;本文提出了一种基于YOLOv5的无人机视频检测与计数系…

软光栅透视校正插值写好了

我这文章写的六,自己不写什么过程,直接发张图片.我发一下我看的引用. 透视矫正插值 Perspective-Correct Interpolation 计算机图形学六&#xff1a;正确使用重心坐标插值(透视矫正插值(Perspective-Correct Interpolation))和图形渲染管线总结 一开始写错了,改了大概两天改…

STM32-创建工程模板

STM32 工程模板没有统一的格式&#xff0c;可以参考 ST 官方的示例模板或者根据自己的开发经验和使用习惯总结。 Project Template 文档以库函数工程模板为例&#xff0c;HAL 库工程模板对应参考即可。 Official Project Template ST 发布的标准外设库 (STM32 Standard Per…

OpenCV-20卷积操作

一、什么是图像卷积 图像卷积就是卷积在图像上按照滑动遍历像素时不断的相乘求和的过程。 绿色为图片&#xff0c; 黄色为卷积核&#xff0c; 粉色为最终得到的卷积特征。 二、步长 步长就是卷积核在图像上移动的步幅&#xff0c;每次移动一个方格则步幅为1。且一般为1。 若…

vue3中ref和reactive联系与区别以及如何选择

vue3中ref和reactive区别与联系 区别 1、ref既可定义基本数据类型&#xff0c;也可以定义引用数据类型&#xff0c;reactive只能定义应用数据类型 2、ref在js中取响应值需要使用 .value&#xff0c;而reactive则直接取用既可 3、ref定义的对象通过.value重新分配新对象时依旧…

大模型日报-20240111

AI 浪潮席卷 CES 2024&#xff0c;英伟达股价创历史新高&#xff01;二季度量产国内特供 H20 芯片 https://mp.weixin.qq.com/s/3E0xD4VhP0PMSXjPbJPb-A 本周一&#xff0c;NVIDIA 在 CES 开幕前举行的重磅演讲中&#xff0c;重点介绍了生成式 AI 模型及其在创造逼真角色方面的…

数据库设计规范[掌握好规范,设计出的表一般不会差]

数据库设计 命名规范 数据库表名、字段名、索引名等都要命名规范&#xff0c;可读性高&#xff08;一般要求用英文&#xff09;&#xff0c;让别人一看命名&#xff0c;就知道这个字段表示什么意思 user_name, user_age 表名&#xff0c;字段名必须使用小写字母或者数字&am…

element ui el-table展示列表,结合分页+过滤功能

vueelement-ui实现的列表展示&#xff0c;列表分页&#xff0c;列表筛选功能 1&#xff0c;分页器 el-table模块下面是分页器代码 <el-pagination></el-pagination> <el-table></el-table> <!-- 分页器 --><div class"block" st…

P4学习(一) 环境搭建

系列文章目录 第一章 P4学习入门之虚拟机环境搭建 文章目录 系列文章目录前言一、P4是什么&#xff1f;二、搭建步骤1.下载虚拟机镜像2.虚拟机管理软件载入镜像2.1 找到你镜像的所在位置2.2 打开VMware Workstation2.3 载入镜像 3.检验环境是否配置成功 P4 的真机环境搭建 前言…

【无标题】山姆奥特曼喊话AI创业者

这里写自定山姆奥特曼充满激情地向创业者们发出呼吁&#xff0c;他表示AI是一个可以媲美互联网早期机遇的巨大机会。与此相关的人士认为&#xff0c;现在是互联网和移动互联网创业者们行动起来的时候了&#xff01;他们应该全面拥抱大模型的应用层创业。第一波红利期在6-8个月内…

中国大学生计算机设计大赛—人工智能实践赛赛道—赛后感想

1.比赛介绍 中国大学生计算机设计大赛是我国高校面向本科生最早的赛事之一&#xff0c;是全国普通高校大学生竞赛排行榜榜单赛事之一。自2008年开赛至2019年&#xff0c;一直由教育部高校与计算机相关教指委等或独立或联合主办。大赛的目的是以赛促学、以赛促教、以赛促创&…