网站建设定制开发Gateway 网关 (一) Nacos 动态配置路由

1、网站建设定制开发准备一个环境跟一个普普通通的Spring Cloud项目

2、导包,网站建设定制开发我这里是把Nacos网站建设定制开发的注册中心跟配置中心都搞了,网站建设定制开发动态配置的话主要是用到配置中心,主要是这几个包,部分工具类的包或者是spring cloud的其他包就忽略了。

  1. <dependency>
  2. <groupId>com.alibaba.cloud</groupId>
  3. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  4. <version>2021.1</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.alibaba.cloud</groupId>
  8. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  9. <version>2021.1</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.cloud</groupId>
  13. <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  14. </dependency>
  15. <!-- spring-cloud-starter-gateway:路由转发、请求过滤(权限校验、限流以及监控等)-->
  16. <!-- spring-boot-starter-webflux:反应式Web框架-->
  17. <!-- spring-boot-starter-actuator:监控系统健康-->
  18. <dependency>
  19. <groupId>org.springframework.cloud</groupId>
  20. <artifactId>spring-cloud-starter-gateway</artifactId>
  21. <version>2.2.9.RELEASE</version>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.springframework</groupId>
  25. <artifactId>spring-webmvc</artifactId>
  26. <version>5.2.7.RELEASE</version>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.springframework.boot</groupId>
  30. <artifactId>spring-boot-starter-webflux</artifactId>
  31. </dependency>
  32. <dependency>
  33. <groupId>com.alibaba</groupId>
  34. <artifactId>fastjson</artifactId>
  35. <version>1.2.8</version>
  36. </dependency>

导包说明:spring-boot-starter-web包跟gateway的包是有冲突的,所以这玩意不能要,有的记得删掉。

另外gateway+spring boot +spring cloud 的版本都是挂钩的,随便搞版本的话,大概率是要交学费的。

我这里spring boot的版本是2.3.12.RELEASE,spring cloud的版本是Hoxton.SR12,gateway的版本是2.2.9.RELEASE,仅供参考,具体可以搜一下,有对照表的。

3、配置,这里不作说明了,具体含义可以查看官网:nacos.io

  1. spring:
  2. freemarker:
  3. check-template-location: false
  4. profiles:
  5. active: dev
  6. jackson:
  7. time-zone: GMT+8
  8. application:
  9. name: gateway-router
  10. datasource:
  11. druid:
  12. test-on-borrow=true:
  13. cloud:
  14. nacos:
  15. #这个是注册中心
  16. discovery:
  17. server-addr: 192.168.2.200:8848
  18. service: gateway-router
  19. #这个才是配置中心
  20. config:
  21. server-addr: 192.168.2.200:8848
  22. name: gateway-router
  23. namespace: public
  24. group: DEFAULT_GROUP
  25. loadbalancer:
  26. ribbon:
  27. enabled: false

如果发现Nacos的心跳日志一直打,很烦人的话,可以加上这句屏蔽掉

  1. logging:
  2. level:
  3. com.alibaba.nacos.client.config.impl: WARN

4、application启动类记得加上标注

@EnableDiscoveryClient

5、配置读取类GatewayConfig,与上方的配置项对应,不要漏,会报错。

  1. @Configuration
  2. @Slf4j
  3. public class GatewayConfig {
  4. public static final long DEFAULT_TIMEOUT = 30000;
  5. public static String NACOS_SERVER_ADDR;
  6. public static String NACOS_NAMESPACE;
  7. public static String NACOS_ROUTE_DATA_ID;
  8. public static String NACOS_ROUTE_GROUP;
  9. @Value("${spring.cloud.nacos.config.server-addr}")
  10. public void setNacosServerAddr(String nacosServerAddr) {
  11. NACOS_SERVER_ADDR = nacosServerAddr;
  12. }
  13. @Value("${spring.cloud.nacos.config.namespace}")
  14. public void setNacosNamespace(String nacosNamespace) {
  15. NACOS_NAMESPACE = nacosNamespace;
  16. }
  17. @Value("${spring.cloud.nacos.config.name}")
  18. public void setNacosRouteDataId(String nacosRouteDataId) {
  19. NACOS_ROUTE_DATA_ID = nacosRouteDataId;
  20. }
  21. @Value("${spring.cloud.nacos.config.group}")
  22. public void setNacosRouteGroup(String nacosRouteGroup) {
  23. NACOS_ROUTE_GROUP = nacosRouteGroup;
  24. }
  25. }

6、动态路由基础控制类DynamicRouteServiceImpl,我抄过来的时候是带log代码的,这里我都去掉了,自己加就好。

  1. @Slf4j
  2. @Service
  3. public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
  4. @Autowired
  5. private RouteDefinitionWriter routeDefinitionWriter;
  6. @Autowired
  7. private RouteDefinitionLocator routeDefinitionLocator;
  8. /**
  9. * 发布事件
  10. */
  11. @Autowired
  12. private ApplicationEventPublisher publisher;
  13. @Override
  14. public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
  15. this.publisher = applicationEventPublisher;
  16. }
  17. /**
  18. * 删除路由
  19. * @param id
  20. * @return
  21. */
  22. public String delete(String id) {
  23. try {
  24. this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
  25. this.publisher.publishEvent(new RefreshRoutesEvent(this));
  26. return "delete success";
  27. } catch (Exception e) {
  28. return "delete fail";
  29. }
  30. }
  31. /**
  32. * 更新路由
  33. * @param definitions
  34. * @return
  35. */
  36. public String updateList(List<RouteDefinition> definitions) {
  37. // 删除缓存routerDefinition
  38. List<RouteDefinition> routeDefinitionsExits = routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst();
  39. if (!CollectionUtils.isEmpty(routeDefinitionsExits)) {
  40. routeDefinitionsExits.forEach(routeDefinition -> {
  41. delete(routeDefinition.getId());
  42. });
  43. }
  44. definitions.forEach(definition -> {
  45. updateById(definition);
  46. });
  47. return "success";
  48. }
  49. /**
  50. * 更新路由
  51. * @param definition
  52. * @return
  53. */
  54. public String updateById(RouteDefinition definition) {
  55. try {
  56. this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
  57. } catch (Exception e) {
  58. return "update fail,not find route routeId: "+definition.getId();
  59. }
  60. try {
  61. routeDefinitionWriter.save(Mono.just(definition)).subscribe();
  62. this.publisher.publishEvent(new RefreshRoutesEvent(this));
  63. return "success";
  64. } catch (Exception e) {
  65. return "update route fail";
  66. }
  67. }
  68. /**
  69. * 增加路由
  70. * @param definition
  71. * @return
  72. */
  73. public String add(RouteDefinition definition) {
  74. routeDefinitionWriter.save(Mono.just(definition)).subscribe();
  75. this.publisher.publishEvent(new RefreshRoutesEvent(this));
  76. return "success";
  77. }
  78. }

7、核心注册类DynamicRouteServiceImplByNacos

  1. @Component
  2. @Slf4j
  3. @DependsOn({"gatewayConfig"}) // 依赖于gatewayConfig bean
  4. public class DynamicRouteServiceImplByNacos {
  5. @Autowired
  6. private DynamicRouteServiceImpl dynamicRouteService;
  7. private ConfigService configService;
  8. @PostConstruct
  9. public void init() {
  10. try{
  11. configService = initConfigService();
  12. if(configService == null){
  13. return;
  14. }
  15. //从nacos拿初始配置
  16. String configInfo = configService.getConfig(GatewayConfig.NACOS_ROUTE_DATA_ID, GatewayConfig.NACOS_ROUTE_GROUP, GatewayConfig.DEFAULT_TIMEOUT);
  17. List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
  18. for(RouteDefinition definition : definitionList){
  19. dynamicRouteService.add(definition);
  20. }
  21. } catch (Exception e) {
  22. }
  23. //注册监听,nacos配置有更新的话同步更新一下配置
  24. dynamicRouteByNacosListener(GatewayConfig.NACOS_ROUTE_DATA_ID,GatewayConfig.NACOS_ROUTE_GROUP);
  25. }
  26. /**
  27. * 监听Nacos下发的动态路由配置
  28. * @param dataId
  29. * @param group
  30. */
  31. public void dynamicRouteByNacosListener (String dataId, String group){
  32. try {
  33. configService.addListener(dataId, group, new Listener() {
  34. @Override
  35. public void receiveConfigInfo(String configInfo) {
  36. List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
  37. dynamicRouteService.updateList(definitionList);
  38. }
  39. @Override
  40. public Executor getExecutor() {
  41. return null;
  42. }
  43. });
  44. } catch (NacosException e) {
  45. }
  46. }
  47. /**
  48. * 初始化网关路由 nacos config
  49. * @return
  50. */
  51. private ConfigService initConfigService(){
  52. try{
  53. Properties properties = new Properties();
  54. properties.setProperty("serverAddr",GatewayConfig.NACOS_SERVER_ADDR);
  55. properties.setProperty("namespace",GatewayConfig.NACOS_NAMESPACE);
  56. return configService= NacosFactory.createConfigService(properties);
  57. } catch (Exception e) {
  58. return null;
  59. }
  60. }
  61. }

8、Nacos配置

Data ID:gateway-router 

//这里是以json的形式,所以直接与服务名称一致即可,如果用的是yml格式,估计得用“${prefix}-${spring.profiles.active}.${file-extension}”格式

Group:DEFAULT_GROUP

配置类型是json,内容:

  1. [{
  2. "id": "test-router",
  3. "order": 0,
  4. "predicates": [{
  5. "args": {
  6. "pattern": "/test/**"
  7. },
  8. "name": "Path"
  9. }],
  10. "filters":[{
  11. "args": {
  12. "_genkey_0":"1"
  13. },
  14. "name":"StripPrefix"
  15. }],
  16. "uri": "lb://test-service"
  17. },{
  18. "id": "baidu-router",
  19. "order": 2,
  20. "predicates": [{
  21. "args": {
  22. "pattern": "/baidu/**"
  23. },
  24. "name": "Path"
  25. }],
  26. "uri": "http://baidu.com"
  27. }]

这里配置了两个路由:

第一个路由是将/test/**规则转发到test-service服务,并且去掉前缀(即:/test/home等同于http://test-service/home)

第二个路由是将/baidu/**规则转发到百度,且不去掉前缀(即:/baidu/home等同于访问http://baidu.com/baidu/home)

9、运行

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发