1、网站建设定制开发准备一个环境跟一个普普通通的Spring Cloud项目
2、导包,网站建设定制开发我这里是把Nacos网站建设定制开发的注册中心跟配置中心都搞了,网站建设定制开发动态配置的话主要是用到配置中心,主要是这几个包,部分工具类的包或者是spring cloud的其他包就忽略了。
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
- <version>2021.1</version>
- </dependency>
-
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
- <version>2021.1</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-loadbalancer</artifactId>
- </dependency>
-
- <!-- spring-cloud-starter-gateway:路由转发、请求过滤(权限校验、限流以及监控等)-->
- <!-- spring-boot-starter-webflux:反应式Web框架-->
- <!-- spring-boot-starter-actuator:监控系统健康-->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-gateway</artifactId>
- <version>2.2.9.RELEASE</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>5.2.7.RELEASE</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-webflux</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.8</version>
- </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
- spring:
- freemarker:
- check-template-location: false
- profiles:
- active: dev
- jackson:
- time-zone: GMT+8
- application:
- name: gateway-router
- datasource:
- druid:
- test-on-borrow=true:
- cloud:
- nacos:
- #这个是注册中心
- discovery:
- server-addr: 192.168.2.200:8848
- service: gateway-router
- #这个才是配置中心
- config:
- server-addr: 192.168.2.200:8848
- name: gateway-router
- namespace: public
- group: DEFAULT_GROUP
- loadbalancer:
- ribbon:
- enabled: false
如果发现Nacos的心跳日志一直打,很烦人的话,可以加上这句屏蔽掉
- logging:
- level:
- com.alibaba.nacos.client.config.impl: WARN
4、application启动类记得加上标注
@EnableDiscoveryClient
5、配置读取类GatewayConfig,与上方的配置项对应,不要漏,会报错。
- @Configuration
- @Slf4j
- public class GatewayConfig {
- public static final long DEFAULT_TIMEOUT = 30000;
-
- public static String NACOS_SERVER_ADDR;
-
- public static String NACOS_NAMESPACE;
-
- public static String NACOS_ROUTE_DATA_ID;
-
- public static String NACOS_ROUTE_GROUP;
-
- @Value("${spring.cloud.nacos.config.server-addr}")
- public void setNacosServerAddr(String nacosServerAddr) {
- NACOS_SERVER_ADDR = nacosServerAddr;
- }
-
- @Value("${spring.cloud.nacos.config.namespace}")
- public void setNacosNamespace(String nacosNamespace) {
- NACOS_NAMESPACE = nacosNamespace;
- }
-
- @Value("${spring.cloud.nacos.config.name}")
- public void setNacosRouteDataId(String nacosRouteDataId) {
- NACOS_ROUTE_DATA_ID = nacosRouteDataId;
- }
-
- @Value("${spring.cloud.nacos.config.group}")
- public void setNacosRouteGroup(String nacosRouteGroup) {
- NACOS_ROUTE_GROUP = nacosRouteGroup;
- }
- }
6、动态路由基础控制类DynamicRouteServiceImpl,我抄过来的时候是带log代码的,这里我都去掉了,自己加就好。
- @Slf4j
- @Service
- public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
- @Autowired
- private RouteDefinitionWriter routeDefinitionWriter;
- @Autowired
- private RouteDefinitionLocator routeDefinitionLocator;
-
- /**
- * 发布事件
- */
- @Autowired
- private ApplicationEventPublisher publisher;
-
- @Override
- public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
- this.publisher = applicationEventPublisher;
- }
-
- /**
- * 删除路由
- * @param id
- * @return
- */
- public String delete(String id) {
- try {
- this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
- this.publisher.publishEvent(new RefreshRoutesEvent(this));
- return "delete success";
- } catch (Exception e) {
- return "delete fail";
- }
- }
-
- /**
- * 更新路由
- * @param definitions
- * @return
- */
- public String updateList(List<RouteDefinition> definitions) {
- // 删除缓存routerDefinition
- List<RouteDefinition> routeDefinitionsExits = routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst();
- if (!CollectionUtils.isEmpty(routeDefinitionsExits)) {
- routeDefinitionsExits.forEach(routeDefinition -> {
- delete(routeDefinition.getId());
- });
- }
- definitions.forEach(definition -> {
- updateById(definition);
- });
- return "success";
- }
-
- /**
- * 更新路由
- * @param definition
- * @return
- */
- public String updateById(RouteDefinition definition) {
- try {
- this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
- } catch (Exception e) {
- return "update fail,not find route routeId: "+definition.getId();
- }
- try {
- routeDefinitionWriter.save(Mono.just(definition)).subscribe();
- this.publisher.publishEvent(new RefreshRoutesEvent(this));
- return "success";
- } catch (Exception e) {
- return "update route fail";
- }
- }
-
- /**
- * 增加路由
- * @param definition
- * @return
- */
- public String add(RouteDefinition definition) {
- routeDefinitionWriter.save(Mono.just(definition)).subscribe();
- this.publisher.publishEvent(new RefreshRoutesEvent(this));
- return "success";
- }
- }
7、核心注册类DynamicRouteServiceImplByNacos
- @Component
- @Slf4j
- @DependsOn({"gatewayConfig"}) // 依赖于gatewayConfig bean
- public class DynamicRouteServiceImplByNacos {
-
- @Autowired
- private DynamicRouteServiceImpl dynamicRouteService;
-
-
- private ConfigService configService;
-
- @PostConstruct
- public void init() {
- try{
- configService = initConfigService();
- if(configService == null){
- return;
- }
- //从nacos拿初始配置
- String configInfo = configService.getConfig(GatewayConfig.NACOS_ROUTE_DATA_ID, GatewayConfig.NACOS_ROUTE_GROUP, GatewayConfig.DEFAULT_TIMEOUT);
- List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
- for(RouteDefinition definition : definitionList){
- dynamicRouteService.add(definition);
- }
- } catch (Exception e) {
- }
- //注册监听,nacos配置有更新的话同步更新一下配置
- dynamicRouteByNacosListener(GatewayConfig.NACOS_ROUTE_DATA_ID,GatewayConfig.NACOS_ROUTE_GROUP);
- }
-
- /**
- * 监听Nacos下发的动态路由配置
- * @param dataId
- * @param group
- */
- public void dynamicRouteByNacosListener (String dataId, String group){
- try {
- configService.addListener(dataId, group, new Listener() {
- @Override
- public void receiveConfigInfo(String configInfo) {
- List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
- dynamicRouteService.updateList(definitionList);
- }
- @Override
- public Executor getExecutor() {
- return null;
- }
- });
- } catch (NacosException e) {
- }
- }
-
- /**
- * 初始化网关路由 nacos config
- * @return
- */
- private ConfigService initConfigService(){
- try{
- Properties properties = new Properties();
- properties.setProperty("serverAddr",GatewayConfig.NACOS_SERVER_ADDR);
- properties.setProperty("namespace",GatewayConfig.NACOS_NAMESPACE);
- return configService= NacosFactory.createConfigService(properties);
- } catch (Exception e) {
- return null;
- }
- }
-
- }
8、Nacos配置
Data ID:gateway-router
//这里是以json的形式,所以直接与服务名称一致即可,如果用的是yml格式,估计得用“${prefix}-${spring.profiles.active}.${file-extension}”格式
Group:DEFAULT_GROUP
配置类型是json,内容:
- [{
- "id": "test-router",
- "order": 0,
- "predicates": [{
- "args": {
- "pattern": "/test/**"
- },
- "name": "Path"
- }],
- "filters":[{
- "args": {
- "_genkey_0":"1"
- },
- "name":"StripPrefix"
- }],
- "uri": "lb://test-service"
- },{
- "id": "baidu-router",
- "order": 2,
- "predicates": [{
- "args": {
- "pattern": "/baidu/**"
- },
- "name": "Path"
- }],
- "uri": "http://baidu.com"
- }]
这里配置了两个路由:
第一个路由是将/test/**规则转发到test-service服务,并且去掉前缀(即:/test/home等同于http://test-service/home)
第二个路由是将/baidu/**规则转发到百度,且不去掉前缀(即:/baidu/home等同于访问http://baidu.com/baidu/home)
9、运行