记一次gateway+nacos 实现动态路由时报java.util.ConcurrentModificationExceptioni ConcurrentModificationEx null 错误

实现代码如下

package demo.assets.gateway.service;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 动态更新路由网关service
 * 1)实现一个Spring提供的事件推送接口ApplicationEventPublisherAware
 * 2)提供动态路由的基础方法,可通过获取bean操作该类的方法。该类提供新增路由、更新路由、删除路由,然后实现发布的功能。
 */
@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) {
        publisher = applicationEventPublisher;
    }

    /**
     * 删除路由
     * @param id
     * @return
     */
    public String delete(String id) {
        try {
            log.info("gateway delete route id {}",id);
            this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
            publisher.publishEvent(new RefreshRoutesEvent(this));
            return "delete success";
        } catch (Exception e) {
            return "delete fail";
        }
    }
    /**
     * 更新路由
     * @param definitions
     * @return
     */
    public String updateList(List<RouteDefinition> definitions) {
        log.info("gateway update route {}",definitions);
        // 删除缓存routerDefinition
        List<RouteDefinition> routeDefinitionsExits =  routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst();
        if (!CollectionUtils.isEmpty(routeDefinitionsExits)) {
            routeDefinitionsExits.forEach(routeDefinition -> {
                log.info("delete routeDefinition:{}", routeDefinition);
                delete(routeDefinition.getId());
            });
        }
        definitions.forEach(definition -> {
            updateById(definition);
        });
        return "success";
    }

    /**
     * 更新路由
     * @param definition
     * @return
     */
    public String updateById(RouteDefinition definition) {
        try {
            log.info("gateway update route {}",definition);
            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();
            publisher.publishEvent(new RefreshRoutesEvent(this));
            return "success";
        } catch (Exception e) {
            return "update route fail";
        }
    }

    /**
     * 增加路由
     * @param definition
     * @return
     */
    public String add(RouteDefinition definition) {
        try {
            log.info("gateway add route {}",new RefreshRoutesEvent(this));
            routeDefinitionWriter.delete(Mono.just(definition.getId()));
            routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            publisher.publishEvent(new RefreshRoutesEvent(this));
            return "success";
        } catch (Exception e){
//            e.printStackTrace();
            log.error("gateway add route error:{}",definition.getId());
        }
        return "fail";
    }
}

具体报错如下: 

reactor.core.Exceptions$ErrorCallbackNotImplemented: java.util.ConcurrentModificationException
Caused by: java.util.ConcurrentModificationException: null
	at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:711) ~[na:1.8.0_91]
	at java.util.LinkedHashMap$LinkedValueIterator.next(LinkedHashMap.java:739) ~[na:1.8.0_91]
	at reactor.core.publisher.FluxIterable$IterableSubscription.poll(FluxIterable.java:415) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxMergeSequential$MergeSequentialMain.drain(FluxMergeSequential.java:399) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxMergeSequential$MergeSequentialMain.innerComplete(FluxMergeSequential.java:321) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxMergeSequential$MergeSequentialInner.onComplete(FluxMergeSequential.java:576) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:160) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onComplete(FluxMap.java:262) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxFilter$FilterConditionalSubscriber.onComplete(FluxFilter.java:293) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:838) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:600) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.innerComplete(FluxFlatMap.java:909) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxFlatMap$FlatMapInner.onComplete(FluxFlatMap.java:1013) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1765) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxFirstNonEmptyEmitting$FirstNonEmptyEmittingSubscriber.onComplete(FluxFirstNonEmptyEmitting.java:333) ~[spring-cloud-commons-2.2.3.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxSubscribeOn$SubscribeOnSubscriber.onComplete(FluxSubscribeOn.java:159) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxIterable$IterableSubscription.fastPath(FluxIterable.java:357) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:222) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxSubscribeOn$SubscribeOnSubscriber.requestUpstream(FluxSubscribeOn.java:124) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxSubscribeOn$SubscribeOnSubscriber.onSubscribe(FluxSubscribeOn.java:117) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:161) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.Flux.subscribe(Flux.java:8325) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:199) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.MonoFlatMapMany.subscribeOrReturn(MonoFlatMapMany.java:49) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxFromMonoOperator.subscribe(FluxFromMonoOperator.java:76) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.publisher.FluxSubscribeOn$SubscribeOnSubscriber.run(FluxSubscribeOn.java:187) ~[reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84) [reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE]
	at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37) [reactor-core-3.3.11.RELEASE.jar:3.3.11.RELEASE

经过调试最终发现报错代码为下面几处发布事件的代码中:

 

 百度无果,然后自己尝试调整代码,解决报错问题,

解决方案是把发布事件的代码移到循环之外,循环完之后再发布更新事件

修改代码如下,所有发布事件的地方修改方法同理

 全部改完之后运行重启gateway,运行结果如下

 gateway运行正常,不再报

2022-08-05 17:32:05.756 ERROR 22360 --- [oundedElastic-2] reactor.core.scheduler.Schedulers        : Scheduler worker in group main failed with an uncaught exception

reactor.core.Exceptions$ErrorCallbackNotImplemented: java.util.ConcurrentModificationException
Caused by: java.util.ConcurrentModificationException: null 错误

至此问题解决,在此记录下,希望能帮到遇到同样问题的小伙伴们,小白初学,这个问题的具体原因不详,还请知道的大佬指点

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值