soul网关源码解析-数据同步

简单描述

soul的数据同步分为2种方式

  1. Soul 网关在启动时会从从配置服务同步配置数据,并且支持推拉模式获取配置变更信息,并且更新本地缓存
  2. 管理后台发生变更通过推拉模式同步数据到网关.
    在这里插入图片描述

soul如何实现同步

soul为了实现解耦采用的是spring事件监听机制 也就是观察者模式的一种实现.

Spring实现机制的主要相关类
1.ApplicationEventPublisher:发布事件;
2.ApplicationEvent:Spring 事件,记录事件源、时间和数据;
3.ApplicationListener:事件监听者,观察者;

soul发布事件

这里我主要看下插件的数据同步(其他数据的同步类似)
soul通过ApplicationEventPublisherpublishEvent方法发布需要变更的数据.

soul事件的实现

类 DataChangedEvent事件的信息.

public class DataChangedEvent extends ApplicationEvent {

    private DataEventTypeEnum eventType;

    private ConfigGroupEnum groupKey;

    /**
     * Instantiates a new Data changed event.
     *
     * @param groupKey the group key
     * @param type     the type
     * @param source   the source
     */
    public DataChangedEvent(final ConfigGroupEnum groupKey, final DataEventTypeEnum type, final List<?> source) {
        super(source);
        this.eventType = type;
        this.groupKey = groupKey;
    }

    /**
     * Gets event type.
     *
     * @return the event type
     */
    DataEventTypeEnum getEventType() {
        return eventType;
    }

    @Override
    public List<?> getSource() {
        return (List<?>) super.getSource();
    }

    /**
     * Gets group key.
     *
     * @return the group key
     */
    public ConfigGroupEnum getGroupKey() {
        return this.groupKey;
    }

}

从这类中我们可以看出主要包含的信息

1.groupKey(指定同步数据的分组ConfigGroupEnum(包含了选择器SELECTOR,规则RULE等))
2.eventType(指定操作的类型DataEventTypeEnum(包含了新增CREATE,更新UPDATE等))
3.List<?> source(我们需要操作的数据)

soul监听者实现

通过DataChangedEventDispatcher进行转发
先看下类的关系图在这里插入图片描述

public class DataChangedEventDispatcher implements ApplicationListener<DataChangedEvent>, InitializingBean {

    private ApplicationContext applicationContext;

	//注册的监听者
    private List<DataChangedListener> listeners;

    public DataChangedEventDispatcher(final ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Override
    @SuppressWarnings("unchecked")
    public void onApplicationEvent(final DataChangedEvent event) {
        for (DataChangedListener listener : listeners) {
            switch (event.getGroupKey()) {
                case APP_AUTH:
                    listener.onAppAuthChanged((List<AppAuthData>) event.getSource(), event.getEventType());
                    break;
                case PLUGIN:
                    listener.onPluginChanged((List<PluginData>) event.getSource(), event.getEventType());
                    break;
                case RULE:
                    listener.onRuleChanged((List<RuleData>) event.getSource(), event.getEventType());
                    break;
                case SELECTOR:
                    listener.onSelectorChanged((List<SelectorData>) event.getSource(), event.getEventType());
                    break;
                case META_DATA:
                    listener.onMetaDataChanged((List<MetaData>) event.getSource(), event.getEventType());
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + event.getGroupKey());
            }
        }
    }

    @Override
    public void afterPropertiesSet() {
        Collection<DataChangedListener> listenerBeans = applicationContext.getBeansOfType(DataChangedListener.class).values();
        this.listeners = Collections.unmodifiableList(new ArrayList<>(listenerBeans));
    }

}

我们可以看到变量里保存了监听者的信息
private List listeners;
事件有改动的时候就会循环通知监听者

监听者如果注册的

在这里soul采用了spring注册最简单的方式,
把监听器部署到ApplicationContext,实际上就是将将监听器交给Spring 容器管理,所以最简单的方法只需在自定义的上加上@Component注解

soul如果通过配置yml文件实现不同注册监听者

这里我们可以看下DataSyncConfiguration类中实现
我们可以看到实现了不同监听者的配置.
通过@ConditionalOnProperty注解中是否包含的信息来判断这个配置注解是否生效.

    @Configuration
    @ConditionalOnProperty(name = "soul.sync.http.enabled", havingValue = "true")
    @EnableConfigurationProperties(HttpSyncProperties.class)
    static class HttpLongPollingListener {

        @Bean
        @ConditionalOnMissingBean(HttpLongPollingDataChangedListener.class)
        public HttpLongPollingDataChangedListener httpLongPollingDataChangedListener(final HttpSyncProperties httpSyncProperties) {
            return new HttpLongPollingDataChangedListener(httpSyncProperties);
        }

    }

至此已经完成了数据同步的简单分析.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值